diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-06-06 16:17:58 +0300 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-06-06 16:17:58 +0300 |
commit | 54729bbc60045fa86d0a2a2bcc0119fb9da204f5 (patch) | |
tree | e7595cefaa0afdcedf56e8168738706d0b83f841 | |
parent | dfd4dd67c5e27865035702ddce998eaebf285381 (diff) | |
parent | ec8b38b7bd6762164c268f84489dc7ea538feb77 (diff) | |
download | mariadb-git-54729bbc60045fa86d0a2a2bcc0119fb9da204f5.tar.gz |
merged mysql-5.5->mysql-5.5-security
243 files changed, 7888 insertions, 1383 deletions
diff --git a/.bzrignore b/.bzrignore index 05597220950..a851f547392 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3129,3 +3129,7 @@ libmysqld/examples/mysql_embedded sql/.empty mysys/thr_lock VERSION.dep +info_macros.cmake +Docs/INFO_BIN +Docs/INFO_SRC +Testing diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index c7f434d1bb3..00bd4965f87 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (C) 2000, 2007 MySQL AB +# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -250,7 +250,7 @@ gcov_compile_flags="$gcov_compile_flags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov" gcov_link_flags="-fprofile-arcs -ftest-coverage" -gcov_configs="--disable-shared" +gcov_configs="--with-gcov" # gprof diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index ca77dfb84d7..9791ac04f22 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -293,7 +293,8 @@ extended_usage() version string suffix: [none] All packages except Classic include support for user-defined - partitioning. + partitioning. All packages include support for Performance + Schema. If --with-debug is used, an additional "-debug" is appended to the version string. diff --git a/CMakeLists.txt b/CMakeLists.txt index 235a65a6437..6766f76c665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,6 +172,13 @@ IF(ENABLE_DEBUG_SYNC) SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC") ENDIF() +OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF) +IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE) + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov") +ENDIF() + OPTION(ENABLED_LOCAL_INFILE "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE) diff --git a/client/mysql.cc b/client/mysql.cc index 5f33cad6dba..671c9ef59b9 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1564,11 +1564,11 @@ static struct my_option my_long_options[] = &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index b364acd5e61..2f8c108f15a 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -92,7 +92,7 @@ static struct my_option my_long_options[]= 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " "has already been executed for the current version of MySQL.", @@ -109,7 +109,7 @@ static struct my_option my_long_options[]= GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 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, " diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 82cea8e78c9..8826b6713be 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -206,11 +206,11 @@ static struct my_option my_long_options[] = &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG, SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index b374fa748b9..d19f6253eb2 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1052,7 +1052,7 @@ static struct my_option my_long_options[] = 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"disable-log-bin", 'D', "Disable binary log. This is useful, if you " "enabled --to-last-log and are sending the output to the same MySQL server. " @@ -1080,7 +1080,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to connect to remote server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 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, " diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 78a1ec7d87d..7765cde6692 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -102,7 +102,7 @@ static struct my_option my_long_options[] = &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"fast",'F', "Check only tables that haven't been closed properly.", &opt_fast, &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, @@ -142,7 +142,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 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, " diff --git a/client/mysqldump.c b/client/mysqldump.c index 90d63bff8e7..61bab7c54cc 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -501,11 +501,11 @@ static struct my_option my_long_options[] = {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 7966766c1eb..7862f8f794f 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -93,7 +93,7 @@ static struct my_option my_long_options[] = 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"delete", 'd', "First delete all rows from table.", &opt_delete, &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -145,7 +145,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 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, " diff --git a/client/mysqlshow.c b/client/mysqlshow.c index f8a32aae2c0..ad31c982d02 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -191,7 +191,7 @@ static struct my_option my_long_options[] = 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 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}, @@ -207,7 +207,7 @@ static struct my_option my_long_options[] = "solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 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, " diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 88e80c0c7f8..393cbb0ed89 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -590,7 +590,7 @@ static struct my_option my_long_options[] = &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", 'F', "Delimiter to use in SQL statements supplied in file or command line.", @@ -634,7 +634,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a6bd80059c1..77289b3380f 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6423,7 +6423,7 @@ static struct my_option my_long_options[] = &opt_connect_timeout, &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG, 120, 0, 3600 * 12, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/cmake/configure.pl b/cmake/configure.pl index b24afa034c7..bf872264953 100644 --- a/cmake/configure.pl +++ b/cmake/configure.pl @@ -190,6 +190,11 @@ foreach my $option (@ARGV) $cmakeargs = $cmakeargs." \"-DWITH_COMMENT=".substr($option,13)."\""; next; } + if ($option =~ /with-gcov/) + { + $cmakeargs = $cmakeargs." -DENABLE_GCOV=ON"; + next; + } $option = uc($option); $option =~ s/-/_/g; diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 601e208d96d..bbf29c2e46c 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -99,6 +99,13 @@ IF(UNIX) ENDIF() # +# plugin_tests's value should not be used by imported plugins, +# just use if(INSTALL_PLUGINTESTDIR). +# The plugin must set its own install path for tests +# +FILE(GLOB plugin_tests ${CMAKE_SOURCE_DIR}/plugin/*/tests) + +# # STANDALONE layout # SET(INSTALL_BINDIR_STANDALONE "bin") @@ -122,6 +129,7 @@ SET(INSTALL_SQLBENCHDIR_STANDALONE ".") SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") # SET(INSTALL_MYSQLDATADIR_STANDALONE "data") +SET(INSTALL_PLUGINTESTDIR_STANDALONE ${plugin_tests}) # # RPM layout @@ -152,6 +160,7 @@ SET(INSTALL_SQLBENCHDIR_RPM "") SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") # SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") +SET(INSTALL_PLUGINTESTDIR_RPM ${plugin_tests}) # # DEB layout @@ -177,6 +186,7 @@ SET(INSTALL_SQLBENCHDIR_DEB ".") SET(INSTALL_SUPPORTFILESDIR_DEB "support-files") # SET(INSTALL_MYSQLDATADIR_DEB "data") +SET(INSTALL_PLUGINTESTDIR_DEB ${plugin_tests}) # # SVR4 layout @@ -202,6 +212,7 @@ SET(INSTALL_SQLBENCHDIR_SVR4 ".") SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") # SET(INSTALL_MYSQLDATADIR_SVR4 "/var/lib/mysql") +SET(INSTALL_PLUGINTESTDIR_SVR4 ${plugin_tests}) # Clear cached variables if install layout was changed @@ -216,7 +227,7 @@ SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "") # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE # layout is chosen) FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN - INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA) + INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST) SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} CACHE STRING "${var} installation directory" ${FORCE}) MARK_AS_ADVANCED(INSTALL_${var}DIR) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 477fd1d2b88..68bbb337e15 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -341,6 +341,7 @@ SET(SIGNAL_RETURN_TYPE_IS_VOID 1 CACHE INTERNAL "") SET(C_HAS_inline CACHE INTERNAL "") SET(C_HAS___inline 1 CACHE INTERNAL "") SET(FIONREAD_IN_SYS_IOCTL CACHE INTERNAL "") +SET(FIONREAD_IN_SYS_FILIO CACHE INTERNAL "") SET(GWINSZ_IN_SYS_IOCTL CACHE INTERNAL "") SET(HAVE_CXXABI_H CACHE INTERNAL "") SET(HAVE_NDIR_H CACHE INTERNAL "") diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index c6dd3fc451f..376dd84fc38 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. # # 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 @@ -27,6 +27,23 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) # [LINK_LIBRARIES lib1...libN] # [DEPENDENCIES target1...targetN] +# Append collections files for the plugin to the common files +# Make sure we don't copy twice if running cmake again + +MACRO(PLUGIN_APPEND_COLLECTIONS plugin) + SET(fcopied "${CMAKE_CURRENT_SOURCE_DIR}/tests/collections/FilesCopied") + IF(EXISTS ${fcopied}) + RETURN() + ENDIF() + FILE(GLOB collections ${CMAKE_CURRENT_SOURCE_DIR}/tests/collections/*) + FOREACH(cfile ${collections}) + FILE(READ ${cfile} contents) + GET_FILENAME_COMPONENT(fname ${cfile} NAME) + FILE(APPEND ${CMAKE_SOURCE_DIR}/mysql-test/collections/${fname} "${contents}") + FILE(APPEND ${fcopied} "${fname}\n") + ENDFOREACH() +ENDMACRO() + MACRO(MYSQL_ADD_PLUGIN) MYSQL_PARSE_ARGUMENTS(ARG "LINK_LIBRARIES;DEPENDENCIES;MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME" @@ -180,6 +197,10 @@ MACRO(MYSQL_ADD_PLUGIN) # Install dynamic library MYSQL_INSTALL_TARGETS(${target} DESTINATION ${INSTALL_PLUGINDIR} COMPONENT Server) INSTALL_DEBUG_TARGET(${target} DESTINATION ${INSTALL_PLUGINDIR}/debug) + # For internal testing in PB2, append collections files + IF(DEFINED ENV{PB2WORKDIR}) + PLUGIN_APPEND_COLLECTIONS(${plugin}) + ENDIF() ELSE() IF(WITHOUT_${plugin}) # Update cache variable diff --git a/configure.cmake b/configure.cmake index 77d8b9e1faa..0014c1d7b49 100644 --- a/configure.cmake +++ b/configure.cmake @@ -345,6 +345,7 @@ CHECK_FUNCTION_EXISTS (fconvert HAVE_FCONVERT) CHECK_FUNCTION_EXISTS (fdatasync HAVE_FDATASYNC) CHECK_SYMBOL_EXISTS(fdatasync "unistd.h" HAVE_DECL_FDATASYNC) CHECK_FUNCTION_EXISTS (fesetround HAVE_FESETROUND) +CHECK_FUNCTION_EXISTS (fedisableexcept HAVE_FEDISABLEEXCEPT) CHECK_FUNCTION_EXISTS (fpsetmask HAVE_FPSETMASK) CHECK_FUNCTION_EXISTS (fseeko HAVE_FSEEKO) CHECK_FUNCTION_EXISTS (fsync HAVE_FSYNC) diff --git a/include/my_base.h b/include/my_base.h index 347bda01bef..17c8e833be9 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -446,7 +446,8 @@ enum ha_base_keytype { #define HA_ERR_FILE_TOO_SHORT 175 /* File too short */ #define HA_ERR_WRONG_CRC 176 /* Wrong CRC on page */ #define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */ -#define HA_ERR_LAST 177 /* Copy of last error nr */ +#define HA_ERR_INDEX_COL_TOO_LONG 178 /* Index column length exceeds limit */ +#define HA_ERR_LAST 178 /* Copy of last error nr */ /* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/include/my_compiler.h b/include/my_compiler.h index 5f898621159..e3ff80fad40 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -140,6 +140,14 @@ struct my_aligned_storage #endif /* __cplusplus */ +# ifndef MY_ALIGNED +/* + Make sure MY_ALIGNED can be used also on platforms where we don't + have a way of aligning data structures. +*/ +#define MY_ALIGNED(size) +#endif + #include <my_attribute.h> #endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_getopt.h b/include/my_getopt.h index 47feb21d85e..6c1db277db8 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2004 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _my_getopt_h #define _my_getopt_h @@ -86,7 +86,9 @@ struct my_option typedef my_bool (*my_get_one_option)(int, const struct my_option *, char *); -typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...); +typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...) + ATTRIBUTE_FORMAT_FPTR(printf, 2, 3); + /** Used to retrieve a reference to the object (variable) that holds the value for the given option. For example, if var_type is GET_UINT, the function diff --git a/include/my_sys.h b/include/my_sys.h index f0b2c1a0636..e13ef1af067 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -627,6 +627,8 @@ extern FILE *my_freopen(const char *path, const char *mode, FILE *stream); extern int my_fclose(FILE *fd,myf MyFlags); extern File my_fileno(FILE *fd); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); +extern void thr_set_sync_wait_callback(void (*before_sync)(void), + void (*after_sync)(void)); extern int my_sync(File fd, myf my_flags); extern int my_sync_dir(const char *dir_name, myf my_flags); extern int my_sync_dir_by_file(const char *file_name, myf my_flags); diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h index 8811c832949..5072ad2b44c 100644 --- a/include/mysql/plugin_audit.h +++ b/include/mysql/plugin_audit.h @@ -24,16 +24,7 @@ #define MYSQL_AUDIT_CLASS_MASK_SIZE 1 -#define MYSQL_AUDIT_INTERFACE_VERSION 0x0200 - -/* - The first word in every event class struct indicates the specific - class of the event. -*/ -struct mysql_event -{ - unsigned int event_class; -}; +#define MYSQL_AUDIT_INTERFACE_VERSION 0x0300 /************************************************************************* @@ -55,7 +46,6 @@ struct mysql_event struct mysql_event_general { - unsigned int event_class; unsigned int event_subclass; int general_error_code; unsigned long general_thread_id; @@ -87,7 +77,6 @@ struct mysql_event_general struct mysql_event_connection { - unsigned int event_class; unsigned int event_subclass; int status; unsigned long thread_id; @@ -118,9 +107,9 @@ struct mysql_event_connection waiting for the next query from the client. event_notify() is invoked whenever an event occurs which is of any - class for which the plugin has interest. The first word of the - mysql_event argument indicates the specific event class and the - remainder of the structure is as required for that class. + class for which the plugin has interest. The second argument + indicates the specific event class and the third argument is data + as required for that class. class_mask is an array of bits used to indicate what event classes that this plugin wants to receive. @@ -130,7 +119,7 @@ struct st_mysql_audit { int interface_version; void (*release_thd)(MYSQL_THD); - void (*event_notify)(MYSQL_THD, const struct mysql_event *); + void (*event_notify)(MYSQL_THD, unsigned int, const void *); unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; }; diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 0e5b97d8717..16aaeab21c3 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include <mysql/service_thd_wait.h> typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include <mysql/service_thread_scheduler.h> struct scheduler_functions; @@ -188,13 +195,8 @@ void mysql_query_cache_invalidate4(void* thd, void *thd_get_ha_data(const void* thd, const struct handlerton *hton); void thd_set_ha_data(void* thd, const struct handlerton *hton, const void *ha_data); -struct mysql_event -{ - unsigned int event_class; -}; struct mysql_event_general { - unsigned int event_class; unsigned int event_subclass; int general_error_code; unsigned long general_thread_id; @@ -210,7 +212,6 @@ struct mysql_event_general }; struct mysql_event_connection { - unsigned int event_class; unsigned int event_subclass; int status; unsigned long thread_id; @@ -233,6 +234,6 @@ struct st_mysql_audit { int interface_version; void (*release_thd)(void*); - void (*event_notify)(void*, const struct mysql_event *); + void (*event_notify)(void*, unsigned int, const void *); unsigned long class_mask[1]; }; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 88588d03b9e..e65278c518e 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include <mysql/service_thd_wait.h> typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include <mysql/service_thread_scheduler.h> struct scheduler_functions; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 2c2c1adbf88..c29eac45b19 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include <mysql/service_thd_wait.h> typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include <mysql/service_thread_scheduler.h> struct scheduler_functions; diff --git a/include/mysql/service_thd_wait.h b/include/mysql/service_thd_wait.h index 2a8f5e610a3..f5d2a75f5fc 100644 --- a/include/mysql/service_thd_wait.h +++ b/include/mysql/service_thd_wait.h @@ -50,15 +50,35 @@ extern "C" { #endif +/* + One should only report wait events that could potentially block for a + long time. A mutex wait is too short of an event to report. The reason + is that an event which is reported leads to a new thread starts + executing a query and this has a negative impact of usage of CPU caches + and thus the expected gain of starting a new thread must be higher than + the expected cost of lost performance due to starting a new thread. + + Good examples of events that should be reported are waiting for row locks + that could easily be for many milliseconds or even seconds and the same + holds true for global read locks, table locks and other meta data locks. + Another event of interest is going to sleep for an extended time. +*/ typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(MYSQL_THD, thd_wait_type); + void (*thd_wait_begin_func)(MYSQL_THD, int); void (*thd_wait_end_func)(MYSQL_THD); } *thd_wait_service; @@ -70,7 +90,7 @@ extern struct thd_wait_service_st { #else -void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type); +void thd_wait_begin(MYSQL_THD thd, int wait_type); void thd_wait_end(MYSQL_THD thd); #endif diff --git a/include/mysql/thread_pool_priv.h b/include/mysql/thread_pool_priv.h new file mode 100644 index 00000000000..fc9a2bc6424 --- /dev/null +++ b/include/mysql/thread_pool_priv.h @@ -0,0 +1,121 @@ +/* + Copyright (C) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + + 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 +*/ + +#ifndef THREAD_POOL_PRIV_INCLUDED +#define THREAD_POOL_PRIV_INCLUDED + +/* + The thread pool requires access to some MySQL server error codes, this is + accessed from mysqld_error.h. + We need access to the struct that defines the thread pool plugin interface + which is accessed through scheduler.h. + All accesses to THD variables and functions are defined in this header file. + A thread pool can also use DEBUG_SYNC and must thus include + debug_sync.h + To handle definitions of Information Schema plugins it is also required + to include sql_profile.h and table.h. +*/ +#include <mysqld_error.h> /* To get ER_ERROR_ON_READ */ +#define MYSQL_SERVER 1 +#include <scheduler.h> +#include <debug_sync.h> +#include <sql_profile.h> +#include <table.h> + +/* Needed to get access to scheduler variables */ +void* thd_get_scheduler_data(THD *thd); +void thd_set_scheduler_data(THD *thd, void *data); +PSI_thread* thd_get_psi(THD *thd); +void thd_set_psi(THD *thd, PSI_thread *psi); + +/* Interface to THD variables and functions */ +void thd_set_killed(THD *thd); +void thd_clear_errors(THD *thd); +void thd_set_thread_stack(THD *thd, char *stack_start); +void thd_lock_thread_count(THD *thd); +void thd_unlock_thread_count(THD *thd); +void thd_close_connection(THD *thd); +THD *thd_get_current_thd(); +void thd_new_connection_setup(THD *thd, char *stack_start); +void thd_lock_data(THD *thd); +void thd_unlock_data(THD *thd); +bool thd_is_transaction_active(THD *thd); +int thd_connection_has_data(THD *thd); +void thd_set_net_read_write(THD *thd, uint val); +void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var); +my_socket thd_get_fd(THD *thd); + +/* Print to the MySQL error log */ +void sql_print_error(const char *format, ...); + +/* Store a table record */ +bool schema_table_store_record(THD *thd, TABLE *table); + +/* + The thread pool must be able to execute statements using the connection + state in THD object. This is the main objective of the thread pool to + schedule the start of these commands. +*/ +bool do_command(THD *thd); + +/* + The thread pool requires an interface to the connection logic in the + MySQL Server since the thread pool will maintain the event logic on + the TCP connection of the MySQL Server. Thus new connections, dropped + connections will be discovered by the thread pool and it needs to + ensure that the proper MySQL Server logic attached to these events is + executed. +*/ +/* Initialise a new connection handler thread */ +bool init_new_connection_handler_thread(); +/* Set up connection thread before use as execution thread */ +bool setup_connection_thread_globals(THD *thd); +/* Prepare connection as part of connection set-up */ +bool thd_prepare_connection(THD *thd); +/* Release auditing before executing statement */ +void mysql_audit_release(THD *thd); +/* Check if connection is still alive */ +bool thd_is_connection_alive(THD *thd); +/* Close connection with possible error code */ +void close_connection(THD *thd, uint errcode); +/* End the connection before closing it */ +void end_connection(THD *thd); +/* Cleanup the THD object */ +void thd_cleanup(THD *thd); +/* Decrement connection counter */ +void dec_connection_count(); +/* Destroy THD object */ +void delete_thd(THD *thd); + +/* + thread_created is maintained by thread pool when activated since + user threads are created by the thread pool (and also special + threads to maintain the thread pool). This is done through + inc_thread_created. + + max_connections is needed to calculate the maximum number of threads + that is allowed to be started by the thread pool. The method + get_max_connections() gets reference to this variable. + + connection_attrib is the thread attributes for connection threads, + the method get_connection_attrib provides a reference to these + attributes. +*/ +void inc_thread_created(void); +ulong get_max_connections(void); +pthread_attr_t *get_connection_attrib(void); +#endif diff --git a/include/violite.h b/include/violite.h index 140f021ebb4..ba057028ed2 100644 --- a/include/violite.h +++ b/include/violite.h @@ -134,13 +134,13 @@ struct st_VioSSLFd SSL_CTX *ssl_context; }; -int sslaccept(struct st_VioSSLFd*, Vio *, long timeout); -int sslconnect(struct st_VioSSLFd*, Vio *, long timeout); +int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); +int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); struct st_VioSSLFd *new_VioSSLConnectorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher); + const char *cipher, enum enum_ssl_init_error* error); struct st_VioSSLFd *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file,const char *ca_path, diff --git a/libmysql/authentication_win/plugin_client.cc b/libmysql/authentication_win/plugin_client.cc index 72769ada8f6..30dc5b1493d 100644 --- a/libmysql/authentication_win/plugin_client.cc +++ b/libmysql/authentication_win/plugin_client.cc @@ -20,6 +20,16 @@ #include "common.h" +/* + The following MS C++ specific pragma embeds a comment in the resulting + object file. A "lib" comment tells the linker to use the specified + library, thus the dependency is handled automagically. +*/ + +#ifdef _MSC_VER +#pragma comment(lib, "Secur32") +#endif + static int win_auth_client_plugin_init(char*, size_t, int, va_list) { return 0; diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index b99b3f2de30..a2d066b1eba 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -51,7 +51,7 @@ const char *client_errors[]= "Error on SHOW SLAVE HOSTS:", "Error connecting to slave:", "Error connecting to master:", - "SSL connection error", + "SSL connection error: %-.100s", "Malformed packet", "This client library is licensed only for use with MySQL servers having '%s' license", "Invalid use of null pointer", diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index b07ae1de96b..34f8f685e45 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -50,6 +50,23 @@ extern "C" void unireg_clear(int exit_code) DBUG_VOID_RETURN; } +/* + Wrapper error handler for embedded server to call client/server error + handler based on whether thread is in client/server context +*/ + +static void embedded_error_handler(uint error, const char *str, myf MyFlags) +{ + DBUG_ENTER("embedded_error_handler"); + + /* + If current_thd is NULL, it means restore_global has been called and + thread is in client context, then call client error handler else call + server error handler. + */ + DBUG_RETURN(current_thd ? my_message_sql(error, str, MyFlags): + my_message_stderr(error, str, MyFlags)); +} /* Reads error information from the MYSQL_DATA and puts @@ -106,7 +123,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql->status != MYSQL_STATUS_READY) { set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); - return 1; + result= 1; + goto end; } /* Clear result variables */ @@ -147,6 +165,9 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, #if defined(ENABLED_PROFILING) thd->profiling.finish_current_query(); #endif + +end: + thd->restore_globals(); return result; } @@ -545,7 +566,10 @@ int init_embedded_server(int argc, char **argv, char **groups) return 1; } - error_handler_hook = my_message_sql; + /* + set error_handler_hook to embedded_error_handler wrapper. + */ + error_handler_hook= embedded_error_handler; acl_error= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 5ecc8ef8c64..6ef1a377b6c 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -2,33 +2,27 @@ # in alphabetical order. This also helps with merge conflict resolution. binlog.binlog_multi_engine # joro : NDB tests marked as experimental as agreed with bochklin -binlog.binlog_bug23533 # skozlov: BUG#12371924 funcs_1.charset_collation_1 # depends on compile-time decisions -main.func_math @freebsd # Bug#43020 2010-05-04 alik main.func_math fails on FreeBSD in PB2 -main.gis-rtree @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server -main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_multi_bug38499 times out sporadically -main.outfile_loaddata @solaris # Bug#46895 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) -main.signal_demo3 @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun -main.sp @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun -main.type_float @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server -main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeout fails on OpenSolaris +main.func_math @freebsd # Bug#11751977 2010-05-04 alik main.func_math fails on FreeBSD in PB2 +main.lock_multi_bug38499 # Bug#11755645 2009-09-19 alik main.lock_multi_bug38499 times out sporadically +main.outfile_loaddata @solaris # Bug#11755168 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) +main.signal_demo3 @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +main.sp @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +main.wait_timeout @solaris # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris +rpl.rpl_innodb_bug28430 # Bug#11754425 +rpl.rpl_bug37426 # WL#5867: skozlov: test case moved from unused bugs suite rpl.rpl_heartbeat_basic # BUG#12403008 2011-04-27 sven fails sporadically -rpl.rpl_innodb_bug28430 # Bug#46029 rpl.rpl_show_slave_hosts # BUG#12416700 2011-05-02 sven fails sporadically -sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun -sys_vars.plugin_dir_basic # Bug#52223 2010-11-24 alik Test "plugin_dir_basic" does not support RPM build (test) directory structure -sys_vars.wait_timeout_func # Bug#41255 2010-04-26 alik wait_timeout_func fails +sys_vars.max_sp_recursion_depth_func @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wait_timeout_func fails # BUG #59055 : All ndb tests should be removed from the repository # Leaving the sys_vars tests for now. sys_vars.all_vars.test fails on removing ndb tests sys_vars.ndb_log_update_as_write_basic sys_vars.have_ndbcluster_basic sys_vars.ndb_log_updated_only_basic - -main.gis-rtree # svoj: due to BUG#38965 -main.type_float # svoj: due to BUG#38965 -main.type_newdecimal # svoj: due to BUG#38965 +sys_vars.rpl_init_slave_func # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5 diff --git a/mysql-test/extra/rpl_tests/check_type.inc b/mysql-test/extra/rpl_tests/check_type.inc index 63491d81da4..97300753d38 100644 --- a/mysql-test/extra/rpl_tests/check_type.inc +++ b/mysql-test/extra/rpl_tests/check_type.inc @@ -11,18 +11,28 @@ # on the slave) # $can_convert True if conversion shall work, false if it # shall generate an error +# $engine_type The storage engine to be used for storing table +# on both master and slave +if (!$engine_type) +{ + # Use the default storage engine + let $engine_type=`SELECT @@storage_engine`; +} connection master; disable_warnings; DROP TABLE IF EXISTS t1; enable_warnings; -eval CREATE TABLE t1 (a $source_type); +eval CREATE TABLE t1( + pk INT NOT NULL PRIMARY KEY, + a $source_type +) ENGINE=$engine_type; sync_slave_with_master; eval ALTER TABLE t1 MODIFY a $target_type; connection master; -eval INSERT INTO t1 VALUES($source_value); +eval INSERT INTO t1 VALUES(1, $source_value); if ($can_convert) { sync_slave_with_master; eval SELECT a = $target_value into @compare FROM t1; diff --git a/mysql-test/include/have_archive_plugin.inc b/mysql-test/include/have_archive_plugin.inc index 98e146ca20b..03b382d6344 100644 --- a/mysql-test/include/have_archive_plugin.inc +++ b/mysql-test/include/have_archive_plugin.inc @@ -1,5 +1,10 @@ +disable_query_log; if (`select plugin_library IS NULL from information_schema.plugins where plugin_name LIKE '%archive%'`) { --skip archive plugin not available } +if (`SELECT @@plugin_dir != '$ARCHIVE_PLUGIN_DIR'`) { + --skip Archive plugin requires that --plugin-dir is set to the archive plugin dir (either the .opt file does not contain \$ARCHIVE_PLUGIN_OPT or another plugin is in use) +} +enable_query_log;
\ No newline at end of file diff --git a/mysql-test/include/have_blackhole_plugin.inc b/mysql-test/include/have_blackhole_plugin.inc index 749efd343d6..bd1c1ac8af7 100644 --- a/mysql-test/include/have_blackhole_plugin.inc +++ b/mysql-test/include/have_blackhole_plugin.inc @@ -1,5 +1,11 @@ +disable_query_log; if (`select plugin_library IS NULL from information_schema.plugins where plugin_name LIKE '%blackhole%'`) { --skip blackhole plugin not available; } +if (`SELECT @@plugin_dir != '$BLACKHOLE_PLUGIN_DIR'`) { + --skip Blackhole plugin requires that --plugin-dir is set to the blackhole plugin dir (either the .opt file does not contain \$BLACKHOLE_PLUGIN_OPT or another plugin is in use) +} +enable_query_log; + diff --git a/mysql-test/include/not_threadpool.inc b/mysql-test/include/not_threadpool.inc new file mode 100644 index 00000000000..a49c8cfcc32 --- /dev/null +++ b/mysql-test/include/not_threadpool.inc @@ -0,0 +1,5 @@ +if (`SELECT count(*) FROM information_schema.GLOBAL_VARIABLES WHERE + VARIABLE_NAME = 'THREAD_HANDLING' AND + VARIABLE_VALUE = 'loaded-dynamically'`){ + skip Test requires: 'not_threadpool'; +} diff --git a/mysql-test/include/wait_show_condition.inc b/mysql-test/include/wait_show_condition.inc index 68e05ce4644..ae1600a7e30 100644 --- a/mysql-test/include/wait_show_condition.inc +++ b/mysql-test/include/wait_show_condition.inc @@ -31,6 +31,21 @@ # Created: 2009-02-18 mleich # +if (!$condition) +{ + --die ERROR IN TEST: the "condition" variable must be set +} + +if (!$field) +{ + --die ERROR IN TEST: the "field" variable must be set +} + +if (!$show_statement) +{ + --die ERROR IN TEST: the "show_statement" variable must be set +} + let $max_run_time= 30; if ($wait_timeout) { diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index c0f6535b96e..b0c4a1337d8 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -1,5 +1,5 @@ # -*- cperl -*- -# Copyright (C) 2008 MySQL AB, 2009 Sun Microsystems, Inc. +# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. # # 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 @@ -21,6 +21,7 @@ use Carp; use My::Platform; use File::Temp qw/ tempfile tempdir /; +use mtr_results; my $hint_mysqld; # Last resort guess for executable path @@ -80,7 +81,7 @@ sub _gdb { return if $? >> 8; return unless $gdb_output; - print <<EOF, $gdb_output, "\n"; + resfile_print <<EOF, $gdb_output, "\n"; Output from gdb follows. The first stack trace is from the failing thread. The following stack traces are from all threads (so the failing one is duplicated). @@ -124,7 +125,7 @@ sub _dbx { return if $? >> 8; return unless $dbx_output; - print <<EOF, $dbx_output, "\n"; + resfile_print <<EOF . $dbx_output . "\n"; Output from dbx follows. Stack trace is printed for all threads in order, above this you should see info about which thread was the failing one. ---------------------------- @@ -244,7 +245,7 @@ sub _cdb { $cdb_output=~ s/^Child\-SP RetAddr Call Site//gm; $cdb_output=~ s/\+0x([0-9a-fA-F]+)//gm; - print <<EOF, $cdb_output, "\n"; + resfile_print <<EOF, $cdb_output, "\n"; Output from cdb follows. Faulting thread is printed twice,with and without function parameters Search for STACK_TEXT to see the stack trace of the faulting thread. Callstacks of other threads are printed after it. diff --git a/mysql-test/lib/My/Test.pm b/mysql-test/lib/My/Test.pm index c756a677052..895afd210e7 100644 --- a/mysql-test/lib/My/Test.pm +++ b/mysql-test/lib/My/Test.pm @@ -1,6 +1,6 @@ # -*- cperl -*- -# Copyright (C) 2008 MySQL AB -# +# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +# # 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. @@ -23,6 +23,7 @@ package My::Test; use strict; use warnings; use Carp; +use mtr_results; sub new { @@ -66,9 +67,26 @@ sub is_failed { } +my %result_names= ( + 'MTR_RES_PASSED' => 'pass', + 'MTR_RES_FAILED' => 'fail', + 'MTR_RES_SKIPPED' => 'skipped', + ); + sub write_test { my ($test, $sock, $header)= @_; + if ($::opt_resfile && defined $test->{'result'}) { + resfile_test_info("result", $result_names{$test->{'result'}}); + if ($test->{'timeout'}) { + resfile_test_info("comment", "Timeout"); + } elsif (defined $test->{'comment'}) { + resfile_test_info("comment", $test->{'comment'}); + } + resfile_test_info("result", "warning") if defined $test->{'check'}; + resfile_to_test($test); + } + # Give the test a unique key before serializing it $test->{key}= "$test" unless defined $test->{key}; @@ -113,6 +131,7 @@ sub read_test { $test->{$key}= _decode($value); } } + resfile_from_test($test) if $::opt_resfile; return $test; } diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index c3dd43c12ca..d677645d9da 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -287,9 +287,11 @@ sub collect_one_suite($) "mysql-test/suite", "mysql-test", # Look in storage engine specific suite dirs - "storage/*/mysql-test-suites" + "storage/*/mtr", + # Look in plugin specific suite dir + "plugin/$suite/tests", ], - [$suite]); + [$suite, "mtr"]); } mtr_verbose("suitedir: $suitedir"); } diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index a7b5afd9fd7..e50e8cc77df 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -31,6 +31,7 @@ sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_exe_maybe_exists(@); +sub mtr_compress_file($); sub mtr_milli_sleep($); sub start_timer($); sub has_expired($); @@ -199,6 +200,40 @@ sub mtr_exe_exists (@) { } } +# +# Try to compress file using tools that might be available. +# If zip/gzip is not available, just silently ignore. +# + +sub mtr_compress_file ($) { + my ($filename)= @_; + + mtr_error ("File to compress not found: $filename") unless -f $filename; + + my $did_compress= 0; + + if (IS_WINDOWS) + { + # Capture stderr + my $ziperr= `zip $filename.zip $filename 2>&1`; + if ($?) { + print "$ziperr\n" if $ziperr !~ /recognized as an internal or external/; + } else { + unlink($filename); + $did_compress=1; + } + } + else + { + my $gzres= system("gzip $filename"); + $did_compress= ! $gzres; + if ($gzres && $gzres != -1) { + mtr_error ("Error: have gzip but it fails to compress core file"); + } + } + mtr_print("Compressed file $filename") if $did_compress; +} + sub mtr_milli_sleep ($) { die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1; diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 2fec916c724..f6b3cf6bda5 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -34,6 +34,7 @@ use My::Platform; use POSIX qw[ _exit ]; use IO::Handle qw[ flush ]; require "mtr_io.pl"; +use mtr_results; my $tot_real_time= 0; @@ -96,6 +97,7 @@ sub mtr_report_test_passed ($) { { $timer_str= mtr_fromfile("$::opt_vardir/log/timer"); $tinfo->{timer}= $timer_str; + resfile_test_info('duration', $timer_str) if $::opt_resfile; } # Big warning if status already set @@ -301,6 +303,7 @@ sub mtr_report_stats ($$;$) { time - $BASETIME, "seconds executing testcases"); } + resfile_global("duration", time - $BASETIME) if $::opt_resfile; my $warnlog= "$::opt_vardir/log/warnings"; if ( -f $warnlog ) diff --git a/mysql-test/lib/mtr_results.pm b/mysql-test/lib/mtr_results.pm new file mode 100644 index 00000000000..92b03756c04 --- /dev/null +++ b/mysql-test/lib/mtr_results.pm @@ -0,0 +1,167 @@ +# -*- cperl -*- +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +package mtr_results; +use strict; +use IO::Handle qw[ flush ]; + +use base qw(Exporter); +our @EXPORT= qw(resfile_init resfile_global resfile_new_test resfile_test_info + resfile_output resfile_output_file resfile_print + resfile_print_test resfile_to_test resfile_from_test ); + +my %curr_result; # Result for current test +my $curr_output; # Output for current test +my $do_resfile; + +END { + close RESF if $do_resfile; +} + +sub resfile_init($) +{ + my $fname= shift; + open (RESF, " > $fname") or die ("Could not open result file $fname"); + %curr_result= (); + $curr_output= ""; + $do_resfile= 1; +} + +# Strings need to be quoted if they start with white space or ", +# or if they contain newlines. Pass a reference to the string. +# If the string is quoted, " must be escaped, thus \ also must be escaped + +sub quote_value($) +{ + my $stref= shift; + + for ($$stref) { + return unless /^[\s"]/ or /\n/; + s/\\/\\\\/g; + s/"/\\"/g; + $_= '"' . $_ . '"'; + } +} + +# Output global variable setting to result file. + +sub resfile_global($$) +{ + return unless $do_resfile; + my ($tag, $val) = @_; + $val= join (' ', @$val) if ref($val) eq 'ARRAY'; + quote_value(\$val); + print RESF "$tag : $val\n"; +} + +# Prepare to add results for new test + +sub resfile_new_test() +{ + %curr_result= (); + $curr_output= ""; +} + +# Add (or change) one variable setting for current test + +sub resfile_test_info($$) +{ + my ($tag, $val) = @_; + return unless $do_resfile; + quote_value(\$val); + $curr_result{$tag} = $val; +} + +# Add to output value for current test. +# Will be quoted if necessary, truncated if length over 5000. + +sub resfile_output($) +{ + return unless $do_resfile; + + for (shift) { + my $len= length; + if ($len > 5000) { + my $trlen= $len - 5000; + $_= substr($_, 0, 5000) . "\n[TRUNCATED $trlen chars removed]\n"; + } + s/\\/\\\\/g; + s/"/\\"/g; + $curr_output .= $_; + } +} + +# Add to output, read from named file + +sub resfile_output_file($) +{ + resfile_output(::mtr_grab_file(shift)) if $do_resfile; +} + +# Print text, and also append to current output if we're collecting results + +sub resfile_print($) +{ + my $txt= shift; + print($txt); + resfile_output($txt) if $do_resfile; +} + +# Print results for current test, then reset +# (So calling a second time without having generated new results +# will have no effect) + +sub resfile_print_test() +{ + return unless %curr_result; + + print RESF "{\n"; + while (my ($t, $v) = each %curr_result) { + print RESF "$t : $v\n"; + } + if ($curr_output) { + chomp($curr_output); + print RESF " output : " . $curr_output . "\"\n"; + } + print RESF "}\n"; + IO::Handle::flush(\*RESF); + resfile_new_test(); +} + +# Add current test results to test object (to send from worker) + +sub resfile_to_test($) +{ + return unless $do_resfile; + my $tinfo= shift; + my @res_array= %curr_result; + $tinfo->{'resfile'}= \@res_array; + $tinfo->{'output'}= $curr_output if $curr_output; +} + +# Get test results (from worker) from test object + +sub resfile_from_test($) +{ + return unless $do_resfile; + my $tinfo= shift; + my $res_array= $tinfo->{'resfile'}; + return unless $res_array; + %curr_result= @$res_array; + $curr_output= $tinfo->{'output'} if defined $tinfo->{'output'}; +} + +1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f3f1181562b..f2487130015 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -96,6 +96,7 @@ use mtr_cases; use mtr_report; use mtr_match; use mtr_unique; +use mtr_results; use IO::Socket::INET; use IO::Select; @@ -245,6 +246,8 @@ my $build_thread= 0; my $opt_record; my $opt_report_features; +our $opt_resfile= $ENV{'MTR_RESULT_FILE'} || 0; + my $opt_skip_core; our $opt_check_testcases= 1; @@ -260,7 +263,6 @@ my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds sub suite_timeout { return $opt_suite_timeout * 60; }; -sub check_timeout { return $opt_testcase_timeout * 6; }; my $opt_wait_all; my $opt_user_args; @@ -296,6 +298,8 @@ sub testcase_timeout ($) { return $opt_testcase_timeout * 60; } +sub check_timeout ($) { return testcase_timeout($_[0]) / 10; } + our $opt_warnings= 1; our $opt_include_ndbcluster= 0; @@ -322,6 +326,14 @@ my $opt_parallel= $ENV{MTR_PARALLEL} || 1; select(STDOUT); $| = 1; # Automatically flush STDOUT +# Used by --result-file for for formatting times + +sub isotime($) { + my ($sec,$min,$hr,$day,$mon,$yr)= gmtime($_[0]); + return sprintf "%d-%02d-%02dT%02d:%02d:%02dZ", + $yr+1900, $mon+1, $day, $hr, $min, $sec; +} + main(); @@ -426,11 +438,21 @@ sub main { my $server_port = $server->sockport(); mtr_report("Using server port $server_port"); + if ($opt_resfile) { + resfile_init("$opt_vardir/mtr-results.txt"); + print_global_resfile(); + } + # -------------------------------------------------------------------------- # Read definitions from include/plugin.defs # read_plugin_defs("include/plugin.defs"); + # Also read from any plugin local plugin.defs + for (glob "$basedir/plugin/*/tests/mtr/plugin.defs") { + read_plugin_defs($_); + } + # Simplify reference to semisync plugins $ENV{'SEMISYNC_PLUGIN_OPT'}= $ENV{'SEMISYNC_MASTER_PLUGIN_OPT'}; @@ -641,6 +663,8 @@ sub run_test_server ($$$) { mtr_report(" - deleting it, already saved", "$opt_max_save_core"); unlink("$core_file"); + } else { + mtr_compress_file($core_file) unless @opt_cases; } ++$num_saved_cores; } @@ -649,6 +673,7 @@ sub run_test_server ($$$) { $savedir); } } + resfile_print_test(); $num_saved_datadir++; $num_failed_test++ unless ($result->{retries} || $result->{exp_fail}); @@ -671,6 +696,7 @@ sub run_test_server ($$$) { } } + resfile_print_test(); # Retry test run after test failure my $retries= $result->{retries} || 2; my $test_has_failed= $result->{failures} || 0; @@ -958,6 +984,49 @@ sub set_vardir { } +sub print_global_resfile { + resfile_global("start_time", isotime $^T); + resfile_global("user_id", $<); + resfile_global("embedded-server", $opt_embedded_server ? 1 : 0); + resfile_global("ps-protocol", $opt_ps_protocol ? 1 : 0); + resfile_global("sp-protocol", $opt_sp_protocol ? 1 : 0); + resfile_global("view-protocol", $opt_view_protocol ? 1 : 0); + resfile_global("cursor-protocol", $opt_cursor_protocol ? 1 : 0); + resfile_global("ssl", $opt_ssl ? 1 : 0); + resfile_global("compress", $opt_compress ? 1 : 0); + resfile_global("parallel", $opt_parallel); + resfile_global("check-testcases", $opt_check_testcases ? 1 : 0); + resfile_global("mysqld", \@opt_extra_mysqld_opt); + resfile_global("debug", $opt_debug ? 1 : 0); + resfile_global("gcov", $opt_gcov ? 1 : 0); + resfile_global("gprof", $opt_gprof ? 1 : 0); + resfile_global("valgrind", $opt_valgrind ? 1 : 0); + resfile_global("callgrind", $opt_callgrind ? 1 : 0); + resfile_global("mem", $opt_mem ? 1 : 0); + resfile_global("tmpdir", $opt_tmpdir); + resfile_global("vardir", $opt_vardir); + resfile_global("fast", $opt_fast ? 1 : 0); + resfile_global("force-restart", $opt_force_restart ? 1 : 0); + resfile_global("reorder", $opt_reorder ? 1 : 0); + resfile_global("sleep", $opt_sleep); + resfile_global("repeat", $opt_repeat); + resfile_global("user", $opt_user); + resfile_global("testcase-timeout", $opt_testcase_timeout); + resfile_global("suite-timeout", $opt_suite_timeout); + resfile_global("shutdown-timeout", $opt_shutdown_timeout ? 1 : 0); + resfile_global("warnings", $opt_warnings ? 1 : 0); + resfile_global("max-connections", $opt_max_connections); +# resfile_global("default-myisam", $opt_default_myisam ? 1 : 0); + resfile_global("product", "MySQL"); + # Somewhat hacky code to convert numeric version back to dot notation + my $v1= int($mysql_version_id / 10000); + my $v2= int(($mysql_version_id % 10000)/100); + my $v3= $mysql_version_id % 100; + resfile_global("version", "$v1.$v2.$v3"); +} + + + sub command_line_setup { my $opt_comment; my $opt_usage; @@ -1100,6 +1169,7 @@ sub command_line_setup { 'max-connections=i' => \$opt_max_connections, 'default-myisam!' => \&collect_option, 'report-times' => \$opt_report_times, + 'result-file' => \$opt_resfile, 'unit-tests!' => \$opt_ctest, 'help|h' => \$opt_usage, @@ -3351,7 +3421,7 @@ sub check_testcase($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result; @@ -3423,7 +3493,7 @@ test case was executed:\n"; } elsif ( $proc->{timeout} ) { $tinfo->{comment}.= "Timeout for 'check-testcase' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; $result= 4; } else { @@ -3513,7 +3583,7 @@ sub run_on_all($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result; @@ -3544,7 +3614,7 @@ sub run_on_all($$) } elsif ($proc->{timeout}) { $tinfo->{comment}.= "Timeout for '$run' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; } else { # Unknown process returned, most likley a crash, abort everything @@ -3650,6 +3720,18 @@ sub timezone { # Storage for changed environment variables my %old_env; +sub resfile_report_test ($) { + my $tinfo= shift; + + resfile_new_test(); + + resfile_test_info("name", $tinfo->{name}); + resfile_test_info("variation", $tinfo->{combination}) + if $tinfo->{combination}; + resfile_test_info("start_time", isotime time); +} + + # # Run a single test case # @@ -3662,6 +3744,7 @@ sub run_testcase ($) { my $tinfo= shift; mtr_verbose("Running test:", $tinfo->{name}); + resfile_report_test($tinfo) if $opt_resfile; # Allow only alpanumerics pluss _ - + . in combination names, # or anything beginning with -- (the latter comes from --combination) @@ -3867,6 +3950,7 @@ sub run_testcase ($) { # Test case suceeded, but it has produced unexpected # warnings, continue in $res == 1 $res= 1; + resfile_output($tinfo->{'warnings'}) if $opt_resfile; } if ( $res == 0 ) @@ -3883,6 +3967,7 @@ sub run_testcase ($) { # Test case had sideeffects, not fatal error, just continue stop_all_servers($opt_shutdown_timeout); mtr_report("Resuming tests...\n"); + resfile_output($tinfo->{'check'}) if $opt_resfile; } else { # Test case check failed fatally, probably a server crashed @@ -3944,6 +4029,9 @@ sub run_testcase ($) { # Save info from this testcase run to mysqltest.log if( -f $path_current_testlog) { + if ($opt_resfile && $res && $res != 62) { + resfile_output_file($path_current_testlog); + } mtr_appendfile_to_file($path_current_testlog, $path_testlog); unlink($path_current_testlog); } @@ -4251,7 +4339,7 @@ sub check_warnings ($) { # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result= 0; @@ -4303,7 +4391,7 @@ sub check_warnings ($) { } elsif ( $proc->{timeout} ) { $tinfo->{comment}.= "Timeout for 'check warnings' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; $result= 4; } else { diff --git a/mysql-test/r/archive_debug.result b/mysql-test/r/archive_debug.result new file mode 100644 index 00000000000..cc5a3761a99 --- /dev/null +++ b/mysql-test/r/archive_debug.result @@ -0,0 +1,12 @@ +# +# BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK +# WITH PARTITIONED ARCHIVE TABLES +# +CREATE TABLE t1(a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(1); +SET SESSION debug='d,simulate_archive_open_failure'; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check error Corrupt +SET SESSION debug=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 291dcfdf92a..a80c52ebf9d 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -2046,7 +2046,7 @@ create table t2 as select concat(a) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `concat(a)` varbinary(2) DEFAULT NULL + `concat(a)` varbinary(4) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (a year); @@ -2355,7 +2355,7 @@ insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; Field Type Null Key Default Extra -a varbinary(2) YES NULL +a varbinary(4) YES NULL select hex(a) from v1; hex(a) 3031 diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index 58f023b2b79..cff4f6b7442 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -2438,7 +2438,7 @@ create table t2 as select concat(a) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET cp1251 DEFAULT NULL + `concat(a)` varchar(4) CHARACTER SET cp1251 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (a year); @@ -2747,7 +2747,7 @@ insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; Field Type Null Key Default Extra -a varchar(2) YES NULL +a varchar(4) YES NULL select hex(a) from v1; hex(a) 3031 diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 2ecb9d6aeba..12a76302397 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -2465,7 +2465,7 @@ create table t2 as select concat(a) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) DEFAULT NULL + `concat(a)` varchar(4) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (a year); @@ -2774,7 +2774,7 @@ insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; Field Type Null Key Default Extra -a varchar(2) YES NULL +a varchar(4) YES NULL select hex(a) from v1; hex(a) 3031 diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index e687822c235..dc922f8490a 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -3299,7 +3299,7 @@ create table t2 as select concat(a) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET ucs2 DEFAULT NULL + `concat(a)` varchar(4) CHARACTER SET ucs2 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (a year); @@ -3608,7 +3608,7 @@ insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; Field Type Null Key Default Extra -a varchar(2) YES NULL +a varchar(4) YES NULL select hex(a) from v1; hex(a) 00300031 diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index db981fbe298..cfbf6cee3a2 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -4177,7 +4177,7 @@ create table t2 as select concat(a) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET utf8 DEFAULT NULL + `concat(a)` varchar(4) CHARACTER SET utf8 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (a year); @@ -4486,7 +4486,7 @@ insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; Field Type Null Key Default Extra -a varchar(2) YES NULL +a varchar(4) YES NULL select hex(a) from v1; hex(a) 3031 diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index b1cb70fa43c..74f2c19c8fe 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -794,3 +794,14 @@ DROP TABLE t1; SET @@sort_buffer_size = @old_sort_buffer_size; SET @@max_heap_table_size = @old_max_heap_table_size; End of 5.1 tests +# +# Bug #11744875: 4082: integer lengths cause truncation with distinct concat and innodb +# +CREATE TABLE t1 (a INT(1), b INT(1)); +INSERT INTO t1 VALUES (1111, 2222), (3333, 4444); +SELECT DISTINCT CONCAT(a,b) AS c FROM t1 ORDER BY 1; +c +11112222 +33334444 +DROP TABLE t1; +End of 5.5 tests diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index b0ca5daaea2..b08bb7ae488 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -535,6 +535,7 @@ DROP EVENT e3; DROP EVENT e2; DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +SET TIMESTAMP=DEFAULT; drop event if exists new_event; CREATE EVENT new_event ON SCHEDULE EVERY 0 SECOND DO SELECT 1; ERROR HY000: INTERVAL is either not positive or too big @@ -756,6 +757,45 @@ SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation DROP DATABASE event_test1; DROP DATABASE event_test12; +# +# Bug#12546938 (formerly known as bug#61005): +# CREATE IF NOT EXIST EVENT WILL CREATE MULTIPLE RUNNING EVENTS +# +USE events_test; +SET GLOBAL event_scheduler = ON; +DROP TABLE IF EXISTS table_bug12546938; +DROP EVENT IF EXISTS event_Bug12546938; +CREATE TABLE table_bug12546938 (i INT); +# Create an event which will be executed with a small delay +# and won't be automatically dropped after that. +CREATE EVENT event_Bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN +INSERT INTO table_bug12546938 VALUES(1); +END +| +# Now try to create the same event using CREATE EVENT IF NOT EXISTS. +# A warning should be emitted. A new event should not be created nor +# the old event should be re-executed. +CREATE EVENT IF NOT EXISTS event_bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN +INSERT INTO table_bug12546938 VALUES (1); +END +| +Warnings: +Note 1537 Event 'event_bug12546938' already exists +# Wait until at least one instance of event is executed. +# Check that only one instance of our event was executed. +SELECT COUNT(*) FROM table_bug12546938; +COUNT(*) +1 +# Clean-up. +DROP EVENT IF EXISTS event_Bug12546938; +DROP TABLE table_bug12546938; +SET GLOBAL EVENT_SCHEDULER = OFF; DROP DATABASE events_test; SET GLOBAL event_scheduler= 'ON'; SET @@global.concurrent_insert= @concurrent_insert; diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index ac24ef4dea9..c93e33f98b9 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -543,6 +543,12 @@ ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')) -4939092.0000 Warnings: Warning 1292 Truncated incorrect DOUBLE value: 'a' +# +# Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +# +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); +SUM(DISTINCT (TRUNCATE((.1), NULL))) +NULL End of 5.1 tests # # Bug #8433: Overflow must be an error diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index b1bf0a6a830..e6ef9bdfe61 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1389,6 +1389,15 @@ NULL SELECT DATE_FORMAT('0000-00-11', '%w'); DATE_FORMAT('0000-00-11', '%w') NULL +# +# Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +# +SELECT MAKEDATE(11111111,1); +MAKEDATE(11111111,1) +NULL +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); +WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1) +NULL End of 5.1 tests # # Bug#57039: constant subtime expression returns incorrect result. diff --git a/mysql-test/r/implicit_char_to_num_conversion.result b/mysql-test/r/implicit_char_to_num_conversion.result new file mode 100644 index 00000000000..8f24a6b293c --- /dev/null +++ b/mysql-test/r/implicit_char_to_num_conversion.result @@ -0,0 +1,366 @@ +DROP TABLE IF EXISTS t5; +CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +HEX(c1) +0 +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +HEX(c1) +0 +2 +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +HEX(c1) +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +HEX(c1) +0 +1 +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +HEX(c1) +0 +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +HEX(c1) +1 +2 +DROP TABLE t5; +CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +95.95 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +c1 +-10.10 +0.00 +95.95 +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +c1 +-10.10 +0.00 +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +c1 +1.00 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95 +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +c1 +-8 +10 +11 +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +c1 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +c1 +-8 +10 +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +c1 +11 +95 +DROP TABLE t5; +CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-200 +100 +111 +395 +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +c1 +395 +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +c1 +-200 +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +c1 +-200 +111 +395 +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +c1 +-200 +100 +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +c1 +395 +DROP TABLE t5; +CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +c1 +-8388607 +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +c1 +311 +88608 +DROP TABLE t5; +CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-2147483647 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +c1 +-2147483647 +15 +1011 +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +c1 +-2147483647 +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +c1 +1011 +9388607 +DROP TABLE t5; +CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +c1 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +c1 +3372036854775808 +DROP TABLE t5; +CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; diff --git a/mysql-test/r/innodb_mysql_lock.result b/mysql-test/r/innodb_mysql_lock.result index cd9487721b6..4c7e7f11987 100644 --- a/mysql-test/r/innodb_mysql_lock.result +++ b/mysql-test/r/innodb_mysql_lock.result @@ -164,6 +164,8 @@ id value SET lock_wait_timeout=1; ALTER TABLE t1 ADD INDEX idx(value); ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ALTER TABLE t1 ADD INDEX idx(value); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default SELECT * FROM t1; id value diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result index 71f567a4ad2..605aaf4df5a 100644 --- a/mysql-test/r/innodb_mysql_sync.result +++ b/mysql-test/r/innodb_mysql_sync.result @@ -94,6 +94,95 @@ SET DEBUG_SYNC= 'RESET'; # Bug#42230 during add index, cannot do queries on storage engines # that implement add_index # +DROP DATABASE IF EXISTS db1; +DROP TABLE IF EXISTS t1; +# Test 1: Secondary index, should not block reads (original test case). +# Connection default +CREATE DATABASE db1; +CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb; +INSERT INTO db1.t1(value) VALUES (1), (2); +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +# Sending: +ALTER TABLE db1.t1 ADD INDEX(value); +# Connection con1 +SET DEBUG_SYNC= "now WAIT_FOR manage"; +USE db1; +SELECT * FROM t1; +id value +1 1 +2 2 +SET DEBUG_SYNC= "now SIGNAL query"; +# Connection default +# Reaping: ALTER TABLE db1.t1 ADD INDEX(value) +DROP DATABASE db1; +# Test 2: Primary index (implicit), should block reads. +CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +# Sending: +ALTER TABLE t1 ADD UNIQUE INDEX(a); +# Connection con1 +SET DEBUG_SYNC= "now WAIT_FOR manage"; +USE test; +# Sending: +SELECT * FROM t1; +# Connection con2 +# Waiting for SELECT to be blocked by the metadata lock on t1 +SET DEBUG_SYNC= "now SIGNAL query"; +# Connection default +# Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a) +# Connection con1 +# Reaping: SELECT * FROM t1 +a b +# Test 3: Primary index (explicit), should block reads. +# Connection default +ALTER TABLE t1 DROP INDEX a; +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +# Sending: +ALTER TABLE t1 ADD PRIMARY KEY (a); +# Connection con1 +SET DEBUG_SYNC= "now WAIT_FOR manage"; +# Sending: +SELECT * FROM t1; +# Connection con2 +# Waiting for SELECT to be blocked by the metadata lock on t1 +SET DEBUG_SYNC= "now SIGNAL query"; +# Connection default +# Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a) +# Connection con1 +# Reaping: SELECT * FROM t1 +a b +# Test 4: Secondary unique index, should not block reads. +# Connection default +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +# Sending: +ALTER TABLE t1 ADD UNIQUE (b); +# Connection con1 +SET DEBUG_SYNC= "now WAIT_FOR manage"; +SELECT * FROM t1; +a b +SET DEBUG_SYNC= "now SIGNAL query"; +# Connection default +# Reaping: ALTER TABLE t1 ADD UNIQUE (b) +SET DEBUG_SYNC= "RESET"; +DROP TABLE t1; # -# DISABLED due to Bug#11815600 +# Bug#11853126 RE-ENABLE CONCURRENT READS WHILE CREATING SECONDARY INDEX +# IN INNODB # +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; +INSERT INTO t1 VALUES (1, 12345), (2, 23456); +# Connection con1 +SET SESSION debug= "+d,alter_table_rollback_new_index"; +ALTER TABLE t1 ADD PRIMARY KEY(a); +ERROR HY000: Unknown error +SELECT * FROM t1; +a b +1 12345 +2 23456 +# Connection default +SELECT * FROM t1; +a b +1 12345 +2 23456 +DROP TABLE t1; diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index 480cec792c0..3418348854f 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -126,7 +126,7 @@ renamed 1 select * from v3 where renamed=1 group by renamed; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def v3 v3 renamed renamed 8 11 0 Y 32896 0 63 +def v3 v3 renamed renamed 8 12 0 Y 32896 0 63 renamed drop table t1; drop view v1,v2,v3; diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 6389438c993..72bbaa71da5 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -44,13 +44,13 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1 drop user ssl_user1@localhost, ssl_user2@localhost, ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; -mysqltest: Could not open connection 'default': 2026 SSL connection error -mysqltest: Could not open connection 'default': 2026 SSL connection error -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation SSL error: Unable to get private key from '' -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get private key SSL error: Unable to get certificate from '' -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get certificate SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA @@ -83,7 +83,7 @@ Ssl_cipher AES128-SHA SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher AES128-SHA -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: SSL_CTX_new failed CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); @@ -189,7 +189,7 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; SSL error: Unable to get private key from 'MYSQL_TEST_DIR/std_data/client-cert.pem' -mysqldump: Got error: 2026: SSL connection error when trying to connect +mysqldump: Got error: 2026: SSL connection error: Unable to get private key when trying to connect DROP TABLE t1; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index 50a3a02fe4d..ec78fe65802 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -153,7 +153,9 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_2"; ** until a broadcast signal reaches them causing both threads to ** come alive and check the condition. SET DEBUG_SYNC="now SIGNAL go2"; +** Wait for thd2 to receive the signal SET DEBUG_SYNC="now SIGNAL go3"; +** Wait for thd3 to receive the signal ** ** Finally signal the DELETE statement on THD1 one last time. ** The stmt will complete the query cache invalidation and return diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index c0cd0f7bc1a..ce3acba9b8a 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -238,11 +238,5 @@ SELECT 9; 9 DROP PROCEDURE p1; DROP FUNCTION f1; -DROP VIEW IF EXISTS v1; -CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; -SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; -SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; -NAME -DROP VIEW v1; set @@global.concurrent_insert= @old_concurrent_insert; SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/r/status_bug17954.result b/mysql-test/r/status_bug17954.result new file mode 100644 index 00000000000..5c244cd8aca --- /dev/null +++ b/mysql-test/r/status_bug17954.result @@ -0,0 +1,13 @@ +set @old_concurrent_insert= @@global.concurrent_insert; +set @@global.concurrent_insert= 0; +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; +flush status; +DROP VIEW IF EXISTS v1; +CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; +SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; +SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; +NAME +DROP VIEW v1; +set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 819e41f41c5..c9db73c5f85 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1920,4 +1920,17 @@ SELECT SUM(DISTINCT a) FROM t1; SUM(DISTINCT a) 0.0000 DROP TABLE t1; +# +# Bug#55436: buffer overflow in debug binary of dbug_buff in +# Field_new_decimal::store_value +# +SET SQL_MODE=''; +CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM; +INSERT INTO t1 SET f1 = -64878E-85; +Warnings: +Note 1265 Data truncated for column 'f1' at row 1 +SELECT f1 FROM t1; +f1 +0.000000000000000000000000 +DROP TABLE IF EXISTS t1; End of 5.1 tests diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index ac3d52b9ead..d99c2363d62 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -271,7 +271,7 @@ drop table t2; create table t2 (primary key (auto)) select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; show full columns from t2; Field Type Collation Null Key Default Extra Privileges Comment -auto int(6) unsigned NULL NO PRI 0 # +auto int(11) unsigned NULL NO PRI 0 # t1 int(1) NULL NO 0 # t2 varchar(1) latin1_swedish_ci NO # t3 varchar(256) latin1_swedish_ci NO # diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result index 71b32393d82..02908502c8b 100644 --- a/mysql-test/r/variables-big.result +++ b/mysql-test/r/variables-big.result @@ -1,3 +1,4 @@ +SET @def_var= @@session.transaction_prealloc_size; SET SESSION transaction_prealloc_size=1024*1024*1024*1; SHOW PROCESSLIST; Id User Host db Command Time State Info @@ -18,3 +19,4 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*5; SHOW PROCESSLIST; Id User Host db Command Time State Info <Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST +SET @@session.transaction_prealloc_size= @def_var; diff --git a/mysql-test/suite/binlog/r/binlog_innodb_row.result b/mysql-test/suite/binlog/r/binlog_innodb_row.result index 093628c29cc..61f961f16da 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb_row.result +++ b/mysql-test/suite/binlog/r/binlog_innodb_row.result @@ -59,3 +59,20 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */ ############################################### +# +# Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED +# +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb; +CREATE TABLE t2(a INT) engine=myisam; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +INSERT INTO t2 VALUES (1); +INSERT IGNORE INTO t1 VALUES (1); +COMMIT; +INSERT INTO t1 VALUES (2); +START TRANSACTION; +INSERT INTO t2 VALUES (2); +UPDATE IGNORE t1 SET a=1 WHERE a=2; +COMMIT; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/r/binlog_reset_master.result b/mysql-test/suite/binlog/r/binlog_reset_master.result new file mode 100644 index 00000000000..b3d605560ff --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_reset_master.result @@ -0,0 +1 @@ +RESET MASTER; 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 20d82557122..da2e24506fd 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 @@ -698,7 +698,7 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`= @b + bug27417(2) ;file_id=# master-bin.000001 # Query # # ROLLBACK /* the output must denote there is the query */; drop trigger trg_del_t2; @@ -950,7 +950,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`= @b + bug27417(2) ;file_id=# master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/binlog/t/binlog_innodb_row.test b/mysql-test/suite/binlog/t/binlog_innodb_row.test index b491510c9c9..f4ad1058a7e 100644 --- a/mysql-test/suite/binlog/t/binlog_innodb_row.test +++ b/mysql-test/suite/binlog/t/binlog_innodb_row.test @@ -77,3 +77,29 @@ DROP TEMPORARY TABLE t1; -- echo ############################################### -- source include/show_binlog_events.inc -- echo ############################################### + + +--echo # +--echo # Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb; +CREATE TABLE t2(a INT) engine=myisam; + +INSERT INTO t1 VALUES (1); +START TRANSACTION; +INSERT INTO t2 VALUES (1); +INSERT IGNORE INTO t1 VALUES (1); +COMMIT; + +INSERT INTO t1 VALUES (2); +START TRANSACTION; +INSERT INTO t2 VALUES (2); +UPDATE IGNORE t1 SET a=1 WHERE a=2; +COMMIT; + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/t/binlog_reset_master.test b/mysql-test/suite/binlog/t/binlog_reset_master.test new file mode 100644 index 00000000000..b7ad69da3ea --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_reset_master.test @@ -0,0 +1,26 @@ +# ==== Purpose ==== +# +# Test bugs in RESET MASTER. + +--source include/have_debug.inc +--source include/have_log_bin.inc + +####################################################################### +# BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run +# Problem: MYSQL_BIN_LOG::reset_logs acquired LOCK_thread_count and +# LOCK_log in the wrong order. This could cause a deadlock when +# RESET MASTER was run concurrently with a disconnecting thread. +####################################################################### + +# We use sleep, not debug_sync, because the sync point needs to be in +# the thread shut down code after the debug sync facility has been +# shut down. +--let $write_var= SET DEBUG="+d,sleep_after_lock_thread_count_before_delete_thd"; CREATE TEMPORARY TABLE test.t1 (a INT); +--let $write_to_file= GENERATE +--disable_query_log +--source include/write_var_to_file.inc +--enable_query_log + +--exec $MYSQL < $write_to_file +RESET MASTER; +--remove_file $write_to_file diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index d80a42c6e27..1abc9951322 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -9,5 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#57291 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed -binlog_spurious_ddl_errors : BUG#54195 2010-06-03 alik binlog_spurious_ddl_errors.test fails, thus disabled +binlog_truncate_innodb : BUG#11764459 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed +binlog_spurious_ddl_errors : BUG#11761680 2010-06-03 alik binlog_spurious_ddl_errors.test fails, thus disabled diff --git a/mysql-test/suite/federated/disabled.def b/mysql-test/suite/federated/disabled.def index 9a9149ec80a..3b114aa380b 100644 --- a/mysql-test/suite/federated/disabled.def +++ b/mysql-test/suite/federated/disabled.def @@ -9,4 +9,4 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -federated_transactions : Bug#29523 Transactions do not work +federated_transactions : Bug#11746899 Transactions do not work diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 1faad628d76..220a091adfe 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -885,31 +885,31 @@ create table t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob, i blob,j blob,k blob,l blob,m blob,n blob,o blob,p blob, q blob,r blob,s blob,t blob,u blob) engine=innodb row_format=dynamic; -create index t1a on t1 (a(1)); -create index t1b on t1 (b(1)); -create index t1c on t1 (c(1)); -create index t1d on t1 (d(1)); -create index t1e on t1 (e(1)); -create index t1f on t1 (f(1)); -create index t1g on t1 (g(1)); -create index t1h on t1 (h(1)); -create index t1i on t1 (i(1)); -create index t1j on t1 (j(1)); -create index t1k on t1 (k(1)); -create index t1l on t1 (l(1)); -create index t1m on t1 (m(1)); -create index t1n on t1 (n(1)); -create index t1o on t1 (o(1)); -create index t1p on t1 (p(1)); -create index t1q on t1 (q(1)); -create index t1r on t1 (r(1)); -create index t1s on t1 (s(1)); -create index t1t on t1 (t(1)); -create index t1u on t1 (u(1)); +create index t1a on t1 (a(767)); +create index t1b on t1 (b(767)); +create index t1c on t1 (c(767)); +create index t1d on t1 (d(767)); +create index t1e on t1 (e(767)); +create index t1f on t1 (f(767)); +create index t1g on t1 (g(767)); +create index t1h on t1 (h(767)); +create index t1i on t1 (i(767)); +create index t1j on t1 (j(767)); +create index t1k on t1 (k(767)); +create index t1l on t1 (l(767)); +create index t1m on t1 (m(767)); +create index t1n on t1 (n(767)); +create index t1o on t1 (o(767)); +create index t1p on t1 (p(767)); +create index t1q on t1 (q(767)); +create index t1r on t1 (r(767)); +create index t1s on t1 (s(767)); +create index t1t on t1 (t(767)); +create index t1u on t1 (u(767)); ERROR HY000: Too big row -create index t1ut on t1 (u(1), t(1)); +create index t1ut on t1 (u(767), t(767)); ERROR HY000: Too big row -create index t1st on t1 (s(1), t(1)); +create index t1st on t1 (s(767), t(767)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -934,32 +934,32 @@ t1 CREATE TABLE `t1` ( `s` blob, `t` blob, `u` blob, - KEY `t1a` (`a`(1)), - KEY `t1b` (`b`(1)), - KEY `t1c` (`c`(1)), - KEY `t1d` (`d`(1)), - KEY `t1e` (`e`(1)), - KEY `t1f` (`f`(1)), - KEY `t1g` (`g`(1)), - KEY `t1h` (`h`(1)), - KEY `t1i` (`i`(1)), - KEY `t1j` (`j`(1)), - KEY `t1k` (`k`(1)), - KEY `t1l` (`l`(1)), - KEY `t1m` (`m`(1)), - KEY `t1n` (`n`(1)), - KEY `t1o` (`o`(1)), - KEY `t1p` (`p`(1)), - KEY `t1q` (`q`(1)), - KEY `t1r` (`r`(1)), - KEY `t1s` (`s`(1)), - KEY `t1t` (`t`(1)), - KEY `t1st` (`s`(1),`t`(1)) + KEY `t1a` (`a`(767)), + KEY `t1b` (`b`(767)), + KEY `t1c` (`c`(767)), + KEY `t1d` (`d`(767)), + KEY `t1e` (`e`(767)), + KEY `t1f` (`f`(767)), + KEY `t1g` (`g`(767)), + KEY `t1h` (`h`(767)), + KEY `t1i` (`i`(767)), + KEY `t1j` (`j`(767)), + KEY `t1k` (`k`(767)), + KEY `t1l` (`l`(767)), + KEY `t1m` (`m`(767)), + KEY `t1n` (`n`(767)), + KEY `t1o` (`o`(767)), + KEY `t1p` (`p`(767)), + KEY `t1q` (`q`(767)), + KEY `t1r` (`r`(767)), + KEY `t1s` (`s`(767)), + KEY `t1t` (`t`(767)), + KEY `t1st` (`s`(767),`t`(767)) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC -create index t1u on t1 (u(1)); +create index t1u on t1 (u(767)); ERROR HY000: Too big row alter table t1 row_format=compact; -create index t1u on t1 (u(1)); +create index t1u on t1 (u(767)); drop table t1; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; diff --git a/mysql-test/suite/innodb/r/innodb_index_large_prefix.result b/mysql-test/suite/innodb/r/innodb_index_large_prefix.result new file mode 100644 index 00000000000..6e2d3527ee9 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_index_large_prefix.result @@ -0,0 +1,185 @@ +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; +create table worklog5743(a TEXT not null, primary key (a(1000))) +ROW_FORMAT=DYNAMIC, engine = innodb; +insert into worklog5743 values(repeat("a", 20000)); +update worklog5743 set a = (repeat("b", 16000)); +create index idx on worklog5743(a(2000)); +begin; +update worklog5743 set a = (repeat("x", 17000)); +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +select a = repeat("x", 17000) from worklog5743; +a = repeat("x", 17000) +0 +select a = repeat("b", 16000) from worklog5743; +a = repeat("b", 16000) +1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a = repeat("x", 17000) from worklog5743; +a = repeat("x", 17000) +1 +rollback; +drop table worklog5743; +create table worklog5743(a1 int, a2 TEXT not null) +ROW_FORMAT=DYNAMIC, engine = innodb; +create index idx on worklog5743(a1, a2(2000)); +insert into worklog5743 values(9, repeat("a", 10000)); +begin; +update worklog5743 set a1 = 1000; +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE worklog5743 ref idx idx 5 const 1 Using where +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +a1 a2 = repeat("a", 10000) +9 1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +a1 a2 = repeat("a", 10000) +rollback; +drop table worklog5743; +create table worklog5743(a1 int, a2 TEXT not null) +ROW_FORMAT=DYNAMIC, engine = innodb; +create index idx on worklog5743(a1, a2(50)); +insert into worklog5743 values(9, repeat("a", 10000)); +begin; +update worklog5743 set a1 = 1000; +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE worklog5743 ref idx idx 5 const 1 Using where +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +a1 a2 = repeat("a", 10000) +9 1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +a1 a2 = repeat("a", 10000) +rollback; +drop table worklog5743; +create table worklog5743_2(a1 int, a2 TEXT not null) +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +create table worklog5743_4(a1 int, a2 TEXT not null) +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +create index idx1 on worklog5743_2(a1, a2(942)); +ERROR HY000: Too big row +create index idx1 on worklog5743_2(a1, a2(940)); +create index idx1 on worklog5743_4(a1, a2(1966)); +ERROR HY000: Too big row +create index idx1 on worklog5743_4(a1, a2(1964)); +insert into worklog5743_2 values(9, repeat("a", 10000)); +insert into worklog5743_4 values(9, repeat("a", 10000)); +begin; +update worklog5743_2 set a1 = 1000; +update worklog5743_4 set a1 = 1000; +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +explain select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE worklog5743_2 ref idx1 idx1 5 const 1 Using where +select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +a1 a2 = repeat("a", 10000) +9 1 +select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; +a1 a2 = repeat("a", 10000) +9 1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +a1 a2 = repeat("a", 10000) +select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; +a1 a2 = repeat("a", 10000) +rollback; +drop table worklog5743_2; +drop table worklog5743_4; +create table worklog5743(a1 int, a2 varchar(3000)) +ROW_FORMAT=DYNAMIC, engine = innodb; +create index idx on worklog5743(a1, a2); +insert into worklog5743 values(9, repeat("a", 3000)); +begin; +update worklog5743 set a1 = 1000; +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +explain select a1 from worklog5743 where a1 = 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE worklog5743 ref idx idx 5 const 1 Using where; Using index +select a1 from worklog5743 where a1 = 9; +a1 +9 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a1 from worklog5743 where a1 = 9; +a1 +rollback; +drop table worklog5743; +create table worklog5743(a TEXT not null, primary key (a(1000))) +engine = innodb; +ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +create table worklog5743(a TEXT) engine = innodb; +create index idx on worklog5743(a(1000)); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +create index idx on worklog5743(a(725)); +insert into worklog5743 values(repeat("a", 20000)); +begin; +insert into worklog5743 values(repeat("b", 20000)); +update worklog5743 set a = (repeat("x", 25000)); +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +select a = repeat("a", 20000) from worklog5743; +a = repeat("a", 20000) +1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +select a = repeat("x", 25000) from worklog5743; +a = repeat("x", 25000) +1 +1 +rollback; +drop table worklog5743; +create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC, engine = innodb; +create index idx on worklog5743(a(3073)); +Warnings: +Warning 1071 Specified key was too long; max key length is 3072 bytes +Warning 1071 Specified key was too long; max key length is 3072 bytes +create index idx2 on worklog5743(a(3072)); +show create table worklog5743; +Table Create Table +worklog5743 CREATE TABLE `worklog5743` ( + `a` text NOT NULL, + KEY `idx` (`a`(3072)), + KEY `idx2` (`a`(3072)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +drop table worklog5743; +create table worklog5743(a TEXT not null) engine = innodb; +create index idx on worklog5743(a(768)); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes. +create index idx2 on worklog5743(a(767)); +drop table worklog5743; +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_per_table=0; +SET GLOBAL innodb_file_format_max=Antelope; +SET GLOBAL innodb_large_prefix=0; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 7d96a4acf3f..b6976e43bcb 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2663,7 +2663,6 @@ COUNT(*) 1537 SET SESSION sort_buffer_size = DEFAULT; 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". @@ -2685,6 +2684,23 @@ t2 CREATE TABLE `t2` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; # +# Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +# UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +# +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +# Even though temporary table was locked for READ we +# still allow writes to it to be compatible with MyISAM. +# This is possible since due to fact that temporary tables +# are specific to connection and therefore locking for them +# is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; +End of 5.1 tests +# # Bug#44613 SELECT statement inside FUNCTION takes a shared lock # DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result b/mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result new file mode 100644 index 00000000000..73d75241a10 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result @@ -0,0 +1,1354 @@ +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; +DROP TABLE IF EXISTS worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE +col_1_varchar PRIMARY 3072 BTREE +col_1_varchar prefix_idx 3072 BTREE +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072)); +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE +col_1_text PRIMARY 3072 BTREE +col_1_text prefix_idx 3072 BTREE +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743; +col_1_text = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_mediumtext MEDIUMTEXT , col_2_mediumtext MEDIUMTEXT , +PRIMARY KEY (col_1_mediumtext(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_mediumtext (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_mediumtext = REPEAT("a", 4000),col_2_mediumtext = REPEAT("o", 4000) +FROM worklog5743; +col_1_mediumtext = REPEAT("a", 4000) col_2_mediumtext = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_mediumtext = REPEAT("c", 4000) +WHERE col_1_mediumtext = REPEAT("a", 4000) +AND col_2_mediumtext = REPEAT("o", 4000); +SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_mediumtext = REPEAT("c", 4000) +AND col_2_mediumtext = REPEAT("o", 4000); +col_1_mediumtext = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_mediumtext = REPEAT("b", 4000); +SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743; +col_1_mediumtext = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_longtext LONGTEXT , col_2_longtext LONGTEXT , +PRIMARY KEY (col_1_longtext(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_longtext (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_longtext = REPEAT("a", 4000) , col_2_longtext = REPEAT("o", 4000) +FROM worklog5743; +col_1_longtext = REPEAT("a", 4000) col_2_longtext = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_longtext = REPEAT("c", 4000) +WHERE col_1_longtext = REPEAT("a", 4000) +AND col_2_longtext = REPEAT("o", 4000); +SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_longtext = REPEAT("c", 4000) +AND col_2_longtext = REPEAT("o", 4000); +col_1_longtext = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_longtext = REPEAT("b", 4000); +SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743; +col_1_longtext = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_blob (3072)); +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE +col_1_blob PRIMARY 3072 BTREE +col_1_blob prefix_idx 3072 BTREE +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743; +col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +col_1_blob = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743; +col_1_blob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_mediumblob MEDIUMBLOB , col_2_mediumblob MEDIUMBLOB , +PRIMARY KEY (col_1_mediumblob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_mediumblob (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_mediumblob = REPEAT("a", 4000),col_2_mediumblob = REPEAT("o", 4000) +FROM worklog5743; +col_1_mediumblob = REPEAT("a", 4000) col_2_mediumblob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_mediumblob = REPEAT("c", 4000) +WHERE col_1_mediumblob = REPEAT("a", 4000) +AND col_2_mediumblob = REPEAT("o", 4000); +SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_mediumblob = REPEAT("c", 4000) +AND col_2_mediumblob = REPEAT("o", 4000); +col_1_mediumblob = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_mediumblob = REPEAT("b", 4000); +SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743; +col_1_mediumblob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_longblob LONGBLOB , col_2_longblob LONGBLOB , +PRIMARY KEY (col_1_longblob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_longblob (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_longblob = REPEAT("a", 4000) , col_2_longblob = REPEAT("o", 4000) +FROM worklog5743; +col_1_longblob = REPEAT("a", 4000) col_2_longblob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_longblob = REPEAT("c", 4000) +WHERE col_1_longblob = REPEAT("a", 4000) +AND col_2_longblob = REPEAT("o", 4000); +SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_longblob = REPEAT("c", 4000) +AND col_2_longblob = REPEAT("o", 4000); +col_1_longblob = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_longblob = REPEAT("b", 4000); +SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743; +col_1_longblob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) , +PRIMARY KEY (col_1_varbinary(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varbinary = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 (col_1_char CHAR (255) , col_2_char CHAR (255), +col_3_char CHAR (255), col_4_char CHAR (255),col_5_char CHAR (255), +col_6_char CHAR (255), col_7_char CHAR (255),col_8_char CHAR (255), +col_9_char CHAR (255), col_10_char CHAR (255),col_11_char CHAR (255), +col_12_char CHAR (255), col_13_char CHAR (255),col_14_char CHAR (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +CREATE INDEX prefix_idx ON worklog5743(col_1_char(250),col_2_char(250), +col_3_char(250),col_4_char(250),col_5_char(250),col_6_char(250), +col_7_char(250),col_8_char(250),col_9_char(250),col_10_char(250), +col_11_char(250),col_12_char(250),col_13_char(72) +); +INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +SELECT col_1_char = REPEAT("a", 255) , col_2_char = REPEAT("o", 255) FROM worklog5743; +col_1_char = REPEAT("a", 255) col_2_char = REPEAT("o", 255) +1 1 +0 0 +UPDATE worklog5743 SET col_1_char = REPEAT("c", 255) +WHERE col_1_char = REPEAT("a", 255) AND col_2_char = REPEAT("o", 255); +SELECT col_1_char = REPEAT("c", 255) FROM worklog5743 +WHERE col_1_char = REPEAT("c", 255) AND col_2_char = REPEAT("o", 255); +col_1_char = REPEAT("c", 255) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_char = REPEAT("b", 255); +SELECT col_1_char = REPEAT("c", 255) FROM worklog5743; +col_1_char = REPEAT("c", 255) +1 +0 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 (col_1_binary BINARY (255) , col_2_binary BINARY (255), +col_3_binary BINARY(255),col_4_binary BINARY (255),col_5_binary BINARY (255), +col_6_binary BINARY(255),col_7_binary BINARY (255),col_8_binary BINARY (255), +col_9_binary BINARY(255),col_10_binary BINARY (255),col_11_binary BINARY (255), +col_12_binary BINARY(255),col_13_binary BINARY (255),col_14_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +CREATE INDEX prefix_idx ON worklog5743(col_1_binary (250),col_2_binary (250), +col_3_binary (250),col_4_binary (250),col_5_binary (250), +col_6_binary (250),col_7_binary (250),col_8_binary (250), +col_9_binary (250),col_10_binary (250),col_11_binary (250), +col_12_binary (250),col_13_binary (72) +); +INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +SELECT col_1_binary = REPEAT("a", 255) , col_2_binary = REPEAT("o", 255) FROM worklog5743; +col_1_binary = REPEAT("a", 255) col_2_binary = REPEAT("o", 255) +1 1 +0 0 +UPDATE worklog5743 SET col_1_binary = REPEAT("c", 255) +WHERE col_1_binary = REPEAT("a", 255) +AND col_2_binary = REPEAT("o", 255); +SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743 +WHERE col_1_binary = REPEAT("c", 255) +AND col_2_binary = REPEAT("o", 255); +col_1_binary = REPEAT("c", 255) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_binary = REPEAT("b", 255); +SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743; +col_1_binary = REPEAT("c", 255) +1 +0 +DROP TABLE worklog5743; +CREATE TABLE worklog5743_key2 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key2; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key2 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2 +WHERE col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key2; +CREATE TABLE worklog5743_key4 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key4; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key4 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key4; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key4; +CREATE TABLE worklog5743_key8 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key8; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key8 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key8; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key8; +CREATE TABLE worklog5743_key2 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key2; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key2 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key2 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key2; +col_1_text = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key2; +CREATE TABLE worklog5743_key4 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key4; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key4 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key4; +col_1_text = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key4; +CREATE TABLE worklog5743_key8 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key8; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key8 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key8; +col_1_text = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key8; +CREATE TABLE worklog5743_key2 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key2; +col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key2 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key2 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +col_1_blob = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key2; +col_1_blob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key2; +CREATE TABLE worklog5743_key4 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key4; +col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key4 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +col_1_blob = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key4; +col_1_blob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key4; +CREATE TABLE worklog5743_key8 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key8; +col_1_blob = REPEAT("a", 4000) col_2_blob = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743_key8 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +col_1_blob = REPEAT("b", 3500) +0 +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key8; +col_1_blob = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743_key8; +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) , +col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("c", 4000) +1 +0 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) , +col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072)); +CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072)); +CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072)); +CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072)); +CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072)); +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +ROLLBACK; +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +COMMIT; +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +ROLLBACK; +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("c", 4000) +0 +0 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) CHARACTER SET 'utf8', +col_2_text TEXT (4000) CHARACTER SET 'utf8', +PRIMARY KEY (col_1_text(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743; +col_1_text = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 (col_1_varchar VARCHAR (4000) CHARACTER SET 'utf8', +col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8' , +PRIMARY KEY (col_1_varchar(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , +col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8', +col_3_text TEXT (4000) CHARACTER SET 'utf8', +col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (500)); +CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (500)); +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +ROLLBACK; +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +COMMIT; +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +ROLLBACK; +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("c", 4000) +0 +0 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) CHARACTER SET 'utf8', +col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("स", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("स", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +col_1_text = REPEAT("स", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_text = REPEAT("क", 4000) +WHERE col_1_text = REPEAT("स", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("क", 4000) +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743; +col_1_text = REPEAT("क", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +"In connection 2" +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +0 1 +"In connection 1" +select @@session.tx_isolation; +@@session.tx_isolation +REPEATABLE-READ +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +0 1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +0 1 +1 1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +START TRANSACTION; +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +"In connection 2" +COMMIT; +"In connection 1" +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +0 1 +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +COMMIT; +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +START TRANSACTION; +"In connection 2" +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +0 1 +COMMIT; +"In connection 1" +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +@@session.tx_isolation +READ-UNCOMMITTED +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +1 1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +COMMIT; +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +START TRANSACTION; +"In connection 2" +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("a", 200) col_2_text = REPEAT("o", 200) +0 1 +ROLLBACK; +"In connection 1" +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +col_1_text = REPEAT("b", 200) col_2_text = REPEAT("o", 200) +0 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +COMMIT; +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +col_1_varchar = REPEAT("c", 4000) +0 +0 +1 +SELECT tbl1.col_1_varchar = tbl2.col_1_varchar +FROM worklog5743 tbl1 , worklog5743 tbl2 +WHERE tbl1.col_1_varchar = tbl2.col_1_varchar ; +tbl1.col_1_varchar = tbl2.col_1_varchar +1 +1 +1 +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ; +tbl1.col_1_varchar = REPEAT("c", 4000) +0 +0 +1 +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar NOT IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ; +tbl1.col_1_varchar = REPEAT("c", 4000) +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 WHERE +col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) +AND col_1_varchar = REPEAT("c", 4000); +tbl1.col_1_varchar = REPEAT("c", 4000) +1 +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar in ( +SELECT tbl2.col_1_varchar FROM worklog5743 tbl2 +WHERE tbl1.col_1_varchar != tbl2.col_1_varchar +) ; +tbl1.col_1_varchar = REPEAT("c", 4000) +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar in ( +SELECT tbl2.col_1_varchar FROM worklog5743 tbl2 +WHERE tbl1.col_1_varchar = tbl2.col_1_varchar +) ; +tbl1.col_1_varchar = REPEAT("c", 4000) +0 +0 +1 +SELECT +REVERSE(col_1_varchar) = REPEAT("c", 4000) , +REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000) +FROM worklog5743; +REVERSE(col_1_varchar) = REPEAT("c", 4000) REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000) +0 0 +0 0 +1 1 +SELECT +UPPER(col_1_varchar) = REPEAT("c", 4000) , +UPPER(col_1_varchar) = REPEAT("C", 4000) , +LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000) +FROM worklog5743; +UPPER(col_1_varchar) = REPEAT("c", 4000) UPPER(col_1_varchar) = REPEAT("C", 4000) LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000) +0 0 0 +0 0 0 +1 1 1 +SELECT +col_1_varchar = REPEAT("c", 4000) +FROM worklog5743 WHERE col_1_varchar like '%c__%'; +col_1_varchar = REPEAT("c", 4000) +1 +SELECT SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10) FROM worklog5743 ; +SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10) +kkkkaaaaaa +kkkkbbbbbb +kkkkcccccc +SELECT CONCAT(SUBSTRING(col_1_varchar,-5,3),'append') FROM worklog5743 ; +CONCAT(SUBSTRING(col_1_varchar,-5,3),'append') +aaaappend +bbbappend +cccappend +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , +col_2_varchar VARCHAR (4000) , +UNIQUE INDEX (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), REPEAT("o", 4000)); +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000)); +INSERT INTO worklog5743 VALUES(NULL,NULL); +INSERT INTO worklog5743 VALUES(NULL,NULL); +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE +FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +COLUMN_NAME INDEX_NAME SUB_PART INDEX_TYPE +col_1_varchar col_1_varchar 3072 BTREE +SELECT col_1_varchar FROM worklog5743 WHERE col_1_varchar IS NULL; +col_1_varchar +NULL +NULL +SELECT col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000)) +FROM worklog5743 WHERE col_1_varchar IS NOT NULL ORDER BY 1; +col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000)) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072))) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY `prefix_primary` (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY' +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY `prefix_primary` (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +col_1_varchar = REPEAT("a", 4000) col_2_varchar = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +col_1_varchar = REPEAT("c", 4000) +1 +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY' +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +col_1_varchar = REPEAT("c", 4000) +0 +1 +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR(4000) , col_2_varchar VARCHAR(4000) , +PRIMARY KEY (col_1_varchar (3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("c", 3500) , REPEAT("o", 3500)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +" Switching to con1 connection For select " +SELECT col_1_varchar = REPEAT("c", 3500) , col_2_varchar = REPEAT("o", 3500) +FROM worklog5743; +col_1_varchar = REPEAT("c", 3500) col_2_varchar = REPEAT("o", 3500) +1 1 +" Switching to default connection For DMLs " +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500)); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("o", 3500); +col_1_varchar = REPEAT("b", 3500) +0 +0 +COMMIT; +" Switching to con1 connection For Dropping index and some DMLs " +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("k", 3500),REPEAT("p", 3500)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +UPDATE worklog5743 SET col_1_varchar = REPEAT("b", 3500) +WHERE col_1_varchar = REPEAT("a", 3500) +AND col_2_varchar = REPEAT("o", 3500); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("o", 3500); +col_1_varchar = REPEAT("b", 3500) +1 +0 +" Switching to default connection For DELETE " +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 3500); +SELECT col_1_varchar = REPEAT("a", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("p", 3500); +col_1_varchar = REPEAT("a", 3500) +0 +" Switching to con1 connection to commit changes " +COMMIT; +" Switching to default connection to drop and end sub-test " +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) , +PRIMARY KEY (col_1_varbinary(3072))) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000) +FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) col_2_varbinary = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +1 +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_varbinary = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("b", 4000) +AND col_2_varbinary = REPEAT("p", 4000); +col_1_varbinary = REPEAT("b", 4000) +1 +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (2000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) +1 +0 +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +DROP INDEX prefix_idx ON worklog5743; +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (4000)); +Warnings: +Warning 1071 Specified key was too long; max key length is 3072 bytes +Warning 1071 Specified key was too long; max key length is 3072 bytes +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743; +col_1_varbinary = REPEAT("a", 4000) +1 +0 +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +col_1_varbinary = REPEAT("c", 4000) +DROP TABLE worklog5743; +CREATE TABLE worklog5743 (col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(500)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +1 +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("b", 4000) AND col_2_text = REPEAT("p", 4000); +col_1_text = REPEAT("b", 4000) +1 +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) +1 +0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +DROP INDEX prefix_idx ON worklog5743; +CREATE INDEX prefix_idx ON worklog5743(col_1_text (4000)); +Warnings: +Warning 1071 Specified key was too long; max key length is 3072 bytes +Warning 1071 Specified key was too long; max key length is 3072 bytes +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) +1 +0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) col_2_text = REPEAT("o", 4000) +1 1 +0 0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +1 +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +ALTER TABLE worklog5743 DROP PRIMARY KEY; +SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("b", 4000) +AND col_2_text = REPEAT("p", 4000); +col_1_text = REPEAT("b", 4000) +1 +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (700)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) +1 +0 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (950)); +ERROR HY000: Too big row +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +col_1_text = REPEAT("a", 4000) +0 +1 +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +col_1_text = REPEAT("c", 4000) +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (900)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (3073)); +ERROR 42000: Specified key was too long; max key length is 3072 bytes +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_BLOB BLOB (4000) , PRIMARY KEY (col_1_BLOB(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (500)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (3073)); +ERROR 42000: Specified key was too long; max key length is 3072 bytes +DROP TABLE worklog5743; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), +REPEAT("o", 4000)); +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000)); +ALTER TABLE worklog5743 ADD PRIMARY KEY `pk_idx` (col_1_varchar(3000)); +ERROR 23000: Duplicate entry 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' for key 'PRIMARY' +DROP TABLE worklog5743; +set global innodb_large_prefix=0; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ERROR 42000: Specified key was too long; max key length is 767 bytes +set global innodb_large_prefix=0; +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(767)) +) engine = innodb; +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1000)); +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +Warning 1071 Specified key was too long; max key length is 767 bytes +DROP TABLE worklog5743; +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_per_table=0; +SET GLOBAL innodb_file_format_max=Antelope; +SET GLOBAL innodb_large_prefix=0; diff --git a/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result b/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result new file mode 100644 index 00000000000..09756954b92 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result @@ -0,0 +1,91 @@ +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; +DROP TABLE IF EXISTS worklog5743; +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500)); +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +"In connection 2" +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500)); +"In connection 1" +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +START TRANSACTION; +"In connection default ....restarting the server" +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500); +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +"In connection default ....restarting the server" +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +"In connection 1" +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +START TRANSACTION; +UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500); +SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("b", 3500) col_2_text = REPEAT("o", 3500) +1 1 +"In connection default ....restarting the server" +SELECT COUNT(*) FROM worklog5743; +COUNT(*) +1 +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) +1 1 +DROP TABLE worklog5743; +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_per_table=0; +SET GLOBAL innodb_file_format_max=Antelope; +SET GLOBAL innodb_large_prefix=0; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index be555c6104e..9f7bd92fb83 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -426,36 +426,36 @@ create table t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob, i blob,j blob,k blob,l blob,m blob,n blob,o blob,p blob, q blob,r blob,s blob,t blob,u blob) engine=innodb row_format=dynamic; -create index t1a on t1 (a(1)); -create index t1b on t1 (b(1)); -create index t1c on t1 (c(1)); -create index t1d on t1 (d(1)); -create index t1e on t1 (e(1)); -create index t1f on t1 (f(1)); -create index t1g on t1 (g(1)); -create index t1h on t1 (h(1)); -create index t1i on t1 (i(1)); -create index t1j on t1 (j(1)); -create index t1k on t1 (k(1)); -create index t1l on t1 (l(1)); -create index t1m on t1 (m(1)); -create index t1n on t1 (n(1)); -create index t1o on t1 (o(1)); -create index t1p on t1 (p(1)); -create index t1q on t1 (q(1)); -create index t1r on t1 (r(1)); -create index t1s on t1 (s(1)); -create index t1t on t1 (t(1)); +create index t1a on t1 (a(767)); +create index t1b on t1 (b(767)); +create index t1c on t1 (c(767)); +create index t1d on t1 (d(767)); +create index t1e on t1 (e(767)); +create index t1f on t1 (f(767)); +create index t1g on t1 (g(767)); +create index t1h on t1 (h(767)); +create index t1i on t1 (i(767)); +create index t1j on t1 (j(767)); +create index t1k on t1 (k(767)); +create index t1l on t1 (l(767)); +create index t1m on t1 (m(767)); +create index t1n on t1 (n(767)); +create index t1o on t1 (o(767)); +create index t1p on t1 (p(767)); +create index t1q on t1 (q(767)); +create index t1r on t1 (r(767)); +create index t1s on t1 (s(767)); +create index t1t on t1 (t(767)); --error 139 -create index t1u on t1 (u(1)); +create index t1u on t1 (u(767)); --error 139 -create index t1ut on t1 (u(1), t(1)); -create index t1st on t1 (s(1), t(1)); +create index t1ut on t1 (u(767), t(767)); +create index t1st on t1 (s(767), t(767)); show create table t1; --error 139 -create index t1u on t1 (u(1)); +create index t1u on t1 (u(767)); alter table t1 row_format=compact; -create index t1u on t1 (u(1)); +create index t1u on t1 (u(767)); drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_index_large_prefix.test b/mysql-test/suite/innodb/t/innodb_index_large_prefix.test new file mode 100644 index 00000000000..3ed8aa6e096 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_index_large_prefix.test @@ -0,0 +1,271 @@ +# Testcase for worklog #5743: Lift the limit of index key prefixes + +--source include/have_innodb.inc + +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; + +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; + +# Create a table of DYNAMIC format, with a primary index of 1000 bytes in +# size +create table worklog5743(a TEXT not null, primary key (a(1000))) +ROW_FORMAT=DYNAMIC, engine = innodb; + +# Do some insertion and update to excercise the external cache +# code path +insert into worklog5743 values(repeat("a", 20000)); + +# default session, update the table +update worklog5743 set a = (repeat("b", 16000)); + +# Create a secondary index +create index idx on worklog5743(a(2000)); + +# Start a few sessions to do selections on table being updated in default +# session, so it would rebuild the previous version from undo log. +# 1) Default session: Initiate an update on the externally stored column +# 2) Session con1: Select from table with repeated read +# 3) Session con2: Select from table with read uncommitted +# 4) Default session: rollback updates + +begin; +update worklog5743 set a = (repeat("x", 17000)); + +# Start a new session to select the column to force it build +# an earlier version of the clustered index through undo log. So it should +# just see the result of repeat("b", 16000) +select @@session.tx_isolation; +--connect (con1,localhost,root,,) +select a = repeat("x", 17000) from worklog5743; +select a = repeat("b", 16000) from worklog5743; + +# Start another session doing "read uncommitted" query, it +# should see the uncommitted update +--connect (con2,localhost,root,,) +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 17000) from worklog5743; + +# Roll back the transaction +--connection default +rollback; + +drop table worklog5743; + +# Create a table with only a secondary index has large prefix column +create table worklog5743(a1 int, a2 TEXT not null) +ROW_FORMAT=DYNAMIC, engine = innodb; + +create index idx on worklog5743(a1, a2(2000)); + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +# Create a table with a secondary index has small (50 bytes) prefix column +create table worklog5743(a1 int, a2 TEXT not null) +ROW_FORMAT=DYNAMIC, engine = innodb; + +create index idx on worklog5743(a1, a2(50)); + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +# Create a table of ROW_FORMAT=COMPRESSED format +create table worklog5743_2(a1 int, a2 TEXT not null) +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; + +create table worklog5743_4(a1 int, a2 TEXT not null) +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; + +# The maximum overall index record (not prefix) length for this table +# is page_zip_empty_size() / 2, which is 960. "Too big row" error ( +# HA_ERR_TO_BIG_ROW) will be printed if this limit is exceeded. +# Considering other fields and their overhead, the maximum length +# for column a2 is 940 or 941 depending on the zlib version used and +# compressBound() value used in page_zip_empty_size() (please refer +# to Bug #47495 for more detail). +-- error 139 +create index idx1 on worklog5743_2(a1, a2(942)); + +create index idx1 on worklog5743_2(a1, a2(940)); + +# similarly, the maximum index record length for the table is +# 1984. Considering other fields and their overhead, the +# maximum length for column a2 is 1964 or 1965 (please refer +# to Bug #47495 for more detail). +-- error 139 +create index idx1 on worklog5743_4(a1, a2(1966)); + +create index idx1 on worklog5743_4(a1, a2(1964)); + +insert into worklog5743_2 values(9, repeat("a", 10000)); +insert into worklog5743_4 values(9, repeat("a", 10000)); + +begin; + +update worklog5743_2 set a1 = 1000; +update worklog5743_4 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743_2 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743_4 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743_2; +drop table worklog5743_4; + +# Create a table with varchar column, and create index directly on this +# large column (without prefix) +create table worklog5743(a1 int, a2 varchar(3000)) +ROW_FORMAT=DYNAMIC, engine = innodb; + +# Create an index with large column without prefix +create index idx on worklog5743(a1, a2); + +insert into worklog5743 values(9, repeat("a", 3000)); + +begin; + +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1 from worklog5743 where a1 = 9; +select a1 from worklog5743 where a1 = 9; + +# Do read uncommitted, it would show there is no row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1 from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +# Create a table with old format, and the limit is 768 bytes. +-- error ER_INDEX_COLUMN_TOO_LONG +create table worklog5743(a TEXT not null, primary key (a(1000))) +engine = innodb; + +create table worklog5743(a TEXT) engine = innodb; + +# Excercise the column length check in ha_innobase::add_index() +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(1000)); + +# This should be successful +create index idx on worklog5743(a(725)); + +# Perform some DMLs +insert into worklog5743 values(repeat("a", 20000)); + +begin; +insert into worklog5743 values(repeat("b", 20000)); +update worklog5743 set a = (repeat("x", 25000)); + +# Start a new session to select the table to force it build +# an earlier version of the cluster index through undo log +select @@session.tx_isolation; +--connection con1 +select a = repeat("a", 20000) from worklog5743; + +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 25000) from worklog5743; + +--connection default +rollback; + +drop table worklog5743; + +# Some border line test on the column length. +# We have a limit of 3072 bytes for Barracuda table +create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC, engine = innodb; + +# Length exceeds maximum supported key length, will auto-truncated to 3072 +create index idx on worklog5743(a(3073)); + +create index idx2 on worklog5743(a(3072)); + +show create table worklog5743; + +drop table worklog5743; + +# We have a limit of 767 bytes for Antelope table +create table worklog5743(a TEXT not null) engine = innodb; + +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); + +create index idx2 on worklog5743(a(767)); + +drop table worklog5743; + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig; diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index acc843341eb..910b93b443b 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -830,8 +830,6 @@ SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; ---echo End of 5.1 tests - --echo # --echo # Test for bug #39932 "create table fails if column for FK is in different @@ -852,6 +850,28 @@ drop table t2, t1; --echo # +--echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +--echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +--echo # Even though temporary table was locked for READ we +--echo # still allow writes to it to be compatible with MyISAM. +--echo # This is possible since due to fact that temporary tables +--echo # are specific to connection and therefore locking for them +--echo # is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; + +--echo End of 5.1 tests + + +--echo # --echo # Bug#44613 SELECT statement inside FUNCTION takes a shared lock --echo # diff --git a/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test b/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test new file mode 100644 index 00000000000..2bc89bf05d2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test @@ -0,0 +1,1339 @@ +######## suite/innodb/t/innodb_prefix_index_liftedlimit.test ########## +# # +# Testcase for worklog WL#5743: Lift the limit of index key prefixes # +# Accorrding to WL#5743 - prefix index limit is increased from 767 # +# to 3072 for innodb. This change is applicable with Barracuda file # +# format. # +# All sub-test in this file focus on prefix index along with other # +# operations # +# # +# # +# Creation: # +# 2011-05-19 Implemented this test as part of WL#5743 # +# # +###################################################################### + + +--source include/have_innodb.inc +# Save innodb variables +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; + +# Set Innodb file format as feature works for Barracuda file format +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; + +-- disable_warnings +DROP TABLE IF EXISTS worklog5743; +-- enable_warnings +#------------------------------------------------------------------------------ +# Prefix index with VARCHAR data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +# check IS +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with TEXT data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072)); +# check IS +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with MEDIUMTEXT data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_mediumtext MEDIUMTEXT , col_2_mediumtext MEDIUMTEXT , +PRIMARY KEY (col_1_mediumtext(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_mediumtext (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_mediumtext = REPEAT("a", 4000),col_2_mediumtext = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_mediumtext = REPEAT("c", 4000) +WHERE col_1_mediumtext = REPEAT("a", 4000) +AND col_2_mediumtext = REPEAT("o", 4000); +SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_mediumtext = REPEAT("c", 4000) +AND col_2_mediumtext = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_mediumtext = REPEAT("b", 4000); +SELECT col_1_mediumtext = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with LONGTEXT data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_longtext LONGTEXT , col_2_longtext LONGTEXT , +PRIMARY KEY (col_1_longtext(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_longtext (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_longtext = REPEAT("a", 4000) , col_2_longtext = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_longtext = REPEAT("c", 4000) +WHERE col_1_longtext = REPEAT("a", 4000) +AND col_2_longtext = REPEAT("o", 4000); +SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_longtext = REPEAT("c", 4000) +AND col_2_longtext = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_longtext = REPEAT("b", 4000); +SELECT col_1_longtext = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with BLOB data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_blob (3072)); +# check IS +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE FROM +INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with MEDIUMBLOB data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_mediumblob MEDIUMBLOB , col_2_mediumblob MEDIUMBLOB , +PRIMARY KEY (col_1_mediumblob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_mediumblob (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_mediumblob = REPEAT("a", 4000),col_2_mediumblob = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_mediumblob = REPEAT("c", 4000) +WHERE col_1_mediumblob = REPEAT("a", 4000) +AND col_2_mediumblob = REPEAT("o", 4000); +SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_mediumblob = REPEAT("c", 4000) +AND col_2_mediumblob = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_mediumblob = REPEAT("b", 4000); +SELECT col_1_mediumblob = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with LONGBLOB data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_longblob LONGBLOB , col_2_longblob LONGBLOB , +PRIMARY KEY (col_1_longblob(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_longblob (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_longblob = REPEAT("a", 4000) , col_2_longblob = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_longblob = REPEAT("c", 4000) +WHERE col_1_longblob = REPEAT("a", 4000) +AND col_2_longblob = REPEAT("o", 4000); +SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_longblob = REPEAT("c", 4000) +AND col_2_longblob = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_longblob = REPEAT("b", 4000); +SELECT col_1_longblob = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with VARBINARY data type , primary/secondary index and DML ops +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) , +PRIMARY KEY (col_1_varbinary(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with CHAR data type , composite index and DML ops +CREATE TABLE worklog5743 (col_1_char CHAR (255) , col_2_char CHAR (255), +col_3_char CHAR (255), col_4_char CHAR (255),col_5_char CHAR (255), +col_6_char CHAR (255), col_7_char CHAR (255),col_8_char CHAR (255), +col_9_char CHAR (255), col_10_char CHAR (255),col_11_char CHAR (255), +col_12_char CHAR (255), col_13_char CHAR (255),col_14_char CHAR (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +# Create index with total prefix index length = 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_char(250),col_2_char(250), +col_3_char(250),col_4_char(250),col_5_char(250),col_6_char(250), +col_7_char(250),col_8_char(250),col_9_char(250),col_10_char(250), +col_11_char(250),col_12_char(250),col_13_char(72) +); +INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +SELECT col_1_char = REPEAT("a", 255) , col_2_char = REPEAT("o", 255) FROM worklog5743; +UPDATE worklog5743 SET col_1_char = REPEAT("c", 255) +WHERE col_1_char = REPEAT("a", 255) AND col_2_char = REPEAT("o", 255); +SELECT col_1_char = REPEAT("c", 255) FROM worklog5743 +WHERE col_1_char = REPEAT("c", 255) AND col_2_char = REPEAT("o", 255); +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255),REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_char = REPEAT("b", 255); +SELECT col_1_char = REPEAT("c", 255) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with BINARY data type , composite index and DML ops +CREATE TABLE worklog5743 (col_1_binary BINARY (255) , col_2_binary BINARY (255), +col_3_binary BINARY(255),col_4_binary BINARY (255),col_5_binary BINARY (255), +col_6_binary BINARY(255),col_7_binary BINARY (255),col_8_binary BINARY (255), +col_9_binary BINARY(255),col_10_binary BINARY (255),col_11_binary BINARY (255), +col_12_binary BINARY(255),col_13_binary BINARY (255),col_14_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +# Create index with total prefix index length = 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_binary (250),col_2_binary (250), +col_3_binary (250),col_4_binary (250),col_5_binary (250), +col_6_binary (250),col_7_binary (250),col_8_binary (250), +col_9_binary (250),col_10_binary (250),col_11_binary (250), +col_12_binary (250),col_13_binary (72) +); +INSERT INTO worklog5743 VALUES(REPEAT("b", 255) , REPEAT("p", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +SELECT col_1_binary = REPEAT("a", 255) , col_2_binary = REPEAT("o", 255) FROM worklog5743; +UPDATE worklog5743 SET col_1_binary = REPEAT("c", 255) +WHERE col_1_binary = REPEAT("a", 255) +AND col_2_binary = REPEAT("o", 255); +SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743 +WHERE col_1_binary = REPEAT("c", 255) +AND col_2_binary = REPEAT("o", 255); +INSERT INTO worklog5743 VALUES(REPEAT("a", 255) , REPEAT("o", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255), +REPEAT("a", 255) , REPEAT("o", 255), REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_binary = REPEAT("b", 255); +SELECT col_1_binary = REPEAT("c", 255) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with VARCHAR data type , primary/seconday index , DML ops +# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8. + +# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following +CREATE TABLE worklog5743_key2 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_varchar (767)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key2; +UPDATE worklog5743_key2 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2 +WHERE col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key2; +DROP TABLE worklog5743_key2; + +# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following +CREATE TABLE worklog5743_key4 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_varchar (767)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key4; +UPDATE worklog5743_key4 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key4; +DROP TABLE worklog5743_key4; + +# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following +CREATE TABLE worklog5743_key8 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_varchar (767)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743_key8; +UPDATE worklog5743_key8 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743_key8; +DROP TABLE worklog5743_key8; + +# Prefix index with TEXT data type , primary/seconday index , DML ops +# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8. + +# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following +CREATE TABLE worklog5743_key2 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_text (767)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key2; +UPDATE worklog5743_key2 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key2 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key2; +DROP TABLE worklog5743_key2; + +# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following +CREATE TABLE worklog5743_key4 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_text (767)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key4; +UPDATE worklog5743_key4 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key4; +DROP TABLE worklog5743_key4; + +# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following +CREATE TABLE worklog5743_key8 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_text (767)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743_key8; +UPDATE worklog5743_key8 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743_key8; +DROP TABLE worklog5743_key8; + +# Prefix index with BLOB data type , primary/seconday index , DML ops +# and COMPRESSED row format. KEY_BLOCK_SIZE is varied as 2 , 4 , 8. + +# With KEY_BLOCK_SIZE = 2,prefix index limit comes around ~948 for following +CREATE TABLE worklog5743_key2 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key2 (col_1_blob (767)); +INSERT INTO worklog5743_key2 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key2; +UPDATE worklog5743_key2 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key2 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +INSERT INTO worklog5743_key2 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key2 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key2; +DROP TABLE worklog5743_key2; + +# With KEY_BLOCK_SIZE = 4,prefix index limit comes around ~1964 for following +CREATE TABLE worklog5743_key4 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(1964)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, engine = innodb; +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key4 (col_1_blob (767)); +INSERT INTO worklog5743_key4 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key4; +UPDATE worklog5743_key4 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key4 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +INSERT INTO worklog5743_key4 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key4 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key4; +DROP TABLE worklog5743_key4; + +# With KEY_BLOCK_SIZE = 8,prefix index limit comes around ~3072 for following +CREATE TABLE worklog5743_key8 ( +col_1_blob BLOB (4000) , col_2_blob BLOB (4000) , +PRIMARY KEY (col_1_blob(3072)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8, engine = innodb; +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +#CREATE INDEX prefix_idx ON worklog5743_key8 (col_1_blob (767)); +INSERT INTO worklog5743_key8 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_blob = REPEAT("a", 4000) , col_2_blob = REPEAT("o", 4000) +FROM worklog5743_key8; +UPDATE worklog5743_key8 SET col_1_blob = REPEAT("c", 4000) +WHERE col_1_blob = REPEAT("a", 4000) AND col_2_blob = REPEAT("o", 4000); +SELECT col_1_blob = REPEAT("b", 3500) FROM worklog5743_key8 +WHERE col_1_blob = REPEAT("c", 4000) AND col_2_blob = REPEAT("o", 4000); +INSERT INTO worklog5743_key8 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743_key8 WHERE col_1_blob = REPEAT("b", 4000); +SELECT col_1_blob = REPEAT("c", 4000) FROM worklog5743_key8; +DROP TABLE worklog5743_key8; + + +#------------------------------------------------------------------------------ +# Create mutiple prefix index. We can not create prefix index length > 16K +# as index is written in undo log page which of 16K size. +# So we can create max 5 prefix index of length 3072 on table +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) , +col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); + +# Update hangs if we create following 5 indexes. Uncomment them once its fix +# Bug#12547647 - UPDATE LOGGING COULD EXCEED LOG PAGE SIZE +#CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072)); +#CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072)); +#CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072)); +#CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072)); +#CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072)); + +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Create mutiple prefix index. We can not create prefix index length > 16K as +# we write in undo log page which of 16K size. +# so we can create max 5 prefix index of length 3072 on table. +# Similar to above case but with transactions +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) , +col_3_text TEXT (4000), col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; + + +# Update hangs if we create following 5 indexes. Uncomment them once its fix +CREATE INDEX prefix_idx1 ON worklog5743(col_1_varbinary (3072)); +CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (3072)); +CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (3072)); +CREATE INDEX prefix_idx4 ON worklog5743(col_4_blob (3072)); +CREATE INDEX prefix_idx5 ON worklog5743(col_5_text (3072)); + +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +ROLLBACK; +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +COMMIT; +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; + +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +ROLLBACK; +# Uncomment Update fater Bug#12547647 is fixed - UPDATE LOGGING COULD EXCEED LOG PAGE SIZE +# Bug#12547647 - UPDATE LOGGING COULD EXCEED LOG PAGE SIZE +#UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +#WHERE col_1_varbinary = REPEAT("a", 4000) +#AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with utf8 charset +# utf8 charcter takes 3 bytes in mysql so prefix index limit is 3072/3 = 1024 +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) CHARACTER SET 'utf8', +col_2_text TEXT (4000) CHARACTER SET 'utf8', +PRIMARY KEY (col_1_text(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +# Prefix index with utf8 charset + varchar. +# For varchar we also log the column itself as oppose of TEXT so it error +# with limit 1024 due to overhead. +-- error 1118 +CREATE TABLE worklog5743 (col_1_varchar VARCHAR (4000) CHARACTER SET 'utf8', +col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8' , +PRIMARY KEY (col_1_varchar(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; + +#------------------------------------------------------------------------------ +# prefinx index on utf8 charset with transaction +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , +col_2_varchar VARCHAR (4000) CHARACTER SET 'utf8', +col_3_text TEXT (4000) CHARACTER SET 'utf8', +col_4_blob BLOB (4000),col_5_text TEXT (4000), +col_6_varchar VARCHAR (4000), col_7_binary BINARY (255) +) ROW_FORMAT=DYNAMIC, engine = innodb; + + +CREATE INDEX prefix_idx2 ON worklog5743(col_2_varchar (500)); +CREATE INDEX prefix_idx3 ON worklog5743(col_3_text (500)); + +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +ROLLBACK; +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +COMMIT; +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; + +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +ROLLBACK; +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000), +REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000), +REPEAT("a", 4000) , REPEAT("a", 255) +); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("b", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with utf8 charset on TEXT data type with actual utf8 character +# like "स" and "क" +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) CHARACTER SET 'utf8', +col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(1024)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("स", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1024)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("स", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("क", 4000) +WHERE col_1_text = REPEAT("स", 4000) AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 4000); +SELECT col_1_text = REPEAT("क", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with transaction when 2 client are ruuning there transaction +# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and +# READ UNCOMMITTED. +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; + +--echo "In connection 1" +--connect (con1,localhost,root,,) +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; + + +--echo "In connection 2" +--connect (con2,localhost,root,,) +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +# Uncomment after Bug#12552164 - TRANSACTION CAN NOT SEE OLD VERSION ROWS THAT +# BEING UPDATED +#UPDATE worklog5743 SET col_1_varchar = REPEAT("d", 200) WHERE col_1_varchar = +#REPEAT("a", 200) AND col_2_varchar = REPEAT("o", 200); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; + + +--echo "In connection 1" +--connection con1 +select @@session.tx_isolation; +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +START TRANSACTION; + +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; + +--echo "In connection 2" +--connection con2 +COMMIT; +# Wait for commit +let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist +WHERE info='COMMIT'; +--source include/wait_condition.inc + +--echo "In connection 1" +--connection con1 +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +COMMIT; + +--connection default +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Prefix index with transaction when 2 client are ruuning there transaction +# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and +# READ UNCOMMITTED. Same as above case but con2 starts tnx before con1 + +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; + +--echo "In connection 1" +--connection con1 +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +START TRANSACTION; + + +--echo "In connection 2" +--connection con2 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +COMMIT; +# Wait for commit +let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist +WHERE info='COMMIT'; +--source include/wait_condition.inc + + +--echo "In connection 1" +--connection con1 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +COMMIT; + +--connection default +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ + +# Prefix index with transaction when 2 client are ruuning there transaction +# in different sessions.With ISOLATION LEVEL as REPEATABLE READ and +# READ UNCOMMITTED. Same as above cases but with ROLLBACK + +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 200) , REPEAT("o", 200)); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; + +--echo "In connection 1" +--connection con1 +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +START TRANSACTION; + + +--echo "In connection 2" +--connection con2 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 200) , REPEAT("o", 200)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("a", 200); +SELECT col_1_text = REPEAT("a", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +ROLLBACK; +# Wait for rollback +let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist +WHERE info='COMMIT'; +--source include/wait_condition.inc + + +--echo "In connection 1" +--connection con1 +SELECT col_1_text = REPEAT("b", 200) , col_2_text = REPEAT("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +COMMIT; + +--disconnect con1 +--disconnect con2 + +--connection default +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ +# Select queries on prefix index column as index will be used in queries. +# Use few select functions , join condition , subqueries. + +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; + +# Select with Join +SELECT tbl1.col_1_varchar = tbl2.col_1_varchar +FROM worklog5743 tbl1 , worklog5743 tbl2 +WHERE tbl1.col_1_varchar = tbl2.col_1_varchar ; + +# Select in subquey +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ; +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar NOT IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) ; +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 WHERE +col_1_varchar IN (SELECT tbl2.col_1_varchar FROM worklog5743 tbl2) +AND col_1_varchar = REPEAT("c", 4000); +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar in ( +SELECT tbl2.col_1_varchar FROM worklog5743 tbl2 +WHERE tbl1.col_1_varchar != tbl2.col_1_varchar +) ; +SELECT tbl1.col_1_varchar = REPEAT("c", 4000) FROM worklog5743 tbl1 +WHERE col_1_varchar in ( +SELECT tbl2.col_1_varchar FROM worklog5743 tbl2 +WHERE tbl1.col_1_varchar = tbl2.col_1_varchar +) ; + +# function +SELECT +REVERSE(col_1_varchar) = REPEAT("c", 4000) , +REVERSE(REVERSE(col_1_varchar)) = REPEAT("c", 4000) +FROM worklog5743; +SELECT +UPPER(col_1_varchar) = REPEAT("c", 4000) , +UPPER(col_1_varchar) = REPEAT("C", 4000) , +LOWER(UPPER(col_1_varchar)) = REPEAT("c", 4000) +FROM worklog5743; +SELECT +col_1_varchar = REPEAT("c", 4000) +FROM worklog5743 WHERE col_1_varchar like '%c__%'; +SELECT SUBSTRING(INSERT(col_1_varchar, 1, 4, 'kkkk'),1,10) FROM worklog5743 ; +SELECT CONCAT(SUBSTRING(col_1_varchar,-5,3),'append') FROM worklog5743 ; + + +DROP TABLE worklog5743; + +#------------------------------------------------------------------------------ +# Prefix index with NULL values +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , +col_2_varchar VARCHAR (4000) , +UNIQUE INDEX (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), REPEAT("o", 4000)); +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000)); +INSERT INTO worklog5743 VALUES(NULL,NULL); +INSERT INTO worklog5743 VALUES(NULL,NULL); +# check IS +SELECT COLUMN_NAME,INDEX_NAME,SUB_PART,INDEX_TYPE +FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'worklog5743' ; +SELECT col_1_varchar FROM worklog5743 WHERE col_1_varchar IS NULL; +SELECT col_1_varchar = concat(REPEAT("a", 2000),REPEAT("b", 2000)) +FROM worklog5743 WHERE col_1_varchar IS NOT NULL ORDER BY 1; + + +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- +# Try drop and add secondary prefix index +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072))) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +# Drop index +DROP INDEX prefix_idx ON worklog5743; + +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +# Again add index +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- + +# Try drop and add primary prefix index +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY `prefix_primary` (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +# Drop index +ALTER TABLE worklog5743 DROP PRIMARY KEY; + +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) +AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) +AND col_2_varchar = REPEAT("o", 4000); +# Again add index +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072)); + +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +--error 1062 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +# ----------------------------------------------------------------------------- + +# Try drop and add both (primary/secondary) prefix index +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY `prefix_primary` (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +# Drop primary index +ALTER TABLE worklog5743 DROP PRIMARY KEY; +# Drop secondary index +DROP INDEX prefix_idx ON worklog5743; + +SELECT col_1_varchar = REPEAT("a", 4000) , col_2_varchar = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varchar = REPEAT("c", 4000) +WHERE col_1_varchar = REPEAT("a", 4000) AND col_2_varchar = REPEAT("o", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varchar = REPEAT("c", 4000) AND col_2_varchar = REPEAT("o", 4000); +# Again add index +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar(3072)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); + +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +--error 1062 +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 4000); +SELECT col_1_varchar = REPEAT("c", 4000) FROM worklog5743; +DROP TABLE worklog5743; + + +# ----------------------------------------------------------------------------- +# Drop index from differnt session +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR(4000) , col_2_varchar VARCHAR(4000) , +PRIMARY KEY (col_1_varchar (3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("c", 3500) , REPEAT("o", 3500)); +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (3072)); + +# Start new session +--connect (con1,localhost,root,,) + + +--echo " Switching to con1 connection For select " +--connection con1 +SELECT col_1_varchar = REPEAT("c", 3500) , col_2_varchar = REPEAT("o", 3500) +FROM worklog5743; + +--echo " Switching to default connection For DMLs " +--connection default +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500)); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("o", 3500); +COMMIT; + +--echo " Switching to con1 connection For Dropping index and some DMLs " +--connection con1 +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("k", 3500),REPEAT("p", 3500)); +# Drop primary index +ALTER TABLE worklog5743 DROP PRIMARY KEY; +UPDATE worklog5743 SET col_1_varchar = REPEAT("b", 3500) +WHERE col_1_varchar = REPEAT("a", 3500) +AND col_2_varchar = REPEAT("o", 3500); +SELECT col_1_varchar = REPEAT("b", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("o", 3500); + +--echo " Switching to default connection For DELETE " +--connection default +DELETE FROM worklog5743 WHERE col_1_varchar = REPEAT("b", 3500); +SELECT col_1_varchar = REPEAT("a", 3500) FROM worklog5743 +WHERE col_2_varchar = REPEAT("p", 3500); + +--echo " Switching to con1 connection to commit changes " +--connection con1 +COMMIT; + +--echo " Switching to default connection to drop and end sub-test " +--connection default +DROP TABLE worklog5743; + + + +# ----------------------------------------------------------------------------- +# Create prefix index with length < 3072 , length = 3072 , length > 3072 +# - varbinary data type + secondary index +CREATE TABLE worklog5743 ( +col_1_varbinary VARBINARY (4000) , col_2_varbinary VARBINARY (4000) , +PRIMARY KEY (col_1_varbinary(3072))) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index of 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) , col_2_varbinary = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +# Drop index +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_varbinary = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("b", 4000) +AND col_2_varbinary = REPEAT("p", 4000); + + +# Again add index length < 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (2000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +# Drop index +DROP INDEX prefix_idx ON worklog5743; + +# Again add index length > 3072. +# If "innodb_large_prefix" is turned on, than the index prefix larger than 3072 +# will be truncated to 3072. If the table is REDUNDANT and COMPACT, which does +# not support prefix > 767, the create index will be rejected. +CREATE INDEX prefix_idx ON worklog5743(col_1_varbinary (4000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_varbinary = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_varbinary = REPEAT("c", 4000) +WHERE col_1_varbinary = REPEAT("a", 4000) +AND col_2_varbinary = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_varbinary = REPEAT("c", 4000); +SELECT col_1_varbinary = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_varbinary = REPEAT("c", 4000) +AND col_2_varbinary = REPEAT("o", 4000); + + +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- +# Create prefix index with length < 3072 , length = 3072 , length > 3072 +# text data type + secondary index +CREATE TABLE worklog5743 (col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(500)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index of 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_text (3072)); +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) +FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +# Drop index +DROP INDEX prefix_idx ON worklog5743; +SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("b", 4000) AND col_2_text = REPEAT("p", 4000); + +# Again add index length < 3072 +CREATE INDEX prefix_idx ON worklog5743(col_1_text (1000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); +# Drop index +DROP INDEX prefix_idx ON worklog5743; + +# Again add index length > 3072. Expect error.Length exceeds maximum supported +# key length +# Again add index length > 3072. +# If "innodb_large_prefix" is turned on, than the index prefix larger than 3072 +# will be truncated to 3072. If the table is REDUNDANT and COMPACT, which does +# not support prefix > 767, the create index will be rejected. +CREATE INDEX prefix_idx ON worklog5743(col_1_text (4000)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) AND col_2_text = REPEAT("o", 4000); + +DROP TABLE worklog5743; + + +# ----------------------------------------------------------------------------- +# Create prefix index with length < 948 , length = 948 , length > 948 +# For compressed row type + primary key +CREATE TABLE worklog5743 ( +col_1_text TEXT (4000) , col_2_text TEXT (4000) , +PRIMARY KEY (col_1_text(948)) +) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000) , REPEAT("o", 4000)); +# Create index of 767 +INSERT INTO worklog5743 VALUES(REPEAT("b", 4000) , REPEAT("p", 4000)); +SELECT col_1_text = REPEAT("a", 4000) , col_2_text = REPEAT("o", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +# Drop index +#DROP INDEX prefix_idx ON worklog5743; +ALTER TABLE worklog5743 DROP PRIMARY KEY; +SELECT col_1_text = REPEAT("b", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("b", 4000) +AND col_2_text = REPEAT("p", 4000); + +# Again add index length < 767 +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (700)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); +# Drop index +ALTER TABLE worklog5743 DROP PRIMARY KEY; + +# Again add index length > 948. Expect error 'to big row ' due to exceed +# in key length. +-- error 139 +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_text (950)); +INSERT INTO worklog5743 VALUES(REPEAT("a", 4000),REPEAT("o", 4000)); +SELECT col_1_text = REPEAT("a", 4000) FROM worklog5743; +UPDATE worklog5743 SET col_1_text = REPEAT("c", 4000) +WHERE col_1_text = REPEAT("a", 4000) +AND col_2_text = REPEAT("o", 4000); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("c", 4000); +SELECT col_1_text = REPEAT("c", 4000) FROM worklog5743 +WHERE col_1_text = REPEAT("c", 4000) +AND col_2_text = REPEAT("o", 4000); + +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- +# Create prefix index with length < 3072 , length = 3072 , length > 3072 +# data types VARCHAR +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (900)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +# Again add index length > 3072. Expect error.Length exceeds maximum supported +# key length +# Again add index length > 3072. +# If "innodb_large_prefix" is turned on, than the index prefix larger than 3072 +# will be truncated to 3072. If the table is REDUNDANT and COMPACT, which does +# not support prefix > 767, the create index will be rejected. +# Index length is truncated only for 'create index' , but error if we add +# prefix index with length > 3072 +--error ER_TOO_LONG_KEY +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_varchar (3073)); +DROP TABLE worklog5743; + + +CREATE TABLE worklog5743 ( +col_1_BLOB BLOB (4000) , PRIMARY KEY (col_1_BLOB(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +ALTER TABLE worklog5743 DROP PRIMARY KEY; +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (500)); +ALTER TABLE worklog5743 DROP PRIMARY KEY; +# Negative case +# Again add index length > 3072. Expect error.Length exceeds maximum supported +# key length +# Index length is truncated only for 'create index' , but error if we add +# prefix index with length > 3072 +--error ER_TOO_LONG_KEY +ALTER TABLE worklog5743 ADD PRIMARY KEY (col_1_BLOB (3073)); + +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- +# Error on adding larger prefix if violates unique index. +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 1000),REPEAT("c", 1000)), +REPEAT("o", 4000)); +INSERT INTO worklog5743 +VALUES(concat(REPEAT("a", 2000),REPEAT("b", 2000)), REPEAT("o", 4000)); +--error 1062 +ALTER TABLE worklog5743 ADD PRIMARY KEY `pk_idx` (col_1_varchar(3000)); +DROP TABLE worklog5743; + +# ----------------------------------------------------------------------------- +set global innodb_large_prefix=0; +# Prefix index > 767 is allowed if innodb_large_prefix is set to 1 +--error ER_TOO_LONG_KEY +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; + + +# ----------------------------------------------------------------------------- +set global innodb_large_prefix=0; +# Backward compatibility test - Index lenghth > 767 is truncated for REDUNDANT +# and COMPACT +CREATE TABLE worklog5743 ( +col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) , +PRIMARY KEY (col_1_varchar(767)) +) engine = innodb; +# Prefix index > 767 is truncated with REDUNDANT and COMPACT +CREATE INDEX prefix_idx ON worklog5743(col_1_varchar (1000)); +DROP TABLE worklog5743; +#------------------------------------------------------------------------------ + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig; diff --git a/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test new file mode 100644 index 00000000000..9d3c52206ff --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test @@ -0,0 +1,125 @@ +######## suite/innodb/t/innodb_prefix_iindex_restart_server.test ##### +# # +# Testcase for worklog WL#5743: Lift the limit of index key prefixes # +# Test scenario : Stop the server in between when prefix index are # +# created and see if state is preserved after restart # +# # +# Creation: # +# 2011-06-02 Implemented this test as part of WL#5743 # +# # +###################################################################### + +# Test restart the server and "shutdown_server" looks for pid file +# which is not there with embedded mode +--source include/not_embedded.inc +--source include/have_innodb.inc +# Save innodb variables +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; + +# Set Innodb file format as feature works for Barracuda file format +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; + +-- disable_warnings +DROP TABLE IF EXISTS worklog5743; +-- enable_warnings + + +#------------------------------------------------------------------------------ +# Stop the server in between when prefix index are created and see if state is +# correct when server is restarted. +# Server is restarted at differnt points. + +CREATE TABLE worklog5743 ( +col_1_text TEXT(4000) , col_2_text TEXT(4000) , +PRIMARY KEY (col_1_text(3072)) +) ROW_FORMAT=DYNAMIC, engine = innodb; +INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500)); +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +--echo "In connection 1" +--connect (con1,localhost,root,,) +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; + + +--echo "In connection 2" +--connect (con2,localhost,root,,) +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500)); + + +--echo "In connection 1" +--connection con1 +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +START TRANSACTION; + + +--echo "In connection default ....restarting the server" +--connection default +# Restart the server +-- source include/restart_mysqld.inc +SELECT COUNT(*) FROM worklog5743; +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +--disconnect con1 +--disconnect con2 + +--echo "In connection 1" +--connect (con1,localhost,root,,) +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +START TRANSACTION; +INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500)); +DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500); +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +--echo "In connection default ....restarting the server" +--connection default +# Restart the server +-- source include/restart_mysqld.inc +SELECT COUNT(*) FROM worklog5743; +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +--disconnect con1 + +--echo "In connection 1" +--connect (con2,localhost,root,,) +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +START TRANSACTION; +UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500); +SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +--echo "In connection default ....restarting the server" +--connection default +# Restart the server +-- source include/restart_mysqld.inc +SELECT COUNT(*) FROM worklog5743; +SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM +worklog5743; + +DROP TABLE worklog5743; + + +#------------------------------------------------------------------------------ + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig; + diff --git a/mysql-test/suite/perfschema/t/no_threads.test b/mysql-test/suite/perfschema/t/no_threads.test index f98aa8abdb7..dd0bd076dfc 100644 --- a/mysql-test/suite/perfschema/t/no_threads.test +++ b/mysql-test/suite/perfschema/t/no_threads.test @@ -17,6 +17,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/not_threadpool.inc # Setup : in this main thread diff --git a/mysql-test/suite/perfschema/t/one_thread_per_con.test b/mysql-test/suite/perfschema/t/one_thread_per_con.test index 5393152f7d2..fc4d17e34c7 100644 --- a/mysql-test/suite/perfschema/t/one_thread_per_con.test +++ b/mysql-test/suite/perfschema/t/one_thread_per_con.test @@ -17,6 +17,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/not_threadpool.inc # Setup diff --git a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result index 2fd9dc6294e..902bc1cda00 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result @@ -93,4 +93,31 @@ Slave 44 DROP TABLE t1; SET SESSION sql_mode=@old_mode; [slave] + +Bug #60580/#11902767: +"statement improperly replicated crashes slave sql thread" + +[master] +CREATE TABLE t1(f1 INT, f2 INT); +CREATE TABLE t2(f1 INT, f2 TIMESTAMP); +INSERT INTO t2 VALUES(1, '2011-03-22 21:01:28'); +INSERT INTO t2 VALUES(2, '2011-03-21 21:01:28'); +INSERT INTO t2 VALUES(3, '2011-03-20 21:01:28'); +CREATE TABLE t3 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM t2 +WHERE f1 IN (SELECT f1 FROM t3 WHERE (t3.f2 IS NULL)); +SELECT 1 INTO OUTFILE 'MYSQLD_DATADIR/bug60580.csv' FROM DUAL; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug60580.csv' INTO TABLE t1 (@f1) SET f2 = (SELECT f1 FROM v1 WHERE f1=@f1); +SELECT * FROM t1; +f1 f2 +NULL NULL +[slave] +SELECT * FROM t1; +f1 f2 +NULL NULL +[master] +DROP VIEW v1; +DROP TABLE t1, t2, t3; +[slave] include/rpl_end.inc +# End of 5.1 tests diff --git a/mysql-test/suite/rpl/r/rpl_relayspace.result b/mysql-test/suite/rpl/r/rpl_relayspace.result index 2815974c78f..fb21540aa31 100644 --- a/mysql-test/suite/rpl/r/rpl_relayspace.result +++ b/mysql-test/suite/rpl/r/rpl_relayspace.result @@ -1,7 +1,6 @@ include/master-slave.inc [connection master] -stop slave; -include/wait_for_slave_to_stop.inc +include/stop_slave.inc create table t1 (a int); drop table t1; create table t1 (a int); @@ -9,10 +8,8 @@ drop table t1; reset slave; start slave io_thread; include/wait_for_slave_param.inc [Slave_IO_State] -stop slave io_thread; +include/stop_slave_io.inc reset slave; -start slave; -select master_pos_wait('master-bin.001',200,6)=-1; -master_pos_wait('master-bin.001',200,6)=-1 -0 +include/start_slave.inc +include/assert.inc [Assert that master_pos_wait does not timeout nor it returns NULL] include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result index 107cd8f63cc..2ada5670e04 100644 --- a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result +++ b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result @@ -8,8 +8,7 @@ SHOW SLAVE HOSTS; Server_id Host Port Master_id 3 slave2 DEFAULT_PORT 1 2 SLAVE_PORT 1 -STOP SLAVE IO_THREAD; -include/wait_for_slave_io_to_stop.inc +include/stop_slave_io.inc SHOW SLAVE HOSTS; Server_id Host Port Master_id 2 SLAVE_PORT 1 diff --git a/mysql-test/suite/rpl/r/rpl_typeconv.result b/mysql-test/suite/rpl/r/rpl_typeconv.result index 0d2f3cb26f7..f9d5b50b4e2 100644 --- a/mysql-test/suite/rpl/r/rpl_typeconv.result +++ b/mysql-test/suite/rpl/r/rpl_typeconv.result @@ -534,7 +534,7 @@ BIT(6) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> BIT(5) BIT(12) ALL_LOSSY,ALL_NON_LOSSY <Correct value> BIT(12) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> DROP TABLE type_conversions; -call mtr.add_suppression("Slave SQL.*Column 0 of table .test.t1. cannot be converted from type.* Error_code: 1677"); +call mtr.add_suppression("Slave SQL.*Column 1 of table .test.t1. cannot be converted from type.* Error_code: 1677"); DROP TABLE t1; set global slave_type_conversions = @saved_slave_type_conversions; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 5d10653b7d9..a45fdb47ae6 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,8 +10,8 @@ # ############################################################################## -rpl_row_create_table : Bug#51574 2010-02-27 andrei failed different way than earlier with bug#45576 -rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux -rpl_get_master_version_and_clock : Bug#59178 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock +rpl_row_create_table : Bug#11759274 2010-02-27 andrei failed different way than earlier with bug#45576 +rpl_spec_variables : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux +rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out diff --git a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test index a54d216cb7c..4ebe572741f 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test +++ b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test @@ -186,4 +186,55 @@ SET SESSION sql_mode=@old_mode; sync_slave_with_master; connection master; + +--echo +--echo Bug #60580/#11902767: +--echo "statement improperly replicated crashes slave sql thread" +--echo + +--echo [master] +connection master; +let $MYSQLD_DATADIR= `select @@datadir`; + +CREATE TABLE t1(f1 INT, f2 INT); +CREATE TABLE t2(f1 INT, f2 TIMESTAMP); + +INSERT INTO t2 VALUES(1, '2011-03-22 21:01:28'); +INSERT INTO t2 VALUES(2, '2011-03-21 21:01:28'); +INSERT INTO t2 VALUES(3, '2011-03-20 21:01:28'); + +CREATE TABLE t3 AS SELECT * FROM t2; + +CREATE VIEW v1 AS SELECT * FROM t2 + WHERE f1 IN (SELECT f1 FROM t3 WHERE (t3.f2 IS NULL)); + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval SELECT 1 INTO OUTFILE '$MYSQLD_DATADIR/bug60580.csv' FROM DUAL; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug60580.csv' INTO TABLE t1 (@f1) SET f2 = (SELECT f1 FROM v1 WHERE f1=@f1); + +SELECT * FROM t1; + +sleep 1; + +--echo [slave] +sync_slave_with_master; + +SELECT * FROM t1; + +--remove_file $MYSQLD_DATADIR/bug60580.csv + +--echo [master] +connection master; + +DROP VIEW v1; +DROP TABLE t1, t2, t3; + +--echo [slave] +sync_slave_with_master; + +connection master; --source include/rpl_end.inc + +--echo # End of 5.1 tests diff --git a/mysql-test/suite/rpl/t/rpl_relayspace.test b/mysql-test/suite/rpl/t/rpl_relayspace.test index 2ad6936dd50..fc33d6bc0ba 100644 --- a/mysql-test/suite/rpl/t/rpl_relayspace.test +++ b/mysql-test/suite/rpl/t/rpl_relayspace.test @@ -2,9 +2,9 @@ # to force the deadlock after one event. source include/master-slave.inc; +--let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1) connection slave; -stop slave; ---source include/wait_for_slave_to_stop.inc +--source include/stop_slave.inc connection master; # This will generate a master's binlog > 10 bytes create table t1 (a int); @@ -20,20 +20,33 @@ let $slave_param_value= Waiting for the slave SQL thread to free enough relay lo source include/wait_for_slave_param.inc; # A bug caused the I/O thread to refuse stopping. -stop slave io_thread; +--source include/stop_slave_io.inc reset slave; -start slave; -# The I/O thread stops filling the relay log when -# it's >10b. And the SQL thread cannot purge this relay log -# as purge is done only when the SQL thread switches to another -# relay log, which does not exist here. -# So we should have a deadlock. -# if it is not resolved automatically we'll detect -# it with master_pos_wait that waits for farther than 1Ob; -# it will timeout after 10 seconds; -# also the slave will probably not cooperate to shutdown -# (as 2 threads are locked) -select master_pos_wait('master-bin.001',200,6)=-1; +--source include/start_slave.inc + +# The I/O thread stops filling the relay log when it's >10b. And the +# SQL thread cannot purge this relay log as purge is done only when +# the SQL thread switches to another relay log, which does not exist +# here. So we should have a deadlock. If it is not resolved +# automatically we'll detect it with master_pos_wait that waits for +# farther than 1Ob; it will timeout after 300 seconds (which is inline +# with the default used for sync_slave_with_master and will protect us +# against slow test envs); also the slave will probably not cooperate +# to shutdown (as 2 threads are locked) +--let $outcome= `SELECT MASTER_POS_WAIT('$master_log_file',200,300) AS mpw;` + +# master_pos_wait returns: +# +# * >= 0, the number of events the slave had to wait to advance to the +# position +# +# * -1, if there was a timeout +# +# * NULL, if an error occurred, or the SQL thread was not started, +# slave master info is not initialized, the arguments are incorrect +--let $assert_text= Assert that master_pos_wait does not timeout nor it returns NULL +--let $assert_cond= $outcome IS NOT NULL AND $outcome <> -1 +--source include/assert.inc # End of 4.1 tests --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test index eb2e883847f..105f1873659 100644 --- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test @@ -23,14 +23,13 @@ connection master; let $show_statement= SHOW SLAVE HOSTS; let $field= Server_id; # 3 is server_id of slave2. -let $connection= ='3'; +let $condition= ='3'; source include/wait_show_condition.inc; --replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT SHOW SLAVE HOSTS; connection slave2; -STOP SLAVE IO_THREAD; -source include/wait_for_slave_io_to_stop.inc; +--source include/stop_slave_io.inc connection master; let $show_statement= SHOW SLAVE HOSTS; diff --git a/mysql-test/suite/rpl/t/rpl_typeconv-master.opt b/mysql-test/suite/rpl/t/rpl_typeconv-master.opt new file mode 100644 index 00000000000..de048691031 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_typeconv-master.opt @@ -0,0 +1 @@ +--testcase-timeout=40 diff --git a/mysql-test/suite/rpl/t/rpl_typeconv.test b/mysql-test/suite/rpl/t/rpl_typeconv.test index efe3dc15353..efcbe97049f 100644 --- a/mysql-test/suite/rpl/t/rpl_typeconv.test +++ b/mysql-test/suite/rpl/t/rpl_typeconv.test @@ -61,7 +61,7 @@ SELECT RPAD(Source, 15, ' ') AS Source_Type, enable_query_log; DROP TABLE type_conversions; -call mtr.add_suppression("Slave SQL.*Column 0 of table .test.t1. cannot be converted from type.* Error_code: 1677"); +call mtr.add_suppression("Slave SQL.*Column 1 of table .test.t1. cannot be converted from type.* Error_code: 1677"); connection master; DROP TABLE t1; diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index fae91659ecd..3cee368853f 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -14,8 +14,10 @@ There should be *no* variables listed below: INNODB_ROLLBACK_SEGMENTS INNODB_STATS_METHOD INNODB_FILE_FORMAT_MAX +INNODB_LARGE_PREFIX INNODB_ROLLBACK_SEGMENTS INNODB_STATS_METHOD INNODB_FILE_FORMAT_MAX +INNODB_LARGE_PREFIX drop table t1; drop table t2; diff --git a/mysql-test/suite/sys_vars/t/all_vars.test b/mysql-test/suite/sys_vars/t/all_vars.test index a00b7d5fbb9..5e8ce6d8abf 100644 --- a/mysql-test/suite/sys_vars/t/all_vars.test +++ b/mysql-test/suite/sys_vars/t/all_vars.test @@ -14,6 +14,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/not_embedded.inc +--source include/not_threadpool.inc # 2010-01-28 OBN Added support to load 'innodb' and 'semisync' if possible. # As we need to have there variables loaded if the components exist but do diff --git a/mysql-test/suite/sys_vars/t/disabled.def b/mysql-test/suite/sys_vars/t/disabled.def index 483eea9daeb..1cabae00b6f 100644 --- a/mysql-test/suite/sys_vars/t/disabled.def +++ b/mysql-test/suite/sys_vars/t/disabled.def @@ -9,9 +9,9 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -query_cache_size_basic_32 : Bug#36747: Allocating a large query cache is not deterministic -query_cache_size_basic_64 : Bug#36747: Allocating a large query cache is not deterministic -transaction_prealloc_size_basic_32 : Bug#36747 -transaction_prealloc_size_basic_64 : Bug#36747 -#thread_cache_size_func : Bug#40575: 2008-11-07 joro main.thread_cache_size_func fails in pushbuild when run with pool of threads +query_cache_size_basic_32 : Bug#11748572: Allocating a large query cache is not deterministic +query_cache_size_basic_64 : Bug#11748572: Allocating a large query cache is not deterministic +transaction_prealloc_size_basic_32 : Bug#11748572 +transaction_prealloc_size_basic_64 : Bug#11748572 +#thread_cache_size_func : Bug#11750172: 2008-11-07 joro main.thread_cache_size_func fails in pushbuild when run with pool of threads diff --git a/mysql-test/suite/sys_vars/t/slow_launch_time_func.test b/mysql-test/suite/sys_vars/t/slow_launch_time_func.test index 1f384888f81..c9fc357b10f 100644 --- a/mysql-test/suite/sys_vars/t/slow_launch_time_func.test +++ b/mysql-test/suite/sys_vars/t/slow_launch_time_func.test @@ -31,6 +31,7 @@ # --source include/not_embedded.inc +--source include/not_threadpool.inc SET @global_slow_launch_time = @@GLOBAL.slow_launch_time; diff --git a/mysql-test/suite/sys_vars/t/thread_cache_size_func.test b/mysql-test/suite/sys_vars/t/thread_cache_size_func.test index fe9f4242c0d..9bffa32ca2b 100644 --- a/mysql-test/suite/sys_vars/t/thread_cache_size_func.test +++ b/mysql-test/suite/sys_vars/t/thread_cache_size_func.test @@ -28,6 +28,7 @@ # --source include/not_embedded.inc +--source include/not_threadpool.inc SET @global_thread_cache_size = @@GLOBAL.thread_cache_size; diff --git a/mysql-test/suite/sys_vars/t/wait_timeout_func.test b/mysql-test/suite/sys_vars/t/wait_timeout_func.test index e33c39016cc..313d9e8191d 100644 --- a/mysql-test/suite/sys_vars/t/wait_timeout_func.test +++ b/mysql-test/suite/sys_vars/t/wait_timeout_func.test @@ -22,6 +22,7 @@ ############################################################################### --source include/not_embedded.inc +--source include/not_threadpool.inc SET @start_value= @@global.wait_timeout; diff --git a/mysql-test/t/archive_debug.test b/mysql-test/t/archive_debug.test new file mode 100644 index 00000000000..9cece254140 --- /dev/null +++ b/mysql-test/t/archive_debug.test @@ -0,0 +1,13 @@ +--source include/have_archive.inc +--source include/have_debug.inc + +--echo # +--echo # BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK +--echo # WITH PARTITIONED ARCHIVE TABLES +--echo # +CREATE TABLE t1(a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(1); +SET SESSION debug='d,simulate_archive_open_failure'; +CHECK TABLE t1; +SET SESSION debug=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 063bbb9ce4b..872e6712070 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,11 +9,11 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -lowercase_table3 : Bug#54845 2010-06-30 alik main.lowercase_table3 on Mac OSX -query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically -log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists -read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists -sum_distinct-big : Bug#56927 2010-11-15 mattiasj was not tested -alter_table-big : Bug#37248 2010-11-15 mattiasj was not tested -create-big : Bug#37248 2010-11-15 mattiasj was not tested +lowercase_table3 : Bug#11762269 2010-06-30 alik main.lowercase_table3 on Mac OSX +read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exists +sum_distinct-big : Bug#11764126 2010-11-15 mattiasj was not tested +alter_table-big : Bug#11748731 2010-11-15 mattiasj was not tested +create-big : Bug#11748731 2010-11-15 mattiasj was not tested archive-big : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc +main.query_cache_28249 : Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically +log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index bf4c23562cf..84073d15109 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -614,3 +614,16 @@ SET @@sort_buffer_size = @old_sort_buffer_size; SET @@max_heap_table_size = @old_max_heap_table_size; --echo End of 5.1 tests + + +--echo # +--echo # Bug #11744875: 4082: integer lengths cause truncation with distinct concat and innodb +--echo # + +CREATE TABLE t1 (a INT(1), b INT(1)); +INSERT INTO t1 VALUES (1111, 2222), (3333, 4444); +SELECT DISTINCT CONCAT(a,b) AS c FROM t1 ORDER BY 1; +DROP TABLE t1; + + +--echo End of 5.5 tests diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 9432e64e032..036a1132acd 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -857,6 +857,7 @@ DROP EVENT e2; DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +SET TIMESTAMP=DEFAULT; # # START - BUG#28666 CREATE EVENT ... EVERY 0 SECOND let server crash @@ -1235,6 +1236,55 @@ SHOW EVENTS; DROP DATABASE event_test1; DROP DATABASE event_test12; +--echo # +--echo # Bug#12546938 (formerly known as bug#61005): +--echo # CREATE IF NOT EXIST EVENT WILL CREATE MULTIPLE RUNNING EVENTS +--echo # +USE events_test; +SET GLOBAL event_scheduler = ON; + +--disable_warnings +DROP TABLE IF EXISTS table_bug12546938; +DROP EVENT IF EXISTS event_Bug12546938; +--enable_warnings +CREATE TABLE table_bug12546938 (i INT); + +delimiter |; + +--echo # Create an event which will be executed with a small delay +--echo # and won't be automatically dropped after that. +CREATE EVENT event_Bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN + INSERT INTO table_bug12546938 VALUES(1); +END +| + +--echo # Now try to create the same event using CREATE EVENT IF NOT EXISTS. +--echo # A warning should be emitted. A new event should not be created nor +--echo # the old event should be re-executed. +CREATE EVENT IF NOT EXISTS event_bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN + INSERT INTO table_bug12546938 VALUES (1); +END +| + +delimiter ;| + +--echo # Wait until at least one instance of event is executed. +let $wait_condition= SELECT COUNT(*) FROM table_bug12546938; +--source include/wait_condition.inc + +--echo # Check that only one instance of our event was executed. +SELECT COUNT(*) FROM table_bug12546938; + +--echo # Clean-up. +DROP EVENT IF EXISTS event_Bug12546938; +DROP TABLE table_bug12546938; +SET GLOBAL EVENT_SCHEDULER = OFF; ########################################################################### # diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 0e704fecf57..0d59f98a313 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -370,6 +370,12 @@ DROP TABLE t1; SELECT ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')); +--echo # +--echo # Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +--echo # + +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); + --echo End of 5.1 tests --echo # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index add741e12a7..86f465b3a6e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -902,6 +902,13 @@ SELECT DATE_FORMAT('0000-00-11', '%W'); SELECT DATE_FORMAT('0000-00-11', '%a'); SELECT DATE_FORMAT('0000-00-11', '%w'); +--echo # +--echo # Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +--echo # + +SELECT MAKEDATE(11111111,1); +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); + --echo End of 5.1 tests --echo # diff --git a/mysql-test/t/implicit_char_to_num_conversion.test b/mysql-test/t/implicit_char_to_num_conversion.test new file mode 100644 index 00000000000..f3da83ff2c1 --- /dev/null +++ b/mysql-test/t/implicit_char_to_num_conversion.test @@ -0,0 +1,174 @@ +########### implicit_char_to_num_conversion.test ####################### +# # +# This test aims at using string/char literal in comparison operators # +# without explicit type-cast. This is a bug test for Bug#11766521 # +# - Incorrect result is returned if string/char literal is used with # +# comparision operator and bit data type column. Test is extended to # +# include numeric data type comparison with string/char literal # +# # +# # +# Creation: # +# 2011-05-10 vfisrekar Implement this test as part of Bug#11766521 # +# # +######################################################################## + +--disable_warnings +DROP TABLE IF EXISTS t5; +--enable_warnings + +let $default_engine = `select @@SESSION.default_storage_engine`; + +# Bug#11766521 - BIT Datatype comparison in where clause return incorrect +# result for '=' , '<=>' operators +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +# Enable Following two select after Bug#11766521 fix +# SELECT HEX(c1) FROM t5 WHERE c1 = '1' ORDER BY c1; +# SELECT HEX(c1) FROM t5 WHERE c1 <=> '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# FLOAT Data-type +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +# Following two queries does not return result may be due to Bug#11766521. +# Enable them after Bug#11766521 fix. +# SELECT c1 FROM t5 WHERE c1 = '10.10' ORDER BY c1; +# SELECT c1 FROM t5 WHERE c2 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# TINYINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +DROP TABLE t5; + +# SMALLINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +DROP TABLE t5; + +# MEDIUMINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +DROP TABLE t5; + +# INT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +DROP TABLE t5; + +# BIGINT Data-type +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +DROP TABLE t5; + +# DOUBLE Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# NUMERIC Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# DECIMAL Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index bc73e8411ca..589bb898d6a 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1,6 +1,9 @@ # This test uses grants, which can't get tested for embedded server -- source include/not_embedded.inc +#Don't run this test when thread_pool active +--source include/not_threadpool.inc + # check that CSV engine was compiled in, as the result of the test depends # on the presence of the log tables (which are CSV-based). --source include/have_csv.inc diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test index 7326f33b113..f1aebfa4bed 100644 --- a/mysql-test/t/information_schema_db.test +++ b/mysql-test/t/information_schema_db.test @@ -2,6 +2,9 @@ # in the embedded server by default). So skip the test in embedded-server mode. -- source include/not_embedded.inc +#Don't run this test when thread_pool active +--source include/not_threadpool.inc + -- source include/testdb_only.inc --disable_warnings diff --git a/mysql-test/t/innodb_mysql_lock.test b/mysql-test/t/innodb_mysql_lock.test index f1dc0d52484..629da27660e 100644 --- a/mysql-test/t/innodb_mysql_lock.test +++ b/mysql-test/t/innodb_mysql_lock.test @@ -300,6 +300,10 @@ SELECT * FROM t1; --echo # Connection con1 --connection con1 SET lock_wait_timeout=1; +# Test with two timeouts, as the first version of this patch +# only worked with one timeout. +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 ADD INDEX idx(value); --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD INDEX idx(value); diff --git a/mysql-test/t/innodb_mysql_sync.test b/mysql-test/t/innodb_mysql_sync.test index 13c854d6b61..ec8fa55fc5c 100644 --- a/mysql-test/t/innodb_mysql_sync.test +++ b/mysql-test/t/innodb_mysql_sync.test @@ -2,6 +2,7 @@ # Test file for InnoDB tests that require the debug sync facility # --source include/have_innodb.inc +--source include/have_debug.inc --source include/have_debug_sync.inc # Save the initial number of concurrent sessions. --source include/count_sessions.inc @@ -152,133 +153,155 @@ disconnect con1; --echo # that implement add_index --echo # +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP TABLE IF EXISTS t1; +--enable_warnings + +connect(con1,localhost,root); +connect(con2,localhost,root); + +--echo # Test 1: Secondary index, should not block reads (original test case). + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb; +INSERT INTO db1.t1(value) VALUES (1), (2); +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +--echo # Sending: +--send ALTER TABLE db1.t1 ADD INDEX(value) + +--echo # Connection con1 +connection con1; +SET DEBUG_SYNC= "now WAIT_FOR manage"; +# Neither of these two statements should be blocked +USE db1; +SELECT * FROM t1; +SET DEBUG_SYNC= "now SIGNAL query"; + +--echo # Connection default +connection default; +--echo # Reaping: ALTER TABLE db1.t1 ADD INDEX(value) +--reap +DROP DATABASE db1; + +--echo # Test 2: Primary index (implicit), should block reads. + +CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +--echo # Sending: +--send ALTER TABLE t1 ADD UNIQUE INDEX(a) + +--echo # Connection con1 +connection con1; +SET DEBUG_SYNC= "now WAIT_FOR manage"; +USE test; +--echo # Sending: +--send SELECT * FROM t1 + +--echo # Connection con2 +connection con2; +--echo # Waiting for SELECT to be blocked by the metadata lock on t1 +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for table metadata lock' + AND info='SELECT * FROM t1'; +--source include/wait_condition.inc +SET DEBUG_SYNC= "now SIGNAL query"; + +--echo # Connection default +connection default; +--echo # Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a) +--reap + +--echo # Connection con1 +connection con1; +--echo # Reaping: SELECT * FROM t1 +--reap + +--echo # Test 3: Primary index (explicit), should block reads. + +--echo # Connection default +connection default; +ALTER TABLE t1 DROP INDEX a; +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +--echo # Sending: +--send ALTER TABLE t1 ADD PRIMARY KEY (a) + +--echo # Connection con1 +connection con1; +SET DEBUG_SYNC= "now WAIT_FOR manage"; +--echo # Sending: +--send SELECT * FROM t1 + +--echo # Connection con2 +connection con2; +--echo # Waiting for SELECT to be blocked by the metadata lock on t1 +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for table metadata lock' + AND info='SELECT * FROM t1'; +--source include/wait_condition.inc +SET DEBUG_SYNC= "now SIGNAL query"; + +--echo # Connection default +connection default; +--echo # Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a) +--reap + +--echo # Connection con1 +connection con1; +--echo # Reaping: SELECT * FROM t1 +--reap + +--echo # Test 4: Secondary unique index, should not block reads. + +--echo # Connection default +connection default; +SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; +--echo # Sending: +--send ALTER TABLE t1 ADD UNIQUE (b) + +--echo # Connection con1 +connection con1; +SET DEBUG_SYNC= "now WAIT_FOR manage"; +SELECT * FROM t1; +SET DEBUG_SYNC= "now SIGNAL query"; + +--echo # Connection default +connection default; +--echo # Reaping: ALTER TABLE t1 ADD UNIQUE (b) +--reap + +disconnect con1; +disconnect con2; +SET DEBUG_SYNC= "RESET"; +DROP TABLE t1; + + --echo # ---echo # DISABLED due to Bug#11815600 +--echo # Bug#11853126 RE-ENABLE CONCURRENT READS WHILE CREATING SECONDARY INDEX +--echo # IN INNODB --echo # -#--disable_warnings -#DROP DATABASE IF EXISTS db1; -#DROP TABLE IF EXISTS t1; -#--enable_warnings -# -#connect(con1,localhost,root); -#connect(con2,localhost,root); -# -#--echo # Test 1: Secondary index, should not block reads (original test case). -# -#--echo # Connection default -#connection default; -#CREATE DATABASE db1; -#CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb; -#INSERT INTO db1.t1(value) VALUES (1), (2); -#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; -#--echo # Sending: -#--send ALTER TABLE db1.t1 ADD INDEX(value) -# -#--echo # Connection con1 -#connection con1; -#SET DEBUG_SYNC= "now WAIT_FOR manage"; -# # Neither of these two statements should be blocked -#USE db1; -#SELECT * FROM t1; -#SET DEBUG_SYNC= "now SIGNAL query"; -# -#--echo # Connection default -#connection default; -#--echo # Reaping: ALTER TABLE db1.t1 ADD INDEX(value) -#--reap -#DROP DATABASE db1; -# -#--echo # Test 2: Primary index (implicit), should block reads. -# -#CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; -#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; -#--echo # Sending: -#--send ALTER TABLE t1 ADD UNIQUE INDEX(a) -# -#--echo # Connection con1 -#connection con1; -#SET DEBUG_SYNC= "now WAIT_FOR manage"; -#USE test; -#--echo # Sending: -#--send SELECT * FROM t1 -# -#--echo # Connection con2 -#connection con2; -#--echo # Waiting for SELECT to be blocked by the metadata lock on t1 -#let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist -# WHERE state= 'Waiting for table metadata lock' -# AND info='SELECT * FROM t1'; -#--source include/wait_condition.inc -#SET DEBUG_SYNC= "now SIGNAL query"; -# -#--echo # Connection default -#connection default; -#--echo # Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a) -#--reap -# -#--echo # Connection con1 -#connection con1; -#--echo # Reaping: SELECT * FROM t1 -#--reap -# -#--echo # Test 3: Primary index (explicit), should block reads. -# -#--echo # Connection default -#connection default; -#ALTER TABLE t1 DROP INDEX a; -#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; -#--echo # Sending: -#--send ALTER TABLE t1 ADD PRIMARY KEY (a) -# -#--echo # Connection con1 -#connection con1; -#SET DEBUG_SYNC= "now WAIT_FOR manage"; -#--echo # Sending: -#--send SELECT * FROM t1 -# -#--echo # Connection con2 -#connection con2; -#--echo # Waiting for SELECT to be blocked by the metadata lock on t1 -#let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist -# WHERE state= 'Waiting for table metadata lock' -# AND info='SELECT * FROM t1'; -#--source include/wait_condition.inc -#SET DEBUG_SYNC= "now SIGNAL query"; -# -#--echo # Connection default -#connection default; -#--echo # Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a) -#--reap -# -#--echo # Connection con1 -#connection con1; -#--echo # Reaping: SELECT * FROM t1 -#--reap -# -#--echo # Test 4: Secondary unique index, should not block reads. -# -#--echo # Connection default -#connection default; -#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query"; -#--echo # Sending: -#--send ALTER TABLE t1 ADD UNIQUE (b) -# -#--echo # Connection con1 -#connection con1; -#SET DEBUG_SYNC= "now WAIT_FOR manage"; -#SELECT * FROM t1; -#SET DEBUG_SYNC= "now SIGNAL query"; -# -#--echo # Connection default -#connection default; -#--echo # Reaping: ALTER TABLE t1 ADD UNIQUE (b) -#--reap -# -#disconnect con1; -#disconnect con2; -#SET DEBUG_SYNC= "RESET"; -#DROP TABLE t1; +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; +INSERT INTO t1 VALUES (1, 12345), (2, 23456); + +--echo # Connection con1 +--connect (con1,localhost,root) +SET SESSION debug= "+d,alter_table_rollback_new_index"; +--error ER_UNKNOWN_ERROR +ALTER TABLE t1 ADD PRIMARY KEY(a); +SELECT * FROM t1; + +--echo # Connection default +--connection default +SELECT * FROM t1; +DROP TABLE t1; +disconnect con1; # Check that all connections opened by test cases in this file are really diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 9e94bb44171..f36d5a2169d 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -9,6 +9,7 @@ -- source include/not_embedded.inc -- source include/have_debug_sync.inc +-- source include/not_threadpool.inc --disable_warnings SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 66ec8e22ab1..515e2bcf325 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -2,6 +2,8 @@ -- source include/not_embedded.inc # Test lists tables in Information_schema, and InnoDB adds some -- source include/have_innodb.inc +# Don't test when thread_pool active +--source include/not_threadpool.inc --disable_warnings DROP TABLE IF EXISTS t1,t2,test1,test2; diff --git a/mysql-test/t/named_pipe.test b/mysql-test/t/named_pipe.test index 0e6c963024f..23a11d61222 100644 --- a/mysql-test/t/named_pipe.test +++ b/mysql-test/t/named_pipe.test @@ -3,6 +3,9 @@ # other platforms --source include/windows.inc +# thread pool causes different results +-- source include/not_threadpool.inc + # Only run this test if named pipe is avaliable let $nmp= query_get_value("SHOW VARIABLES LIKE 'named_pipe'", Value, 1); if ($nmp != ON){ diff --git a/mysql-test/t/no-threads.test b/mysql-test/t/no-threads.test index fd8365e5678..c2b326897f8 100644 --- a/mysql-test/t/no-threads.test +++ b/mysql-test/t/no-threads.test @@ -1,3 +1,4 @@ +--source include/not_threadpool.inc # # Test the --thread-handler=no-threads option # diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index 2f85813d1ef..70b3c81168d 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -208,7 +208,17 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_2"; --echo ** until a broadcast signal reaches them causing both threads to --echo ** come alive and check the condition. SET DEBUG_SYNC="now SIGNAL go2"; +--echo ** Wait for thd2 to receive the signal +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = "Waiting for query cache lock"; +--source include/wait_condition.inc SET DEBUG_SYNC="now SIGNAL go3"; +--echo ** Wait for thd3 to receive the signal +let $wait_condition= + SELECT COUNT(*) = 2 FROM information_schema.processlist + WHERE state = "Waiting for query cache lock"; +--source include/wait_condition.inc --echo ** --echo ** Finally signal the DELETE statement on THD1 one last time. diff --git a/mysql-test/t/shm.test b/mysql-test/t/shm.test index 0f880e58741..4c765c43c1b 100644 --- a/mysql-test/t/shm.test +++ b/mysql-test/t/shm.test @@ -2,6 +2,9 @@ # to optimize things we skip this test on all other platforms --source include/windows.inc +# thread pool causes different results +-- source include/not_threadpool.inc + # Only run this test if shared memory is avaliable let $shm= query_get_value("SHOW VARIABLES LIKE 'shared_memory'", Value, 1); if ($shm != ON){ diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 9965875af55..26c7a89bf5c 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -354,21 +354,6 @@ DROP FUNCTION f1; # End of 5.1 tests -# -# Bug#17954 Threads_connected > Threads_created -# - ---disable_warnings -DROP VIEW IF EXISTS v1; ---enable_warnings - -CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; - -SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; -SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; - -DROP VIEW v1; - # Restore global concurrent_insert value. Keep in the end of the test file. --connection default set @@global.concurrent_insert= @old_concurrent_insert; diff --git a/mysql-test/t/status_bug17954.test b/mysql-test/t/status_bug17954.test new file mode 100644 index 00000000000..36430cceeff --- /dev/null +++ b/mysql-test/t/status_bug17954.test @@ -0,0 +1,54 @@ +# This test requires that --log-output includes 'table', and the general +# log is on + +# embedded server causes different stat +-- source include/not_embedded.inc + +# thread pool causes different results +-- source include/not_threadpool.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# Disable concurrent inserts to avoid sporadic test failures as it might +# affect the the value of variables used throughout the test case. +set @old_concurrent_insert= @@global.concurrent_insert; +set @@global.concurrent_insert= 0; + +# Disable logging to table, since this will also cause table locking and unlocking, which will +# show up in SHOW STATUS and may cause sporadic failures + +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; + +# PS causes different statistics +--disable_ps_protocol + +flush status; + +# +# Bug#17954 Threads_connected > Threads_created +# + +--disable_warnings +DROP VIEW IF EXISTS v1; +--enable_warnings + +CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; + +SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; +SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS where variable_name like '%thread%'; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES; + +DROP VIEW v1; + +# Restore global concurrent_insert value. Keep in the end of the test file. +--connection default +set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index bd70e64b1ad..f1eeabbd924 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1519,4 +1519,19 @@ SELECT AVG(DISTINCT a) FROM t1; SELECT SUM(DISTINCT a) FROM t1; DROP TABLE t1; +--echo # +--echo # Bug#55436: buffer overflow in debug binary of dbug_buff in +--echo # Field_new_decimal::store_value +--echo # + +# this threw memory warnings on Windows. Also make sure future changes +# don't change these results, as per usual. +SET SQL_MODE=''; +CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM; +INSERT INTO t1 SET f1 = -64878E-85; +SELECT f1 FROM t1; +DROP TABLE IF EXISTS t1; + + + --echo End of 5.1 tests diff --git a/mysql-test/t/variables-big.test b/mysql-test/t/variables-big.test index 6c357bb6e54..53f426757b6 100644 --- a/mysql-test/t/variables-big.test +++ b/mysql-test/t/variables-big.test @@ -34,6 +34,7 @@ # There is a significant probablitity that this tests fails with testcase # timeout if the testing box is not powerful enough. # +SET @def_var= @@session.transaction_prealloc_size; --disable_warnings SET SESSION transaction_prealloc_size=1024*1024*1024*1; @@ -53,3 +54,5 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*5; SHOW PROCESSLIST; --enable_warnings +SET @@session.transaction_prealloc_size= @def_var; + diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index 4ed01ac8083..127d7807761 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -146,6 +146,7 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox) */ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) { + struct st_my_thread_var *var; uint32 pins, next, top_ver; LF_PINS *el; /* @@ -188,7 +189,12 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) el->link= pins; el->purgatory_count= 0; el->pinbox= pinbox; - el->stack_ends_here= & my_thread_var->stack_ends_here; + var= my_thread_var; + /* + Threads that do not call my_thread_init() should still be + able to use the LF_HASH. + */ + el->stack_ends_here= (var ? & var->stack_ends_here : NULL); return el; } @@ -327,34 +333,36 @@ static int match_pins(LF_PINS *el, void *addr) */ static void _lf_pinbox_real_free(LF_PINS *pins) { - int npins, alloca_size; - void *list, **addr; + int npins; + void *list; + void **addr= NULL; void *first= NULL, *last= NULL; LF_PINBOX *pinbox= pins->pinbox; npins= pinbox->pins_in_array+1; #ifdef HAVE_ALLOCA - alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; - /* create a sorted list of pinned addresses, to speed up searches */ - if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + if (pins->stack_ends_here != NULL) { - struct st_harvester hv; - addr= (void **) alloca(alloca_size); - hv.granary= addr; - hv.npins= npins; - /* scan the dynarray and accumulate all pinned addresses */ - _lf_dynarray_iterate(&pinbox->pinarray, - (lf_dynarray_func)harvest_pins, &hv); - - npins= hv.granary-addr; - /* and sort them */ - if (npins) - qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; + /* create a sorted list of pinned addresses, to speed up searches */ + if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + { + struct st_harvester hv; + addr= (void **) alloca(alloca_size); + hv.granary= addr; + hv.npins= npins; + /* scan the dynarray and accumulate all pinned addresses */ + _lf_dynarray_iterate(&pinbox->pinarray, + (lf_dynarray_func)harvest_pins, &hv); + + npins= hv.granary-addr; + /* and sort them */ + if (npins) + qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + } } - else #endif - addr= 0; list= pins->purgatory; pins->purgatory= 0; diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h index 2d192d7a35f..b4bbf07702c 100644 --- a/mysys/my_handler_errors.h +++ b/mysys/my_handler_errors.h @@ -65,7 +65,8 @@ static const char *handler_error_messages[]= "Got a fatal error during initialzaction of handler", "File to short; Expected more data in file", "Read page with wrong checksum", - "Too many active concurrent transactions" + "Too many active concurrent transactions", + "Index column length exceeds limit" }; extern void my_handler_error_register(void); diff --git a/mysys/my_sync.c b/mysys/my_sync.c index e33a9342afa..076b9b40642 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -17,6 +17,16 @@ #include "mysys_err.h" #include <errno.h> +static void (*before_sync_wait)(void)= 0; +static void (*after_sync_wait)(void)= 0; + +void thr_set_sync_wait_callback(void (*before_wait)(void), + void (*after_wait)(void)) +{ + before_sync_wait= before_wait; + after_sync_wait= after_wait; +} + /* Sync data in file to disk @@ -46,6 +56,8 @@ int my_sync(File fd, myf my_flags) DBUG_ENTER("my_sync"); DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags)); + if (before_sync_wait) + (*before_sync_wait)(); do { #if defined(F_FULLFSYNC) @@ -75,6 +87,8 @@ int my_sync(File fd, myf my_flags) int er= errno; if (!(my_errno= er)) my_errno= -1; /* Unknown error */ + if (after_sync_wait) + (*after_sync_wait)(); if ((my_flags & MY_IGNORE_BADFD) && (er == EBADF || er == EINVAL || er == EROFS)) { @@ -84,6 +98,11 @@ int my_sync(File fd, myf my_flags) else if (my_flags & MY_WME) my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno); } + else + { + if (after_sync_wait) + (*after_sync_wait)(); + } DBUG_RETURN(res); } /* my_sync */ diff --git a/packaging/WiX/ca/CMakeLists.txt b/packaging/WiX/ca/CMakeLists.txt index a03ceb9a5d2..6872dc99d94 100644 --- a/packaging/WiX/ca/CMakeLists.txt +++ b/packaging/WiX/ca/CMakeLists.txt @@ -13,15 +13,43 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) -LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) +INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc ${WIX_DIR}/SDK/inc) +LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - LINK_LIBRARIES(wcautil_x64 dutil_x64 msi version) + SET(WIX_ARCH_SUFFIX "_x64") ELSE() - LINK_LIBRARIES(wcautil dutil msi version) + SET(WIX_ARCH_SUFFIX) ENDIF() - -ADD_LIBRARY(wixca SHARED ${WIXCA_SOURCES}) + +IF(MSVC_VERSION EQUAL 1400) + SET(WIX35_MSVC_SUFFIX "_2005") +ELSEIF(MSVC_VERSION EQUAL 1500) + SET(WIX35_MSVC_SUFFIX "_2008") +ELSEIF(MSVC_VERSION EQUAL 1600) + SET(WIX35_MSVC_SUFFIX "_2010") +ELSE() + # When next VS is out, add the correct version here + MESSAGE(FATAL_ERROR "Unknown VS version") +ENDIF() + +MESSAGE(STATUS "Searching for wcautil${WIX_ARCH_SUFFIX} or wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} in ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib") +MESSAGE(STATUS "Searching for dutil${WIX_ARCH_SUFFIX} or dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} in ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib") + +FIND_LIBRARY(WIX_WCAUTIL_LIBRARY + NAMES wcautil${WIX_ARCH_SUFFIX} wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + HINTS ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) + +FIND_LIBRARY(WIX_DUTIL_LIBRARY + NAMES dutil${WIX_ARCH_SUFFIX} dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + PATHS ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) + +MESSAGE(STATUS "Found: ${WIX_WCAUTIL_LIBRARY}") +MESSAGE(STATUS "Found: ${WIX_DUTIL_LIBRARY}") + +ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) +ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES}) +TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} + msi version ) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index a1899b701fd..dd2e9fd9d85 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -15,6 +15,28 @@ SET(COPYING_RTF "@COPYING_RTF@") SET(CPACK_WIX_CONFIG "@CPACK_WIX_CONFIG@")
SET(CPACK_WIX_INCLUDE "@CPACK_WIX_INCLUDE@")
+LIST(APPEND EXCLUDE_DIRS
+ bin/debug
+ data/test
+ lib/plugin/debug
+ mysql-test
+ scripts
+ sql-bench
+)
+
+LIST(APPEND EXCLUDE_FILES
+ bin/echo.exe
+ bin/mysql_client_test_embedded.exe
+ bin/mysqld-debug.exe
+ bin/mysqltest_embedded.exe
+ bin/replace.exe
+ lib/debug/mysqlserver.lib
+ lib/libmysqld.dll
+ lib/libmysqld.lib
+ lib/mysqlserver.lib
+ lib/mysqlservices.lib
+)
+
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(Win64 " Win64='yes'")
SET(Platform x64)
@@ -197,11 +219,18 @@ ENDMACRO() FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root)
+ FILE(RELATIVE_PATH dir_rel ${topdir} ${dir})
+ IF(dir_rel)
+ LIST(FIND EXCLUDE_DIRS ${dir_rel} TO_EXCLUDE)
+ IF(NOT TO_EXCLUDE EQUAL -1)
+ MESSAGE(STATUS "excluding directory: ${dir_rel}")
+ RETURN()
+ ENDIF()
+ ENDIF()
FILE(GLOB all_files ${dir}/*)
IF(NOT all_files)
RETURN()
ENDIF()
- FILE(RELATIVE_PATH dir_rel ${topdir} ${dir})
IF(dir_rel)
MAKE_DIRECTORY(${dir_root}/${dir_rel})
MAKE_WIX_IDENTIFIER("${dir_rel}" id)
@@ -215,18 +244,31 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FOREACH(f ${all_files})
IF(NOT IS_DIRECTORY ${f})
FILE(RELATIVE_PATH rel ${topdir} ${f})
- MAKE_WIX_IDENTIFIER("${rel}" id)
- FILE(TO_NATIVE_PATH ${f} f_native)
- GET_FILENAME_COMPONENT(f_ext "${f}" EXT)
- # According to MSDN each DLL or EXE should be in the own component
- IF(f_ext MATCHES ".exe" OR f_ext MATCHES ".dll")
-
- FILE(APPEND ${file} " <Component Id='C.${id}' Guid='*' ${Win64}>\n")
- FILE(APPEND ${file} " <File Id='F.${id}' KeyPath='yes' Source='${f_native}'/>\n")
- FILE(APPEND ${file} " </Component>\n")
- FILE(APPEND ${file_comp} " <ComponentRef Id='C.${id}'/>\n")
- ELSE()
- SET(NONEXEFILES "${NONEXEFILES}\n<File Id='F.${id}' Source='${f_native}'/>" )
+ SET(TO_EXCLUDE)
+ IF(rel MATCHES "\\.pdb$")
+ SET(TO_EXCLUDE TRUE)
+ ELSE()
+ LIST(FIND EXCLUDE_FILES ${rel} RES)
+ IF(NOT RES EQUAL -1)
+ SET(TO_EXCLUDE TRUE)
+ ENDIF()
+ ENDIF()
+ IF(TO_EXCLUDE)
+ MESSAGE(STATUS "excluding file: ${rel}")
+ ELSE()
+ MAKE_WIX_IDENTIFIER("${rel}" id)
+ FILE(TO_NATIVE_PATH ${f} f_native)
+ GET_FILENAME_COMPONENT(f_ext "${f}" EXT)
+ # According to MSDN each DLL or EXE should be in the own component
+ IF(f_ext MATCHES ".exe" OR f_ext MATCHES ".dll")
+
+ FILE(APPEND ${file} " <Component Id='C.${id}' Guid='*' ${Win64}>\n")
+ FILE(APPEND ${file} " <File Id='F.${id}' KeyPath='yes' Source='${f_native}'/>\n")
+ FILE(APPEND ${file} " </Component>\n")
+ FILE(APPEND ${file_comp} " <ComponentRef Id='C.${id}'/>\n")
+ ELSE()
+ SET(NONEXEFILES "${NONEXEFILES}\n<File Id='F.${id}' Source='${f_native}'/>" )
+ ENDIF()
ENDIF()
ENDIF()
ENDFOREACH()
@@ -247,18 +289,18 @@ ENDFUNCTION() FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix)
FILE(RELATIVE_PATH rel ${topdir} ${dir})
- IF(rel AND IS_DIRECTORY "${f}")
+ IF(rel)
MAKE_WIX_IDENTIFIER("${rel}" id)
GET_FILENAME_COMPONENT(name ${dir} NAME)
FILE(APPEND ${file} "${prefix}<Directory Id='D.${id}' Name='${name}'>\n")
ENDIF()
FILE(GLOB all_files ${dir}/*)
- FOREACH(f ${all_files})
+ FOREACH(f ${all_files})
IF(IS_DIRECTORY ${f})
TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ")
ENDIF()
ENDFOREACH()
- IF(rel AND IS_DIRECTORY "${f}")
+ IF(rel)
FILE(APPEND ${file} "${prefix}</Directory>\n")
ENDIF()
ENDFUNCTION()
@@ -317,16 +359,25 @@ ENDIF() FILE(REMOVE mysql_server.wixobj)
EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE} -ext WixUtilExtension mysql_server.wxs ${EXTRA_CANDLE_ARGS}
+ RESULT_VARIABLE CANDLE_RESULT
)
+
+IF(CANDLE_RESULT)
+ MESSAGE(FATAL_ERROR "ERROR: can't run candle")
+ENDIF()
+
EXECUTE_PROCESS(
COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension
mysql_server.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi
${EXTRA_LIGHT_ARGS}
+ RESULT_VARIABLE LIGHT_RESULT
)
+IF(LIGHT_RESULT)
+ MESSAGE(FATAL_ERROR "ERROR: can't run light")
+ENDIF()
+
# Switch monolithic install on again
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=1 ${CMAKE_BINARY_DIR}
- OUTPUT_QUIET
)
-
diff --git a/packaging/WiX/custom_ui.wxs b/packaging/WiX/custom_ui.wxs index 90db5c416fe..1dc1ef28e4f 100644 --- a/packaging/WiX/custom_ui.wxs +++ b/packaging/WiX/custom_ui.wxs @@ -1,7 +1,22 @@ <Include xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
- <WixVariable Id="WixUICostingPopupOptOut" Value="1" Overridable="yes" />
<UI Id="WixUI_Mondo_Custom">
+ <Dialog Id="CustomWelcomeDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="220" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
+ <Publish Event="NewDialog" Value="LicenseAgreementDlg">NOT OLDERVERSIONBEINGUPGRADED</Publish>
+ <Publish Event="NewDialog" Value="UpgradeDlg">OLDERVERSIONBEINGUPGRADED</Publish>
+ </Control>
+ <Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" Disabled="yes" />
+ <Control Id="Description" Type="Text" X="135" Y="80" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" />
+ <Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgTitle)" />
+ <Control Id="CopyrightText" Type="Text" X="135" Y="200" Width="220" Height="40" Transparent="yes" Text="Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved." />
+ <Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeDlgBitmap)" />
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ </Dialog>
+
<Dialog Id="UpgradeDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="Upgrade">
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
@@ -47,10 +62,7 @@ <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
- <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg" Order="1">NOT OLDERVERSIONBEINGUPGRADED</Publish>
- <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="UpgradeDlg" Order="2">OLDERVERSIONBEINGUPGRADED</Publish>
-
- <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="CustomWelcomeDlg">1</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="SetupTypeDlg" Order="2">LicenseAccepted = "1"</Publish>
<Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
@@ -74,7 +86,11 @@ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
- <Publish Dialog="UpgradeDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Dialog="UpgradeDlg" Control="Back" Event="NewDialog" Value="CustomWelcomeDlg">1</Publish>
+
+ <InstallUISequence>
+ <Show Dialog="CustomWelcomeDlg" Before="ProgressDlg">NOT Installed</Show>
+ </InstallUISequence>
</UI>
<UIRef Id="WixUI_Common" />
diff --git a/plugin/audit_null/audit_null.c b/plugin/audit_null/audit_null.c index 4d231d3e39b..161bd1cea70 100644 --- a/plugin/audit_null/audit_null.c +++ b/plugin/audit_null/audit_null.c @@ -81,11 +81,12 @@ static int audit_null_plugin_deinit(void *arg __attribute__((unused))) */ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)), - const struct mysql_event *event) + unsigned int event_class, + const void *event) { /* prone to races, oh well */ number_of_calls++; - if (event->event_class == MYSQL_AUDIT_GENERAL_CLASS) + if (event_class == MYSQL_AUDIT_GENERAL_CLASS) { const struct mysql_event_general *event_general= (const struct mysql_event_general *) event; diff --git a/sql-common/client.c b/sql-common/client.c index abaea310aae..f38467ff731 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1840,6 +1840,8 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) ssl_verify_server_cert() vio pointer to a SSL connected vio server_hostname name of the server that we connected to + errptr if we fail, we'll return (a pointer to a string + describing) the reason here RETURN VALUES 0 Success @@ -1849,7 +1851,7 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) -static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) +static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr) { SSL *ssl; X509 *server_cert; @@ -1860,19 +1862,19 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) if (!(ssl= (SSL*)vio->ssl_arg)) { - DBUG_PRINT("error", ("No SSL pointer found")); + *errptr= "No SSL pointer found"; DBUG_RETURN(1); } if (!server_hostname) { - DBUG_PRINT("error", ("No server hostname supplied")); + *errptr= "No server hostname supplied"; DBUG_RETURN(1); } if (!(server_cert= SSL_get_peer_certificate(ssl))) { - DBUG_PRINT("error", ("Could not get server certificate")); + *errptr= "Could not get server certificate"; DBUG_RETURN(1); } @@ -1901,7 +1903,7 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) DBUG_RETURN(0); } } - DBUG_PRINT("error", ("SSL certificate validation failure")); + *errptr= "SSL certificate validation failure"; DBUG_RETURN(1); } @@ -2507,6 +2509,9 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, /* Do the SSL layering. */ struct st_mysql_options *options= &mysql->options; struct st_VioSSLFd *ssl_fd; + enum enum_ssl_init_error ssl_init_error; + const char *cert_error; + unsigned long ssl_error; /* Send mysql->client_flag, max_packet_size - unencrypted otherwise @@ -2526,9 +2531,11 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, options->ssl_cert, options->ssl_ca, options->ssl_capath, - options->ssl_cipher))) + options->ssl_cipher, + &ssl_init_error))) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error)); goto error; } mysql->connector_fd= (unsigned char *) ssl_fd; @@ -2536,18 +2543,24 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, /* Connect to the server */ DBUG_PRINT("info", ("IO layer change in progress...")); if (sslconnect(ssl_fd, net->vio, - (long) (mysql->options.connect_timeout))) + (long) (mysql->options.connect_timeout), &ssl_error)) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + char buf[512]; + ERR_error_string_n(ssl_error, buf, 512); + buf[511]= 0; + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), + buf); goto error; } DBUG_PRINT("info", ("IO layer change done!")); /* Verify server cert */ if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && - ssl_verify_server_cert(net->vio, mysql->host)) + ssl_verify_server_cert(net->vio, mysql->host, &cert_error)) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), cert_error); goto error; } } diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 4f353597d6d..7f69ae54037 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1745,11 +1745,20 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) We don't use enter_cond()/exit_cond(). They do not save old mutex and cond. This would prohibit the use of DEBUG_SYNC between other places of enter_cond() and exit_cond(). + + We need to check for existence of thd->mysys_var to also make + it possible to use DEBUG_SYNC framework in scheduler when this + variable has been set to NULL. */ - old_mutex= thd->mysys_var->current_mutex; - old_cond= thd->mysys_var->current_cond; - thd->mysys_var->current_mutex= &debug_sync_global.ds_mutex; - thd->mysys_var->current_cond= &debug_sync_global.ds_cond; + if (thd->mysys_var) + { + old_mutex= thd->mysys_var->current_mutex; + old_cond= thd->mysys_var->current_cond; + thd->mysys_var->current_mutex= &debug_sync_global.ds_mutex; + thd->mysys_var->current_cond= &debug_sync_global.ds_cond; + } + else + old_mutex= NULL; set_timespec(abstime, action->timeout); DBUG_EXECUTE("debug_sync_exec", { @@ -1804,11 +1813,16 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) is locked. (See comment in THD::exit_cond().) */ mysql_mutex_unlock(&debug_sync_global.ds_mutex); - mysql_mutex_lock(&thd->mysys_var->mutex); - thd->mysys_var->current_mutex= old_mutex; - thd->mysys_var->current_cond= old_cond; - thd_proc_info(thd, old_proc_info); - mysql_mutex_unlock(&thd->mysys_var->mutex); + if (old_mutex) + { + mysql_mutex_lock(&thd->mysys_var->mutex); + thd->mysys_var->current_mutex= old_mutex; + thd->mysys_var->current_cond= old_cond; + thd_proc_info(thd, old_proc_info); + mysql_mutex_unlock(&thd->mysys_var->mutex); + } + else + thd_proc_info(thd, old_proc_info); } else { diff --git a/sql/debug_sync.h b/sql/debug_sync.h index 9ac7da39d4d..ba3739e8ad5 100644 --- a/sql/debug_sync.h +++ b/sql/debug_sync.h @@ -39,7 +39,7 @@ class THD; } while (0) /* Command line option --debug-sync-timeout. See mysqld.cc. */ -extern uint opt_debug_sync_timeout; +extern MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout; /* Default WAIT_FOR timeout if command line option is given without argument. */ #define DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT 300 diff --git a/sql/derror.cc b/sql/derror.cc index db9cd3c0c58..2b4cc13073e 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2005 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -108,7 +107,6 @@ bool read_texts(const char *file_name, const char *language, char lang_path[FN_REFLEN]; uchar *buff; uchar head[32],*pos; - const char *errmsg; DBUG_ENTER("read_texts"); LINT_INIT(buff); @@ -185,18 +183,9 @@ Check that the above file is the right version for this program!", DBUG_RETURN(0); err: - switch (funktpos) { - case 2: - errmsg= "Not enough memory for messagefile '%s'"; - break; - case 1: - errmsg= "Can't read from messagefile '%s'"; - break; - default: - errmsg= "Can't find messagefile '%s'"; - break; - } - sql_print_error(errmsg, name); + sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" : + ((funktpos == 1) ? "Can't read from messagefile '%s'" : + "Can't find messagefile '%s'"), name); if (file != FERR) (void) mysql_file_close(file, MYF(MY_WME)); DBUG_RETURN(1); diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 75d1c8ef8e8..9d52627fa83 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -620,18 +620,21 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type, only creates a record on disk. @pre The thread handle has no open tables. - @param[in,out] thd THD - @param[in] parse_data Parsed event definition - @param[in] create_if_not TRUE if IF NOT EXISTS clause was provided - to CREATE EVENT statement - + @param[in,out] thd THD + @param[in] parse_data Parsed event definition + @param[in] create_if_not TRUE if IF NOT EXISTS clause was provided + to CREATE EVENT statement + @param[out] event_already_exists When method is completed successfully + set to true if event already exists else + set to false @retval FALSE success @retval TRUE error */ bool Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, - my_bool create_if_not) + bool create_if_not, + bool *event_already_exists) { int ret= 1; TABLE *table= NULL; @@ -663,6 +666,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, { if (create_if_not) { + *event_already_exists= true; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS), parse_data->name.str); @@ -670,8 +674,10 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, } else my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), parse_data->name.str); + goto end; - } + } else + *event_already_exists= false; DBUG_PRINT("info", ("non-existent, go forward")); diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index 58484d17f06..162ec5d1243 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -73,7 +73,8 @@ public: Event_db_repository(){} bool - create_event(THD *thd, Event_parse_data *parse_data, my_bool create_if_not); + create_event(THD *thd, Event_parse_data *parse_data, bool create_if_not, + bool *event_already_exists); bool update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, diff --git a/sql/events.cc b/sql/events.cc index 23a0dc9eb52..819eca63e5c 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -284,6 +284,7 @@ create_query_string(THD *thd, String *buf) return 0; } + /** Create a new event. @@ -304,8 +305,8 @@ bool Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { - int ret; - bool save_binlog_row_based; + bool ret; + bool save_binlog_row_based, event_already_exists; DBUG_ENTER("Events::create_event"); if (check_if_system_tables_error()) @@ -345,28 +346,32 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, DBUG_RETURN(TRUE); /* On error conditions my_error() is called so no need to handle here */ - if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists))) + if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists, + &event_already_exists))) { Event_queue_element *new_element; bool dropped= 0; - if (!(new_element= new Event_queue_element())) - ret= TRUE; // OOM - else if ((ret= db_repository->load_named_event(thd, parse_data->dbname, - parse_data->name, - new_element))) + if (!event_already_exists) { - if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name, - TRUE)) - dropped= 1; - delete new_element; - } - else - { - /* TODO: do not ignore the out parameter and a possible OOM error! */ - bool created; - if (event_queue) - event_queue->create_event(thd, new_element, &created); + if (!(new_element= new Event_queue_element())) + ret= TRUE; // OOM + else if ((ret= db_repository->load_named_event(thd, parse_data->dbname, + parse_data->name, + new_element))) + { + if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name, + TRUE)) + dropped= 1; + delete new_element; + } + else + { + /* TODO: do not ignore the out parameter and a possible OOM error! */ + bool created; + if (event_queue) + event_queue->create_event(thd, new_element, &created); + } } /* binlog the create event unless it's been successfully dropped @@ -380,14 +385,14 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { sql_print_error("Event Error: An error occurred while creating query string, " "before writing it into binary log."); - ret= TRUE; + ret= true; } else - { - /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER - will be written into the binary log as the definer for the SQL thread. */ + /* + If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER + will be written into the binary log as the definer for the SQL thread. + */ ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); - } } } /* Restore the state of binlog format */ @@ -445,7 +450,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, !sortcmp_lex_string(parse_data->name, *new_name, system_charset_info)) { - my_error(ER_EVENT_SAME_NAME, MYF(0), parse_data->name.str); + my_error(ER_EVENT_SAME_NAME, MYF(0)); DBUG_RETURN(TRUE); } diff --git a/sql/field.cc b/sql/field.cc index 7ffc399718c..76fd6dc191c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -2608,7 +2607,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) DBUG_ENTER("Field_new_decimal::store_value"); #ifndef DBUG_OFF { - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, decimal_value))); } #endif @@ -2623,7 +2622,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) } #ifndef DBUG_OFF { - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("info", ("saving with precision %d scale: %d value %s", (int)precision, (int)dec, dbug_decimal_as_string(dbug_buff, decimal_value))); @@ -2692,7 +2691,7 @@ int Field_new_decimal::store(const char *from, uint length, } #ifndef DBUG_OFF - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, &decimal_value))); #endif @@ -9268,7 +9267,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, if (decimals >= NOT_FIXED_DEC) { my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name, - NOT_FIXED_DEC-1); + static_cast<ulong>(NOT_FIXED_DEC - 1)); DBUG_RETURN(TRUE); } @@ -9338,8 +9337,8 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, my_decimal_trim(&length, &decimals); if (length > DECIMAL_MAX_PRECISION) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(length), + fld_name, static_cast<ulong>(DECIMAL_MAX_PRECISION)); DBUG_RETURN(TRUE); } if (length < decimals) @@ -9563,7 +9562,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, if (length > MAX_BIT_FIELD_LENGTH) { my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, - MAX_BIT_FIELD_LENGTH); + static_cast<ulong>(MAX_BIT_FIELD_LENGTH)); DBUG_RETURN(TRUE); } pack_length= (length + 7) / 8; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 20745db9ce9..3c825ff3b4e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -8699,7 +8698,7 @@ NDB_SHARE *ndbcluster_get_share(const char *key, TABLE *table, DBUG_PRINT("error", ("get_share: failed to alloc share")); if (!have_lock) mysql_mutex_unlock(&ndbcluster_mutex); - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(*share)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(*share))); DBUG_RETURN(0); } } diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index e46b6b25f9c..c4b71bf32cf 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sql_priv.h" #include "unireg.h" // REQUIRED: for other includes @@ -1225,12 +1224,14 @@ ndbcluster_update_slock(THD *thd, } if (ndb_error) + { + char buf[1024]; + my_snprintf(buf, sizeof(buf), "Could not release lock on '%s.%s'", + db, table_name); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), - ndb_error->code, - ndb_error->message, - "Could not release lock on '%s.%s'", - db, table_name); + ndb_error->code, ndb_error->message, buf); + } if (trans) ndb->closeTransaction(trans); ndb->setDatabaseName(save_db); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 754d5dc99cf..785d118a5f4 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This handler was developed by Mikael Ronstrom for version 5.1 of MySQL. @@ -1069,6 +1069,10 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, static bool print_admin_msg(THD* thd, const char* msg_type, const char* db_name, const char* table_name, const char* op_name, const char *fmt, ...) + ATTRIBUTE_FORMAT(printf, 6, 7); +static bool print_admin_msg(THD* thd, const char* msg_type, + const char* db_name, const char* table_name, + const char* op_name, const char *fmt, ...) { va_list args; Protocol *protocol= thd->protocol; @@ -6652,22 +6656,29 @@ bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info, /** - Support of fast or online add/drop index + Support of in-place add/drop index */ -int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) +int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, + handler_add_index **add) { handler **file; int ret= 0; DBUG_ENTER("ha_partition::add_index"); + *add= new handler_add_index(table, key_info, num_of_keys); /* There has already been a check in fix_partition_func in mysql_alter_table before this call, which checks for unique/primary key violations of the partitioning function. So no need for extra check here. */ for (file= m_file; *file; file++) - if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys))) + { + handler_add_index *add_index; + if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys, &add_index))) goto err; + if ((ret= (*file)->final_add_index(add_index, true))) + goto err; + } DBUG_RETURN(ret); err: if (file > m_file) @@ -6692,6 +6703,42 @@ err: } +/** + Second phase of in-place add index. + + @note If commit is false, index changes are rolled back by dropping the + added indexes. If commit is true, nothing is done as the indexes + were already made active in ::add_index() + */ + +int ha_partition::final_add_index(handler_add_index *add, bool commit) +{ + DBUG_ENTER("ha_partition::final_add_index"); + // Rollback by dropping indexes. + if (!commit) + { + TABLE *table_arg= add->table; + uint num_of_keys= add->num_of_keys; + handler **file; + uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys); + uint old_num_of_keys= table_arg->s->keys; + uint i; + /* The newly created keys have the last id's */ + for (i= 0; i < num_of_keys; i++) + key_numbers[i]= i + old_num_of_keys; + if (!table_arg->key_info) + table_arg->key_info= add->key_info; + for (file= m_file; *file; file++) + { + (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys); + (void) (*file)->final_drop_index(table_arg); + } + if (table_arg->key_info == add->key_info) + table_arg->key_info= NULL; + } + DBUG_RETURN(0); +} + int ha_partition::prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index b0b11da823f..091efcfa727 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1055,7 +1055,9 @@ public: They are used for on-line/fast alter table add/drop index: ------------------------------------------------------------------------- */ - virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys); + virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, + handler_add_index **add); + virtual int final_add_index(handler_add_index *add, bool commit); virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys); virtual int final_drop_index(TABLE *table_arg); diff --git a/sql/handler.cc b/sql/handler.cc index 445e1ec5a3c..580677242bd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -278,7 +278,7 @@ handler *get_ha_partition(partition_info *part_info) } else { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(ha_partition)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(ha_partition))); } DBUG_RETURN(((handler*) partition)); } @@ -357,6 +357,7 @@ int ha_init_errors(void) SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER_DEFAULT(ER_AUTOINC_READ_FAILED)); SETMSG(HA_ERR_AUTOINC_ERANGE, ER_DEFAULT(ER_WARN_DATA_OUT_OF_RANGE)); SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER_DEFAULT(ER_TOO_MANY_CONCURRENT_TRXS)); + SETMSG(HA_ERR_INDEX_COL_TOO_LONG, ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG)); /* Register the error messages for use with my_error(). */ return my_error_register(get_handler_errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -1638,7 +1639,8 @@ int ha_recover(HASH *commit_list) } if (!info.list) { - sql_print_error(ER(ER_OUTOFMEMORY), info.len*sizeof(XID)); + sql_print_error(ER(ER_OUTOFMEMORY), + static_cast<int>(info.len*sizeof(XID))); DBUG_RETURN(1); } @@ -2860,6 +2862,9 @@ void handler::print_error(int error, myf errflag) case HA_ERR_TOO_MANY_CONCURRENT_TRXS: textno= ER_TOO_MANY_CONCURRENT_TRXS; break; + case HA_ERR_INDEX_COL_TOO_LONG: + textno= ER_INDEX_COLUMN_TOO_LONG; + break; default: { /* The error was "unknown" to this function. diff --git a/sql/handler.h b/sql/handler.h index fbc52170297..893d8f015f5 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1159,6 +1159,27 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); */ #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1) + +/** + Index creation context. + Created by handler::add_index() and freed by handler::final_add_index(). +*/ + +class handler_add_index +{ +public: + /* Table where the indexes are added */ + TABLE* const table; + /* Indexes being created */ + KEY* const key_info; + /* Size of key_info[] */ + const uint num_of_keys; + handler_add_index(TABLE *table_arg, KEY *key_info_arg, uint num_of_keys_arg) + : table (table_arg), key_info (key_info_arg), num_of_keys (num_of_keys_arg) + {} + virtual ~handler_add_index() {} +}; + /** The handler class is the interface for dynamically loadable storage engines. Do not add ifdefs and take care when adding or @@ -1717,8 +1738,36 @@ public: virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; - virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) +/** + First phase of in-place add index. + Handlers are supposed to create new indexes here but not make them + visible. + + @param table_arg Table to add index to + @param key_info Information about new indexes + @param num_of_key Number of new indexes + @param add[out] Context of handler specific information needed + for final_add_index(). + + @note This function can be called with less than exclusive metadata + lock depending on which flags are listed in alter_table_flags. +*/ + virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, + handler_add_index **add) { return (HA_ERR_WRONG_COMMAND); } + +/** + Second and last phase of in-place add index. + Commit or rollback pending new indexes. + + @param add Context of handler specific information from add_index(). + @param commit If true, commit. If false, rollback index changes. + + @note This function is called with exclusive metadata lock. +*/ + virtual int final_add_index(handler_add_index *add, bool commit) + { return (HA_ERR_WRONG_COMMAND); } + virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } diff --git a/sql/item.cc b/sql/item.cc index 0aac941740f..fee6381a25f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2011,6 +2011,61 @@ Item_field::Item_field(THD *thd, Item_field *item) collation.set(DERIVATION_IMPLICIT); } + +/** + Calculate the max column length not taking into account the + limitations over integer types. + + When storing data into fields the server currently just ignores the + limits specified on integer types, e.g. 1234 can safely be stored in + an int(2) and will not cause an error. + Thus when creating temporary tables and doing transformations + we must adjust the maximum field length to reflect this fact. + We take the un-restricted maximum length and adjust it similarly to + how the declared length is adjusted wrt unsignedness etc. + TODO: this all needs to go when we disable storing 1234 in int(2). + + @param field_par Original field the use to calculate the lengths + @param max_length Item's calculated explicit max length + @return The adjusted max length +*/ + +inline static uint32 +adjust_max_effective_column_length(Field *field_par, uint32 max_length) +{ + uint32 new_max_length= field_par->max_display_length(); + uint32 sign_length= (field_par->flags & UNSIGNED_FLAG) ? 0 : 1; + + switch (field_par->type()) + { + case MYSQL_TYPE_INT24: + /* + Compensate for MAX_MEDIUMINT_WIDTH being 1 too long (8) + compared to the actual number of digits that can fit into + the column. + */ + new_max_length+= 1; + /* fall through */ + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + + /* Take out the sign and add a conditional sign */ + new_max_length= new_max_length - 1 + sign_length; + break; + + /* BINGINT is always 20 no matter the sign */ + case MYSQL_TYPE_LONGLONG: + /* make gcc happy */ + default: + break; + } + + /* Adjust only if the actual precision based one is bigger than specified */ + return new_max_length > max_length ? new_max_length : max_length; +} + + void Item_field::set_field(Field *field_par) { field=result_field=field_par; // for easy coding with fields @@ -2024,6 +2079,9 @@ void Item_field::set_field(Field *field_par) collation.set(field_par->charset(), field_par->derivation(), field_par->repertoire()); fix_char_length(field_par->char_length()); + + max_length= adjust_max_effective_column_length(field_par, max_length); + fixed= 1; if (field->table->s->tmp_table == SYSTEM_TMP_TABLE) any_privileges= 0; diff --git a/sql/item_create.cc b/sql/item_create.cc index 1ae65926013..28cc5beaf25 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -5215,8 +5215,8 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, decoded_size= strtoul(c_len, NULL, 10); if (errno != 0) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), c_len, a->name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), INT_MAX, a->name, + static_cast<ulong>(DECIMAL_MAX_PRECISION)); return NULL; } len= decoded_size; @@ -5229,8 +5229,8 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, decoded_size= strtoul(c_dec, NULL, 10); if ((errno != 0) || (decoded_size > UINT_MAX)) { - my_error(ER_TOO_BIG_SCALE, MYF(0), c_dec, a->name, - DECIMAL_MAX_SCALE); + my_error(ER_TOO_BIG_SCALE, MYF(0), INT_MAX, a->name, + static_cast<ulong>(DECIMAL_MAX_SCALE)); return NULL; } dec= decoded_size; @@ -5243,14 +5243,14 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, } if (len > DECIMAL_MAX_PRECISION) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), len, a->name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(len), a->name, + static_cast<ulong>(DECIMAL_MAX_PRECISION)); return 0; } if (dec > DECIMAL_MAX_SCALE) { my_error(ER_TOO_BIG_SCALE, MYF(0), dec, a->name, - DECIMAL_MAX_SCALE); + static_cast<ulong>(DECIMAL_MAX_SCALE)); return 0; } res= new (thd->mem_root) Item_decimal_typecast(a, len, dec); diff --git a/sql/item_func.cc b/sql/item_func.cc index 24d0d94c6c5..754eae6d55b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -52,6 +51,8 @@ #include "sp.h" #include "set_var.h" #include "debug_sync.h" +#include <mysql/plugin.h> +#include <mysql/service_thd_wait.h> #ifdef NO_EMBEDDED_ACCESS_CHECKS #define sp_restore_security_context(A,B) while (0) {} @@ -1094,7 +1095,7 @@ err: push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), - name, 1); + name, 1L); return dec; } @@ -2258,6 +2259,9 @@ void Item_func_round::fix_length_and_dec() } val1= args[1]->val_int(); + if ((null_value= args[1]->is_null())) + return; + val1_unsigned= args[1]->unsigned_flag; if (val1 < 0) decimals_to_set= val1_unsigned ? INT_MAX : 0; @@ -3152,7 +3156,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, if (!tmp_udf) { - my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno); + my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str); DBUG_RETURN(TRUE); } u_d=tmp_udf; @@ -3890,6 +3894,7 @@ longlong Item_func_get_lock::val_int() timed_cond.set_timeout(timeout * ULL(1000000000)); error= 0; + thd_wait_begin(thd, THD_WAIT_USER_LOCK); while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); @@ -3901,6 +3906,7 @@ longlong Item_func_get_lock::val_int() } error= 0; } + thd_wait_end(thd); if (ull->locked) { @@ -4118,6 +4124,7 @@ longlong Item_func_sleep::val_int() thd->mysys_var->current_cond= &cond; error= 0; + thd_wait_begin(thd, THD_WAIT_SLEEP); while (!thd->killed) { error= timed_cond.wait(&cond, &LOCK_user_locks); @@ -4125,6 +4132,7 @@ longlong Item_func_sleep::val_int() break; error= 0; } + thd_wait_end(thd); thd_proc_info(thd, 0); mysql_mutex_unlock(&LOCK_user_locks); mysql_mutex_lock(&thd->mysys_var->mutex); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e1a4fcc8def..5a5284ca388 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -3702,7 +3701,8 @@ String *Item_func_uncompress::val_str(String *str) push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_BIG_FOR_UNCOMPRESS, ER(ER_TOO_BIG_FOR_UNCOMPRESS), - current_thd->variables.max_allowed_packet); + static_cast<int>(current_thd->variables. + max_allowed_packet)); goto err; } if (buffer.realloc((uint32)new_size)) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 5f30787f015..b642e38d8c6 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1591,6 +1591,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 1; bzero(ltime, sizeof(MYSQL_TIME)); get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); + + if ((null_value= (fuzzy_date & TIME_NO_ZERO_DATE) && + (ltime->year == 0 || ltime->month == 0 || ltime->day == 0))) + return TRUE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } @@ -2779,7 +2784,7 @@ String *Item_func_makedate::val_str(String *str) long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) @@ -2822,7 +2827,7 @@ longlong Item_func_makedate::val_int() long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) diff --git a/sql/log.cc b/sql/log.cc index fe782c5d621..9080dcd7fa2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3372,12 +3372,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) DBUG_ENTER("reset_logs"); ha_reset_logs(thd); - /* - We need to get both locks to be sure that no one is trying to - write to the index log file. - */ - mysql_mutex_lock(&LOCK_log); - mysql_mutex_lock(&LOCK_index); /* The following mutex is needed to ensure that no threads call @@ -3387,6 +3381,13 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) */ mysql_mutex_lock(&LOCK_thread_count); + /* + We need to get both locks to be sure that no one is trying to + write to the index log file. + */ + mysql_mutex_lock(&LOCK_log); + mysql_mutex_lock(&LOCK_index); + /* Save variables so that we can reopen the log */ save_name=name; name=0; // Protect against free @@ -5993,7 +5994,7 @@ int TC_LOG_MMAP::open(const char *opt_name) { pg->next=pg+1; pg->waiters=0; - pg->state=POOL; + pg->state=PS_POOL; mysql_mutex_init(key_PAGE_lock, &pg->lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_PAGE_cond, &pg->cond, 0); pg->start=(my_xid *)(data + i*tc_log_page_size); @@ -6167,7 +6168,7 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid) cookie= (ulong)((uchar *)p->ptr - data); // can never be zero *p->ptr++= xid; p->free--; - p->state= DIRTY; + p->state= PS_DIRTY; /* to sync or not to sync - this is the question */ mysql_mutex_unlock(&LOCK_active); @@ -6179,13 +6180,13 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid) p->waiters++; /* note - it must be while (), not do ... while () here - as p->state may be not DIRTY when we come here + as p->state may be not PS_DIRTY when we come here */ - while (p->state == DIRTY && syncing) + while (p->state == PS_DIRTY && syncing) mysql_cond_wait(&p->cond, &LOCK_sync); p->waiters--; - err= p->state == ERROR; - if (p->state != DIRTY) // page was synced + err= p->state == PS_ERROR; + if (p->state != PS_DIRTY) // page was synced { if (p->waiters == 0) mysql_cond_signal(&COND_pool); // in case somebody's waiting @@ -6223,7 +6224,7 @@ int TC_LOG_MMAP::sync() pool_last->next=syncing; pool_last=syncing; syncing->next=0; - syncing->state= err ? ERROR : POOL; + syncing->state= err ? PS_ERROR : PS_POOL; mysql_cond_broadcast(&syncing->cond); // signal "sync done" mysql_cond_signal(&COND_pool); // in case somebody's waiting mysql_mutex_unlock(&LOCK_pool); @@ -6506,8 +6507,11 @@ int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) { DBUG_ENTER("TC_LOG_BINLOG::unlog"); mysql_mutex_lock(&LOCK_prep_xids); - DBUG_ASSERT(prepared_xids > 0); - if (--prepared_xids == 0) { + // prepared_xids can be 0 if the transaction had ignorable errors. + DBUG_ASSERT(prepared_xids >= 0); + if (prepared_xids > 0) + prepared_xids--; + if (prepared_xids == 0) { DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids)); mysql_cond_signal(&COND_prep_xids); } diff --git a/sql/log.h b/sql/log.h index 7f7d1a1cf3a..0f0f81dd402 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LOG_H #define LOG_H @@ -63,9 +63,9 @@ class TC_LOG_MMAP: public TC_LOG { public: // only to keep Sun Forte on sol9x86 happy typedef enum { - POOL, // page is in pool - ERROR, // last sync failed - DIRTY // new xids added since last sync + PS_POOL, // page is in pool + PS_ERROR, // last sync failed + PS_DIRTY // new xids added since last sync } PAGE_STATE; private: @@ -687,7 +687,7 @@ void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void sql_print_information(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); typedef void (*sql_print_message_func)(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); + ATTRIBUTE_FORMAT_FPTR(printf, 1, 2); extern sql_print_message_func sql_print_message_handlers[]; int error_log_print(enum loglevel level, const char *format, diff --git a/sql/log_event.cc b/sql/log_event.cc index 39b4791ff3d..763bbf81a81 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8441,6 +8441,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) m_field_metadata, m_field_metadata_size, m_null_bits, m_flags); table_list->m_tabledef_valid= TRUE; + table_list->m_conv_table= NULL; table_list->open_type= OT_BASE_ONLY; /* diff --git a/sql/mdl.cc b/sql/mdl.cc index 3aed54ce12d..21410db2d22 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -18,6 +18,8 @@ #include "debug_sync.h" #include <hash.h> #include <mysqld_error.h> +#include <mysql/plugin.h> +#include <mysql/service_thd_wait.h> #ifdef HAVE_PSI_INTERFACE static PSI_mutex_key key_MDL_map_mutex; @@ -973,10 +975,14 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, old_msg= thd_enter_cond(thd, &m_COND_wait_status, &m_LOCK_wait_status, wait_state_name); + thd_wait_begin(thd, THD_WAIT_META_DATA_LOCK); while (!m_wait_status && !thd_killed(thd) && wait_result != ETIMEDOUT && wait_result != ETIME) + { wait_result= mysql_cond_timedwait(&m_COND_wait_status, &m_LOCK_wait_status, abs_timeout); + } + thd_wait_end(thd); if (m_wait_status == EMPTY) { diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index a5b60739b26..3b5fa81eab9 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -99,10 +99,11 @@ int my_decimal2string(uint mask, const my_decimal *d, UNSIGNED. Hence the buffer for a ZEROFILLed value is the length the user requested, plus one for a possible decimal point, plus one if the user only wanted decimal places, but we force a leading - zero on them. Because the type is implicitly UNSIGNED, we do not - need to reserve a character for the sign. For all other cases, - fixed_prec will be 0, and my_decimal_string_length() will be called - instead to calculate the required size of the buffer. + zero on them, plus one for the '\0' terminator. Because the type + is implicitly UNSIGNED, we do not need to reserve a character for + the sign. For all other cases, fixed_prec will be 0, and + my_decimal_string_length() will be called instead to calculate the + required size of the buffer. */ int length= (fixed_prec ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1) @@ -332,7 +333,7 @@ print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length) const char *dbug_decimal_as_string(char *buff, const my_decimal *val) { - int length= DECIMAL_MAX_STR_LENGTH; + int length= DECIMAL_MAX_STR_LENGTH + 1; /* minimum size for buff */ if (!val) return "NULL"; (void)decimal2string((decimal_t*) val, buff, &length, 0,0,0); diff --git a/sql/my_decimal.h b/sql/my_decimal.h index f3fd39f5721..6ac9d25b87d 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -62,7 +62,7 @@ typedef struct st_mysql_time MYSQL_TIME; /** maximum length of string representation (number of maximum decimal - digits + 1 position for sign + 1 position for decimal point) + digits + 1 position for sign + 1 position for decimal point, no terminator) */ #define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2) @@ -243,6 +243,7 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, inline int my_decimal_string_length(const my_decimal *d) { + /* length of string representation including terminating '\0' */ return decimal_string_size(d); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b349c5f91b1..6b00a6b3009 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -163,12 +163,12 @@ extern int memcntl(caddr_t, size_t, int, caddr_t, int, int); int initgroups(const char *,unsigned int); #endif -#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) +#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT) #include <ieeefp.h> #ifdef HAVE_FP_EXCEPT // Fix type conflict typedef fp_except fp_except_t; #endif -#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ +#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */ #ifdef HAVE_SYS_FPU_H /* for IRIX to use set_fpc_csr() */ #include <sys/fpu.h> @@ -194,19 +194,24 @@ extern "C" my_bool reopen_fstreams(const char *filename, inline void setup_fpu() { -#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) +#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT) /* We can't handle floating point exceptions with threads, so disable this on freebsd - Don't fall for overflow, underflow,divide-by-zero or loss of precision + Don't fall for overflow, underflow,divide-by-zero or loss of precision. + fpsetmask() is deprecated in favor of fedisableexcept() in C99. */ -#if defined(__i386__) +#if defined(FP_X_DNML) fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); #else fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); -#endif /* __i386__ */ -#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ +#endif /* FP_X_DNML */ +#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */ + +#ifdef HAVE_FEDISABLEEXCEPT + fedisableexcept(FE_ALL_EXCEPT); +#endif #ifdef HAVE_FESETROUND /* Set FPU rounding mode to "round-to-nearest" */ @@ -422,7 +427,7 @@ my_bool opt_super_large_pages= 0; my_bool opt_myisam_use_mmap= 0; uint opt_large_page_size= 0; #if defined(ENABLED_DEBUG_SYNC) -uint opt_debug_sync_timeout= 0; +MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout= 0; #endif /* defined(ENABLED_DEBUG_SYNC) */ my_bool opt_old_style_user_limits= 0, trust_function_creators= 0; /* @@ -2009,6 +2014,49 @@ extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) /* + Cleanup THD object + + SYNOPSIS + thd_cleanup() + thd Thread handler +*/ + +void thd_cleanup(THD *thd) +{ + thd->cleanup(); +} + +/* + Decrease number of connections + + SYNOPSIS + dec_connection_count() +*/ + +void dec_connection_count() +{ + mysql_mutex_lock(&LOCK_connection_count); + --connection_count; + mysql_mutex_unlock(&LOCK_connection_count); +} + + +/* + Delete the THD object and decrease number of threads + + SYNOPSIS + delete_thd() + thd Thread handler +*/ + +void delete_thd(THD *thd) +{ + thread_count--; + delete thd; +} + + +/* Unlink thd from global list of available connections and free thd SYNOPSIS @@ -2023,15 +2071,17 @@ void unlink_thd(THD *thd) { DBUG_ENTER("unlink_thd"); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); - thd->cleanup(); - - mysql_mutex_lock(&LOCK_connection_count); - --connection_count; - mysql_mutex_unlock(&LOCK_connection_count); + thd_cleanup(thd); + dec_connection_count(); mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - delete thd; + /* + Used by binlog_reset_master. It would be cleaner to use + DEBUG_SYNC here, but that's not possible because the THD's debug + sync feature has been shut down at this point. + */ + DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); + delete_thd(thd); DBUG_VOID_RETURN; } @@ -4923,6 +4973,14 @@ static bool read_init_file(char *file_name) } +/** + Increment number of created threads +*/ +void inc_thread_created(void) +{ + thread_created++; +} + #ifndef EMBEDDED_LIBRARY /* diff --git a/sql/mysqld.h b/sql/mysqld.h index 303ee5bec0f..d2366224b3f 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -216,6 +216,10 @@ extern char err_shared_dir[]; extern TYPELIB thread_handling_typelib; extern my_decimal decimal_zero; +/* + THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(MEM_ROOT**,THR_MALLOC); #ifdef HAVE_PSI_INTERFACE @@ -503,6 +507,10 @@ get_thread_running() extern "C" THD *_current_thd_noinline(); #define _current_thd() _current_thd_noinline() #else +/* + THR_THD is a key which will be used to set/get THD* for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(THD*, THR_THD); inline THD *_current_thd(void) { diff --git a/sql/password.c b/sql/password.c index 3b69705cc87..236e7bde0d5 100644 --- a/sql/password.c +++ b/sql/password.c @@ -205,21 +205,16 @@ void scramble_323(char *to, const char *message, const char *password) } -/* - Check scrambled message - Used in pre 4.1 password handling - SYNOPSIS - check_scramble_323() - scrambled scrambled message to check. - message original random message which was used for scrambling; must - be exactly SCRAMBLED_LENGTH_323 bytes long and - NULL-terminated. - hash_pass password which should be used for scrambling - All params are IN. +/** + Check scrambled message. Used in pre 4.1 password handling. - RETURN VALUE - 0 - password correct - !0 - password invalid + @param scrambled Scrambled message to check. + @param message Original random message which was used for scrambling. + @param hash_pass Password which should be used for scrambling. + + @remark scrambled and message must be SCRAMBLED_LENGTH_323 bytes long. + + @return FALSE if password is correct, TRUE otherwise. */ my_bool @@ -228,9 +223,16 @@ check_scramble_323(const unsigned char *scrambled, const char *message, { struct rand_struct rand_st; ulong hash_message[2]; - uchar buff[16],*to,extra; /* Big enough for check */ + /* Big enough for checks. */ + uchar buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1]; + uchar *to, extra; const uchar *pos; + /* Ensure that the scrambled message is null-terminated. */ + memcpy(scrambled_buff, scrambled, SCRAMBLE_LENGTH_323); + scrambled_buff[SCRAMBLE_LENGTH_323]= '\0'; + scrambled= scrambled_buff; + hash_password(hash_message, message, SCRAMBLE_LENGTH_323); randominit(&rand_st,hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f2653894ea7..e72c813f09f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -26,6 +26,8 @@ #include "rpl_utility.h" #include "transaction.h" #include "sql_parse.h" // end_trans, ROLLBACK +#include <mysql/plugin.h> +#include <mysql/service_thd_wait.h> static int count_relay_log_space(Relay_log_info* rli); @@ -799,6 +801,7 @@ int Relay_log_info::wait_for_pos(THD* thd, String* log_name, We are going to mysql_cond_(timed)wait(); if the SQL thread stops it will wake us up. */ + thd_wait_begin(thd, THD_WAIT_BINLOG); if (timeout > 0) { /* @@ -816,6 +819,7 @@ int Relay_log_info::wait_for_pos(THD* thd, String* log_name, } else mysql_cond_wait(&data_cond, &data_lock); + thd_wait_end(thd); DBUG_PRINT("info",("Got signal of master update or timed out")); if (error == ETIMEDOUT || error == ETIME) { @@ -1254,6 +1258,16 @@ void Relay_log_info::clear_tables_to_lock() tables_to_lock->m_tabledef.table_def::~table_def(); tables_to_lock->m_tabledef_valid= FALSE; } + + /* + If blob fields were used during conversion of field values + from the master table into the slave table, then we need to + free the memory used temporarily to store their values before + copying into the slave's table. + */ + if (tables_to_lock->m_conv_table) + free_blobs(tables_to_lock->m_conv_table); + tables_to_lock= static_cast<RPL_TABLE_LIST*>(tables_to_lock->next_global); tables_to_lock_count--; diff --git a/sql/scheduler.cc b/sql/scheduler.cc index d61a452b99e..a3848e20be5 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -80,14 +80,26 @@ scheduler_functions *thread_scheduler= NULL; */ /**@{*/ -static void scheduler_wait_begin(void) { +extern "C" +{ +static void scheduler_wait_lock_begin(void) { + MYSQL_CALLBACK(thread_scheduler, + thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK)); +} + +static void scheduler_wait_lock_end(void) { + MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd)); +} + +static void scheduler_wait_sync_begin(void) { MYSQL_CALLBACK(thread_scheduler, - thd_wait_begin, (current_thd, THD_WAIT_ROW_TABLE_LOCK)); + thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK)); } -static void scheduler_wait_end(void) { +static void scheduler_wait_sync_end(void) { MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd)); } +}; /**@}*/ /** @@ -98,7 +110,10 @@ static void scheduler_wait_end(void) { mysqld.cc, so this init function will always be called. */ static void scheduler_init() { - thr_set_lock_wait_callback(scheduler_wait_begin, scheduler_wait_end); + thr_set_lock_wait_callback(scheduler_wait_lock_begin, + scheduler_wait_lock_end); + thr_set_sync_wait_callback(scheduler_wait_sync_begin, + scheduler_wait_sync_end); } /* @@ -137,10 +152,6 @@ void one_thread_scheduler() thd_scheduler::thd_scheduler() : m_psi(NULL), data(NULL) { -#ifndef DBUG_OFF - dbug_explain[0]= '\0'; - set_explain= FALSE; -#endif } diff --git a/sql/scheduler.h b/sql/scheduler.h index b5a175434b6..7cf54dec004 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -72,11 +72,6 @@ enum scheduler_types void one_thread_per_connection_scheduler(); void one_thread_scheduler(); -enum pool_command_op -{ - NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP -}; - /* To be used for pool-of-threads (implemeneted differently on various OSs) */ @@ -97,15 +92,15 @@ public: void *data; /* scheduler-specific data structure */ -# ifndef DBUG_OFF - char dbug_explain[512]; - bool set_explain; -# endif - thd_scheduler(); ~thd_scheduler(); }; +void *thd_get_scheduler_data(THD *thd); +void thd_set_scheduler_data(THD *thd, void *data); +PSI_thread* thd_get_psi(THD *thd); +void thd_set_psi(THD *thd, PSI_thread *psi); + extern scheduler_functions *thread_scheduler; #endif diff --git a/sql/set_var.cc b/sql/set_var.cc index f31fe6a351d..8e48e0213f0 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -117,7 +117,8 @@ void sys_var_end() sys_var constructor @param chain variables are linked into chain for mysql_add_sys_var_chain() - @param name_arg the name of the variable. @sa my_option::name + @param name_arg the name of the variable. Must be 0-terminated and exist + for the liftime of the sys_var object. @sa my_option::name @param comment shown in mysqld --help, @sa my_option::comment @param flags_arg or'ed flag_enum values @param off offset of the global variable value from the @@ -164,8 +165,8 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg, */ DBUG_ASSERT(parse_flag == PARSE_NORMAL || getopt_id <= 0 || getopt_id >= 255); - name.str= name_arg; - name.length= strlen(name_arg); + name.str= name_arg; // ER_NO_DEFAULT relies on 0-termination of name_arg + name.length= strlen(name_arg); // and so does this. DBUG_ASSERT(name.length <= NAME_CHAR_LEN); bzero(&option, sizeof(option)); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 6898028df70..09620f2d260 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6405,3 +6405,6 @@ ER_TABLE_NEEDS_REBUILD WARN_OPTION_BELOW_LIMIT eng "The value of '%s' should be no less than the value of '%s'" + +ER_INDEX_COLUMN_TOO_LONG + eng "Index column size too large. The maximum column size is %lu bytes." diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c8368be953b..7b175cb0256 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" @@ -550,7 +550,7 @@ sp_head::operator delete(void *ptr, size_t size) throw() sp_head::sp_head() - :Query_arena(&main_mem_root, INITIALIZED_FOR_SP), + :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP), m_flags(0), m_sp_cache_version(0), unsafe_flags(0), @@ -1066,7 +1066,7 @@ void sp_head::recursion_level_error(THD *thd) if (m_type == TYPE_ENUM_PROCEDURE) { my_error(ER_SP_RECURSION_LIMIT, MYF(0), - thd->variables.max_sp_recursion_depth, + static_cast<int>(thd->variables.max_sp_recursion_depth), m_name.str); } else @@ -1208,7 +1208,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) Query_arena *old_arena; /* per-instruction arena */ MEM_ROOT execute_mem_root; - Query_arena execute_arena(&execute_mem_root, INITIALIZED_FOR_SP), + Query_arena execute_arena(&execute_mem_root, STMT_INITIALIZED_FOR_SP), backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; @@ -1489,7 +1489,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->m_reprepare_observer= save_reprepare_observer; thd->stmt_arena= old_arena; - state= EXECUTED; + state= STMT_EXECUTED; /* Restore the caller's original warning information area: @@ -1647,7 +1647,7 @@ sp_head::execute_trigger(THD *thd, sp_rcontext *nctx = NULL; bool err_status= FALSE; MEM_ROOT call_mem_root; - Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); Query_arena backup_arena; DBUG_ENTER("sp_head::execute_trigger"); @@ -1788,7 +1788,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, String binlog_buf(buf, sizeof(buf), &my_charset_bin); bool err_status= FALSE; MEM_ROOT call_mem_root; - Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); Query_arena backup_arena; DBUG_ENTER("sp_head::execute_function"); DBUG_PRINT("info", ("function %s", m_name.str)); @@ -2545,7 +2545,7 @@ sp_head::restore_thd_mem_root(THD *thd) DBUG_ENTER("sp_head::restore_thd_mem_root"); Item *flist= free_list; // The old list set_query_arena(thd); // Get new free_list and mem_root - state= INITIALIZED_FOR_SP; + state= STMT_INITIALIZED_FOR_SP; DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx", (ulong) &mem_root, (ulong) &thd->mem_root)); @@ -3010,7 +3010,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, (thd->stmt_da->sql_errno() != ER_CANT_REOPEN_TABLE && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE && thd->stmt_da->sql_errno() != ER_UPDATE_TABLE_USED)) - thd->stmt_arena->state= Query_arena::EXECUTED; + thd->stmt_arena->state= Query_arena::STMT_EXECUTED; /* Merge here with the saved parent's values diff --git a/sql/sp_head.h b/sql/sp_head.h index 5efd48fc7c6..4d5e2dd95ab 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -560,7 +560,7 @@ public: /// Should give each a name or type code for debugging purposes? sp_instr(uint ip, sp_pcontext *ctx) - :Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) + :Query_arena(0, STMT_INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) {} virtual ~sp_instr() diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7d7595899d7..a065d8f9219 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2273,13 +2273,12 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, */ else if (!password_len && !combo.plugin.length && no_auto_create) { - my_error(ER_PASSWORD_NO_MATCH, MYF(0), combo.user.str, combo.host.str); + my_error(ER_PASSWORD_NO_MATCH, MYF(0)); goto end; } else if (!can_create_user) { - my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0), - thd->security_ctx->user, thd->security_ctx->host_or_ip); + my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0)); goto end; } else if (combo.plugin.str[0]) @@ -2307,8 +2306,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, /* what == 'N' means revoke */ if (combo.plugin.length && what != 'N') { - my_error(ER_GRANT_PLUGIN_USER_EXISTS, MYF(0), combo.user.length, - combo.user.str); + my_error(ER_GRANT_PLUGIN_USER_EXISTS, MYF(0), + static_cast<int>(combo.user.length), combo.user.str); goto end; } if (combo.password.str) // If password given @@ -3642,6 +3641,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { // Should never happen /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); + thd->lex->restore_backup_query_tables_list(&backup); if (save_binlog_row_based) thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(TRUE); /* purecov: deadcode */ @@ -8398,14 +8398,21 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) } #ifndef EMBEDDED_LIBRARY + +/** Get a string according to the protocol of the underlying buffer. */ +typedef char * (*get_proto_string_func_t) (char **, size_t *, size_t *); + /** - Get a null character terminated string from a user-supplied buffer. + Get a string formatted according to the 4.1 version of the MySQL protocol. - @param buffer[in, out] Pointer to the buffer to be scanned. + @param buffer[in, out] Pointer to the user-supplied buffer to be scanned. @param max_bytes_available[in, out] Limit the bytes to scan. @param string_length[out] The number of characters scanned not including the null character. + @remark Strings are always null character terminated in this version of the + protocol. + @remark The string_length does not include the terminating null character. However, after the call, the buffer is increased by string_length+1 bytes, beyond the null character if there still available bytes to @@ -8416,9 +8423,9 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) */ static -char *get_null_terminated_string(char **buffer, - size_t *max_bytes_available, - size_t *string_length) +char *get_41_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length) { char *str= (char *)memchr(*buffer, '\0', *max_bytes_available); @@ -8428,7 +8435,60 @@ char *get_null_terminated_string(char **buffer, *string_length= (size_t)(str - *buffer); *max_bytes_available-= *string_length + 1; str= *buffer; - *buffer += *string_length + 1; + *buffer += *string_length + 1; + + return str; +} + + +/** + Get a string formatted according to the 4.0 version of the MySQL protocol. + + @param buffer[in, out] Pointer to the user-supplied buffer to be scanned. + @param max_bytes_available[in, out] Limit the bytes to scan. + @param string_length[out] The number of characters scanned not including + the null character. + + @remark If there are not enough bytes left after the current position of + the buffer to satisfy the current string, the string is considered + to be empty and a pointer to empty_c_string is returned. + + @remark A string at the end of the packet is not null terminated. + + @return Pointer to beginning of the string scanned, or a pointer to a empty + string. +*/ +static +char *get_40_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length) +{ + char *str; + size_t len; + + /* No bytes to scan left, treat string as empty. */ + if ((*max_bytes_available) == 0) + { + *string_length= 0; + return empty_c_string; + } + + str= (char *) memchr(*buffer, '\0', *max_bytes_available); + + /* + If the string was not null terminated by the client, + the remainder of the packet is the string. Otherwise, + advance the buffer past the end of the null terminated + string. + */ + if (str == NULL) + len= *string_length= *max_bytes_available; + else + len= (*string_length= (size_t)(str - *buffer)) + 1; + + str= *buffer; + *buffer+= len; + *max_bytes_available-= len; return str; } @@ -8439,7 +8499,7 @@ char *get_null_terminated_string(char **buffer, @param buffer[in, out] The buffer to scan; updates position after scan. @param max_bytes_available[in, out] Limit the number of bytes to scan @param string_length[out] Number of characters scanned - + @remark In case the length is zero, then the total size of the string is considered to be 1 byte; the size byte. @@ -8525,14 +8585,14 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities)); if (mpvio->client_capabilities & CLIENT_SSL) { - char error_string[1024] __attribute__((unused)); + unsigned long errptr; /* Do the SSL layering. */ if (!ssl_acceptor_fd) return packet_error; DBUG_PRINT("info", ("IO layer change in progress...")); - if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout)) + if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr)) { DBUG_PRINT("error", ("Failed to accept new SSL connection")); return packet_error; @@ -8555,7 +8615,20 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) && opt_using_transactions) net->return_status= mpvio->server_status; - + + /* + The 4.0 and 4.1 versions of the protocol differ on how strings + are terminated. In the 4.0 version, if a string is at the end + of the packet, the string is not null terminated. Do not assume + that the returned string is always null terminated. + */ + get_proto_string_func_t get_string; + + if (mpvio->client_capabilities & CLIENT_PROTOCOL_41) + get_string= get_41_protocol_string; + else + get_string= get_40_protocol_string; + /* In order to safely scan a head for '\0' string terminators we must keep track of how many bytes remain in the allocated @@ -8564,8 +8637,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos); size_t user_len; - char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &user_len); + char *user= get_string(&end, &bytes_remaining_in_packet, &user_len); if (user == NULL) return packet_error; @@ -8590,8 +8662,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, /* Old passwords are zero terminated strings. */ - passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &passwd_len); + passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); } if (passwd == NULL) @@ -8602,40 +8673,43 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if (mpvio->client_capabilities & CLIENT_CONNECT_WITH_DB) { - db= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &db_len); + db= get_string(&end, &bytes_remaining_in_packet, &db_len); if (db == NULL) return packet_error; } size_t client_plugin_len= 0; - char *client_plugin= get_null_terminated_string(&end, - &bytes_remaining_in_packet, - &client_plugin_len); + char *client_plugin= get_string(&end, &bytes_remaining_in_packet, + &client_plugin_len); if (client_plugin == NULL) client_plugin= &empty_c_string[0]; - + char db_buff[NAME_LEN + 1]; // buffer to store db in utf8 char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; - - /* Since 4.1 all database names are stored in utf8 */ + + /* + Copy and convert the user and database names to the character set used + by the server. Since 4.1 all database names are stored in UTF-8. Also, + ensure that the names are properly null-terminated as this is relied + upon later. + */ if (db) { db_len= copy_and_convert(db_buff, sizeof(db_buff) - 1, system_charset_info, db, db_len, mpvio->charset_adapter->charset(), &dummy_errors); + db_buff[db_len]= '\0'; db= db_buff; - db_buff[db_len]= 0; } user_len= copy_and_convert(user_buff, sizeof(user_buff) - 1, - system_charset_info, user, user_len, - mpvio->charset_adapter->charset(), - &dummy_errors); + system_charset_info, user, user_len, + mpvio->charset_adapter->charset(), + &dummy_errors); + user_buff[user_len]= '\0'; user= user_buff; - user_buff[user_len]= 0; /* If username starts and ends in "'", chop them off */ if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') @@ -8898,7 +8972,7 @@ err: if (mpvio->status == MPVIO_EXT::FAILURE) { inc_host_errors(mpvio->ip); - my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); } DBUG_RETURN(-1); } @@ -9484,7 +9558,7 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, } inc_host_errors(mpvio->ip); - my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); DBUG_RETURN(CR_ERROR); } @@ -9538,7 +9612,7 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, } inc_host_errors(mpvio->ip); - my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); return CR_ERROR; } diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index 74e9e603ebe..ba2c72b7266 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -21,11 +21,18 @@ extern int finalize_audit_plugin(st_plugin_int *plugin); #ifndef EMBEDDED_LIBRARY +struct st_mysql_event_generic +{ + unsigned int event_class; + const void *event; +}; + unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; static mysql_mutex_t LOCK_audit_mask; -static void event_class_dispatch(THD *thd, const struct mysql_event *event); +static void event_class_dispatch(THD *thd, unsigned int event_class, + const void *event); static inline @@ -64,7 +71,6 @@ typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap); static void general_class_handler(THD *thd, uint event_subtype, va_list ap) { mysql_event_general event; - event.event_class= MYSQL_AUDIT_GENERAL_CLASS; event.event_subclass= event_subtype; event.general_error_code= va_arg(ap, int); event.general_thread_id= thd ? thd->thread_id : 0; @@ -77,14 +83,13 @@ static void general_class_handler(THD *thd, uint event_subtype, va_list ap) event.general_query_length= va_arg(ap, unsigned int); event.general_charset= va_arg(ap, struct charset_info_st *); event.general_rows= (unsigned long long) va_arg(ap, ha_rows); - event_class_dispatch(thd, (const mysql_event*) &event); + event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event); } static void connection_class_handler(THD *thd, uint event_subclass, va_list ap) { mysql_event_connection event; - event.event_class= MYSQL_AUDIT_CONNECTION_CLASS; event.event_subclass= event_subclass; event.status= va_arg(ap, int); event.thread_id= va_arg(ap, unsigned long); @@ -102,7 +107,7 @@ static void connection_class_handler(THD *thd, uint event_subclass, va_list ap) event.ip_length= va_arg(ap, unsigned int); event.database= va_arg(ap, const char *); event.database_length= va_arg(ap, unsigned int); - event_class_dispatch(thd, (const mysql_event *) &event); + event_class_dispatch(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event); } @@ -433,18 +438,19 @@ int finalize_audit_plugin(st_plugin_int *plugin) static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) { - const struct mysql_event *event= (const struct mysql_event *) arg; + const struct st_mysql_event_generic *event_generic= + (const struct st_mysql_event_generic *) arg; unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *); - set_audit_mask(event_class_mask, event->event_class); + set_audit_mask(event_class_mask, event_generic->event_class); /* Check to see if the plugin is interested in this event */ if (check_audit_mask(data->class_mask, event_class_mask)) return 0; /* Actually notify the plugin */ - data->event_notify(thd, event); + data->event_notify(thd, event_generic->event_class, event_generic->event); return 0; } @@ -457,15 +463,19 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) @param[in] event */ -static void event_class_dispatch(THD *thd, const struct mysql_event *event) +static void event_class_dispatch(THD *thd, unsigned int event_class, + const void *event) { + struct st_mysql_event_generic event_generic; + event_generic.event_class= event_class; + event_generic.event= event; /* Check if we are doing a slow global dispatch. This event occurs when thd == NULL as it is not associated with any particular thread. */ if (unlikely(!thd)) { - plugin_foreach(thd, plugins_dispatch, MYSQL_AUDIT_PLUGIN, (void*) event); + plugin_foreach(thd, plugins_dispatch, MYSQL_AUDIT_PLUGIN, &event_generic); } else { @@ -476,7 +486,7 @@ static void event_class_dispatch(THD *thd, const struct mysql_event *event) plugins_last= plugins + thd->audit_class_plugins.elements; for (; plugins < plugins_last; plugins++) - plugins_dispatch(thd, *plugins, (void*) event); + plugins_dispatch(thd, *plugins, &event_generic); } } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f9d85b1e024..43ad400ce64 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3854,7 +3854,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) { /* Give right error message */ thd->clear_error(); - my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno); + my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str); sql_print_error("Couldn't repair table: %s.%s", share->db.str, share->table_name.str); if (entry->file) @@ -7921,7 +7921,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, } if (tablenr > MAX_TABLES) { - my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); + my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES)); DBUG_RETURN(1); } for (table_list= tables; diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 503d830a10e..3b91a68c341 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2006 MySQL AB +/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -242,7 +242,7 @@ void mysql_client_binlog_statement(THD* thd) TODO: Maybe a better error message since the BINLOG statement now contains several events. */ - my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement"); + my_error(ER_UNKNOWN_ERROR, MYF(0)); goto end; } } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4af038bb4e0..7c2ed133f70 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -11,7 +11,8 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ + /***************************************************************************** ** @@ -216,6 +217,252 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ +/** + Get reference to scheduler data object + + @param thd THD object + + @retval Scheduler data object on THD +*/ +void *thd_get_scheduler_data(THD *thd) +{ + return thd->scheduler.data; +} + +/** + Set reference to Scheduler data object for THD object + + @param thd THD object + @param psi Scheduler data object to set on THD +*/ +void thd_set_scheduler_data(THD *thd, void *data) +{ + thd->scheduler.data= data; +} + +/** + Get reference to Performance Schema object for THD object + + @param thd THD object + + @retval Performance schema object for thread on THD +*/ +PSI_thread *thd_get_psi(THD *thd) +{ + return thd->scheduler.m_psi; +} + +/** + Set reference to Performance Schema object for THD object + + @param thd THD object + @param psi Performance schema object for thread +*/ +void thd_set_psi(THD *thd, PSI_thread *psi) +{ + thd->scheduler.m_psi= psi; +} + +/** + Set the state on connection to killed + + @param thd THD object +*/ +void thd_set_killed(THD *thd) +{ + thd->killed= THD::KILL_CONNECTION; +} + +/** + Clear errors from the previous THD + + @param thd THD object +*/ +void thd_clear_errors(THD *thd) +{ + my_errno= 0; + thd->mysys_var->abort= 0; +} + +/** + Set thread stack in THD object + + @param thd Thread object + @param stack_start Start of stack to set in THD object +*/ +void thd_set_thread_stack(THD *thd, char *stack_start) +{ + thd->thread_stack= stack_start; +} + +/** + Lock connection data for the set of connections this connection + belongs to + + @param thd THD object +*/ +void thd_lock_thread_count(THD *) +{ + mysql_mutex_lock(&LOCK_thread_count); +} + +/** + Lock connection data for the set of connections this connection + belongs to + + @param thd THD object +*/ +void thd_unlock_thread_count(THD *) +{ + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); +} + +/** + Close the socket used by this connection + + @param thd THD object +*/ +void thd_close_connection(THD *thd) +{ + if (thd->net.vio) + vio_close(thd->net.vio); +} + +/** + Get current THD object from thread local data + + @retval The THD object for the thread, NULL if not connection thread +*/ +THD *thd_get_current_thd() +{ + return current_thd; +} + +/** + Set up various THD data for a new connection + + thd_new_connection_setup + + @param thd THD object + @param stack_start Start of stack for connection +*/ +void thd_new_connection_setup(THD *thd, char *stack_start) +{ +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + thd_set_psi(thd, + PSI_server->new_thread(key_thread_one_connection, + thd, + thd_get_thread_id((MYSQL_THD)thd))); +#endif + thd->set_time(); + thd->prior_thr_create_utime= thd->thr_create_utime= thd->start_utime= + my_micro_time(); + threads.append(thd); + thd_unlock_thread_count(thd); + DBUG_PRINT("info", ("init new connection. thd: 0x%lx fd: %d", + (ulong)thd, thd->net.vio->sd)); + thd_set_thread_stack(thd, stack_start); +} + +/** + Lock data that needs protection in THD object + + @param thd THD object +*/ +void thd_lock_data(THD *thd) +{ + mysql_mutex_lock(&thd->LOCK_thd_data); +} + +/** + Unlock data that needs protection in THD object + + @param thd THD object +*/ +void thd_unlock_data(THD *thd) +{ + mysql_mutex_unlock(&thd->LOCK_thd_data); +} + +/** + Support method to check if connection has already started transcaction + + @param client_cntx Low level client context + + @retval TRUE if connection already started transaction +*/ +bool thd_is_transaction_active(THD *thd) +{ + return thd->transaction.is_active(); +} + +/** + Check if there is buffered data on the socket representing the connection + + @param thd THD object +*/ +int thd_connection_has_data(THD *thd) +{ + Vio *vio= thd->net.vio; + return vio->has_data(vio); +} + +/** + Set reading/writing on socket, used by SHOW PROCESSLIST + + @param thd THD object + @param val Value to set it to (0 or 1) +*/ +void thd_set_net_read_write(THD *thd, uint val) +{ + thd->net.reading_or_writing= val; +} + +/** + Set reference to mysys variable in THD object + + @param thd THD object + @param mysys_var Reference to set +*/ +void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var) +{ + thd->set_mysys_var(mysys_var); +} + +/** + Get socket file descriptor for this connection + + @param thd THD object + + @retval Socket of the connection +*/ +my_socket thd_get_fd(THD *thd) +{ + return thd->net.vio->sd; +} + +/** + Get thread attributes for connection threads + + @retval Reference to thread attribute for connection threads +*/ +pthread_attr_t *get_connection_attrib(void) +{ + return &connection_attrib; +} + +/** + Get max number of connections + + @retval Max number of connections for MySQL Server +*/ +ulong get_max_connections(void) +{ + return max_connections; +} + /* The following functions form part of the C plugin API */ @@ -493,7 +740,7 @@ bool Drop_table_error_handler::handle_condition(THD *thd, THD::THD() - :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, + :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, /* statement id */ 0), rli_fake(0), user_time(0), in_sub_stmt(0), @@ -1354,6 +1601,25 @@ bool THD::store_globals() return 0; } +/* + Remove the thread specific info (THD and mem_root pointer) stored during + store_global call for this thread. +*/ +bool THD::restore_globals() +{ + /* + Assert that thread_stack is initialized: it's necessary to be able + to track stack overrun. + */ + DBUG_ASSERT(thread_stack); + + /* Undocking the thread specific data. */ + my_pthread_setspecific_ptr(THR_THD, NULL); + my_pthread_setspecific_ptr(THR_MALLOC, NULL); + + return 0; +} + /* Cleanup after query. @@ -2191,7 +2457,7 @@ bool select_export::send_data(List<Item> &items) ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "string", printable_buff, - item->name, row_count); + item->name, static_cast<long>(row_count)); } else if (from_end_pos < res->ptr() + res->length()) { @@ -2200,7 +2466,7 @@ bool select_export::send_data(List<Item> &items) */ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED), - item->full_name(), row_count); + item->full_name(), static_cast<long>(row_count)); } cvt_str.length(bytes); res= &cvt_str; @@ -3297,7 +3563,7 @@ extern "C" void thd_pool_wait_end(MYSQL_THD thd); thd_wait_end MUST be called immediately after waking up again. */ -extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type) +extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type) { MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type)); } @@ -3313,7 +3579,7 @@ extern "C" void thd_wait_end(MYSQL_THD thd) MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (thd)); } #else -extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type) +extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type) { /* do NOTHING for the embedded library */ return; diff --git a/sql/sql_class.h b/sql/sql_class.h index 56d85e7cb6d..a2c622b2326 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -624,14 +624,14 @@ public: /* The states relfects three diffrent life cycles for three different types of statements: - Prepared statement: INITIALIZED -> PREPARED -> EXECUTED. - Stored procedure: INITIALIZED_FOR_SP -> EXECUTED. - Other statements: CONVENTIONAL_EXECUTION never changes. + Prepared statement: STMT_INITIALIZED -> STMT_PREPARED -> STMT_EXECUTED. + Stored procedure: STMT_INITIALIZED_FOR_SP -> STMT_EXECUTED. + Other statements: STMT_CONVENTIONAL_EXECUTION never changes. */ enum enum_state { - INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2, - CONVENTIONAL_EXECUTION= 3, EXECUTED= 4, ERROR= -1 + STMT_INITIALIZED= 0, STMT_INITIALIZED_FOR_SP= 1, STMT_PREPARED= 2, + STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, STMT_ERROR= -1 }; enum_state state; @@ -654,13 +654,13 @@ public: virtual Type type() const; virtual ~Query_arena() {}; - inline bool is_stmt_prepare() const { return state == INITIALIZED; } + inline bool is_stmt_prepare() const { return state == STMT_INITIALIZED; } inline bool is_stmt_prepare_or_first_sp_execute() const - { return (int)state < (int)PREPARED; } + { return (int)state < (int)STMT_PREPARED; } inline bool is_stmt_prepare_or_first_stmt_execute() const - { return (int)state <= (int)PREPARED; } + { return (int)state <= (int)STMT_PREPARED; } inline bool is_conventional() const - { return state == CONVENTIONAL_EXECUTION; } + { return state == STMT_CONVENTIONAL_EXECUTION; } inline void* alloc(size_t size) { return alloc_root(mem_root,size); } inline void* calloc(size_t size) @@ -2199,6 +2199,7 @@ public: void cleanup(void); void cleanup_after_query(); bool store_globals(); + bool restore_globals(); #ifdef SIGNAL_WITH_VIO_CLOSE inline void set_active_vio(Vio* vio) { diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 9d7e20c1d6e..c3b978d7659 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Functions to autenticate and handle reqests for a connection @@ -466,7 +465,7 @@ static int check_connection(THD *thd) if (vio_peer_addr(net->vio, ip, &thd->peer_port, NI_MAXHOST)) { - my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); + my_error(ER_BAD_HOST_ERROR, MYF(0)); return 1; } if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME)))) @@ -477,7 +476,7 @@ static int check_connection(THD *thd) if (ip_to_hostname(&net->vio->remote, thd->main_security_ctx.ip, &thd->main_security_ctx.host, &connect_errors)) { - my_error(ER_BAD_HOST_ERROR, MYF(0), ip); + my_error(ER_BAD_HOST_ERROR, MYF(0)); return 1; } @@ -708,6 +707,32 @@ pthread_handler_t handle_one_connection(void *arg) return 0; } +bool thd_prepare_connection(THD *thd) +{ + bool rc; + lex_start(thd); + rc= login_connection(thd); + MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + if (rc) + return rc; + + MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0], + (char *) thd->security_ctx->host_or_ip); + + prepare_new_connection_state(thd); + return FALSE; +} + +bool thd_is_connection_alive(THD *thd) +{ + NET *net= &thd->net; + if (!net->error && + net->vio != 0 && + !(thd->killed == THD::KILL_CONNECTION)) + return TRUE; + return FALSE; +} + void do_handle_one_connection(THD *thd_arg) { THD *thd= thd_arg; @@ -750,22 +775,13 @@ void do_handle_one_connection(THD *thd_arg) for (;;) { - NET *net= &thd->net; bool rc; - lex_start(thd); - rc= login_connection(thd); - MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + rc= thd_prepare_connection(thd); if (rc) goto end_thread; - MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0], - (char *) thd->security_ctx->host_or_ip); - - prepare_new_connection_state(thd); - - while (!net->error && net->vio != 0 && - !(thd->killed == THD::KILL_CONNECTION)) + while (thd_is_connection_alive(thd)) { mysql_audit_release(thd); if (do_command(thd)) diff --git a/sql/sql_connect.h b/sql/sql_connect.h index ff5a20dfbc2..1b71d95323d 100644 --- a/sql/sql_connect.h +++ b/sql/sql_connect.h @@ -35,6 +35,8 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void decrease_user_connections(USER_CONN *uc); bool thd_init_client_charset(THD *thd, uint cs_number); bool setup_connection_thread_globals(THD *thd); +bool thd_prepare_connection(THD *thd); +bool thd_is_connection_alive(THD *thd); int check_user(THD *thd, enum enum_server_command command, const char *passwd, uint passwd_len, const char *db, diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h index ed7bfac821a..d19d14fa167 100644 --- a/sql/sql_cursor.h +++ b/sql/sql_cursor.h @@ -46,7 +46,7 @@ protected: select_result *result; public: Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg) - :Query_arena(mem_root_arg, INITIALIZED), result(result_arg) + :Query_arena(mem_root_arg, STMT_INITIALIZED), result(result_arg) {} virtual bool is_open() const= 0; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 4475e087163..10afb8962a7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Insert of records */ @@ -3889,7 +3888,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (table->s->fields < values.elements) { - my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L); DBUG_RETURN(-1); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index f82e0948b54..96382400c2c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. 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 @@ -743,8 +743,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, pfields.append("`"); pfields.append(item->name); pfields.append("`"); - pfields.append("="); - val->print(&pfields, QT_ORDINARY); + pfields.append(val->name); } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 24f7fdb8e61..44a9243d8f5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #define MYSQL_LEX 1 #include "my_global.h" @@ -1749,6 +1749,67 @@ bool sp_process_definer(THD *thd) /** + Auxiliary call that opens and locks tables for LOCK TABLES statement + and initializes the list of locked tables. + + @param thd Thread context. + @param tables List of tables to be locked. + + @return FALSE in case of success, TRUE in case of error. +*/ + +static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables) +{ + Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; + uint counter; + TABLE_LIST *table; + + thd->in_lock_tables= 1; + + if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy)) + goto err; + + /* + We allow to change temporary tables even if they were locked for read + by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK + TABLES time and by the statement which is later executed under LOCK TABLES + we ensure that for temporary tables we always request a write lock (such + discrepancy can cause problems for the storage engine). + We don't set TABLE_LIST::lock_type in this case as this might result in + extra warnings from THD::decide_logging_format() even though binary logging + is totally irrelevant for LOCK TABLES. + */ + for (table= tables; table; table= table->next_global) + if (!table->placeholder() && table->table->s->tmp_table) + table->table->reginfo.lock_type= TL_WRITE; + + if (lock_tables(thd, tables, counter, 0) || + thd->locked_tables_list.init_locked_tables(thd)) + goto err; + + thd->in_lock_tables= 0; + + return FALSE; + +err: + thd->in_lock_tables= 0; + + trans_rollback_stmt(thd); + /* + Need to end the current transaction, so the storage engine (InnoDB) + can free its locks if LOCK TABLES locked some tables before finding + that it can't lock a table in its list + */ + trans_commit_implicit(thd); + /* Close tables and release metadata locks. */ + close_thread_tables(thd); + DBUG_ASSERT(!thd->locked_tables_mode); + thd->mdl_context.release_transactional_locks(); + return TRUE; +} + + +/** Execute command saved in thd and lex->sql_command. @param thd Thread handle @@ -3093,31 +3154,11 @@ end_with_restore_list: goto error; thd->variables.option_bits|= OPTION_TABLE_LOCK; - thd->in_lock_tables=1; - { - Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; - - res= (open_and_lock_tables(thd, all_tables, FALSE, 0, - &lock_tables_prelocking_strategy) || - thd->locked_tables_list.init_locked_tables(thd)); - } - - thd->in_lock_tables= 0; + res= lock_tables_open_and_lock_tables(thd, all_tables); if (res) { - trans_rollback_stmt(thd); - /* - Need to end the current transaction, so the storage engine (InnoDB) - can free its locks if LOCK TABLES locked some tables before finding - that it can't lock a table in its list - */ - trans_commit_implicit(thd); - /* Close tables and release metadata locks. */ - close_thread_tables(thd); - DBUG_ASSERT(!thd->locked_tables_mode); - thd->mdl_context.release_transactional_locks(); thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); } else @@ -3412,8 +3453,7 @@ end_with_restore_list: hostname_requires_resolving(user->host.str)) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_HOSTNAME_WONT_WORK, - ER(ER_WARN_HOSTNAME_WONT_WORK), - user->host.str); + ER(ER_WARN_HOSTNAME_WONT_WORK)); // Are we trying to change a password of another user DBUG_ASSERT(user->host.str != 0); @@ -5305,7 +5345,7 @@ mysql_new_select(LEX *lex, bool move_down) lex->nest_level++; if (lex->nest_level > (int) MAX_SELECT_NESTING) { - my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING); + my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0)); DBUG_RETURN(1); } select_lex->nest_level= lex->nest_level; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 52d6757b03a..354548cbda4 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -7025,7 +7025,7 @@ void set_key_field_ptr(KEY *key_info, const uchar *new_buf, void mem_alloc_error(size_t size) { - my_error(ER_OUTOFMEMORY, MYF(0), size); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(size)); } #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index dc5b7b5a37b..5e092f3ef79 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sql_priv.h" // SHOW_MY_BOOL #include "unireg.h" @@ -548,7 +548,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (!cur) { free_plugin_mem(&plugin_dl); - report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length); + report_error(report, ER_OUTOFMEMORY, + static_cast<int>(plugin_dl.dl.length)); DBUG_RETURN(0); } /* @@ -570,7 +571,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0)))) { free_plugin_mem(&plugin_dl); - report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length); + report_error(report, ER_OUTOFMEMORY, + static_cast<int>(plugin_dl.dl.length)); DBUG_RETURN(0); } plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length, @@ -581,7 +583,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl))) { free_plugin_mem(&plugin_dl); - report_error(report, ER_OUTOFMEMORY, sizeof(struct st_plugin_dl)); + report_error(report, ER_OUTOFMEMORY, + static_cast<int>(sizeof(struct st_plugin_dl))); DBUG_RETURN(0); } DBUG_RETURN(tmp); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 779569b10fb..7f2ab1aeb8e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -11,7 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -1467,7 +1467,7 @@ static int mysql_test_select(Prepared_statement *stmt, if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(select_send))); goto error; } @@ -2543,7 +2543,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_execute"); DBUG_VOID_RETURN; } @@ -2597,7 +2597,7 @@ void mysql_sql_stmt_execute(THD *thd) if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - name->length, name->str, "EXECUTE"); + static_cast<int>(name->length), name->str, "EXECUTE"); DBUG_VOID_RETURN; } @@ -2639,7 +2639,7 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_fetch"); DBUG_VOID_RETURN; } @@ -2699,7 +2699,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_reset"); DBUG_VOID_RETURN; } @@ -2712,7 +2712,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) */ reset_stmt_params(stmt); - stmt->state= Query_arena::PREPARED; + stmt->state= Query_arena::STMT_PREPARED; general_log_print(thd, thd->command, NullS); @@ -2774,7 +2774,7 @@ void mysql_sql_stmt_close(THD *thd) if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - name->length, name->str, "DEALLOCATE PREPARE"); + static_cast<int>(name->length), name->str, "DEALLOCATE PREPARE"); else if (stmt->is_in_use()) my_error(ER_PS_NO_RECURSION, MYF(0)); else @@ -2831,7 +2831,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->state= Query_arena::ERROR; + stmt->state= Query_arena::STMT_ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysqld_stmt_send_long_data"); @@ -2855,7 +2855,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) #endif if (thd->stmt_da->is_error()) { - stmt->state= Query_arena::ERROR; + stmt->state= Query_arena::STMT_ERROR; stmt->last_errno= thd->stmt_da->sql_errno(); strncpy(stmt->last_error, thd->stmt_da->message(), MYSQL_ERRMSG_SIZE); } @@ -3010,7 +3010,7 @@ end: Prepared_statement::Prepared_statement(THD *thd_arg) :Statement(NULL, &main_mem_root, - INITIALIZED, ++thd_arg->statement_id_counter), + STMT_INITIALIZED, ++thd_arg->statement_id_counter), thd(thd_arg), result(thd_arg), param_array(0), @@ -3283,7 +3283,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) { setup_set_params(); lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE; - state= Query_arena::PREPARED; + state= Query_arena::STMT_PREPARED; flags&= ~ (uint) IS_IN_USE; /* @@ -3401,7 +3401,7 @@ Prepared_statement::execute_loop(String *expanded_query, int reprepare_attempt= 0; /* Check if we got an error when sending long data */ - if (state == Query_arena::ERROR) + if (state == Query_arena::STMT_ERROR) { my_message(last_errno, last_error, MYF(0)); return TRUE; @@ -3464,7 +3464,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable) Item_change_list save_change_list; thd->change_list.move_elements_to(&save_change_list); - state= CONVENTIONAL_EXECUTION; + state= STMT_CONVENTIONAL_EXECUTION; if (!(lex= new (mem_root) st_lex_local)) return TRUE; @@ -3799,8 +3799,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->set_statement(&stmt_backup); thd->stmt_arena= old_stmt_arena; - if (state == Query_arena::PREPARED) - state= Query_arena::EXECUTED; + if (state == Query_arena::STMT_PREPARED) + state= Query_arena::STMT_EXECUTED; if (error == 0 && this->lex->sql_command == SQLCOM_CALL) { diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index a09aa5511bd..b567e3a1f85 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -86,7 +86,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, When an error is returned, my_message may have not been called and the client will hang waiting for a response. */ - my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed"); + my_error(ER_UNKNOWN_ERROR, MYF(0)); } } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 9783917aaf0..717356a1b8c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1490,7 +1490,7 @@ bool change_master(THD* thd, Master_info* mi) get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i); if (s_id == ::server_id && replicate_same_server_id) { - my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), s_id); + my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id)); ret= TRUE; goto err; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9e9de5e3524..fb5ed62ecdf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2407,12 +2407,11 @@ bool schema_table_store_record(THD *thd, TABLE *table) } -int make_table_list(THD *thd, SELECT_LEX *sel, - LEX_STRING *db_name, LEX_STRING *table_name) +static int make_table_list(THD *thd, SELECT_LEX *sel, + LEX_STRING *db_name, LEX_STRING *table_name) { Table_ident *table_ident; table_ident= new Table_ident(thd, *db_name, *table_name, 1); - sel->init_query(); if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, MDL_SHARED_READ)) return 1; return 0; @@ -2982,91 +2981,190 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex, /** - @brief Fill I_S table for SHOW COLUMNS|INDEX commands + Fill I_S table with data obtained by performing full-blown table open. + + @param thd Thread handler. + @param is_show_fields_or_keys Indicates whether it is a legacy SHOW + COLUMNS or SHOW KEYS statement. + @param table TABLE object for I_S table to be filled. + @param schema_table I_S table description structure. + @param orig_db_name Database name. + @param orig_table_name Table name. + @param open_tables_state_backup Open_tables_state object which is used + to save/restore original status of + variables related to open tables state. + @param can_deadlock Indicates that deadlocks are possible + due to metadata locks, so to avoid + them we should not wait in case if + conflicting lock is present. + + @retval FALSE - Success. + @retval TRUE - Failure. +*/ +static bool +fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, + TABLE *table, ST_SCHEMA_TABLE *schema_table, + LEX_STRING *orig_db_name, + LEX_STRING *orig_table_name, + Open_tables_backup *open_tables_state_backup, + bool can_deadlock) +{ + Query_arena i_s_arena(thd->mem_root, + Query_arena::STMT_CONVENTIONAL_EXECUTION), + backup_arena, *old_arena; + LEX *old_lex= thd->lex, temp_lex, *lex; + LEX_STRING db_name, table_name; + TABLE_LIST *table_list; + bool result= true; + + DBUG_ENTER("fill_schema_table_by_open"); + /* + When a view is opened its structures are allocated on a permanent + statement arena and linked into the LEX tree for the current statement + (this happens even in cases when view is handled through TEMPTABLE + algorithm). - @param[in] thd thread handler - @param[in] tables TABLE_LIST for I_S table - @param[in] schema_table pointer to I_S structure - @param[in] can_deadlock Indicates that deadlocks are possible - due to metadata locks, so to avoid - them we should not wait in case if - conflicting lock is present. - @param[in] open_tables_state_backup pointer to Open_tables_backup object - which is used to save|restore original - status of variables related to - open tables state + To prevent this process from unnecessary hogging of memory in the permanent + arena of our I_S query and to avoid damaging its LEX we use temporary + arena and LEX for table/view opening. - @return Operation status - @retval 0 success - @retval 1 error -*/ + Use temporary arena instead of statement permanent arena. Also make + it active arena and save original one for successive restoring. + */ + old_arena= thd->stmt_arena; + thd->stmt_arena= &i_s_arena; + thd->set_n_backup_active_arena(&i_s_arena, &backup_arena); -static int -fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables, - ST_SCHEMA_TABLE *schema_table, - bool can_deadlock, - Open_tables_backup *open_tables_state_backup) -{ - LEX *lex= thd->lex; - bool res; - LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name; - enum_sql_command save_sql_command= lex->sql_command; - TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first; - TABLE *table= tables->table; - int error= 1; - DBUG_ENTER("fill_schema_show"); + /* Prepare temporary LEX. */ + thd->lex= lex= &temp_lex; + lex_start(thd); + + /* Disable constant subquery evaluation as we won't be locking tables. */ + lex->context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; - lex->all_selects_list= tables->schema_select_lex; /* - Restore thd->temporary_tables to be able to process - temporary tables(only for 'show index' & 'show columns'). - This should be changed when processing of temporary tables for - I_S tables will be done. + Some of process_table() functions rely on wildcard being passed from + old LEX (or at least being initialized). */ - thd->temporary_tables= open_tables_state_backup->temporary_tables; + lex->wild= old_lex->wild; + + /* + Since make_table_list() might change database and table name passed + to it we create copies of orig_db_name and orig_table_name here. + These copies are used for make_table_list() while unaltered values + are passed to process_table() functions. + */ + if (!thd->make_lex_string(&db_name, orig_db_name->str, + orig_db_name->length, FALSE) || + !thd->make_lex_string(&table_name, orig_table_name->str, + orig_table_name->length, FALSE)) + goto end; + + /* + Create table list element for table to be open. Link it with the + temporary LEX. The latter is required to correctly open views and + produce table describing their structure. + */ + if (make_table_list(thd, &lex->select_lex, &db_name, &table_name)) + goto end; + + table_list= lex->select_lex.table_list.first; + + if (is_show_fields_or_keys) + { + /* + Restore thd->temporary_tables to be able to process + temporary tables (only for 'show index' & 'show columns'). + This should be changed when processing of temporary tables for + I_S tables will be done. + */ + thd->temporary_tables= open_tables_state_backup->temporary_tables; + } + else + { + /* + Apply optimization flags for table opening which are relevant for + this I_S table. We can't do this for SHOW COLUMNS/KEYS because of + backward compatibility. + */ + table_list->i_s_requested_object= schema_table->i_s_requested_object; + } + /* Let us set fake sql_command so views won't try to merge themselves into main statement. If we don't do this, SELECT * from information_schema.xxxx will cause problems. - SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' + SQLCOM_SHOW_FIELDS is used because it satisfies + 'only_view_structure()'. */ lex->sql_command= SQLCOM_SHOW_FIELDS; - res= open_normal_and_derived_tables(thd, show_table_list, - (MYSQL_OPEN_IGNORE_FLUSH | - MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | - (can_deadlock ? - MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0))); - lex->sql_command= save_sql_command; + result= open_normal_and_derived_tables(thd, table_list, + (MYSQL_OPEN_IGNORE_FLUSH | + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | + (can_deadlock ? + MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0))); + /* + Restore old value of sql_command back as it is being looked at in + process_table() function. + */ + lex->sql_command= old_lex->sql_command; DEBUG_SYNC(thd, "after_open_table_ignore_flush"); /* - get_all_tables() returns 1 on failure and 0 on success thus - return only these and not the result code of ::process_table() - - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case(this part of code is used only for - 'show columns' & 'show statistics' commands). + XXX: show_table_list has a flag i_is_requested, + and when it's set, open_normal_and_derived_tables() + can return an error without setting an error message + in THD, which is a hack. This is why we have to + check for res, then for thd->is_error() and only then + for thd->main_da.sql_errno(). + + Again we don't do this for SHOW COLUMNS/KEYS because + of backward compatibility. */ - table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - if (!show_table_list->view) - db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db, - show_table_list->db_length, FALSE); - else - db_name= &show_table_list->view_db; - - - error= test(schema_table->process_table(thd, show_table_list, - table, res, db_name, - table_name)); - thd->temporary_tables= 0; - close_tables_for_reopen(thd, &show_table_list, - open_tables_state_backup->mdl_system_tables_svp); - DBUG_RETURN(error); + if (!is_show_fields_or_keys && result && thd->is_error() && + thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) + { + /* + Hide error for a non-existing table. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist. + */ + result= false; + thd->clear_error(); + } + else + { + result= schema_table->process_table(thd, table_list, + table, result, + orig_db_name, + orig_table_name); + } + + +end: + lex->unit.cleanup(); + + /* Restore original LEX value, statement's arena and THD arena values. */ + lex_end(thd->lex); + + if (i_s_arena.free_list) + i_s_arena.free_items(); + + /* + For safety reset list of open temporary tables before closing + all tables open within this Open_tables_state. + */ + thd->temporary_tables= NULL; + close_thread_tables(thd); + thd->mdl_context.rollback_to_savepoint(open_tables_state_backup->mdl_system_tables_svp); + + thd->lex= old_lex; + + thd->stmt_arena= old_arena; + thd->restore_active_arena(&i_s_arena, &backup_arena); + + DBUG_RETURN(result); } @@ -3477,10 +3575,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; TABLE *table= tables->table; - SELECT_LEX *old_all_select_lex= lex->all_selects_list; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; - SELECT_LEX sel; LOOKUP_FIELD_VALUES lookup_field_vals; LEX_STRING *db_name, *table_name; bool with_i_schema; @@ -3488,11 +3584,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) List<LEX_STRING> db_names; List_iterator_fast<LEX_STRING> it(db_names); COND *partial_cond= 0; - uint derived_tables= lex->derived_tables; int error= 1; Open_tables_backup open_tables_state_backup; - uint8 save_context_analysis_only= lex->context_analysis_only; - Query_tables_list query_tables_list_backup; #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; #endif @@ -3511,15 +3604,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ can_deadlock= thd->mdl_context.has_locks(); - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; - lex->reset_n_backup_query_tables_list(&query_tables_list_backup); - /* - Restore Query_tables_list::sql_command value, which was reset - above, as ST_SCHEMA_TABLE::process_table() functions often rely - that this value reflects which SHOW statement is executed. - */ - lex->sql_command= query_tables_list_backup.sql_command; - /* We should not introduce deadlocks even if we already have some tables open and locked, since we won't lock tables which we will @@ -3539,9 +3623,19 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ if (lsel && lsel->table_list.first) { - error= fill_schema_show_cols_or_idxs(thd, tables, schema_table, - can_deadlock, - &open_tables_state_backup); + LEX_STRING db_name, table_name; + + db_name.str= lsel->table_list.first->db; + db_name.length= lsel->table_list.first->db_length; + + table_name.str= lsel->table_list.first->table_name; + table_name.length= lsel->table_list.first->table_name_length; + + error= fill_schema_table_by_open(thd, TRUE, + table, schema_table, + &db_name, &table_name, + &open_tables_state_backup, + can_deadlock); goto err; } @@ -3595,12 +3689,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) it.rewind(); /* To get access to new elements in basis list */ while ((db_name= it++)) { - LEX_STRING orig_db_name; - - /* db_name can be changed in make_table_list() func */ - if (!thd->make_lex_string(&orig_db_name, db_name->str, - db_name->length, FALSE)) - goto err; #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, NULL, 0, 1) || @@ -3678,66 +3766,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) continue; } - int res; - LEX_STRING tmp_lex_string; - /* - Set the parent lex of 'sel' because it is needed by - sel.init_query() which is called inside make_table_list. - */ - sel.parent_lex= lex; - if (make_table_list(thd, &sel, db_name, table_name)) - goto err; - TABLE_LIST *show_table_list= sel.table_list.first; - lex->all_selects_list= &sel; - lex->derived_tables= 0; - lex->sql_command= SQLCOM_SHOW_FIELDS; - show_table_list->i_s_requested_object= - schema_table->i_s_requested_object; DEBUG_SYNC(thd, "before_open_in_get_all_tables"); - res= open_normal_and_derived_tables(thd, show_table_list, - (MYSQL_OPEN_IGNORE_FLUSH | - MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | - (can_deadlock ? MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0))); - lex->sql_command= query_tables_list_backup.sql_command; - /* - XXX: show_table_list has a flag i_is_requested, - and when it's set, open_normal_and_derived_tables() - can return an error without setting an error message - in THD, which is a hack. This is why we have to - check for res, then for thd->is_error() only then - for thd->stmt_da->sql_errno(). - */ - if (res && thd->is_error() && - thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) - { - /* - Hide error for not existing table. - This error can occur for example when we use - where condition with db name and table name and this - table does not exist. - */ - res= 0; - thd->clear_error(); - } - else - { - /* - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case. - */ - thd->make_lex_string(&tmp_lex_string, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - res= schema_table->process_table(thd, show_table_list, table, - res, &orig_db_name, - &tmp_lex_string); - close_tables_for_reopen(thd, &show_table_list, - open_tables_state_backup.mdl_system_tables_svp); - } - DBUG_ASSERT(!lex->query_tables_own_last); - if (res) + + if (fill_schema_table_by_open(thd, FALSE, + table, schema_table, + db_name, table_name, + &open_tables_state_backup, + can_deadlock)) goto err; } } @@ -3753,10 +3788,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) error= 0; err: thd->restore_backup_open_tables_state(&open_tables_state_backup); - lex->restore_backup_query_tables_list(&query_tables_list_backup); - lex->derived_tables= derived_tables; - lex->all_selects_list= old_all_select_lex; - lex->context_analysis_only= save_context_analysis_only; + DBUG_RETURN(error); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f98ac676525..a5cc386d740 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2618,7 +2618,8 @@ int prepare_create_field(Create_field *sql_field, MAX_FIELD_CHARLENGTH) { my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), - MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH); + MYF(0), sql_field->field_name, + static_cast<ulong>(MAX_FIELD_CHARLENGTH)); DBUG_RETURN(1); } } @@ -3614,12 +3615,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_LONG_INDEX_COMMENT, MYF(0), - key_info->name, (uint) INDEX_COMMENT_MAXLEN); + key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN)); DBUG_RETURN(-1); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_INDEX_COMMENT), - key_info->name, (uint) INDEX_COMMENT_MAXLEN); + key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN)); /* do not push duplicate warnings */ if (!check_duplicate_warning(thd, warn_buff, strlen(warn_buff))) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -3747,7 +3748,8 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field) MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, - MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); + static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / + sql_field->charset->mbmaxlen)); DBUG_RETURN(1); } sql_field->sql_type= MYSQL_TYPE_BLOB; @@ -5678,6 +5680,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, uint index_drop_count= 0; uint *index_drop_buffer= NULL; uint index_add_count= 0; + handler_add_index *add= NULL; + bool pending_inplace_add_index= false; uint *index_add_buffer= NULL; uint candidate_key_count= 0; bool no_pk; @@ -6432,6 +6436,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } thd->count_cuted_fields= CHECK_FIELD_IGNORE; + if (error) + goto err_new_table_cleanup; + /* If we did not need to copy, we might still need to add/drop indexes. */ if (! new_table) { @@ -6463,7 +6470,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, key_part->field= table->field[key_part->fieldnr]; } /* Add the indexes. */ - if ((error= table->file->add_index(table, key_info, index_add_count))) + if ((error= table->file->add_index(table, key_info, index_add_count, + &add))) { /* Exchange the key_info for the error message. If we exchange @@ -6475,11 +6483,27 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, table->key_info= save_key_info; goto err_new_table_cleanup; } + pending_inplace_add_index= true; } /*end of if (index_add_count)*/ if (index_drop_count) { + /* Currently we must finalize add index if we also drop indexes */ + if (pending_inplace_add_index) + { + /* Committing index changes needs exclusive metadata lock. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, + table_list->db, + table_list->table_name, + MDL_EXCLUSIVE)); + if ((error= table->file->final_add_index(add, true))) + { + table->file->print_error(error, MYF(0)); + goto err_new_table_cleanup; + } + pending_inplace_add_index= false; + } /* The prepare_drop_index() method takes an array of key numbers. */ key_numbers= (uint*) thd->alloc(sizeof(uint) * index_drop_count); keyno_p= key_numbers; @@ -6520,11 +6544,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } /*end of if (! new_table) for add/drop index*/ - if (error) - goto err_new_table_cleanup; - if (table->s->tmp_table != NO_TMP_TABLE) { + /* + In-place operations are not supported for temporary tables, so + we don't have to call final_add_index() in this case. The assert + verifies that in-place add index has not been done. + */ + DBUG_ASSERT(!pending_inplace_add_index); /* Close lock if this is a transactional table */ if (thd->lock) { @@ -6591,8 +6618,30 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_casedn_str(files_charset_info, old_name); if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME)) + { + if (pending_inplace_add_index) + { + pending_inplace_add_index= false; + table->file->final_add_index(add, false); + } + // Mark this TABLE instance as stale to avoid out-of-sync index information. + table->m_needs_reopen= true; goto err_new_table_cleanup; - + } + if (pending_inplace_add_index) + { + pending_inplace_add_index= false; + DBUG_EXECUTE_IF("alter_table_rollback_new_index", { + table->file->final_add_index(add, false); + my_error(ER_UNKNOWN_ERROR, MYF(0)); + goto err_new_table_cleanup; + }); + if ((error= table->file->final_add_index(add, true))) + { + table->file->print_error(error, MYF(0)); + goto err_new_table_cleanup; + } + } close_all_tables_for_name(thd, table->s, new_name != table_name || new_db != db); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 13a1b8029f2..5ab1a648d09 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. 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 @@ -11574,7 +11574,23 @@ field_or_var: opt_load_data_set_spec: /* empty */ {} - | SET insert_update_list {} + | SET load_data_set_list {} + ; + +load_data_set_list: + load_data_set_list ',' load_data_set_elem + | load_data_set_elem + ; + +load_data_set_elem: + simple_ident_nospvar equal remember_name expr_or_default remember_end + { + LEX *lex= Lex; + if (lex->update_list.push_back($1) || + lex->value_list.push_back($4)) + MYSQL_YYABORT; + $4->set_name($3, (uint) ($5 - $3), YYTHD->charset()); + } ; /* Common definitions */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index ad7bf3fef2a..6c6ccc5209e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -695,7 +695,7 @@ static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type) : Events::stop(); mysql_mutex_lock(&LOCK_global_system_variables); if (ret) - my_error(ER_EVENT_SET_VAR_ERROR, MYF(0)); + my_error(ER_EVENT_SET_VAR_ERROR, MYF(0), 0); return ret; } @@ -2504,7 +2504,7 @@ static bool update_last_insert_id(THD *thd, set_var *var) { if (!var->value) { - my_error(ER_NO_DEFAULT, MYF(0), var->var->name); + my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str); return true; } thd->first_successful_insert_id_in_prev_stmt= @@ -2553,7 +2553,7 @@ static bool update_insert_id(THD *thd, set_var *var) { if (!var->value) { - my_error(ER_NO_DEFAULT, MYF(0), var->var->name); + my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str); return true; } thd->force_one_auto_inc_interval(var->save_result.ulonglong_value); @@ -2576,7 +2576,7 @@ static bool update_rand_seed1(THD *thd, set_var *var) { if (!var->value) { - my_error(ER_NO_DEFAULT, MYF(0), var->var->name); + my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str); return true; } thd->rand.seed1= (ulong) var->save_result.ulonglong_value; @@ -2598,7 +2598,7 @@ static bool update_rand_seed2(THD *thd, set_var *var) { if (!var->value) { - my_error(ER_NO_DEFAULT, MYF(0), var->var->name); + my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str); return true; } thd->rand.seed2= (ulong) var->save_result.ulonglong_value; diff --git a/sql/table.cc b/sql/table.cc index 68e2566ffc1..c62d84743bc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1992,7 +1992,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, Query_arena *backup_stmt_arena_ptr= thd->stmt_arena; Query_arena backup_arena; - Query_arena part_func_arena(&outparam->mem_root, Query_arena::INITIALIZED); + Query_arena part_func_arena(&outparam->mem_root, + Query_arena::STMT_INITIALIZED); thd->set_n_backup_active_arena(&part_func_arena, &backup_arena); thd->stmt_arena= &part_func_arena; bool tmp; @@ -2188,7 +2189,15 @@ void free_blobs(register TABLE *table) for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ; ptr != end ; ptr++) - ((Field_blob*) table->field[*ptr])->free(); + { + /* + Reduced TABLE objects which are used by row-based replication for + type conversion might have some fields missing. Skip freeing BLOB + buffers for such missing fields. + */ + if (table->field[*ptr]) + ((Field_blob*) table->field[*ptr])->free(); + } } @@ -2422,7 +2431,7 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) default: /* Better wrong error than none */ case 4: strxmov(buff, share->normalized_path.str, reg_ext, NullS); - my_error(ER_NOT_FORM_FILE, errortype, buff, 0); + my_error(ER_NOT_FORM_FILE, errortype, buff); break; } DBUG_VOID_RETURN; @@ -3009,7 +3018,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE), table->alias, table_def->count, table->s->fields, - table->s->mysql_version, MYSQL_VERSION_ID); + static_cast<int>(table->s->mysql_version), + MYSQL_VERSION_ID); DBUG_RETURN(TRUE); } else if (MYSQL_VERSION_ID == table->s->mysql_version) diff --git a/sql/unireg.cc b/sql/unireg.cc index 5a44c5e68f5..ae49a0da35c 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,8 +11,7 @@ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Functions to create a unireg form-file from a FIELD and a fieldname-fieldinfo @@ -230,13 +229,13 @@ bool mysql_create_frm(THD *thd, const char *file_name, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), - real_table_name, (uint) TABLE_COMMENT_MAXLEN); + real_table_name, static_cast<ulong>(TABLE_COMMENT_MAXLEN)); my_free(screen_buff); DBUG_RETURN(1); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT), - real_table_name, (uint) TABLE_COMMENT_MAXLEN); + real_table_name, static_cast<ulong>(TABLE_COMMENT_MAXLEN)); /* do not push duplicate warnings */ if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -737,13 +736,14 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, if ((current_thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), - field->field_name, (uint) COLUMN_COMMENT_MAXLEN); + my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, + static_cast<ulong>(COLUMN_COMMENT_MAXLEN)); DBUG_RETURN(1); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_FIELD_COMMENT), - field->field_name, (uint) COLUMN_COMMENT_MAXLEN); + field->field_name, + static_cast<ulong>(COLUMN_COMMENT_MAXLEN)); /* do not push duplicate warnings */ if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -831,7 +831,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, if (reclength > (ulong) file->max_record_length()) { - my_error(ER_TOO_BIG_ROWSIZE, MYF(0), (uint) file->max_record_length()); + my_error(ER_TOO_BIG_ROWSIZE, MYF(0), static_cast<long>(file->max_record_length())); DBUG_RETURN(1); } /* Hack to avoid bugs with small static rows in MySQL */ diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 1e2753027dc..5fc9bc875f8 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -114,6 +114,15 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) errno = 0; s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd; + DBUG_EXECUTE_IF("simulate_archive_open_failure", + { + if (s->file >= 0) + { + my_close(s->file, MYF(0)); + s->file= -1; + my_errno= EMFILE; + } + }); if (s->file < 0 ) { diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index df556a0721c..41c041a2c35 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1685,11 +1685,12 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) azflush(&(share->archive_write), Z_SYNC_FLUSH); mysql_mutex_unlock(&share->mutex); + if (init_archive_reader()) + DBUG_RETURN(HA_ADMIN_CORRUPT); /* Now we will rewind the archive file so that we are positioned at the start of the file. */ - init_archive_reader(); read_data_header(&archive); while (!(rc= get_row(&archive, table->record[0]))) count--; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 6af471494af..0a0db105c95 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -984,7 +984,7 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, var->type= SHOW_CHAR; var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE, - "enum_var is %u, ulong_var is %lu, %.6b", // %b is MySQL extension + "enum_var is %lu, ulong_var is %lu, %.6b", // %b is MySQL extension srv_enum_var, srv_ulong_var, "really"); return 0; } diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 9fa8fc663c9..2aff65e0bf6 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3264,9 +3264,14 @@ btr_estimate_n_rows_in_range_on_level( mtr_start(&mtr); - /* fetch the page */ - block = buf_page_get(space, zip_size, page_no, RW_S_LATCH, - &mtr); + /* Fetch the page. Because we are not holding the + index->lock, the tree may have changed and we may be + attempting to read a page that is no longer part of + the B-tree. We pass BUF_GET_POSSIBLY_FREED in order to + silence a debug assertion about this. */ + block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, + NULL, BUF_GET_POSSIBLY_FREED, + __FILE__, __LINE__, &mtr); page = buf_block_get_frame(block); @@ -3285,6 +3290,13 @@ btr_estimate_n_rows_in_range_on_level( goto inexact; } + /* It is possible but highly unlikely that the page was + originally written by an old version of InnoDB that did + not initialize FIL_PAGE_TYPE on other than B-tree pages. + For example, this could be an almost-empty BLOB page + that happens to contain the magic values in the fields + that we checked above. */ + n_pages_read++; if (page_no != slot1->page_no) { diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index cf5b90a2539..52358c52853 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -2747,6 +2747,7 @@ buf_page_get_gen( case BUF_GET_IF_IN_POOL: case BUF_PEEK_IF_IN_POOL: case BUF_GET_IF_IN_POOL_OR_WATCH: + case BUF_GET_POSSIBLY_FREED: break; default: ut_error; @@ -3062,7 +3063,10 @@ wait_until_unfixed: #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ buf_block_buf_fix_inc(block, file, line); - +#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG + ut_a(mode == BUF_GET_POSSIBLY_FREED + || !block->page.file_page_was_freed); +#endif mutex_exit(&block->mutex); /* Check if this is the first access to the page */ @@ -3075,10 +3079,6 @@ wait_until_unfixed: buf_page_set_accessed_make_young(&block->page, access_time); } -#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG - ut_a(!block->page.file_page_was_freed); -#endif - #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG ut_a(++buf_dbg_counter % 5771 || buf_validate()); ut_a(block->page.buf_fix_count > 0); diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c index 0ef0cfa554a..6d07fc249fa 100644 --- a/storage/innobase/data/data0data.c +++ b/storage/innobase/data/data0data.c @@ -585,7 +585,8 @@ dtuple_convert_big_rec( if (dict_table_get_format(index->table) < DICT_TF_FORMAT_ZIP) { /* up to MySQL 5.1: store a 768-byte prefix locally */ - local_len = BTR_EXTERN_FIELD_REF_SIZE + DICT_MAX_INDEX_COL_LEN; + local_len = BTR_EXTERN_FIELD_REF_SIZE + + DICT_ANTELOPE_MAX_INDEX_COL_LEN; } else { /* new-format table: do not store any BLOB prefix locally */ local_len = BTR_EXTERN_FIELD_REF_SIZE; @@ -757,7 +758,10 @@ dtuple_convert_back_big_rec( local_len -= BTR_EXTERN_FIELD_REF_SIZE; - ut_ad(local_len <= DICT_MAX_INDEX_COL_LEN); + /* Only in REDUNDANT and COMPACT format, we store + up to DICT_ANTELOPE_MAX_INDEX_COL_LEN (768) bytes + locally */ + ut_ad(local_len <= DICT_ANTELOPE_MAX_INDEX_COL_LEN); dfield_set_data(dfield, (char*) b->data - local_len, diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index d0344e72703..9a528d679a7 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -659,9 +659,9 @@ dict_create_index_tree_step( /* printf("Created a new index tree in space %lu root page %lu\n", index->space, index->page_no); */ - page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), - DICT_SYS_INDEXES_PAGE_NO_FIELD, - node->page_no, &mtr); + page_rec_write_field(btr_pcur_get_rec(&pcur), + DICT_SYS_INDEXES_PAGE_NO_FIELD, + node->page_no, &mtr); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -731,9 +731,8 @@ dict_drop_index_tree( root_page_no); */ btr_free_root(space, zip_size, root_page_no, mtr); - page_rec_write_index_page_no(rec, - DICT_SYS_INDEXES_PAGE_NO_FIELD, - FIL_NULL, mtr); + page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, + FIL_NULL, mtr); } /*******************************************************************//** @@ -836,8 +835,8 @@ create: in SYS_INDEXES, so that the database will not get into an inconsistent state in case it crashes between the mtr_commit() below and the following mtr_commit() call. */ - page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, - FIL_NULL, mtr); + page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, + FIL_NULL, mtr); /* We will need to commit the mini-transaction in order to avoid deadlocks in the btr_create() call, because otherwise we would diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index df9db4d7428..1e3aed92cf7 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -1352,36 +1352,63 @@ dict_index_too_big_for_undo( ulint fixed_size = dict_col_get_fixed_size(col, dict_table_is_comp(table)); + ulint max_prefix + = col->max_prefix; if (fixed_size) { /* Fixed-size columns are stored locally. */ max_size = fixed_size; } else if (max_size <= BTR_EXTERN_FIELD_REF_SIZE * 2) { /* Short columns are stored locally. */ - } else if (!col->ord_part) { + } else if (!col->ord_part + || (col->max_prefix + < (ulint) DICT_MAX_FIELD_LEN_BY_FORMAT(table))) { /* See if col->ord_part would be set - because of new_index. */ + because of new_index. Also check if the new + index could have longer prefix on columns + that already had ord_part set */ ulint j; for (j = 0; j < new_index->n_uniq; j++) { if (dict_index_get_nth_col( new_index, j) == col) { + const dict_field_t* field + = dict_index_get_nth_field( + new_index, j); + + if (field->prefix_len + > col->max_prefix) { + max_prefix = + field->prefix_len; + } goto is_ord_part; } } + if (col->ord_part) { + goto is_ord_part; + } + /* This is not an ordering column in any index. Thus, it can be stored completely externally. */ max_size = BTR_EXTERN_FIELD_REF_SIZE; } else { + ulint max_field_len; is_ord_part: + max_field_len = DICT_MAX_FIELD_LEN_BY_FORMAT(table); + /* This is an ordering column in some index. A long enough prefix must be written to the undo log. See trx_undo_page_fetch_ext(). */ + max_size = ut_min(max_size, max_field_len); + + /* We only store the needed prefix length in undo log */ + if (max_prefix) { + ut_ad(dict_table_get_format(table) + >= DICT_TF_FORMAT_ZIP); - if (max_size > REC_MAX_INDEX_COL_LEN) { - max_size = REC_MAX_INDEX_COL_LEN; + max_size = ut_min(max_prefix, max_size); } max_size += BTR_EXTERN_FIELD_REF_SIZE; @@ -1635,15 +1662,16 @@ too_big: /* In dtuple_convert_big_rec(), variable-length columns that are longer than BTR_EXTERN_FIELD_REF_SIZE * 2 may be chosen for external storage. If the column appears - in an ordering column of an index, a longer prefix of - REC_MAX_INDEX_COL_LEN will be copied to the undo log - by trx_undo_page_report_modify() and + in an ordering column of an index, a longer prefix determined + by dict_max_field_len_store_undo() will be copied to the undo + log by trx_undo_page_report_modify() and trx_undo_page_fetch_ext(). It suffices to check the capacity of the undo log whenever new_index includes a column prefix on a column that may be stored externally. */ if (field->prefix_len /* prefix index */ - && !col->ord_part /* not yet ordering column */ + && (!col->ord_part /* not yet ordering column */ + || field->prefix_len > col->max_prefix) && !dict_col_get_fixed_size(col, TRUE) /* variable-length */ && dict_col_get_max_size(col) > BTR_EXTERN_FIELD_REF_SIZE * 2 /* long enough */) { @@ -1660,11 +1688,17 @@ too_big: } undo_size_ok: - /* Flag the ordering columns */ + /* Flag the ordering columns and also set column max_prefix */ for (i = 0; i < n_ord; i++) { + const dict_field_t* field + = dict_index_get_nth_field(new_index, i); - dict_index_get_nth_field(new_index, i)->col->ord_part = 1; + field->col->ord_part = 1; + + if (field->prefix_len > field->col->max_prefix) { + field->col->max_prefix = field->prefix_len; + } } /* Add the new index as the last index for the table */ @@ -1867,14 +1901,14 @@ dict_index_add_col( variable-length fields, so that the extern flag can be embedded in the length word. */ - if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) { + if (field->fixed_len > DICT_MAX_FIXED_COL_LEN) { field->fixed_len = 0; } -#if DICT_MAX_INDEX_COL_LEN != 768 +#if DICT_MAX_FIXED_COL_LEN != 768 /* The comparison limit above must be constant. If it were changed, the disk format of some fixed-length columns would change, which would be a disaster. */ -# error "DICT_MAX_INDEX_COL_LEN != 768" +# error "DICT_MAX_FIXED_COL_LEN != 768" #endif if (!(col->prtype & DATA_NOT_NULL)) { diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index aad3145f7a4..ab1fb16361e 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -429,7 +429,7 @@ dict_process_sys_fields_rec( mach_write_to_8(last_index_id, last_id); err_msg = dict_load_field_low(buf, NULL, sys_field, - pos, last_index_id, heap, rec); + pos, last_index_id, heap, rec, NULL, 0); *index_id = mach_read_from_8(buf); @@ -994,6 +994,9 @@ dict_load_columns( /** Error message for a delete-marked record in dict_load_field_low() */ static const char* dict_load_field_del = "delete-marked record in SYS_FIELDS"; +static const char* dict_load_field_too_big = "column prefix exceeds maximum" + " limit"; + /********************************************************************//** Loads an index field definition from a SYS_FIELDS record to dict_index_t. @@ -1015,7 +1018,12 @@ dict_load_field_low( byte* last_index_id, /*!< in: last index id */ mem_heap_t* heap, /*!< in/out: memory heap for temporary storage */ - const rec_t* rec) /*!< in: SYS_FIELDS record */ + const rec_t* rec, /*!< in: SYS_FIELDS record */ + char* addition_err_str,/*!< out: additional error message + that requires information to be + filled, or NULL */ + ulint err_str_len) /*!< in: length of addition_err_str + in bytes */ { const byte* field; ulint len; @@ -1095,6 +1103,19 @@ err_len: goto err_len; } + if (prefix_len > REC_VERSION_56_MAX_INDEX_COL_LEN) { + if (addition_err_str) { + ut_snprintf(addition_err_str, err_str_len, + "index field '%s' has a prefix length" + " of %lu bytes", + mem_heap_strdupl( + heap, (const char*) field, len), + (ulong) prefix_len); + } + + return(dict_load_field_too_big); + } + if (index) { dict_mem_index_add_field( index, mem_heap_strdupl(heap, (const char*) field, len), @@ -1154,14 +1175,16 @@ dict_load_fields( btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); for (i = 0; i < index->n_fields; i++) { - const char* err_msg; + const char* err_msg; + char addition_err_str[1024]; rec = btr_pcur_get_rec(&pcur); ut_a(btr_pcur_is_on_user_rec(&pcur)); err_msg = dict_load_field_low(buf, index, NULL, NULL, NULL, - heap, rec); + heap, rec, addition_err_str, + sizeof(addition_err_str)); if (err_msg == dict_load_field_del) { /* There could be delete marked records in @@ -1170,7 +1193,24 @@ dict_load_fields( goto next_rec; } else if (err_msg) { - fprintf(stderr, "InnoDB: %s\n", err_msg); + if (err_msg == dict_load_field_too_big) { + fprintf(stderr, "InnoDB: Error: load index" + " '%s' failed.\n" + "InnoDB: %s,\n" + "InnoDB: which exceeds the" + " maximum limit of %lu bytes.\n" + "InnoDB: Please use server that" + " supports long index prefix\n" + "InnoDB: or turn on" + " innodb_force_recovery to load" + " the table\n", + index->name, addition_err_str, + (ulong) (REC_VERSION_56_MAX_INDEX_COL_LEN)); + + } else { + fprintf(stderr, "InnoDB: %s\n", err_msg); + } + error = DB_CORRUPTION; goto func_exit; } @@ -1446,7 +1486,26 @@ corrupted: of the database server */ dict_mem_index_free(index); } else { - dict_load_fields(index, heap); + error = dict_load_fields(index, heap); + + if (error != DB_SUCCESS) { + + fprintf(stderr, "InnoDB: Error: load index '%s'" + " for table '%s' failed\n", + index->name, table->name); + + /* If the force recovery flag is set, and + if the failed index is not the primary index, we + will continue and open other indexes */ + if (srv_force_recovery + && !dict_index_is_clust(index)) { + error = DB_SUCCESS; + goto next_rec; + } else { + goto func_exit; + } + } + error = dict_index_add_to_cache(table, index, index->page, FALSE); /* The data dictionary tables should never contain @@ -1771,9 +1830,18 @@ err_exit: } else { table->fk_max_recusive_level = 0; } - } else if (!srv_force_recovery) { - dict_table_remove_from_cache(table); - table = NULL; + } else { + dict_index_t* index; + + /* Make sure that at least the clustered index was loaded. + Otherwise refuse to load the table */ + index = dict_table_get_first_index(table); + + if (!srv_force_recovery || !index + || !dict_index_is_clust(index)) { + dict_table_remove_from_cache(table); + table = NULL; + } } #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index 8785dfb57ed..982cca5a796 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -232,6 +232,7 @@ dict_mem_fill_column_struct( column->ind = (unsigned int) col_pos; column->ord_part = 0; + column->max_prefix = 0; column->mtype = (unsigned int) mtype; column->prtype = (unsigned int) prtype; column->len = (unsigned int) col_len; diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 0d9846fdbf8..196f4bd3f42 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -856,7 +856,8 @@ fil_node_close_file( ut_a(node->open); ut_a(node->n_pending == 0); ut_a(node->n_pending_flushes == 0); - ut_a(node->modification_counter == node->flush_counter); + ut_a(node->modification_counter == node->flush_counter + || srv_fast_shutdown == 2); ret = os_file_close(node->handle); ut_a(ret); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8efa0523927..11640acbce4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -166,6 +166,7 @@ static my_bool innobase_locks_unsafe_for_binlog = FALSE; 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_large_prefix = FALSE; static char* internal_innobase_data_file_path = NULL; @@ -904,7 +905,7 @@ int convert_error_code_to_mysql( /*========================*/ int error, /*!< in: InnoDB error code */ - ulint flags, /*!< in: InnoDB table flags, or 0 */ + ulint flags, /*!< in: InnoDB table flags, or 0 */ THD* thd) /*!< in: user thread handle or NULL */ { switch (error) { @@ -1008,6 +1009,11 @@ convert_error_code_to_mysql( & DICT_TF_COMPACT) / 2); return(HA_ERR_TO_BIG_ROW); + case DB_TOO_BIG_INDEX_COL: + my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0), + DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)); + return(HA_ERR_INDEX_COL_TOO_LONG); + case DB_NO_SAVEPOINT: return(HA_ERR_NO_SAVEPOINT); @@ -2621,8 +2627,10 @@ innobase_alter_table_flags( uint flags) { return(HA_INPLACE_ADD_INDEX_NO_READ_WRITE + | HA_INPLACE_ADD_INDEX_NO_WRITE | HA_INPLACE_DROP_INDEX_NO_READ_WRITE | HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE + | HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE | HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE | HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE); } @@ -3946,7 +3954,11 @@ UNIV_INTERN uint ha_innobase::max_supported_key_part_length() const { - return(DICT_MAX_INDEX_COL_LEN - 1); + /* A table format specific index column length check will be performed + at ha_innobase::add_index() and row_create_index_for_mysql() */ + return(innobase_large_prefix + ? REC_VERSION_56_MAX_INDEX_COL_LEN + : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1); } /******************************************************************//** @@ -7010,8 +7022,8 @@ ha_innobase::create( if (i != (uint) primary_key_no) { - if ((error = create_index(trx, form, flags, norm_name, - i))) { + if ((error = create_index(trx, form, flags, + norm_name, i))) { goto cleanup; } } @@ -11076,6 +11088,11 @@ static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "With which method to flush data.", NULL, NULL, NULL); +static MYSQL_SYSVAR_BOOL(large_prefix, innobase_large_prefix, + PLUGIN_VAR_NOCMDARG, + "Support large index prefix length of REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "Force InnoDB to not use next-key locking, to use only row-level locking.", @@ -11329,6 +11346,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(flush_log_at_trx_commit), MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), + MYSQL_SYSVAR(large_prefix), MYSQL_SYSVAR(locks_unsafe_for_binlog), MYSQL_SYSVAR(lock_wait_timeout), #ifdef UNIV_LOG_ARCHIVE diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 0c0af8dd887..7ab91a12e81 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -215,7 +215,9 @@ class ha_innobase: public handler bool primary_key_is_clustered(); int cmp_ref(const uchar *ref1, const uchar *ref2); /** Fast index creation (smart ALTER TABLE) @see handler0alter.cc @{ */ - int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys); + int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, + handler_add_index **add); + int final_add_index(handler_add_index *add, bool commit); int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys); int final_drop_index(TABLE *table_arg); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cc7e48ebd44..6d5b7b4668f 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -539,7 +539,7 @@ innobase_create_key_def( if (!new_primary && (key_info->flags & HA_NOSAME) && (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG)) && row_table_got_default_clust_index(table)) { - uint key_part = key_info->key_parts; + uint key_part = key_info->key_parts; new_primary = TRUE; @@ -595,6 +595,27 @@ innobase_create_key_def( } /*******************************************************************//** +Check each index column size, make sure they do not exceed the max limit +@return HA_ERR_INDEX_COL_TOO_LONG if index column size exceeds limit */ +static +int +innobase_check_column_length( +/*=========================*/ + const dict_table_t*table, /*!< in: table definition */ + const KEY* key_info) /*!< in: Indexes to be created */ +{ + ulint max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT(table); + + for (ulint key_part = 0; key_part < key_info->key_parts; key_part++) { + if (key_info->key_part[key_part].length > max_col_len) { + my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0), max_col_len); + return(HA_ERR_INDEX_COL_TOO_LONG); + } + } + return(0); +} + +/*******************************************************************//** Create a temporary tablename using query id, thread id, and id @return temporary tablename */ static @@ -619,6 +640,18 @@ innobase_create_temporary_tablename( return(name); } +class ha_innobase_add_index : public handler_add_index +{ +public: + /** table where the indexes are being created */ + dict_table_t* indexed_table; + ha_innobase_add_index(TABLE* table, KEY* key_info, uint num_of_keys, + dict_table_t* indexed_table_arg) : + handler_add_index(table, key_info, num_of_keys), + indexed_table (indexed_table_arg) {} + ~ha_innobase_add_index() {} +}; + /*******************************************************************//** Create indexes. @return 0 or error number */ @@ -626,12 +659,15 @@ UNIV_INTERN int ha_innobase::add_index( /*===================*/ - TABLE* table, /*!< in: Table where indexes are created */ - KEY* key_info, /*!< in: Indexes to be created */ - uint num_of_keys) /*!< in: Number of indexes to be created */ + TABLE* table, /*!< in: Table where indexes + are created */ + KEY* key_info, /*!< in: Indexes + to be created */ + uint num_of_keys, /*!< in: Number of indexes + to be created */ + handler_add_index** add) /*!< out: context */ { dict_index_t** index; /*!< Index to be created */ - dict_table_t* innodb_table; /*!< InnoDB table in dictionary */ dict_table_t* indexed_table; /*!< Table where indexes are created */ merge_index_def_t* index_defs; /*!< Index definitions */ mem_heap_t* heap; /*!< Heap for index definitions */ @@ -647,6 +683,8 @@ ha_innobase::add_index( ut_a(key_info); ut_a(num_of_keys); + *add = NULL; + if (srv_created_new_raw || srv_force_recovery) { DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -662,20 +700,32 @@ ha_innobase::add_index( DBUG_RETURN(-1); } - innodb_table = indexed_table - = dict_table_get(prebuilt->table->name, FALSE); + indexed_table = dict_table_get(prebuilt->table->name, FALSE); - if (UNIV_UNLIKELY(!innodb_table)) { + if (UNIV_UNLIKELY(!indexed_table)) { DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } + ut_a(indexed_table == prebuilt->table); + /* Check that index keys are sensible */ - error = innobase_check_index_keys(key_info, num_of_keys, innodb_table); + error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table); if (UNIV_UNLIKELY(error)) { DBUG_RETURN(error); } + /* Check each index's column length to make sure they do not + exceed limit */ + for (ulint i = 0; i < num_of_keys; i++) { + error = innobase_check_column_length(prebuilt->table, + &key_info[i]); + + if (error) { + DBUG_RETURN(error); + } + } + heap = mem_heap_create(1024); trx_start_if_not_started(prebuilt->trx); @@ -691,7 +741,7 @@ ha_innobase::add_index( num_of_idx = num_of_keys; index_defs = innobase_create_key_def( - trx, innodb_table, heap, key_info, num_of_idx); + trx, prebuilt->table, heap, key_info, num_of_idx); new_primary = DICT_CLUSTERED & index_defs[0].ind_type; @@ -705,7 +755,7 @@ ha_innobase::add_index( trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); /* Acquire a lock on the table before creating any indexes. */ - error = row_merge_lock_table(prebuilt->trx, innodb_table, + error = row_merge_lock_table(prebuilt->trx, prebuilt->table, new_primary ? LOCK_X : LOCK_S); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { @@ -719,7 +769,7 @@ ha_innobase::add_index( row_mysql_lock_data_dictionary(trx); dict_locked = TRUE; - ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); /* If a new primary key is defined for the table we need to drop the original table and rebuild all indexes. */ @@ -727,15 +777,15 @@ ha_innobase::add_index( if (UNIV_UNLIKELY(new_primary)) { /* This transaction should be the only one operating on the table. */ - ut_a(innodb_table->n_mysql_handles_opened == 1); + ut_a(prebuilt->table->n_mysql_handles_opened == 1); char* new_table_name = innobase_create_temporary_tablename( - heap, '1', innodb_table->name); + heap, '1', prebuilt->table->name); /* Clone the table. */ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); indexed_table = row_merge_create_temporary_table( - new_table_name, index_defs, innodb_table, trx); + new_table_name, index_defs, prebuilt->table, trx); if (!indexed_table) { @@ -749,11 +799,12 @@ ha_innobase::add_index( break; default: error = convert_error_code_to_mysql( - trx->error_state, innodb_table->flags, + trx->error_state, + prebuilt->table->flags, user_thd); } - ut_d(dict_table_check_for_dup_indexes(innodb_table, + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); mem_heap_free(heap); trx_general_rollback_for_mysql(trx, NULL); @@ -768,17 +819,15 @@ ha_innobase::add_index( /* Create the indexes in SYS_INDEXES and load into dictionary. */ - for (ulint i = 0; i < num_of_idx; i++) { + for (num_created = 0; num_created < num_of_idx; num_created++) { - index[i] = row_merge_create_index(trx, indexed_table, - &index_defs[i]); + index[num_created] = row_merge_create_index( + trx, indexed_table, &index_defs[num_created]); - if (!index[i]) { + if (!index[num_created]) { error = trx->error_state; goto error_handling; } - - num_created++; } ut_ad(error == DB_SUCCESS); @@ -800,7 +849,7 @@ ha_innobase::add_index( if (UNIV_UNLIKELY(new_primary)) { /* A primary key is to be built. Acquire an exclusive table lock also on the table that is being created. */ - ut_ad(indexed_table != innodb_table); + ut_ad(indexed_table != prebuilt->table); error = row_merge_lock_table(prebuilt->trx, indexed_table, LOCK_X); @@ -814,7 +863,7 @@ ha_innobase::add_index( /* Read the clustered index of the table and build indexes based on this information using temporary files and merge sort. */ error = row_merge_build_indexes(prebuilt->trx, - innodb_table, indexed_table, + prebuilt->table, indexed_table, index, num_of_idx, table); error_handling: @@ -822,63 +871,15 @@ error_handling: dictionary which were defined. */ switch (error) { - const char* old_name; - char* tmp_name; case DB_SUCCESS: ut_a(!dict_locked); - row_mysql_lock_data_dictionary(trx); - dict_locked = TRUE; + ut_d(mutex_enter(&dict_sys->mutex)); ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); - - if (!new_primary) { - error = row_merge_rename_indexes(trx, indexed_table); - - if (error != DB_SUCCESS) { - row_merge_drop_indexes(trx, indexed_table, - index, num_created); - } - - goto convert_error; - } - - /* If a new primary key was defined for the table and - there was no error at this point, we can now rename - the old table as a temporary table, rename the new - temporary table as the old table and drop the old table. */ - old_name = innodb_table->name; - tmp_name = innobase_create_temporary_tablename(heap, '2', - old_name); - - error = row_merge_rename_tables(innodb_table, indexed_table, - tmp_name, trx); - - if (error != DB_SUCCESS) { - - row_merge_drop_table(trx, indexed_table); - - switch (error) { - case DB_TABLESPACE_ALREADY_EXISTS: - case DB_DUPLICATE_KEY: - innobase_convert_tablename(tmp_name); - my_error(HA_ERR_TABLE_EXIST, MYF(0), tmp_name); - error = HA_ERR_TABLE_EXIST; - break; - default: - goto convert_error; - } - break; - } - - trx_commit_for_mysql(prebuilt->trx); - row_prebuilt_free(prebuilt, TRUE); - prebuilt = row_create_prebuilt(indexed_table); - - indexed_table->n_mysql_handles_opened++; - - error = row_merge_drop_table(trx, innodb_table); - innodb_table = indexed_table; - goto convert_error; + ut_d(mutex_exit(&dict_sys->mutex)); + *add = new ha_innobase_add_index(table, key_info, num_of_keys, + indexed_table); + break; case DB_TOO_BIG_RECORD: my_error(HA_ERR_TO_BIG_ROW, MYF(0)); @@ -894,7 +895,7 @@ error: trx->error_state = DB_SUCCESS; if (new_primary) { - if (indexed_table != innodb_table) { + if (indexed_table != prebuilt->table) { row_merge_drop_table(trx, indexed_table); } } else { @@ -906,38 +907,161 @@ error: row_merge_drop_indexes(trx, indexed_table, index, num_created); } - -convert_error: - if (error == DB_SUCCESS) { - /* Build index is successful. We will need to - rebuild index translation table. Reset the - index entry count in the translation table - to zero, so that translation table will be rebuilt */ - share->idx_trans_tbl.index_count = 0; - } - - error = convert_error_code_to_mysql(error, - innodb_table->flags, - user_thd); } - mem_heap_free(heap); trx_commit_for_mysql(trx); if (prebuilt->trx) { trx_commit_for_mysql(prebuilt->trx); } if (dict_locked) { - ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE)); row_mysql_unlock_data_dictionary(trx); } trx_free_for_mysql(trx); + mem_heap_free(heap); /* There might be work for utility threads.*/ srv_active_wake_master_thread(); - DBUG_RETURN(error); + DBUG_RETURN(convert_error_code_to_mysql(error, prebuilt->table->flags, + user_thd)); +} + +/*******************************************************************//** +Finalize or undo add_index(). +@return 0 or error number */ +UNIV_INTERN +int +ha_innobase::final_add_index( +/*=========================*/ + handler_add_index* add_arg,/*!< in: context from add_index() */ + bool commit) /*!< in: true=commit, false=rollback */ +{ + ha_innobase_add_index* add; + trx_t* trx; + int err = 0; + + DBUG_ENTER("ha_innobase::final_add_index"); + + ut_ad(add_arg); + add = static_cast<class ha_innobase_add_index*>(add_arg); + + /* Create a background transaction for the operations on + the data dictionary tables. */ + trx = innobase_trx_allocate(user_thd); + trx_start_if_not_started(trx); + + /* Flag this transaction as a dictionary operation, so that + the data dictionary will be locked in crash recovery. */ + trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); + + /* Latch the InnoDB data dictionary exclusively so that no deadlocks + or lock waits can happen in it during an index create operation. */ + row_mysql_lock_data_dictionary(trx); + + if (add->indexed_table != prebuilt->table) { + ulint error; + + /* We copied the table (new_primary). */ + if (commit) { + mem_heap_t* heap; + char* tmp_name; + + heap = mem_heap_create(1024); + + /* A new primary key was defined for the table + and there was no error at this point. We can + now rename the old table as a temporary table, + rename the new temporary table as the old + table and drop the old table. */ + tmp_name = innobase_create_temporary_tablename( + heap, '2', prebuilt->table->name); + + error = row_merge_rename_tables( + prebuilt->table, add->indexed_table, + tmp_name, trx); + + switch (error) { + case DB_TABLESPACE_ALREADY_EXISTS: + case DB_DUPLICATE_KEY: + innobase_convert_tablename(tmp_name); + my_error(HA_ERR_TABLE_EXIST, MYF(0), tmp_name); + err = HA_ERR_TABLE_EXIST; + break; + default: + err = convert_error_code_to_mysql( + error, prebuilt->table->flags, + user_thd); + break; + } + + mem_heap_free(heap); + } + + if (!commit || err) { + error = row_merge_drop_table(trx, add->indexed_table); + trx_commit_for_mysql(prebuilt->trx); + } else { + dict_table_t* old_table = prebuilt->table; + trx_commit_for_mysql(prebuilt->trx); + row_prebuilt_free(prebuilt, TRUE); + error = row_merge_drop_table(trx, old_table); + add->indexed_table->n_mysql_handles_opened++; + prebuilt = row_create_prebuilt(add->indexed_table); + } + + err = convert_error_code_to_mysql( + error, prebuilt->table->flags, user_thd); + } else { + /* We created secondary indexes (!new_primary). */ + + if (commit) { + err = convert_error_code_to_mysql( + row_merge_rename_indexes(trx, prebuilt->table), + prebuilt->table->flags, user_thd); + } + + if (!commit || err) { + dict_index_t* index; + dict_index_t* next_index; + + for (index = dict_table_get_first_index( + prebuilt->table); + index; index = next_index) { + + next_index = dict_table_get_next_index(index); + + if (*index->name == TEMP_INDEX_PREFIX) { + row_merge_drop_index( + index, prebuilt->table, trx); + } + } + } + } + + /* If index is successfully built, we will need to rebuild index + translation table. Set valid index entry count in the translation + table to zero. */ + if (err == 0 && commit) { + share->idx_trans_tbl.index_count = 0; + } + + trx_commit_for_mysql(trx); + if (prebuilt->trx) { + trx_commit_for_mysql(prebuilt->trx); + } + + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + row_mysql_unlock_data_dictionary(trx); + + trx_free_for_mysql(trx); + + /* There might be work for utility threads.*/ + srv_active_wake_master_thread(); + + delete add; + DBUG_RETURN(err); } /*******************************************************************//** diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 8fb008997ab..d83d484bace 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -53,6 +53,9 @@ Created 11/5/1995 Heikki Tuuri /*!< Get the page only if it's in the buffer pool, if not then set a watch on the page. */ +#define BUF_GET_POSSIBLY_FREED 16 + /*!< Like BUF_GET, but do not mind + if the file page has been freed. */ /* @} */ /** @name Modes for buf_page_get_known_nowait */ /* @{ */ diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 8a71fa6511a..74a2354bce3 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -110,6 +110,8 @@ enum db_err { DB_PARENT_NO_INDEX, /* the parent table does not have an index that contains the foreign keys as its prefix columns */ + DB_TOO_BIG_INDEX_COL, /* index column size exceeds maximum + limit */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index d6f2bebae3a..f979d0fcc96 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -136,6 +136,19 @@ dict_col_copy_type( /*===============*/ const dict_col_t* col, /*!< in: column */ dtype_t* type); /*!< out: data type */ +/**********************************************************************//** +Determine bytes of column prefix to be stored in the undo log. Please +note if the table format is UNIV_FORMAT_A (< DICT_TF_FORMAT_ZIP), no prefix +needs to be stored in the undo log. +@return bytes of column prefix to be stored in the undo log */ +UNIV_INLINE +ulint +dict_max_field_len_store_undo( +/*==========================*/ + dict_table_t* table, /*!< in: table */ + const dict_col_t* col); /*!< in: column which index prefix + is based on */ + #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG /*********************************************************************//** diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 59606af7056..59811568556 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -911,4 +911,30 @@ dict_table_get_on_id_low( return(table); } + +/**********************************************************************//** +Determine bytes of column prefix to be stored in the undo log. Please +note if the table format is UNIV_FORMAT_A (< DICT_TF_FORMAT_ZIP), no prefix +needs to be stored in the undo log. +@return bytes of column prefix to be stored in the undo log */ +UNIV_INLINE +ulint +dict_max_field_len_store_undo( +/*==========================*/ + dict_table_t* table, /*!< in: table */ + const dict_col_t* col) /*!< in: column which index prefix + is based on */ +{ + ulint prefix_len = 0; + + if (dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP) + { + prefix_len = col->max_prefix + ? col->max_prefix + : DICT_MAX_FIELD_LEN_BY_FORMAT(table); + } + + return(prefix_len); +} + #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 51d07f43446..16177ade713 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -155,7 +155,12 @@ dict_load_field_low( byte* last_index_id, /*!< in: last index id */ mem_heap_t* heap, /*!< in/out: memory heap for temporary storage */ - const rec_t* rec); /*!< in: SYS_FIELDS record */ + const rec_t* rec, /*!< in: SYS_FIELDS record */ + char* addition_err_str,/*!< out: additional error message + that requires information to be + filled, or NULL */ + ulint err_str_len); /*!< in: length of addition_err_str + in bytes */ /********************************************************************//** Loads a table definition and also all its index definitions, and also the cluster definition if the table is a member in a cluster. Also loads diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 51c9c2d1797..3a475fa85fc 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -302,32 +302,58 @@ struct dict_col_struct{ unsigned ord_part:1; /*!< nonzero if this column appears in the ordering fields of an index */ + unsigned max_prefix:12; /*!< maximum index prefix length on + this column. Our current max limit is + 3072 for Barracuda table */ }; -/** @brief DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum -indexed column length (or indexed prefix length). +/** @brief DICT_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and +is the maximum indexed column length (or indexed prefix length) in +ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. Also, in any format, +any fixed-length field that is longer than this will be encoded as +a variable-length field. It is set to 3*256, so that one can create a column prefix index on 256 characters of a TEXT or VARCHAR column also in the UTF-8 charset. In that charset, a character may take at most 3 bytes. This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data files would be at risk! */ -#define DICT_MAX_INDEX_COL_LEN REC_MAX_INDEX_COL_LEN +#define DICT_ANTELOPE_MAX_INDEX_COL_LEN REC_ANTELOPE_MAX_INDEX_COL_LEN + +/** Find out maximum indexed column length by its table format. +For ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT, the maximum +field length is REC_ANTELOPE_MAX_INDEX_COL_LEN - 1 (767). For new +barracuda format, the length could be REC_VERSION_56_MAX_INDEX_COL_LEN +(3072) bytes */ +#define DICT_MAX_FIELD_LEN_BY_FORMAT(table) \ + ((dict_table_get_format(table) < DICT_TF_FORMAT_ZIP) \ + ? (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1) \ + : REC_VERSION_56_MAX_INDEX_COL_LEN) + +#define DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags) \ + ((((flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT)\ + < DICT_TF_FORMAT_ZIP) \ + ? (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1) \ + : REC_VERSION_56_MAX_INDEX_COL_LEN) + +/** Defines the maximum fixed length column size */ +#define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN /** Data structure for a field in an index */ struct dict_field_struct{ dict_col_t* col; /*!< pointer to the table column */ const char* name; /*!< name of the column */ - unsigned prefix_len:10; /*!< 0 or the length of the column + unsigned prefix_len:12; /*!< 0 or the length of the column prefix in bytes in a MySQL index of type, e.g., INDEX (textcol(25)); must be smaller than - DICT_MAX_INDEX_COL_LEN; NOTE that - in the UTF-8 charset, MySQL sets this - to 3 * the prefix len in UTF-8 chars */ + DICT_MAX_FIELD_LEN_BY_FORMAT; + NOTE that in the UTF-8 charset, MySQL + sets this to (mbmaxlen * the prefix len) + in UTF-8 chars */ unsigned fixed_len:10; /*!< 0 or the fixed length of the column if smaller than - DICT_MAX_INDEX_COL_LEN */ + DICT_ANTELOPE_MAX_INDEX_COL_LEN */ }; /** Data structure for an index. Most fields will be diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 3eca80beda4..29fdc3bbe97 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -72,9 +72,10 @@ UNIV_INLINE trx_t* lock_clust_rec_some_has_impl( /*=========================*/ - const rec_t* rec, /*!< in: user record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: user record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the heap_no of the smallest user record on a page. @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */ diff --git a/storage/innobase/include/lock0lock.ic b/storage/innobase/include/lock0lock.ic index 014722f51c4..1d740a5fa43 100644 --- a/storage/innobase/include/lock0lock.ic +++ b/storage/innobase/include/lock0lock.ic @@ -75,9 +75,9 @@ UNIV_INLINE trx_t* lock_clust_rec_some_has_impl( /*=========================*/ - const rec_t* rec, /*!< in: user record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: user record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { trx_id_t trx_id; diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index 3d87eea2710..1db4a4bd735 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -37,6 +37,8 @@ mtr_start( /*======*/ mtr_t* mtr) /*!< out: mini-transaction */ { + UNIV_MEM_INVALID(mtr, sizeof *mtr); + dyn_array_create(&(mtr->memo)); dyn_array_create(&(mtr->log)); diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 0a15dfbf2a1..fc082e9b189 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -619,17 +619,16 @@ page_rec_find_owner_rec( /*====================*/ rec_t* rec); /*!< in: the physical record */ /***********************************************************************//** -This is a low-level operation which is used in a database index creation -to update the page number of a created B-tree to a data dictionary -record. */ -UNIV_INTERN +Write a 32-bit field in a data dictionary record. */ +UNIV_INLINE void -page_rec_write_index_page_no( -/*=========================*/ - rec_t* rec, /*!< in: record to update */ +page_rec_write_field( +/*=================*/ + rec_t* rec, /*!< in/out: record to update */ ulint i, /*!< in: index of the field to update */ ulint page_no,/*!< in: value to write */ - mtr_t* mtr); /*!< in: mtr */ + mtr_t* mtr) /*!< in/out: mini-transaction */ + __attribute__((nonnull)); /************************************************************//** Returns the maximum combined size of records which can be inserted on top of record heap. diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index e9624c2360f..75e562a158d 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -959,6 +959,27 @@ page_get_free_space_of_empty( - 2 * PAGE_DIR_SLOT_SIZE)); } +/***********************************************************************//** +Write a 32-bit field in a data dictionary record. */ +UNIV_INLINE +void +page_rec_write_field( +/*=================*/ + rec_t* rec, /*!< in/out: record to update */ + ulint i, /*!< in: index of the field to update */ + ulint val, /*!< in: value to write */ + mtr_t* mtr) /*!< in/out: mini-transaction */ +{ + byte* data; + ulint len; + + data = rec_get_nth_field_old(rec, i, &len); + + ut_ad(len == 4); + + mlog_write_ulint(data, val, MLOG_4BYTES, mtr); +} + /************************************************************//** Each user record on a page, and also the deleted user records in the heap takes its size plus the fraction of the dir cell size / diff --git a/storage/innobase/include/rem0types.h b/storage/innobase/include/rem0types.h index 8b84d4af233..7afd595be90 100644 --- a/storage/innobase/include/rem0types.h +++ b/storage/innobase/include/rem0types.h @@ -34,13 +34,21 @@ typedef byte rec_t; #define REC_MAX_HEAP_NO (2 * 8192 - 1) #define REC_MAX_N_OWNED (16 - 1) -/* REC_MAX_INDEX_COL_LEN is measured in bytes and is the maximum -indexed column length (or indexed prefix length). It is set to 3*256, -so that one can create a column prefix index on 256 characters of a -TEXT or VARCHAR column also in the UTF-8 charset. In that charset, -a character may take at most 3 bytes. +/* REC_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and is the maximum +indexed field length (or indexed prefix length) for indexes on tables of +ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT format. +Before we support UTF-8 encodings with mbmaxlen = 4, a UTF-8 character +may take at most 3 bytes. So the limit was set to 3*256, so that one +can create a column prefix index on 256 characters of a TEXT or VARCHAR +column also in the UTF-8 charset. This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data files would be at risk! */ -#define REC_MAX_INDEX_COL_LEN 768 +#define REC_ANTELOPE_MAX_INDEX_COL_LEN 768 + +/** Maximum indexed field length for table format DICT_TF_FORMAT_ZIP and +beyond. +This (3072) is the maximum index row length allowed, so we cannot create index +prefix column longer than that. */ +#define REC_VERSION_56_MAX_INDEX_COL_LEN 3072 #endif diff --git a/storage/innobase/include/row0ext.h b/storage/innobase/include/row0ext.h index 43d82d644e6..557da2c4a82 100644 --- a/storage/innobase/include/row0ext.h +++ b/storage/innobase/include/row0ext.h @@ -30,6 +30,7 @@ Created September 2006 Marko Makela #include "row0types.h" #include "data0types.h" #include "mem0mem.h" +#include "dict0types.h" /********************************************************************//** Creates a cache of column prefixes of externally stored columns. @@ -43,13 +44,13 @@ row_ext_create( in the InnoDB table object, as reported by dict_col_get_no(); NOT relative to the records in the clustered index */ + ulint flags, /*!< in: table->flags */ const dtuple_t* tuple, /*!< in: data tuple containing the field references of the externally stored columns; must be indexed by col_no; the clustered index record must be covered by a lock or a page latch to prevent deletion (rollback or purge). */ - ulint zip_size,/*!< compressed page size in bytes, or 0 */ mem_heap_t* heap); /*!< in: heap where created */ /********************************************************************//** @@ -63,7 +64,8 @@ row_ext_lookup_ith( const row_ext_t* ext, /*!< in/out: column prefix cache */ ulint i, /*!< in: index of ext->ext[] */ ulint* len); /*!< out: length of prefix, in bytes, - at most REC_MAX_INDEX_COL_LEN */ + at most the length determined by + DICT_MAX_FIELD_LEN_BY_FORMAT() */ /********************************************************************//** Looks up a column prefix of an externally stored column. @return column prefix, or NULL if the column is not stored externally, @@ -78,13 +80,18 @@ row_ext_lookup( dict_col_get_no(); NOT relative to the records in the clustered index */ ulint* len); /*!< out: length of prefix, in bytes, - at most REC_MAX_INDEX_COL_LEN */ + at most the length determined by + DICT_MAX_FIELD_LEN_BY_FORMAT() */ /** Prefixes of externally stored columns */ struct row_ext_struct{ ulint n_ext; /*!< number of externally stored columns */ const ulint* ext; /*!< col_no's of externally stored columns */ byte* buf; /*!< backing store of the column prefix cache */ + ulint max_len;/*!< maximum prefix length, it could be + REC_ANTELOPE_MAX_INDEX_COL_LEN or + REC_VERSION_56_MAX_INDEX_COL_LEN depending + on row format */ ulint len[1]; /*!< prefix lengths; 0 if not cached */ }; diff --git a/storage/innobase/include/row0ext.ic b/storage/innobase/include/row0ext.ic index 82771a9312a..466046b2821 100644 --- a/storage/innobase/include/row0ext.ic +++ b/storage/innobase/include/row0ext.ic @@ -37,7 +37,7 @@ row_ext_lookup_ith( const row_ext_t* ext, /*!< in/out: column prefix cache */ ulint i, /*!< in: index of ext->ext[] */ ulint* len) /*!< out: length of prefix, in bytes, - at most REC_MAX_INDEX_COL_LEN */ + at most ext->max_len */ { ut_ad(ext); ut_ad(len); @@ -45,11 +45,14 @@ row_ext_lookup_ith( *len = ext->len[i]; + ut_ad(*len <= ext->max_len); + ut_ad(ext->max_len > 0); + if (UNIV_UNLIKELY(*len == 0)) { /* The BLOB could not be fetched to the cache. */ return(field_ref_zero); } else { - return(ext->buf + i * REC_MAX_INDEX_COL_LEN); + return(ext->buf + i * ext->max_len); } } @@ -67,7 +70,7 @@ row_ext_lookup( dict_col_get_no(); NOT relative to the records in the clustered index */ ulint* len) /*!< out: length of prefix, in bytes, - at most REC_MAX_INDEX_COL_LEN */ + at most ext->max_len */ { ulint i; diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h index 110525ecfed..75e15d67246 100644 --- a/storage/innobase/include/row0row.h +++ b/storage/innobase/include/row0row.h @@ -41,13 +41,24 @@ Created 4/20/1996 Heikki Tuuri Gets the offset of the trx id field, in bytes relative to the origin of a clustered index record. @return offset of DATA_TRX_ID */ -UNIV_INTERN +UNIV_INLINE ulint -row_get_trx_id_offset( -/*==================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ +row_get_trx_id_offset_func( +/*=======================*/ +#ifdef UNIV_DEBUG + const rec_t* rec, /*!< in: record */ +#endif /* UNIV_DEBUG */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); +#ifdef UNIV_DEBUG +# define row_get_trx_id_offset(rec, index, offsets) \ + row_get_trx_id_offset_func(rec, index, offsets) +#else /* UNIV_DEBUG */ +# define row_get_trx_id_offset(rec, index, offsets) \ + row_get_trx_id_offset_func(index, offsets) +#endif /* UNIV_DEBUG */ + /*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ @@ -55,9 +66,10 @@ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Reads the roll pointer field from a clustered index record. @return value of the field */ diff --git a/storage/innobase/include/row0row.ic b/storage/innobase/include/row0row.ic index 05c007641af..9d19e430e16 100644 --- a/storage/innobase/include/row0row.ic +++ b/storage/innobase/include/row0row.ic @@ -28,15 +28,45 @@ Created 4/20/1996 Heikki Tuuri #include "trx0undo.h" /*********************************************************************//** +Gets the offset of trx id field, in bytes relative to the origin of +a clustered index record. +@return offset of DATA_TRX_ID */ +UNIV_INLINE +ulint +row_get_trx_id_offset_func( +/*=======================*/ +#ifdef UNIV_DEBUG + const rec_t* rec, /*!< in: record */ +#endif /* UNIV_DEBUG */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ +{ + ulint pos; + ulint offset; + ulint len; + + ut_ad(dict_index_is_clust(index)); + ut_ad(rec_offs_validate(rec, index, offsets)); + + pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); + + offset = rec_get_nth_field_offs(offsets, pos, &len); + + ut_ad(len == DATA_TRX_ID_LEN); + + return(offset); +} + +/*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { ulint offset; diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 9816edc2eaa..7b5e138501d 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -51,7 +51,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#define INNODB_VERSION_BUGFIX 7 +#define INNODB_VERSION_BUGFIX 8 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index ceb4e89c08a..714107304f7 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -359,10 +359,8 @@ static ibool lock_rec_validate_page( /*===================*/ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no);/*!< in: page number */ + const buf_block_t* block) /*!< in: buffer block */ + __attribute__((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /* The lock system */ @@ -1100,10 +1098,10 @@ lock_rec_reset_nth_bit( Gets the first or next record lock on a page. @return next lock, NULL if none exists */ UNIV_INLINE -lock_t* -lock_rec_get_next_on_page( -/*======================*/ - lock_t* lock) /*!< in: a record lock */ +const lock_t* +lock_rec_get_next_on_page_const( +/*============================*/ + const lock_t* lock) /*!< in: a record lock */ { ulint space; ulint page_no; @@ -1133,6 +1131,18 @@ lock_rec_get_next_on_page( } /*********************************************************************//** +Gets the first or next record lock on a page. +@return next lock, NULL if none exists */ +UNIV_INLINE +lock_t* +lock_rec_get_next_on_page( +/*======================*/ + lock_t* lock) /*!< in: a record lock */ +{ + return((lock_t*) lock_rec_get_next_on_page_const(lock)); +} + +/*********************************************************************//** Gets the first record lock on a page, where the page is identified by its file address. @return first lock, NULL if none exists */ @@ -2645,9 +2655,7 @@ lock_move_reorganize_page( mem_heap_free(heap); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); + ut_ad(lock_rec_validate_page(block)); #endif } @@ -2735,12 +2743,8 @@ lock_move_rec_list_end( lock_mutex_exit_kernel(); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); - ut_ad(lock_rec_validate_page(buf_block_get_space(new_block), - buf_block_get_zip_size(block), - buf_block_get_page_no(new_block))); + ut_ad(lock_rec_validate_page(block)); + ut_ad(lock_rec_validate_page(new_block)); #endif } @@ -2848,9 +2852,7 @@ lock_move_rec_list_start( lock_mutex_exit_kernel(); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); + ut_ad(lock_rec_validate_page(block)); #endif } @@ -3833,17 +3835,18 @@ Checks if other transactions have an incompatible mode lock request in the lock queue. @return lock or NULL */ UNIV_INLINE -lock_t* +const lock_t* lock_table_other_has_incompatible( /*==============================*/ - trx_t* trx, /*!< in: transaction, or NULL if all - transactions should be included */ - ulint wait, /*!< in: LOCK_WAIT if also waiting locks are - taken into account, or 0 if not */ - dict_table_t* table, /*!< in: table */ - enum lock_mode mode) /*!< in: lock mode */ + const trx_t* trx, /*!< in: transaction, or NULL if all + transactions should be included */ + ulint wait, /*!< in: LOCK_WAIT if also + waiting locks are taken into + account, or 0 if not */ + const dict_table_t* table, /*!< in: table */ + enum lock_mode mode) /*!< in: lock mode */ { - lock_t* lock; + const lock_t* lock; ut_ad(mutex_own(&kernel_mutex)); @@ -3934,10 +3937,10 @@ static ibool lock_table_has_to_wait_in_queue( /*============================*/ - lock_t* wait_lock) /*!< in: waiting table lock */ + const lock_t* wait_lock) /*!< in: waiting table lock */ { - dict_table_t* table; - lock_t* lock; + const dict_table_t* table; + const lock_t* lock; ut_ad(mutex_own(&kernel_mutex)); ut_ad(lock_get_wait(wait_lock)); @@ -4677,9 +4680,9 @@ static ibool lock_table_queue_validate( /*======================*/ - dict_table_t* table) /*!< in: table */ + const dict_table_t* table) /*!< in: table */ { - lock_t* lock; + const lock_t* lock; ut_ad(mutex_own(&kernel_mutex)); @@ -4715,7 +4718,7 @@ lock_rec_queue_validate( /*====================*/ const buf_block_t* block, /*!< in: buffer block containing rec */ const rec_t* rec, /*!< in: record to look at */ - dict_index_t* index, /*!< in: index, or NULL if not known */ + const dict_index_t* index, /*!< in: index, or NULL if not known */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { trx_t* impl_trx; @@ -4864,46 +4867,37 @@ static ibool lock_rec_validate_page( /*===================*/ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no)/*!< in: page number */ + const buf_block_t* block) /*!< in: buffer block */ { - dict_index_t* index; - buf_block_t* block; - const page_t* page; - lock_t* lock; + const lock_t* lock; const rec_t* rec; ulint nth_lock = 0; ulint nth_bit = 0; ulint i; - mtr_t mtr; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; rec_offs_init(offsets_); ut_ad(!mutex_own(&kernel_mutex)); - - mtr_start(&mtr); - - ut_ad(zip_size != ULINT_UNDEFINED); - block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); - - page = block->frame; + ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); lock_mutex_enter_kernel(); loop: - lock = lock_rec_get_first_on_page_addr(space, page_no); + lock = lock_rec_get_first_on_page_addr(buf_block_get_space(block), + buf_block_get_page_no(block)); if (!lock) { goto function_exit; } +#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG + ut_a(!block->page.file_page_was_freed); +#endif + for (i = 0; i < nth_lock; i++) { - lock = lock_rec_get_next_on_page(lock); + lock = lock_rec_get_next_on_page_const(lock); if (!lock) { goto function_exit; @@ -4926,15 +4920,14 @@ loop: if (i == 1 || lock_rec_get_nth_bit(lock, i)) { - index = lock->index; - rec = page_find_rec_with_heap_no(page, i); + rec = page_find_rec_with_heap_no(block->frame, i); ut_a(rec); - offsets = rec_get_offsets(rec, index, offsets, + offsets = rec_get_offsets(rec, lock->index, offsets, ULINT_UNDEFINED, &heap); #if 0 fprintf(stderr, - "Validating %lu %lu\n", - (ulong) space, (ulong) page_no); + "Validating %u %u\n", + block->page.space, block->page.offset); #endif lock_mutex_exit_kernel(); @@ -4943,7 +4936,8 @@ loop: check WILL break the latching order and may cause a deadlock of threads. */ - lock_rec_queue_validate(block, rec, index, offsets); + lock_rec_queue_validate(block, rec, lock->index, + offsets); lock_mutex_enter_kernel(); @@ -4961,8 +4955,6 @@ loop: function_exit: lock_mutex_exit_kernel(); - mtr_commit(&mtr); - if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -4977,11 +4969,8 @@ ibool lock_validate(void) /*===============*/ { - lock_t* lock; - trx_t* trx; - ib_uint64_t limit; - ulint space; - ulint page_no; + const lock_t* lock; + const trx_t* trx; ulint i; lock_mutex_enter_kernel(); @@ -5006,9 +4995,14 @@ lock_validate(void) for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) { - limit = 0; + ulint space; + ulint page_no; + ib_uint64_t limit = 0; for (;;) { + mtr_t mtr; + buf_block_t* block; + lock = HASH_GET_FIRST(lock_sys->rec_hash, i); while (lock) { @@ -5034,13 +5028,26 @@ lock_validate(void) lock_mutex_exit_kernel(); - lock_rec_validate_page(space, - fil_space_get_zip_size(space), - page_no); + /* The lock and the block that it is referring + to may be freed at this point. We pass + BUF_GET_POSSIBLY_FREED to skip a debug check. + If the lock exists in lock_rec_validate_page() + we assert !block->page.file_page_was_freed. */ - lock_mutex_enter_kernel(); + mtr_start(&mtr); + block = buf_page_get_gen( + space, fil_space_get_zip_size(space), + page_no, RW_X_LATCH, NULL, + BUF_GET_POSSIBLY_FREED, + __FILE__, __LINE__, &mtr); + buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); + + ut_ad(lock_rec_validate_page(block)); + mtr_commit(&mtr); + + limit++; - limit = ut_ull_create(space, page_no + 1); + lock_mutex_enter_kernel(); } } diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c index 88e698ed818..439b429db43 100644 --- a/storage/innobase/mtr/mtr0mtr.c +++ b/storage/innobase/mtr/mtr0mtr.c @@ -265,9 +265,20 @@ mtr_commit( mtr_memo_pop_all(mtr); #endif /* !UNIV_HOTBACKUP */ - ut_d(mtr->state = MTR_COMMITTED); dyn_array_free(&(mtr->memo)); dyn_array_free(&(mtr->log)); +#ifdef UNIV_DEBUG_VALGRIND + /* Declare everything uninitialized except + mtr->start_lsn, mtr->end_lsn and mtr->state. */ + { + ib_uint64_t start_lsn = mtr->start_lsn; + ib_uint64_t end_lsn = mtr->end_lsn; + UNIV_MEM_INVALID(mtr, sizeof *mtr); + mtr->start_lsn = start_lsn; + mtr->end_lsn = end_lsn; + } +#endif /* UNIV_DEBUG_VALGRIND */ + ut_d(mtr->state = MTR_COMMITTED); } #ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 50607e07076..bd48d0e4b6e 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -4051,16 +4051,23 @@ os_aio_func( Windows async i/o, Windows does not allow us to use ordinary synchronous os_file_read etc. on the same file, therefore we have built a special mechanism for synchronous - wait in the Windows case. */ + wait in the Windows case. + Also note that the Performance Schema instrumentation has + been performed by current os_aio_func()'s wrapper function + pfs_os_aio_func(). So we would no longer need to call + Performance Schema instrumented os_file_read() and + os_file_write(). Instead, we should use os_file_read_func() + and os_file_write_func() */ if (type == OS_FILE_READ) { - return(os_file_read(file, buf, offset, + return(os_file_read_func(file, buf, offset, offset_high, n)); } ut_a(type == OS_FILE_WRITE); - return(os_file_write(name, file, buf, offset, offset_high, n)); + return(os_file_write_func(name, file, buf, offset, + offset_high, n)); } try_again: diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c index 964d0e2abef..6064d028ae1 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -1253,28 +1253,6 @@ page_move_rec_list_start( return(TRUE); } - -/***********************************************************************//** -This is a low-level operation which is used in a database index creation -to update the page number of a created B-tree to a data dictionary record. */ -UNIV_INTERN -void -page_rec_write_index_page_no( -/*=========================*/ - rec_t* rec, /*!< in: record to update */ - ulint i, /*!< in: index of the field to update */ - ulint page_no,/*!< in: value to write */ - mtr_t* mtr) /*!< in: mtr */ -{ - byte* data; - ulint len; - - data = rec_get_nth_field_old(rec, i, &len); - - ut_ad(len == 4); - - mlog_write_ulint(data, page_no, MLOG_4BYTES, mtr); -} #endif /* !UNIV_HOTBACKUP */ /**************************************************************//** diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c index f077a56b087..c92ad9dc25b 100644 --- a/storage/innobase/page/page0zip.c +++ b/storage/innobase/page/page0zip.c @@ -464,7 +464,7 @@ page_zip_fields_encode( if (fixed_sum && UNIV_UNLIKELY (fixed_sum + field->fixed_len - > DICT_MAX_INDEX_COL_LEN)) { + > DICT_MAX_FIXED_COL_LEN)) { /* Write out the length of the preceding non-nullable fields, to avoid exceeding the maximum diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index a54b5013155..5a96e608ab5 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -1174,7 +1174,7 @@ rec_convert_dtuple_to_rec_comp( } else if (dfield_is_ext(field)) { ut_ad(ifield->col->len >= 256 || ifield->col->mtype == DATA_BLOB); - ut_ad(len <= REC_MAX_INDEX_COL_LEN + ut_ad(len <= REC_ANTELOPE_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE); *lens-- = (byte) (len >> 8) | 0xc0; *lens-- = (byte) len; diff --git a/storage/innobase/row/row0ext.c b/storage/innobase/row/row0ext.c index 7320f5b1dca..07e970cf485 100644 --- a/storage/innobase/row/row0ext.c +++ b/storage/innobase/row/row0ext.c @@ -44,8 +44,9 @@ row_ext_cache_fill( { const byte* field = dfield_get_data(dfield); ulint f_len = dfield_get_len(dfield); - byte* buf = ext->buf + i * REC_MAX_INDEX_COL_LEN; + byte* buf = ext->buf + i * ext->max_len; + ut_ad(ext->max_len > 0); ut_ad(i < ext->n_ext); ut_ad(dfield_is_ext(dfield)); ut_a(f_len >= BTR_EXTERN_FIELD_REF_SIZE); @@ -56,14 +57,14 @@ row_ext_cache_fill( /* The BLOB pointer is not set: we cannot fetch it */ ext->len[i] = 0; } else { - /* Fetch at most REC_MAX_INDEX_COL_LEN of the column. + /* Fetch at most ext->max_len of the column. The column should be non-empty. However, trx_rollback_or_clean_all_recovered() may try to access a half-deleted BLOB if the server previously crashed during the execution of btr_free_externally_stored_field(). */ ext->len[i] = btr_copy_externally_stored_field_prefix( - buf, REC_MAX_INDEX_COL_LEN, zip_size, field, f_len); + buf, ext->max_len, zip_size, field, f_len); } } @@ -79,16 +80,18 @@ row_ext_create( in the InnoDB table object, as reported by dict_col_get_no(); NOT relative to the records in the clustered index */ + ulint flags, /*!< in: table->flags */ const dtuple_t* tuple, /*!< in: data tuple containing the field references of the externally stored columns; must be indexed by col_no; the clustered index record must be covered by a lock or a page latch to prevent deletion (rollback or purge). */ - ulint zip_size,/*!< compressed page size in bytes, or 0 */ mem_heap_t* heap) /*!< in: heap where created */ { ulint i; + ulint zip_size = dict_table_flags_to_zip_size(flags); + row_ext_t* ret = mem_heap_alloc(heap, (sizeof *ret) + (n_ext - 1) * sizeof ret->len); @@ -97,10 +100,12 @@ row_ext_create( ret->n_ext = n_ext; ret->ext = ext; - ret->buf = mem_heap_alloc(heap, n_ext * REC_MAX_INDEX_COL_LEN); + ret->max_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags); + + ret->buf = mem_heap_alloc(heap, n_ext * ret->max_len); #ifdef UNIV_DEBUG - memset(ret->buf, 0xaa, n_ext * REC_MAX_INDEX_COL_LEN); - UNIV_MEM_ALLOC(ret->buf, n_ext * REC_MAX_INDEX_COL_LEN); + memset(ret->buf, 0xaa, n_ext * ret->max_len); + UNIV_MEM_ALLOC(ret->buf, n_ext * ret->max_len); #endif /* Fetch the BLOB prefixes */ diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index f7e5c5fdceb..e1ada387729 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1997,6 +1997,7 @@ row_create_index_for_mysql( ulint i; ulint len; char* table_name; + dict_table_t* table; #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); @@ -2010,6 +2011,8 @@ row_create_index_for_mysql( que_run_threads()) and thus index->table_name is not available. */ table_name = mem_strdup(index->table_name); + table = dict_table_get_low(table_name); + trx_start_if_not_started(trx); /* Check that the same column does not appear twice in the index. @@ -2042,7 +2045,7 @@ row_create_index_for_mysql( } /* Check also that prefix_len and actual length - < DICT_MAX_INDEX_COL_LEN */ + is less than that from DICT_MAX_FIELD_LEN_BY_FORMAT() */ len = dict_index_get_nth_field(index, i)->prefix_len; @@ -2050,8 +2053,9 @@ row_create_index_for_mysql( len = ut_max(len, field_lengths[i]); } - if (len >= DICT_MAX_INDEX_COL_LEN) { - err = DB_TOO_BIG_RECORD; + /* Column or prefix length exceeds maximum column length */ + if (len > (ulint) DICT_MAX_FIELD_LEN_BY_FORMAT(table)) { + err = DB_TOO_BIG_INDEX_COL; goto error_handling; } @@ -2076,6 +2080,7 @@ row_create_index_for_mysql( que_graph_free((que_t*) que_node_get_parent(thr)); error_handling: + if (err != DB_SUCCESS) { /* We have special error handling here */ @@ -2941,7 +2946,7 @@ row_truncate_table_for_mysql( rec = btr_pcur_get_rec(&pcur); if (root_page_no != FIL_NULL) { - page_rec_write_index_page_no( + page_rec_write_field( rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, root_page_no, &mtr); /* We will need to commit and restart the diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index 72f321288ec..8aa4195a70f 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -47,35 +47,6 @@ Created 4/20/1996 Heikki Tuuri #include "read0read.h" #include "ut0mem.h" -/*********************************************************************//** -Gets the offset of trx id field, in bytes relative to the origin of -a clustered index record. -@return offset of DATA_TRX_ID */ -UNIV_INTERN -ulint -row_get_trx_id_offset( -/*==================*/ - const rec_t* rec __attribute__((unused)), - /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ -{ - ulint pos; - ulint offset; - ulint len; - - ut_ad(dict_index_is_clust(index)); - ut_ad(rec_offs_validate(rec, index, offsets)); - - pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - - offset = rec_get_nth_field_offs(offsets, pos, &len); - - ut_ad(len == DATA_TRX_ID_LEN); - - return(offset); -} - /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. @@ -299,8 +270,7 @@ row_build( 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), + *ext = row_ext_create(j, ext_cols, index->table->flags, row, heap); } else { *ext = NULL; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 66aff528f38..53d0c2ec232 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -99,10 +99,12 @@ row_sel_sec_rec_is_for_blob( ulint clust_len, /*!< in: length of clust_field */ const byte* sec_field, /*!< in: column in secondary index */ ulint sec_len, /*!< in: length of sec_field */ - ulint zip_size) /*!< in: compressed page size, or 0 */ + dict_table_t* table) /*!< in: table */ { ulint len; - byte buf[DICT_MAX_INDEX_COL_LEN]; + byte buf[REC_VERSION_56_MAX_INDEX_COL_LEN]; + ulint zip_size = dict_table_flags_to_zip_size(table->flags); + ulint max_prefix_len = DICT_MAX_FIELD_LEN_BY_FORMAT(table); ut_a(clust_len >= BTR_EXTERN_FIELD_REF_SIZE); @@ -116,7 +118,7 @@ row_sel_sec_rec_is_for_blob( return(FALSE); } - len = btr_copy_externally_stored_field_prefix(buf, sizeof buf, + len = btr_copy_externally_stored_field_prefix(buf, max_prefix_len, zip_size, clust_field, clust_len); @@ -222,8 +224,7 @@ row_sel_sec_rec_is_for_clust_rec( col->mbminmaxlen, clust_field, clust_len, sec_field, sec_len, - dict_table_zip_size( - clust_index->table))) { + clust_index->table)) { goto inequal; } diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index ea71a16bed2..04b3dcb3a4a 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -1211,8 +1211,8 @@ row_upd_replace( } if (n_ext_cols) { - *ext = row_ext_create(n_ext_cols, ext_cols, row, - dict_table_zip_size(table), heap); + *ext = row_ext_create(n_ext_cols, ext_cols, table->flags, row, + heap); } else { *ext = NULL; } diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 23e690b1105..04503d25cd4 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1270,7 +1270,7 @@ retry: #endif /* UNIV_SYNC_DEBUG */ trx->op_info = "waiting in InnoDB queue"; - thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK); + thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK); os_event_wait(slot->event); thd_wait_end(trx->mysql_thd); @@ -1658,7 +1658,7 @@ srv_suspend_mysql_thread( /* Suspend this thread and wait for the event. */ - thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK); + thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_LOCK); os_event_wait(event); thd_wait_end(trx->mysql_thd); diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index e7e9a008db4..5a3b79d0ad5 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -351,10 +351,10 @@ trx_undo_rec_get_col_val( ut_ad(*orig_len >= BTR_EXTERN_FIELD_REF_SIZE); ut_ad(*len > *orig_len); /* @see dtuple_convert_big_rec() */ - ut_ad(*len >= BTR_EXTERN_FIELD_REF_SIZE * 2); + ut_ad(*len >= BTR_EXTERN_FIELD_REF_SIZE); /* we do not have access to index->table here ut_ad(dict_table_get_format(index->table) >= DICT_TF_FORMAT_ZIP - || *len >= REC_MAX_INDEX_COL_LEN + || *len >= col->max_prefix + BTR_EXTERN_FIELD_REF_SIZE); */ @@ -456,9 +456,10 @@ static byte* trx_undo_page_fetch_ext( /*====================*/ - byte* ext_buf, /*!< in: a buffer of - REC_MAX_INDEX_COL_LEN - + BTR_EXTERN_FIELD_REF_SIZE */ + byte* ext_buf, /*!< in: buffer to hold the prefix + data and BLOB pointer */ + ulint prefix_len, /*!< in: prefix size to store + in the undo log */ ulint zip_size, /*!< compressed page size in bytes, or 0 for uncompressed BLOB */ const byte* field, /*!< in: an externally stored column */ @@ -467,7 +468,7 @@ trx_undo_page_fetch_ext( { /* Fetch the BLOB. */ ulint ext_len = btr_copy_externally_stored_field_prefix( - ext_buf, REC_MAX_INDEX_COL_LEN, zip_size, field, *len); + ext_buf, prefix_len, zip_size, field, *len); /* BLOBs should always be nonempty. */ ut_a(ext_len); /* Append the BLOB pointer to the prefix. */ @@ -488,10 +489,11 @@ trx_undo_page_report_modify_ext( byte* ptr, /*!< in: undo log position, at least 15 bytes must be available */ byte* ext_buf, /*!< in: a buffer of - REC_MAX_INDEX_COL_LEN - + BTR_EXTERN_FIELD_REF_SIZE, + DICT_MAX_FIELD_LEN_BY_FORMAT() size, or NULL when should not fetch a longer prefix */ + ulint prefix_len, /*!< prefix size to store in the + undo log */ ulint zip_size, /*!< compressed page size in bytes, or 0 for uncompressed BLOB */ const byte** field, /*!< in/out: the locally stored part of @@ -499,6 +501,8 @@ trx_undo_page_report_modify_ext( ulint* len) /*!< in/out: length of field, in bytes */ { if (ext_buf) { + ut_a(prefix_len > 0); + /* If an ordering column is externally stored, we will have to store a longer prefix of the field. In this case, write to the log a marker followed by the @@ -507,7 +511,7 @@ trx_undo_page_report_modify_ext( ptr += mach_write_compressed(ptr, *len); - *field = trx_undo_page_fetch_ext(ext_buf, zip_size, + *field = trx_undo_page_fetch_ext(ext_buf, prefix_len, zip_size, *field, len); ptr += mach_write_compressed(ptr, *len); @@ -553,7 +557,7 @@ trx_undo_page_report_modify( ulint i; trx_id_t trx_id; ibool ignore_prefix = FALSE; - byte ext_buf[REC_MAX_INDEX_COL_LEN + byte ext_buf[REC_VERSION_56_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE]; ut_a(dict_index_is_clust(index)); @@ -665,6 +669,7 @@ trx_undo_page_report_modify( /* Save to the undo log the old values of the columns to be updated. */ if (update) { + if (trx_undo_left(undo_page, ptr) < 5) { return(0); @@ -693,13 +698,21 @@ trx_undo_page_report_modify( } if (rec_offs_nth_extern(offsets, pos)) { + const dict_col_t* col + = dict_index_get_nth_col(index, pos); + ulint prefix_len + = dict_max_field_len_store_undo( + table, col); + + ut_ad(prefix_len + BTR_EXTERN_FIELD_REF_SIZE + <= sizeof ext_buf); + ptr = trx_undo_page_report_modify_ext( ptr, - dict_index_get_nth_col(index, pos) - ->ord_part + col->ord_part && !ignore_prefix - && flen < REC_MAX_INDEX_COL_LEN - ? ext_buf : NULL, + && flen < REC_ANTELOPE_MAX_INDEX_COL_LEN + ? ext_buf : NULL, prefix_len, dict_table_zip_size(table), &field, &flen); @@ -778,11 +791,20 @@ trx_undo_page_report_modify( &flen); if (rec_offs_nth_extern(offsets, pos)) { + const dict_col_t* col = + dict_index_get_nth_col( + index, pos); + ulint prefix_len = + dict_max_field_len_store_undo( + table, col); + + ut_a(prefix_len < sizeof ext_buf); + ptr = trx_undo_page_report_modify_ext( ptr, - flen < REC_MAX_INDEX_COL_LEN + flen < REC_ANTELOPE_MAX_INDEX_COL_LEN && !ignore_prefix - ? ext_buf : NULL, + ? ext_buf : NULL, prefix_len, dict_table_zip_size(table), &field, &flen); } else { @@ -1082,11 +1104,11 @@ trx_undo_rec_get_partial_row( undo log record. */ if (!ignore_prefix && col->ord_part) { ut_a(dfield_get_len(dfield) - >= 2 * BTR_EXTERN_FIELD_REF_SIZE); + >= BTR_EXTERN_FIELD_REF_SIZE); ut_a(dict_table_get_format(index->table) >= DICT_TF_FORMAT_ZIP || dfield_get_len(dfield) - >= REC_MAX_INDEX_COL_LEN + >= REC_ANTELOPE_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE); } } diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 070d6332a4f..4cb4b7b79c5 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1985,8 +1985,6 @@ trx_undo_free_prepared( /*===================*/ trx_t* trx) /*!< in/out: PREPARED transaction */ { - mutex_enter(&trx->rseg->mutex); - ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS); if (trx->update_undo) { @@ -2001,6 +1999,5 @@ trx_undo_free_prepared( trx->insert_undo); trx_undo_mem_free(trx->insert_undo); } - mutex_exit(&trx->rseg->mutex); } #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index cd0894b132a..a9c0d381e16 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -662,6 +662,8 @@ ut_strerr( return("Table is being used"); case DB_TOO_BIG_RECORD: return("Record too big"); + case DB_TOO_BIG_INDEX_COL: + return("Index columns size too big"); case DB_LOCK_WAIT_TIMEOUT: return("Lock wait timeout"); case DB_NO_REFERENCED_ROW: diff --git a/strings/decimal.c b/strings/decimal.c index 4766c3b2d00..74272b0a903 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -312,8 +312,8 @@ int decimal_actual_fraction(decimal_t *from) from - value to convert to - points to buffer where string representation should be stored - *to_len - in: size of to buffer - out: length of the actually written string + *to_len - in: size of to buffer (incl. terminating '\0') + out: length of the actually written string (excl. '\0') fixed_precision - 0 if representation can be variable length and fixed_decimals will not be checked in this case. Put number as with fixed point position with this @@ -330,6 +330,7 @@ int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals, char filler) { + /* {intg_len, frac_len} output widths; {intg, frac} places in input */ int len, intg, frac= from->frac, i, intg_len, frac_len, fill; /* number digits before decimal point */ int fixed_intg= (fixed_precision ? diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 348ea9b6f29..e789831b3f2 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -19647,10 +19647,10 @@ static struct my_option client_test_long_options[] = &opt_getopt_ll_test, &opt_getopt_ll_test, 0, GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, {"plugin_dir", 0, "Directory for client-side plugins.", - (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", 0, "Default authentication client-side plugin to use.", - (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c index 61b7ae08cf5..c04ef358abe 100644 --- a/unittest/mysys/lf-t.c +++ b/unittest/mysys/lf-t.c @@ -27,6 +27,8 @@ int32 inserts= 0, N; LF_ALLOCATOR lf_allocator; LF_HASH lf_hash; +int with_my_thread_init=0; + /* pin allocator - alloc and release an element in a loop */ @@ -36,7 +38,8 @@ pthread_handler_t test_lf_pinbox(void *arg) int32 x= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_pinbox_get_pins(&lf_allocator.pinbox); @@ -49,7 +52,10 @@ pthread_handler_t test_lf_pinbox(void *arg) pthread_mutex_lock(&mutex); if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); + return 0; } @@ -68,7 +74,8 @@ pthread_handler_t test_lf_alloc(void *arg) int32 x,y= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_alloc_get_pins(&lf_allocator); @@ -101,7 +108,9 @@ pthread_handler_t test_lf_alloc(void *arg) } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); return 0; } @@ -112,7 +121,8 @@ pthread_handler_t test_lf_hash(void *arg) int32 x,y,z,sum= 0, ins= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_hash_get_pins(&lf_hash); @@ -152,14 +162,15 @@ pthread_handler_t test_lf_hash(void *arg) } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + if (with_my_thread_init) + my_thread_end(); return 0; } void do_tests() { - plan(4); + plan(7); lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used)); lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0, @@ -168,9 +179,15 @@ void do_tests() bad= my_atomic_initialize(); ok(!bad, "my_atomic_initialize() returned %d", bad); - test_concurrently("lf_pinbox", test_lf_pinbox, N= THREADS, CYCLES); - test_concurrently("lf_alloc", test_lf_alloc, N= THREADS, CYCLES); - test_concurrently("lf_hash", test_lf_hash, N= THREADS, CYCLES/10); + with_my_thread_init= 1; + test_concurrently("lf_pinbox (with my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (with my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (with my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); + + with_my_thread_init= 0; + test_concurrently("lf_pinbox (without my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (without my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (without my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); lf_hash_destroy(&lf_hash); lf_alloc_destroy(&lf_allocator); diff --git a/vio/test-ssl.c b/vio/test-ssl.c index 1e846727d00..4d158ae83f7 100644 --- a/vio/test-ssl.c +++ b/vio/test-ssl.c @@ -59,6 +59,9 @@ main(int argc, char** argv) struct st_VioSSLFd* ssl_acceptor= 0; struct st_VioSSLFd* ssl_connector= 0; Vio* client_vio=0, *server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -91,16 +94,16 @@ main(int argc, char** argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path, cipher); + ca_path, cipher, &ssl_init_error); client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; client_vio->vioblocking(client_vio, 0, &unused); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; server_vio->vioblocking(client_vio, 0, &unused); - sslaccept(ssl_acceptor,server_vio,60L); + sslaccept(ssl_acceptor,server_vio,60L, &ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c index 643dcbf2c8e..9d8a741e313 100644 --- a/vio/test-sslclient.c +++ b/vio/test-sslclient.c @@ -50,6 +50,9 @@ main( int argc __attribute__((unused)), Vio* client_vio=0; int err; char xbuf[100]="Ohohhhhoh1234"; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -60,7 +63,8 @@ main( int argc __attribute__((unused)), if (ca_path!=0) printf("CApath : %s\n", ca_path); - ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher); + ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher, + &ssl_init_error); if(!ssl_connector) { fatal_error("client:new_VioSSLConnectorFd failed"); } @@ -81,7 +85,7 @@ main( int argc __attribute__((unused)), /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ read(client_vio->sd,xbuf, sizeof(xbuf)); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); err = vio_read(client_vio,xbuf, sizeof(xbuf)); if (err<=0) { my_free(ssl_connector); diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c index 3123a4def2c..35cfa26bd00 100644 --- a/vio/test-sslserver.c +++ b/vio/test-sslserver.c @@ -52,6 +52,7 @@ do_ssl_stuff( TH_ARGS* args) const char* s = "Huhuhuhuuu"; Vio* server_vio; int err; + unsigned long ssl_error; DBUG_ENTER("do_ssl_stuff"); server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE); @@ -60,7 +61,7 @@ do_ssl_stuff( TH_ARGS* args) /* TCP connection is ready. Do server side SSL. */ err = write(server_vio->sd,(uchar*)s, strlen(s)); - sslaccept(args->ssl_acceptor,server_vio,60L); + sslaccept(args->ssl_acceptor,server_vio,60L,&ssl_error); err = server_vio->write(server_vio,(uchar*)s, strlen(s)); DBUG_VOID_RETURN; } diff --git a/vio/viossl.c b/vio/viossl.c index 5cb5f36f20d..49d442f32aa 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -24,6 +24,8 @@ #ifdef HAVE_OPENSSL +#ifndef DBUG_OFF + static void report_errors(SSL* ssl) { @@ -31,9 +33,7 @@ report_errors(SSL* ssl) const char *file; const char *data; int line, flags; -#ifndef DBUG_OFF char buf[512]; -#endif DBUG_ENTER("report_errors"); @@ -51,6 +51,8 @@ report_errors(SSL* ssl) DBUG_VOID_RETURN; } +#endif + size_t vio_ssl_read(Vio *vio, uchar* buf, size_t size) { @@ -144,8 +146,9 @@ void vio_ssl_delete(Vio *vio) static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, - int (*connect_accept_func)(SSL*)) + int (*connect_accept_func)(SSL*), unsigned long *errptr) { + int r; SSL *ssl; my_bool unused; my_bool was_blocking; @@ -160,7 +163,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); - report_errors(ssl); + *errptr= ERR_get_error(); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } @@ -169,10 +172,10 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, vio->sd); - if (connect_accept_func(ssl) < 1) + if ((r= connect_accept_func(ssl)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); - report_errors(ssl); + *errptr= SSL_get_error(ssl, r); SSL_free(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); @@ -220,17 +223,17 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, } -int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslaccept"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, errptr)); } -int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslconnect"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, errptr)); } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 4971dec37fb..4f4dd5758ba 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -165,7 +165,7 @@ static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher, SSL_METHOD *method, - enum enum_ssl_init_error* error) + enum enum_ssl_init_error *error) { DH *dh; struct st_VioSSLFd *ssl_fd; @@ -249,11 +249,10 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd * new_VioSSLConnectorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher) + const char *cipher, enum enum_ssl_init_error* error) { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; - enum enum_ssl_init_error dummy; /* Turn off verification of servers certificate if both @@ -263,7 +262,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, verify= SSL_VERIFY_NONE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, TLSv1_client_method(), &dummy))) + ca_path, cipher, TLSv1_client_method(), error))) { return 0; } diff --git a/vio/viotest-ssl.c b/vio/viotest-ssl.c index 5c68e861d2a..90489b46605 100644 --- a/vio/viotest-ssl.c +++ b/vio/viotest-ssl.c @@ -60,6 +60,9 @@ int main(int argc, char **argv) struct st_VioSSLConnectorFd* ssl_connector=0; Vio* client_vio=0; Vio* server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -92,14 +95,14 @@ int main(int argc, char **argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path); + ca_path, &ssl_init_error); client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; - sslconnect(ssl_connector,client_vio); + sslconnect(ssl_connector,client_vio,&ssl_error); server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; - sslaccept(ssl_acceptor,server_vio); + sslaccept(ssl_acceptor,server_vio,&ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); |