diff options
195 files changed, 4687 insertions, 2284 deletions
diff --git a/.bzrignore b/.bzrignore index d44aefea583..c38cb22d0fd 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1099,6 +1099,7 @@ libmysqld/item_sum.cc libmysqld/item_timefunc.cc libmysqld/item_uniq.cc libmysqld/key.cc +libmysqld/lex_hash.h libmysqld/lib_sql.cpp libmysqld/libmysql.c libmysqld/link_sources @@ -1107,6 +1108,8 @@ libmysqld/log.cc libmysqld/log_event.cc libmysqld/log_event_old.cc libmysqld/md5.c +libmysqld/message.h +libmysqld/message.rc libmysqld/mf_iocache.cc libmysqld/mini_client.cc libmysqld/my_decimal.cc @@ -2882,6 +2885,7 @@ support-files/mysql-3.23.29-gamma.spec support-files/mysql-log-rotate support-files/mysql.server support-files/mysql.spec +support-files/mysqld_multi.server support-files/ndb-config-2-node.ini tags test/ndbapi/bank/bankCreator @@ -2947,6 +2951,7 @@ tests/.deps/thread_test.Po tests/.libs -prune tests/.libs/lt-mysql_client_test tests/.libs/mysql_client_test +tests/bug25714 tests/client_test tests/connect_test tests/mysql_client_test diff --git a/BUILD/compile-solaris-sparc-debug b/BUILD/compile-solaris-sparc-debug index 58fcecf5a71..43cabd644fa 100755 --- a/BUILD/compile-solaris-sparc-debug +++ b/BUILD/compile-solaris-sparc-debug @@ -6,6 +6,6 @@ make -k clean || true path=`dirname $0` . "$path/autorun.sh" -CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug +CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug make -j 4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dc62977846..76d1bdb5921 100644..100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,26 +18,37 @@ PROJECT(MySql) # This reads user configuration, generated by configure.js. INCLUDE(win/configure.data) -# By default, CMake will create Release, Debug, RelWithDebInfo and MinSizeRel -# configurations. The EMBEDDED_ONLY build parameter is necessary because CMake -# doesn't support custom build configurations for VS2005. Since the Debug -# configuration does not work properly with USE_TLS defined -# (see mysys/CMakeLists.txt) the easiest way to debug the Embedded Server is to -# use the RelWithDebInfo configuration without optimizations. -# -# Debug default CXX_FLAGS "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1" -# RelWithDebInfo default CXX_FLAGS "/MD /Zi /O2 /Ob1 /D NDEBUG" -# -IF(NOT EMBEDDED_ONLY) - # Hardcode support for CSV storage engine - SET(WITH_CSV_STORAGE_ENGINE TRUE) -ELSE(NOT EMBEDDED_ONLY) +# Hardcode support for CSV storage engine +SET(WITH_CSV_STORAGE_ENGINE TRUE) + +# CMAKE will not allow custom VS7+ configurations. mysqld and libmysqld +# cannot be built at the same time as they require different configurations +IF(EMBEDDED_ONLY) + ADD_DEFINITIONS(-DEMBEDDED_LIBRARY) + # By default, CMake will create Release, Debug, RelWithDebInfo and MinSizeRel + # configurations. The EMBEDDED_ONLY build parameter is necessary because CMake + # doesn't support custom build configurations for VS2005. Since the Debug + # configuration does not work properly with USE_TLS defined + # (see mysys/CMakeLists.txt) the easiest way to debug the Embedded Server is to + # use the RelWithDebInfo configuration without optimizations. + # + # Debug default CXX_FLAGS "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1" + # RelWithDebInfo default CXX_FLAGS "/MD /Zi /O2 /Ob1 /D NDEBUG" SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /Zi /Od /Ob0 /D NDEBUG" CACHE STRING "No Optimization" FORCE) -ENDIF(NOT EMBEDDED_ONLY) +ENDIF(EMBEDDED_ONLY) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in ${CMAKE_SOURCE_DIR}/include/mysql_version.h @ONLY) +# Set standard options +ADD_DEFINITIONS(-DHAVE_YASSL) + +# Set debug options +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS") + +# Note that some engines are always compiled in, MyISAM, MyISAMMRG and HEAP, +# these three plugin defintions are dummys for symmetry + SET(WITH_HEAP_STORAGE_ENGINE TRUE) ADD_DEFINITIONS(-DWITH_HEAP_STORAGE_ENGINE) SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_heap_plugin") @@ -103,49 +114,43 @@ ENDIF(CYBOZU) # in some places we use DBUG_OFF SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF") +SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDBUG_OFF") +SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDBUG_OFF") IF(CMAKE_GENERATOR MATCHES "Visual Studio 8") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996") SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4996") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /wd4996") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /wd4996") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /wd4996") + SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /wd4996") ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8") IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR CMAKE_GENERATOR MATCHES "Visual Studio 8") - # replace /MDd with /MTd - STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT - ${CMAKE_CXX_FLAGS_DEBUG_INIT}) - STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT - ${CMAKE_C_FLAGS_DEBUG_INIT}) - STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE - ${CMAKE_C_FLAGS_RELEASE}) - STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG - ${CMAKE_C_FLAGS_DEBUG}) - STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE - ${CMAKE_CXX_FLAGS_RELEASE}) - STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG - ${CMAKE_CXX_FLAGS_DEBUG}) - STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO - ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) - STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO - ${CMAKE_C_FLAGS_RELWITHDEBINFO}) + # replace /MDd with /MTd + STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) + STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT ${CMAKE_C_FLAGS_DEBUG_INIT}) + + STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) + STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT}) - # generate .map files - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MAP /MAPINFO:EXPORTS") + # generate map files, set stack size (see bug#20815) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MAP /MAPINFO:EXPORTS") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1048576") - # set stack size (see bug#20815) - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1048576") + # remove support for Exception handling + STRING(REPLACE "/GX" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_INIT ${CMAKE_CXX_FLAGS_INIT}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT}) - # remove support for Exception handling - STRING(REPLACE "/GX" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_INIT - ${CMAKE_CXX_FLAGS_INIT}) - STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT - ${CMAKE_CXX_FLAGS_DEBUG_INIT}) ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR CMAKE_GENERATOR MATCHES "Visual Studio 8") @@ -209,6 +214,8 @@ IF(EMBED_MANIFESTS) ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8 2005 Win64") ENDIF(EMBED_MANIFESTS) +# FIXME "debug" only needed if build type is "Debug", but +# CMAKE_BUILD_TYPE is not set during configure time. ADD_SUBDIRECTORY(vio) ADD_SUBDIRECTORY(dbug) ADD_SUBDIRECTORY(strings) @@ -241,16 +248,13 @@ ENDIF(WITH_FEDERATED_STORAGE_ENGINE) IF(WITH_INNOBASE_STORAGE_ENGINE) ADD_SUBDIRECTORY(storage/innobase) ENDIF(WITH_INNOBASE_STORAGE_ENGINE) -# CMAKE will not allow custom VS7+ configurations. mysqld and libmysqld -# cannot be built at the same time as they require different configurations +ADD_SUBDIRECTORY(libmysql) IF(EMBEDDED_ONLY) - ADD_DEFINITIONS(-DEMBEDDED_LIBRARY) ADD_SUBDIRECTORY(libmysqld) ADD_SUBDIRECTORY(libmysqld/examples) ELSE(EMBEDDED_ONLY) ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(sql) ADD_SUBDIRECTORY(server-tools/instance-manager) - ADD_SUBDIRECTORY(libmysql) ADD_SUBDIRECTORY(tests) ENDIF(EMBEDDED_ONLY) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8a670cf4c4b..2ef55c23c90 100644..100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -14,126 +14,54 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") +# We use the "mysqlclient_notls" library here just as safety, in case +# any of the clients here would go beond the client API and access the +# Thread Local Storage directly. + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -# The old Windows build method used renamed (.cc -> .cpp) source files, fails -# in #include in mysqlbinlog.cc. So disable that using the USING_CMAKE define. -ADD_DEFINITIONS(-DUSING_CMAKE -DYASSL_PREFIX -DUSE_TLS) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/zlib +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/extra/yassl/include - ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include - ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/strings) -SET(YASSL_SOURCES ../extra/yassl/src/buffer.cpp - ../extra/yassl/src/cert_wrapper.cpp - ../extra/yassl/src/crypto_wrapper.cpp - ../extra/yassl/src/handshake.cpp - ../extra/yassl/src/lock.cpp - ../extra/yassl/src/log.cpp - ../extra/yassl/src/socket_wrapper.cpp - ../extra/yassl/src/ssl.cpp - ../extra/yassl/src/timer.cpp - ../extra/yassl/src/yassl_error.cpp - ../extra/yassl/src/yassl_imp.cpp - ../extra/yassl/src/yassl_int.cpp) - -SET(TAOCRYPT_SOURCES ../extra/yassl/taocrypt/src/aes.cpp - ../extra/yassl/taocrypt/src/aestables.cpp - ../extra/yassl/taocrypt/src/algebra.cpp - ../extra/yassl/taocrypt/src/arc4.cpp - ../extra/yassl/taocrypt/src/asn.cpp - ../extra/yassl/taocrypt/src/coding.cpp - ../extra/yassl/taocrypt/src/des.cpp - ../extra/yassl/taocrypt/src/dh.cpp - ../extra/yassl/taocrypt/src/dsa.cpp - ../extra/yassl/taocrypt/src/file.cpp - ../extra/yassl/taocrypt/src/hash.cpp - ../extra/yassl/taocrypt/src/integer.cpp - ../extra/yassl/taocrypt/src/md2.cpp - ../extra/yassl/taocrypt/src/md4.cpp - ../extra/yassl/taocrypt/src/md5.cpp - ../extra/yassl/taocrypt/src/misc.cpp - ../extra/yassl/taocrypt/src/random.cpp - ../extra/yassl/taocrypt/src/ripemd.cpp - ../extra/yassl/taocrypt/src/rsa.cpp - ../extra/yassl/taocrypt/src/sha.cpp) - - -ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c - ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c - ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c - ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c - ../strings/ctype-eucjpms.c ../strings/ctype-extra.c ../strings/ctype-gb2312.c - ../strings/ctype-gbk.c ../strings/ctype-latin1.c ../strings/ctype-mb.c - ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c - ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c - ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c - ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c - ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c - ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c - ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c - ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c - ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c - ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c - ../mysys/mf_wcomp.c ../mysys/mulalloc.c ../mysys/my_access.c ../mysys/my_alloc.c - ../mysys/my_chsize.c ../mysys/my_compress.c ../mysys/my_create.c - ../mysys/my_delete.c ../mysys/my_div.c ../mysys/my_error.c ../mysys/my_file.c - ../mysys/my_fopen.c ../mysys/my_fstream.c ../mysys/my_gethostbyname.c - ../mysys/my_getopt.c ../mysys/my_getwd.c ../mysys/my_init.c ../mysys/my_lib.c - ../mysys/my_malloc.c ../mysys/my_messnc.c ../mysys/my_net.c ../mysys/my_once.c - ../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c - ../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c - ../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c - ../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c - ../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c - ../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c - ../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c - ../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c - ../strings/strfill.c ../mysys/string.c ../strings/strinstr.c ../strings/strmake.c - ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c - ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c - ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c - ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c - ${YASSL_SOURCES} ${TAOCRYPT_SOURCES} - ) - -ADD_DEPENDENCIES(mysqlclient GenError) -ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc) -LINK_DIRECTORIES(${MYSQL_BINARY_DIR}/mysys ${MYSQL_BINARY_DIR}/zlib) -TARGET_LINK_LIBRARIES(mysql mysqlclient mysys zlib dbug wsock32) - -ADD_EXECUTABLE(mysqltest mysqltest.c) -TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys zlib dbug regex wsock32) +ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) +TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) + +ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ../mysys/my_copy.c) +TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) -TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug zlib wsock32) +TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) -ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c) -TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug zlib wsock32) +ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c) +TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32) ADD_EXECUTABLE(mysqlimport mysqlimport.c) -TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug zlib wsock32) +TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32) ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient dbug zlib wsock32) +TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32) ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) ADD_EXECUTABLE(mysqlshow mysqlshow.c) -TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug zlib wsock32) +TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32) -ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc - ../mysys/my_bit.c ../mysys/my_bitmap.c ../mysys/my_vle.c - ../mysys/base64.c) -TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug zlib wsock32) +ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc + ../mysys/mf_tempdir.c + ../mysys/my_new.cc + ../mysys/my_bit.c + ../mysys/my_bitmap.c + ../mysys/my_vle.c + ../mysys/base64.c) +TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32) ADD_EXECUTABLE(mysqladmin mysqladmin.cc) -TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug zlib wsock32) +TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32) ADD_EXECUTABLE(mysqlslap mysqlslap.c) SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") @@ -153,3 +81,4 @@ IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("mysqladmin" "asInvoker") MYSQL_EMBED_MANIFEST("echo" "asInvoker") ENDIF(EMBED_MANIFESTS) + diff --git a/client/client_priv.h b/client/client_priv.h index 8bc8ef692de..a2f61b9e9ca 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -48,7 +48,7 @@ enum options_client OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, - OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS, + OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS, OPT_SERVER_ARG, OPT_START_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, #ifdef HAVE_NDBCLUSTER_DB @@ -79,6 +79,6 @@ enum options_client OPT_SLAP_DETACH, OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, - OPT_DEBUG_INFO, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, - OPT_MAX_CLIENT_OPTION + OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, + OPT_WRITE_BINLOG, OPT_MAX_CLIENT_OPTION }; diff --git a/client/mysql.cc b/client/mysql.cc index fe057c8b8a4..45b049bc518 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -43,7 +43,7 @@ #include <locale.h> #endif -const char *VER= "14.13"; +const char *VER= "14.14"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -51,6 +51,9 @@ const char *VER= "14.13"; /* Buffer to hold 'version' and 'version_comment' */ #define MAX_SERVER_VERSION_LENGTH 128 +/* Array of options to pass to libemysqld */ +#define MAX_SERVER_ARGS 64 + void* sql_alloc(unsigned size); // Don't use mysqld alloc for these void sql_element_free(void *ptr); #include "sql_string.h" @@ -129,7 +132,7 @@ enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT}; typedef enum enum_info_type INFO_TYPE; static MYSQL mysql; /* The connection */ -static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, +static my_bool ignore_errors=0,wait_flag=0,quick=0, connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, using_opt_local_infile=0, @@ -139,9 +142,11 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, show_warnings= 0, executing_query= 0, interrupted_query= 0; +static my_bool debug_info_flag, debug_check_flag; static my_bool column_types_flag; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; +static uint my_end_arg; static char * opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; static char *current_host,*current_db,*current_user=0,*opt_password=0, @@ -302,7 +307,10 @@ static COMMANDS commands[] = { }; static const char *load_default_groups[]= { "mysql","client",0 }; -static const char *server_default_groups[]= + +static int embedded_server_arg_count= 0; +static char *embedded_server_args[MAX_SERVER_ARGS]; +static const char *embedded_server_groups[]= { "server", "embedded", "mysql_SERVER", 0 }; #ifdef HAVE_READLINE @@ -347,15 +355,6 @@ static sig_handler handle_sigint(int sig); int main(int argc,char *argv[]) { char buff[80]; - char *defaults, *extra_defaults, *group_suffix; - char *emb_argv[4]; - int emb_argc; - - /* Get --defaults-xxx args for mysql_server_init() */ - emb_argc= get_defaults_options(argc, argv, &defaults, &extra_defaults, - &group_suffix)+1; - memcpy((char*) emb_argv, (char*) argv, emb_argc * sizeof(*argv)); - emb_argv[emb_argc]= 0; MY_INIT(argv[0]); DBUG_ENTER("main"); @@ -416,7 +415,8 @@ int main(int argc,char *argv[]) my_end(0); exit(1); } - if (mysql_server_init(emb_argc, emb_argv, (char**) server_default_groups)) + if (mysql_server_init(embedded_server_arg_count, embedded_server_args, + (char**) embedded_server_groups)) { free_defaults(defaults_argv); my_end(0); @@ -539,9 +539,11 @@ sig_handler mysql_end(int sig) my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); + while (embedded_server_arg_count > 1) + my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); mysql_server_end(); free_defaults(defaults_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(status.exit_status); } @@ -611,8 +613,11 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"database", 'D', "Database to use.", (uchar**) ¤t_db, (uchar**) ¤t_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, @@ -761,6 +766,8 @@ static struct my_option my_long_options[] = {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" " uses old (pre-4.1.1) protocol", (uchar**) &opt_secure_auth, (uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", (uchar**) &show_warnings, (uchar**) &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -888,7 +895,29 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); break; - break; + case OPT_SERVER_ARG: +#ifdef EMBEDDED_LIBRARY + /* + When the embedded server is being tested, the client needs to be + able to pass command-line arguments to the embedded server so it can + locate the language files and data directory. + */ + if (!embedded_server_arg_count) + { + embedded_server_arg_count= 1; + embedded_server_args[0]= (char*) ""; + } + if (embedded_server_arg_count == MAX_SERVER_ARGS-1 || + !(embedded_server_args[embedded_server_arg_count++]= + my_strdup(argument, MYF(MY_FAE)))) + { + put_info("Can't use server argument", INFO_ERROR); + return 0; + } +#else /*EMBEDDED_LIBRARY */ + printf("WARNING: --server-arg option not supported in this configuration.\n"); +#endif + break; case 'A': opt_rehash= 0; break; @@ -927,7 +956,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); - info_flag= 1; + debug_info_flag= 1; break; case 's': if (argument == disabled_my_option) @@ -1021,6 +1050,10 @@ static int get_options(int argc, char **argv) } if (tty_password) opt_password= get_tty_password(NullS); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return(0); } @@ -3288,7 +3321,7 @@ sql_real_connect(char *host,char *database,char *user,char *password, } connected=1; #ifndef EMBEDDED_LIBRARY - mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens + mysql.reconnect= debug_info_flag; // We want to know if this happens #else mysql.reconnect= 1; #endif diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 504b4c95a8b..5da0235c913 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -17,6 +17,8 @@ #include <sslopt-vars.h> #include "../scripts/mysql_fix_privilege_tables_sql.c" +#define VER "1.1" + #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif @@ -32,7 +34,8 @@ static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; -static my_bool opt_force, opt_verbose; +static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag; +static uint my_end_arg= 0; static char *opt_user= (char*)"root"; static DYNAMIC_STRING ds_args; @@ -56,6 +59,11 @@ static struct my_option my_long_options[]= NO_ARG, 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibilty", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + (uchar**)¬_used, (uchar**)¬_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'd', "Not used by mysql_upgrade. Only for backward compatibilty", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -66,14 +74,14 @@ static struct my_option my_long_options[]= {"debug", '#', "Output debug log", (uchar* *) & default_dbug_option, (uchar* *) & default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory where character sets are.", 0, - 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", - (uchar**)¬_used, (uchar**)¬_used, 0, GET_BOOL, NO_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.", (uchar**)&opt_force, (uchar**)&opt_force, 0, @@ -138,7 +146,7 @@ static void die(const char *fmt, ...) va_end(args); free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); exit(1); } @@ -200,8 +208,9 @@ get_one_option(int optid, const struct my_option *opt, switch (optid) { case '?': - printf("MySQL utility for upgrading database to MySQL version %s\n", - MYSQL_SERVER_VERSION); + printf("%s Ver %s Distrib %s, for %s (%s)\n", + my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts("MySQL utility for upgrading databases to new MySQL versions\n"); my_print_help(my_long_options); exit(0); break; @@ -209,6 +218,7 @@ get_one_option(int optid, const struct my_option *opt, case '#': DBUG_PUSH(argument ? argument : default_dbug_option); add_option= FALSE; + debug_check_flag= 1; break; case 'p': @@ -732,6 +742,10 @@ int main(int argc, char **argv) if (handle_options(&argc, &argv, my_long_options, get_one_option)) die(NULL); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (tty_password) { @@ -780,7 +794,7 @@ int main(int argc, char **argv) create_mysql_upgrade_info_file(); free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); exit(0); } diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index f6ff44c7d56..ce48ad03d33 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -40,9 +40,10 @@ ulonglong last_values[MAX_MYSQL_VAR]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0, - tty_password= 0, info_flag= 0, opt_nobeep; -static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations, - opt_count_iterations= 0; + tty_password= 0, opt_nobeep; +static my_bool debug_info_flag= 0, debug_check_flag= 0; +static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations; +static uint opt_count_iterations= 0, my_end_arg; static ulong opt_connect_timeout, opt_shutdown_timeout; static char * unix_port=0; #ifdef LATER_HAVE_NDBCLUSTER_DB @@ -134,10 +135,16 @@ static struct my_option my_long_options[] = "Number of iterations to make. This works with -i (--sleep) only.", (uchar**) &nr_iterations, (uchar**) &nr_iterations, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DBUG_OFF {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.", (uchar**) &option_force, (uchar**) &option_force, 0, GET_BOOL, NO_ARG, 0, 0, @@ -315,6 +322,10 @@ int main(int argc,char *argv[]) free_defaults(save_argv); exit(ho_error); } + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (argc == 0) { @@ -413,7 +424,7 @@ int main(int argc,char *argv[]) my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(save_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(error ? 1 : 0); return 0; } diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index edade347783..bd045050484 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -65,11 +65,13 @@ static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; static bool opt_base64_output= 0; static const char* database= 0; -static my_bool force_opt= 0, short_form= 0, remote_opt= 0, info_flag; +static my_bool force_opt= 0, short_form= 0, remote_opt= 0; +static my_bool debug_info_flag, debug_check_flag; static my_bool force_if_open_opt= 1; static ulonglong offset = 0; static const char* host = 0; static int port= 0; +static uint my_end_arg; static const char* sock= 0; static const char* user = 0; static char* pass = 0; @@ -727,8 +729,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_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. " "This way you could avoid an endless loop. You would also like to use it " @@ -860,7 +866,7 @@ static void die(const char* fmt, ...) va_end(args); cleanup(); /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG); + my_end(my_end_arg | MY_DONT_FREE_DBUG); exit(1); } @@ -868,7 +874,7 @@ static void die(const char* fmt, ...) static void print_version() { - printf("%s Ver 3.2 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); NETWARE_SET_SCREEN_MODE(1); } @@ -984,7 +990,10 @@ static int parse_args(int *argc, char*** argv) load_defaults("my",load_default_groups,argc,argv); if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); - + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return 0; } @@ -1078,6 +1087,7 @@ static int check_master_version(MYSQL *mysql_arg, break; case '4': *description_event= new Format_description_log_event(3); + break; case '5': /* The server is soon going to send us its Format_description log @@ -1301,9 +1311,15 @@ static void check_header(IO_CACHE* file, pos= my_b_tell(file); my_b_seek(file, (my_off_t)0); if (my_b_read(file, header, sizeof(header))) + { + delete *description_event; die("Failed reading header; Probably an empty file"); + } if (memcmp(header, BINLOG_MAGIC, sizeof(header))) + { + delete *description_event; die("File is not a binary log file"); + } /* Imagine we are running with --start-position=1000. We still need @@ -1324,9 +1340,12 @@ static void check_header(IO_CACHE* file, if (my_b_read(file, buf, sizeof(buf))) { if (file->error) + { + delete *description_event; die("\ Could not read entry at offset %lu : Error in log format or read error", tmp_pos); + } /* Otherwise this is just EOF : this log currently contains 0-2 events. Maybe it's going to be filled in the next @@ -1362,13 +1381,19 @@ Could not read entry at offset %lu : Error in log format or read error", break; else if (buf[4] == FORMAT_DESCRIPTION_EVENT) /* This is 5.0 */ { + Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(*description_event= (Format_description_log_event*) + if (!(new_description_event= (Format_description_log_event*) Log_event::read_log_event(file, *description_event))) /* EOF can't be hit here normally, so it's a real error */ + { + delete *description_event; die("Could not read a Format_description_log_event event \ at offset %lu ; this could be a log format error or read error", tmp_pos); + } + delete *description_event; + *description_event= new_description_event; DBUG_PRINT("info",("Setting description_event")); } else if (buf[4] == ROTATE_EVENT) @@ -1377,8 +1402,11 @@ at offset %lu ; this could be a log format error or read error", my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(ev= Log_event::read_log_event(file, *description_event))) /* EOF can't be hit here normally, so it's a real error */ + { + delete *description_event; die("Could not read a Rotate_log_event event at offset %lu ;" " this could be a log format error or read error", tmp_pos); + } delete ev; } else @@ -1448,7 +1476,10 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, } if (!glob_description_event || !glob_description_event->is_valid()) + { + delete glob_description_event; die("Invalid Format_description log event; could be out of memory"); + } if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE)) { @@ -1597,7 +1628,7 @@ int main(int argc, char** argv) my_free_open_file_info(); load_processor.destroy(); /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG); + my_end(my_end_arg | MY_DONT_FREE_DBUG); if (file_not_closed_error) { @@ -1617,17 +1648,9 @@ int main(int argc, char** argv) the server */ -#if defined(__WIN__) && !defined(USING_CMAKE) -#include "my_decimal.h" -#include "decimal.c" -#include "my_decimal.cpp" -#include "log_event.cpp" -#include "log_event_old.cpp" -#else #include "my_decimal.h" #include "decimal.c" #include "my_decimal.cc" #include "log_event.cc" #include "log_event_old.cc" -#endif diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 372dfe860df..ee8d5c0d6d3 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -15,7 +15,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.4.5" +#define CHECK_VERSION "2.5.0" #include "client_priv.h" #include <m_ctype.h> @@ -33,10 +33,11 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_compress = 0, opt_databases = 0, opt_fast = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, - tty_password= 0, opt_frm= 0, info_flag= 0, + tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, opt_write_binlog= 1; static uint verbose = 0, opt_mysql_port=0; +static int my_end_arg; static char * opt_mysql_unix_port = 0; static char *opt_password = 0, *current_user = 0, *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME, @@ -96,8 +97,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", (uchar**) &default_charset, (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -305,6 +310,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case OPT_TABLES: @@ -375,6 +381,10 @@ static int get_options(int *argc, char ***argv) } if (tty_password) opt_password = get_tty_password(NullS); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return(0); } /* get_options */ @@ -762,7 +772,7 @@ int main(int argc, char **argv) */ if (get_options(&argc, &argv)) { - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(EX_USAGE); } if (dbConnect(current_host, current_user, opt_password)) @@ -804,6 +814,6 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); return(first_error!=0); } /* main */ diff --git a/client/mysqldump.c b/client/mysqldump.c index cfdde285040..566760d2db3 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.12" +#define DUMP_VERSION "10.13" #include <my_global.h> #include <my_sys.h> @@ -100,9 +100,9 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, opt_events= 0, opt_alltspcs=0, opt_notspcs= 0; +static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*mysql=0; -static my_bool insert_pat_inited= 0, info_flag; static DYNAMIC_STRING insert_pat; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -116,7 +116,8 @@ static char compatible_mode_normal_str[255]; static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 -static uint opt_mysql_port= 0, opt_master_data; +static uint opt_mysql_port= 0, opt_master_data; +static uint my_end_arg; static char * opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; @@ -242,8 +243,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", (uchar**) &default_charset, (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -724,7 +729,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); - info_flag= 1; + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': print_version(); exit(0); @@ -858,6 +863,10 @@ static int get_options(int *argc, char ***argv) *mysql_params->p_max_allowed_packet= opt_max_allowed_packet; *mysql_params->p_net_buffer_length= opt_net_buffer_length; + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (opt_delayed) opt_lock=0; /* Can't have lock with delayed */ @@ -1227,6 +1236,125 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) return mysql_real_query(mysql, query_buffer, query_length); } +/** + Rewrite CREATE TRIGGER statement, enclosing DEFINER clause in + version-specific comment. + + This function parses the CREATE TRIGGER statement and encloses + DEFINER-clause in version-specific comment: + input query: CREATE DEFINER=a@b TRIGGER ... + rewritten query: CREATE * / / *!50017 DEFINER=a@b * / / *!50003 TRIGGER ... + + @note This function will go away when WL#3995 is implemented. + + @param[in] trigger_def_str CREATE TRIGGER statement string. + @param[in] trigger_def_length length of the trigger_def_str. + + @return pointer to the new allocated query string. +*/ + +static char *cover_definer_clause_in_trigger(const char *trigger_def_str, + uint trigger_def_length) +{ + char *query_str= NULL; + char *definer_begin= my_case_str(trigger_def_str, trigger_def_length, + C_STRING_WITH_LEN(" DEFINER")); + char *definer_end; + + if (!definer_begin) + return NULL; + + definer_end= my_case_str(definer_begin, strlen(definer_begin), + C_STRING_WITH_LEN(" TRIGGER")); + + if (definer_end) + { + char *query_str_tail; + + /* + Allocate memory for new query string: original string + from SHOW statement and version-specific comments. + */ + query_str= alloc_query_str(trigger_def_length + 23); + + query_str_tail= strnmov(query_str, + trigger_def_str, + definer_begin - trigger_def_str); + + query_str_tail= strmov(query_str_tail, + "*/ /*!50017"); + + query_str_tail= strnmov(query_str_tail, + definer_begin, + definer_end - definer_begin); + + query_str_tail= strxmov(query_str_tail, + "*/ /*!50003", + definer_end, + NullS); + } + + return query_str; +} + +/** + Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER + clause in version-specific comment. + + This function parses the CREATE FUNCTION | PROCEDURE statement and + encloses DEFINER-clause in version-specific comment: + input query: CREATE DEFINER=a@b FUNCTION ... + rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ... + + @note This function will go away when WL#3995 is implemented. + + @param[in] def_str CREATE FUNCTION|PROCEDURE statement string. + @param[in] def_length length of the def_str. + + @return pointer to the new allocated query string. +*/ + +static char *cover_definer_clause_in_sp(const char *def_str, + uint def_str_length) +{ + char *query_str= NULL; + char *definer_begin= my_case_str(def_str, def_str_length, + C_STRING_WITH_LEN(" DEFINER")); + char *definer_end; + + if (!definer_begin) + return NULL; + + definer_end= my_case_str(definer_begin, strlen(definer_begin), + C_STRING_WITH_LEN(" PROCEDURE")); + + if (!definer_end) + { + definer_end= my_case_str(definer_begin, strlen(definer_begin), + C_STRING_WITH_LEN(" FUNCTION")); + } + + if (definer_end) + { + char *query_str_tail; + + /* + Allocate memory for new query string: original string + from SHOW statement and version-specific comments. + */ + query_str= alloc_query_str(def_str_length + 23); + + query_str_tail= strnmov(query_str, def_str, definer_begin - def_str); + query_str_tail= strmov(query_str_tail, "*/ /*!50020"); + query_str_tail= strnmov(query_str_tail, definer_begin, + definer_end - definer_begin); + query_str_tail= strxmov(query_str_tail, "*/ /*!50003", + definer_end, NullS); + } + + return query_str; +} + /* Open a new .sql file to dump the table or view into @@ -1262,7 +1390,7 @@ static void free_resources() dynstr_free(&insert_pat); if (defaults_argv) free_defaults(defaults_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); } @@ -1701,7 +1829,7 @@ static uint dump_events_for_db(char *db) MYSQL_ROW row, event_list_row; char db_cl_name[MY_CS_NAME_SIZE]; - int db_cl_altered; + int db_cl_altered= FALSE; DBUG_ENTER("dump_events_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); @@ -1766,16 +1894,36 @@ static uint dump_events_for_db(char *db) fprintf(sql_file, "DELIMITER %s\n", delimiter); - if (switch_db_collation(sql_file, db_name_buff, delimiter, db_cl_name, - row[6], &db_cl_altered)) + if (mysql_num_fields(event_res) >= 7) { - DBUG_RETURN(1); - } + if (switch_db_collation(sql_file, db_name_buff, delimiter, + db_cl_name, row[6], &db_cl_altered)) + { + DBUG_RETURN(1); + } - switch_cs_variables(sql_file, delimiter, - row[4], /* character_set_client */ - row[4], /* character_set_results */ - row[5]); /* collation_connection */ + switch_cs_variables(sql_file, delimiter, + row[4], /* character_set_client */ + row[4], /* character_set_results */ + row[5]); /* collation_connection */ + } + else + { + /* + mysqldump is being run against the server, that does not + provide character set information in SHOW CREATE + statements. + + NOTE: the dump may be incorrect, since character set + information is required in order to restore event properly. + */ + + fprintf(sql_file, + "--\n" + "-- WARNING: old server version. " + "The following dump may be incomplete.\n" + "--\n"); + } switch_sql_mode(sql_file, delimiter, row[1]); @@ -1788,13 +1936,17 @@ static uint dump_events_for_db(char *db) restore_time_zone(sql_file, delimiter); restore_sql_mode(sql_file, delimiter); - restore_cs_variables(sql_file, delimiter); - if (db_cl_altered) + if (mysql_num_fields(event_res) >= 7) { - if (restore_db_collation(sql_file, db_name_buff, delimiter, - db_cl_name)) - DBUG_RETURN(1); + restore_cs_variables(sql_file, delimiter); + + if (db_cl_altered) + { + if (restore_db_collation(sql_file, db_name_buff, delimiter, + db_cl_name)) + DBUG_RETURN(1); + } } } } /* end of event printing */ @@ -1862,7 +2014,7 @@ static uint dump_routines_for_db(char *db) MYSQL_ROW row, routine_list_row; char db_cl_name[MY_CS_NAME_SIZE]; - int db_cl_altered; + int db_cl_altered= FALSE; DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); @@ -1929,74 +2081,45 @@ static uint dump_routines_for_db(char *db) } else if (strlen(row[2])) { - char *query_str= NULL; - char *definer_begin; - + char *query_str; if (opt_drop) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n", routine_type[i], routine_name); - /* - Cover DEFINER-clause in version-specific comments. - - TODO: this is definitely a BAD IDEA to parse SHOW CREATE output. - However, we can not use INFORMATION_SCHEMA instead: - 1. INFORMATION_SCHEMA provides data in UTF8, but here we - need data in the original character set; - 2. INFORMATION_SCHEMA does not provide information about - routine parameters now. - */ - - definer_begin= my_case_str(row[2], strlen(row[2]), - C_STRING_WITH_LEN(" DEFINER")); + query_str= cover_definer_clause_in_sp(row[2], strlen(row[2])); - if (definer_begin) + if (mysql_num_fields(routine_res) >= 6) { - char *definer_end= my_case_str(definer_begin, - strlen(definer_begin), - C_STRING_WITH_LEN(" PROCEDURE")); - - if (!definer_end) + if (switch_db_collation(sql_file, db_name_buff, ";", + db_cl_name, row[5], &db_cl_altered)) { - definer_end= my_case_str(definer_begin, strlen(definer_begin), - C_STRING_WITH_LEN(" FUNCTION")); + DBUG_RETURN(1); } - if (definer_end) - { - char *query_str_tail; - - /* - Allocate memory for new query string: original string - from SHOW statement and version-specific comments. - */ - query_str= alloc_query_str(strlen(row[2]) + 23); - - query_str_tail= strnmov(query_str, row[2], - definer_begin - row[2]); - query_str_tail= strmov(query_str_tail, "*/ /*!50020"); - query_str_tail= strnmov(query_str_tail, definer_begin, - definer_end - definer_begin); - query_str_tail= strxmov(query_str_tail, "*/ /*!50003", - definer_end, NullS); - } + switch_cs_variables(sql_file, ";", + row[3], /* character_set_client */ + row[3], /* character_set_results */ + row[4]); /* collation_connection */ } - - /* - we need to change sql_mode only for the CREATE - PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name - */ - - if (switch_db_collation(sql_file, db_name_buff, ";", - db_cl_name, row[5], &db_cl_altered)) + else { - DBUG_RETURN(1); + /* + mysqldump is being run against the server, that does not + provide character set information in SHOW CREATE + statements. + + NOTE: the dump may be incorrect, since character set + information is required in order to restore stored + procedure/function properly. + */ + + fprintf(sql_file, + "--\n" + "-- WARNING: old server version. " + "The following dump may be incomplete.\n" + "--\n"); } - switch_cs_variables(sql_file, ";", - row[3], /* character_set_client */ - row[3], /* character_set_results */ - row[4]); /* collation_connection */ switch_sql_mode(sql_file, ";", row[1]); @@ -2007,12 +2130,16 @@ static uint dump_routines_for_db(char *db) (const char *) (query_str != NULL ? query_str : row[2])); restore_sql_mode(sql_file, ";"); - restore_cs_variables(sql_file, ";"); - if (db_cl_altered) + if (mysql_num_fields(routine_res) >= 6) { - if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name)) - DBUG_RETURN(1); + restore_cs_variables(sql_file, ";"); + + if (db_cl_altered) + { + if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name)) + DBUG_RETURN(1); + } } my_free(query_str, MYF(MY_ALLOW_ZERO_PTR)); @@ -2061,7 +2188,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, int len; MYSQL_RES *result; MYSQL_ROW row; - DBUG_ENTER("get_table_structure"); DBUG_PRINT("enter", ("db: %s table: %s", db, table)); @@ -2481,6 +2607,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, fprintf(sql_file, " (%s)",row[7]); /* Sub key */ check_io(sql_file); } + mysql_free_result(result); if (!opt_xml) { if (keynr) @@ -2551,153 +2678,211 @@ continue_xml: DBUG_RETURN((uint) num_fields); } /* get_table_structure */ +static void dump_trigger_old(MYSQL_RES *show_triggers_rs, + MYSQL_ROW *show_trigger_row, + const char *table_name) +{ + FILE *sql_file= md_result_file; -/* + char quoted_table_name_buf[NAME_LEN * 2 + 3]; + char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1); + + char name_buff[NAME_LEN * 4 + 3]; + + DBUG_ENTER("dump_trigger_old"); + + fprintf(sql_file, + "--\n" + "-- WARNING: old server version. " + "The following dump may be incomplete.\n" + "--\n"); + + if (opt_compact) + fprintf(sql_file, "/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n"); + + fprintf(sql_file, + "DELIMITER ;;\n" + "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n" + "/*!50003 CREATE */ ", + (*show_trigger_row)[6]); + + if (mysql_num_fields(show_triggers_rs) > 7) + { + /* + mysqldump can be run against the server, that does not support + definer in triggers (there is no DEFINER column in SHOW TRIGGERS + output). So, we should check if we have this column before + accessing it. + */ + + size_t user_name_len; + char user_name_str[USERNAME_LENGTH + 1]; + char quoted_user_name_str[USERNAME_LENGTH * 2 + 3]; + size_t host_name_len; + char host_name_str[HOSTNAME_LENGTH + 1]; + char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3]; + + parse_user((*show_trigger_row)[7], + strlen((*show_trigger_row)[7]), + user_name_str, &user_name_len, + host_name_str, &host_name_len); + + fprintf(sql_file, + "/*!50017 DEFINER=%s@%s */ ", + quote_name(user_name_str, quoted_user_name_str, FALSE), + quote_name(host_name_str, quoted_host_name_str, FALSE)); + } + + fprintf(sql_file, + "/*!50003 TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n" + "DELIMITER ;\n", + quote_name((*show_trigger_row)[0], name_buff, 0), /* Trigger */ + (*show_trigger_row)[4], /* Timing */ + (*show_trigger_row)[1], /* Event */ + quoted_table_name, + (strchr(" \t\n\r", *((*show_trigger_row)[3]))) ? "" : " ", + (*show_trigger_row)[3] /* Statement */); + + if (opt_compact) + fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n"); + + DBUG_VOID_RETURN; +} + +static int dump_trigger(MYSQL_RES *show_create_trigger_rs, + const char *db_name, + const char *db_cl_name) +{ + FILE *sql_file= md_result_file; + MYSQL_ROW row; + int db_cl_altered= FALSE; - dump_triggers_for_table + DBUG_ENTER("dump_trigger"); - Dumps the triggers given a table/db name. This should be called after - the tables have been dumped in case a trigger depends on the existence - of a table + while ((row= mysql_fetch_row(show_create_trigger_rs))) + { + char *query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2])); + + + if (switch_db_collation(sql_file, db_name, ";", + db_cl_name, row[5], &db_cl_altered)) + DBUG_RETURN(TRUE); + + switch_cs_variables(sql_file, ";", + row[3], /* character_set_client */ + row[3], /* character_set_results */ + row[4]); /* collation_connection */ + + switch_sql_mode(sql_file, ";", row[1]); + + fprintf(sql_file, + "DELIMITER ;;\n" + "/*!50003 %s */;;\n" + "DELIMITER ;\n", + (const char *) (query_str != NULL ? query_str : row[2])); + restore_sql_mode(sql_file, ";"); + restore_cs_variables(sql_file, ";"); + + if (db_cl_altered) + { + if (restore_db_collation(sql_file, db_name, ";", db_cl_name)) + DBUG_RETURN(TRUE); + } + + my_free(query_str, MYF(MY_ALLOW_ZERO_PTR)); + } + + DBUG_RETURN(FALSE); +} + +/** + Dump the triggers for a given table. + + This should be called after the tables have been dumped in case a trigger + depends on the existence of a table. + + @param[in] table_name + @param[in] db_name + + @return Error status. + @retval TRUE error has occurred. + @retval FALSE operation succeed. */ -static void dump_triggers_for_table(char *table, char *db_name) +static int dump_triggers_for_table(char *table_name, char *db_name) { - char *result_table; - char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; + char name_buff[NAME_LEN*4+3]; char query_buff[QUERY_LENGTH]; - uint old_opt_compatible_mode=opt_compatible_mode; - FILE *sql_file= md_result_file; - MYSQL_RES *result; + uint old_opt_compatible_mode= opt_compatible_mode; + MYSQL_RES *show_triggers_rs; MYSQL_ROW row; char db_cl_name[MY_CS_NAME_SIZE]; - int db_cl_altered; DBUG_ENTER("dump_triggers_for_table"); - DBUG_PRINT("enter", ("db: %s, table: %s", db_name, table)); + DBUG_PRINT("enter", ("db: %s, table_name: %s", db_name, table_name)); /* Do not use ANSI_QUOTES on triggers in dump */ opt_compatible_mode&= ~MASK_ANSI_QUOTES; - result_table= quote_name(table, table_buff, 1); - - my_snprintf(query_buff, sizeof(query_buff), - "SHOW TRIGGERS LIKE %s", - quote_for_like(table, name_buff)); - - if (mysql_query_with_error_report(mysql, &result, query_buff)) - { - if (path) - my_fclose(sql_file, MYF(MY_WME)); - DBUG_VOID_RETURN; - } /* Get database collation. */ + if (switch_character_set_results(mysql, "binary")) + DBUG_RETURN(TRUE); + if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name))) - DBUG_VOID_RETURN; + DBUG_RETURN(TRUE); - if (switch_character_set_results(mysql, "binary")) - DBUG_VOID_RETURN; + /* Get list of triggers. */ + + my_snprintf(query_buff, sizeof(query_buff), + "SHOW TRIGGERS LIKE %s", + quote_for_like(table_name, name_buff)); + + if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff)) + DBUG_RETURN(TRUE); /* Dump triggers. */ - while ((row= mysql_fetch_row(result))) + while ((row= mysql_fetch_row(show_triggers_rs))) { - MYSQL_RES *res2; my_snprintf(query_buff, sizeof (query_buff), "SHOW CREATE TRIGGER %s", quote_name(row[0], name_buff, TRUE)); - if (mysql_query_with_error_report(mysql, &res2, query_buff)) + if (mysql_query(mysql, query_buff)) { - if (path) - my_fclose(sql_file, MYF(MY_WME)); - maybe_exit(EX_MYSQLERR); - DBUG_VOID_RETURN; - } - - while ((row= mysql_fetch_row(res2))) - { - char *query_str= NULL; - char *definer_begin; - /* - Cover DEFINER-clause in version-specific comments. - - TODO: this is definitely a BAD IDEA to parse SHOW CREATE output. - However, we can not use INFORMATION_SCHEMA instead: - 1. INFORMATION_SCHEMA provides data in UTF8, but here we - need data in the original character set; - 2. INFORMATION_SCHEMA does not provide information about - routine parameters now. - */ - - definer_begin= my_case_str(row[2], strlen(row[2]), - C_STRING_WITH_LEN(" DEFINER")); + mysqldump is being run against old server, that does not support + SHOW CREATE TRIGGER statement. We should use SHOW TRIGGERS output. - if (definer_begin) - { - char *definer_end= my_case_str(definer_begin, strlen(definer_begin), - C_STRING_WITH_LEN(" TRIGGER")); - - if (definer_end) - { - char *query_str_tail; - - /* - Allocate memory for new query string: original string - from SHOW statement and version-specific comments. - */ - query_str= alloc_query_str(strlen(row[2]) + 23); - - query_str_tail= strnmov(query_str, row[2], - definer_begin - row[2]); - query_str_tail= strmov(query_str_tail, "*/ /*!50017"); - query_str_tail= strnmov(query_str_tail, definer_begin, - definer_end - definer_begin); - query_str_tail= strxmov(query_str_tail, "*/ /*!50003", - definer_end, NullS); - } - } - - if (switch_db_collation(sql_file, db_name, ";", - db_cl_name, row[5], &db_cl_altered)) - DBUG_VOID_RETURN; - - switch_cs_variables(sql_file, ";", - row[3], /* character_set_client */ - row[3], /* character_set_results */ - row[4]); /* collation_connection */ - - switch_sql_mode(sql_file, ";", row[1]); - - fprintf(sql_file, - "DELIMITER ;;\n" - "/*!50003 %s */;;\n" - "DELIMITER ;\n", - (const char *) (query_str != NULL ? query_str : row[2])); + NOTE: the dump may be incorrect, as old SHOW TRIGGERS does not + provide all the necessary information to restore trigger properly. + */ - restore_sql_mode(sql_file, ";"); - restore_cs_variables(sql_file, ";"); + dump_trigger_old(show_triggers_rs, &row, table_name); + } + else + { + MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql); - if (db_cl_altered) + if (!show_create_trigger_rs || + dump_trigger(show_create_trigger_rs, db_name, db_cl_name)) { - if (restore_db_collation(sql_file, db_name, ";", db_cl_name)) - DBUG_VOID_RETURN; + DBUG_RETURN(TRUE); } - my_free(query_str, MYF(MY_ALLOW_ZERO_PTR)); + mysql_free_result(show_create_trigger_rs); } - mysql_free_result(res2); + } - mysql_free_result(result); + mysql_free_result(show_triggers_rs); if (switch_character_set_results(mysql, default_charset)) - DBUG_VOID_RETURN; + DBUG_RETURN(TRUE); /* make sure to set back opt_compatible mode to @@ -2705,7 +2890,7 @@ static void dump_triggers_for_table(char *table, char *db_name) */ opt_compatible_mode=old_opt_compatible_mode; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } static void add_load_option(DYNAMIC_STRING *str, const char *option, @@ -2822,7 +3007,7 @@ static void dump_table(char *table, char *db) /* The "table" could be a view. If so, we don't do anything here. */ - if (strcmp (table_type, "VIEW") == 0) + if (strcmp(table_type, "VIEW") == 0) DBUG_VOID_RETURN; /* Check --no-data flag */ @@ -2912,6 +3097,7 @@ static void dump_table(char *table, char *db) if (mysql_real_query(mysql, query_string.str, query_string.length)) { DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); + dynstr_free(&query_string); DBUG_VOID_RETURN; } } @@ -3266,8 +3452,8 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } mysql_free_result(res); - dynstr_free(&query_string); } + dynstr_free(&query_string); DBUG_VOID_RETURN; err: @@ -3388,6 +3574,7 @@ static int dump_tablespaces(char* ts_where) char extra_format[]= "UNDO_BUFFER_SIZE="; char *ubs; char *endsemi; + DBUG_ENTER("dump_tablespaces"); init_dynamic_string_checked(&sqlbuf, "SELECT LOGFILE_GROUP_NAME," @@ -3419,6 +3606,7 @@ static int dump_tablespaces(char* ts_where) if (mysql_query(mysql, sqlbuf.str) || !(tableres = mysql_store_result(mysql))) { + dynstr_free(&sqlbuf); if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR || mysql_errno(mysql) == ER_BAD_DB_ERROR || mysql_errno(mysql) == ER_UNKNOWN_TABLE) @@ -3427,12 +3615,12 @@ static int dump_tablespaces(char* ts_where) "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES" " table on this server\n--\n"); check_io(md_result_file); - return 0; + DBUG_RETURN(0); } - my_printf_error(0, "Error: Couldn't dump tablespaces %s", + my_printf_error(0, "Error: '%s' when trying to dump tablespaces", MYF(0), mysql_error(mysql)); - return 1; + DBUG_RETURN(1); } buf[0]= 0; @@ -3484,6 +3672,7 @@ static int dump_tablespaces(char* ts_where) } } dynstr_free(&sqlbuf); + mysql_free_result(tableres); init_dynamic_string_checked(&sqlbuf, "SELECT DISTINCT TABLESPACE_NAME," " FILE_NAME," @@ -3501,7 +3690,10 @@ static int dump_tablespaces(char* ts_where) dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME"); if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str)) - return 1; + { + dynstr_free(&sqlbuf); + DBUG_RETURN(1); + } buf[0]= 0; while ((row= mysql_fetch_row(tableres))) @@ -3547,8 +3739,9 @@ static int dump_tablespaces(char* ts_where) } } + mysql_free_result(tableres); dynstr_free(&sqlbuf); - return 0; + DBUG_RETURN(0); } static int dump_all_databases() @@ -3635,8 +3828,11 @@ RETURN VALUES 0 Success. 1 Failure. */ + int init_dumping_tables(char *qdatabase) { + DBUG_ENTER("init_dumping_tables"); + if (!opt_create_db) { char qbuf[256]; @@ -3669,10 +3865,10 @@ int init_dumping_tables(char *qdatabase) { fprintf(md_result_file,"\n%s;\n",row[1]); } + mysql_free_result(dbinfo); } } - - return 0; + DBUG_RETURN(0); } /* init_dumping_tables */ @@ -3717,7 +3913,7 @@ static int init_dumping(char *database, int init_func(char*)) /* Return 1 if we should copy the table */ -my_bool include_table(uchar* hash_key, uint len) +my_bool include_table(const char* hash_key, uint len) { return !hash_search(&ignore_table, (uchar*) hash_key, len); } @@ -3775,7 +3971,14 @@ static int dump_all_tables_in_db(char *database) order_by= 0; if (opt_dump_triggers && ! opt_xml && mysql_get_server_version(mysql) >= 50009) - dump_triggers_for_table(table, database); + { + if (dump_triggers_for_table(table, database)) + { + if (path) + my_fclose(md_result_file, MYF(MY_WME)); + maybe_exit(EX_MYSQLERR); + } + } } } if (opt_events && !opt_xml && @@ -3955,8 +4158,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } else { - maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); - /* We shall countinue here, if --force was given */ + if (!ignore_errors) + { + dynstr_free(&lock_tables_query); + free_root(&root, MYF(0)); + } + maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); + /* We shall countinue here, if --force was given */ } } end= pos; @@ -3965,14 +4173,25 @@ static int dump_selected_tables(char *db, char **table_names, int tables) { if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) + { + if (!ignore_errors) + { + dynstr_free(&lock_tables_query); + free_root(&root, MYF(0)); + } DB_error(mysql, "when doing LOCK TABLES"); /* We shall countinue here, if --force was given */ + } } dynstr_free(&lock_tables_query); if (flush_logs) { if (mysql_refresh(mysql, REFRESH_LOG)) + { + if (!ignore_errors) + free_root(&root, MYF(0)); DB_error(mysql, "when doing refresh"); + } /* We shall countinue here, if --force was given */ } if (opt_xml) @@ -3985,7 +4204,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) dump_table(*pos, db); if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009) - dump_triggers_for_table(*pos, db); + { + if (dump_triggers_for_table(*pos, db)) + { + if (path) + my_fclose(md_result_file, MYF(MY_WME)); + maybe_exit(EX_MYSQLERR); + } + } } /* Dump each selected view */ @@ -4288,7 +4514,8 @@ char check_if_ignore_table(const char *table_name, char *table_type) If these two types, we do want to skip dumping the table */ if (!opt_no_data && - (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM"))) + (!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") || + !strcmp(table_type,"MRG_ISAM"))) result= IGNORE_DATA; } mysql_free_result(res); @@ -4535,6 +4762,9 @@ static my_bool get_view_structure(char *table, char* db) if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { + if (table_res) + mysql_free_result(table_res); + dynstr_free(&ds_view); DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view."); DBUG_RETURN(1); } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 396063731cf..afd9454d6be 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -24,7 +24,7 @@ ** * * ** ************************* */ -#define IMPORT_VERSION "3.6" +#define IMPORT_VERSION "3.7" #include "client_priv.h" #include "mysql_version.h" @@ -49,8 +49,8 @@ static char *add_load_option(char *ptr,const char *object, static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0, replace=0,silent=0,ignore=0,opt_compress=0, opt_low_priority= 0, tty_password= 0; -static my_bool info_flag= 0; -static uint opt_use_threads=0, opt_local_file=0; +static my_bool debug_info_flag= 0, debug_check_flag= 0; +static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0; static char *opt_password=0, *current_user=0, *current_host=0, *current_db=0, *fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, @@ -87,8 +87,12 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delete", 'd', "First delete all rows from table.", (uchar**) &opt_delete, (uchar**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"fields-terminated-by", OPT_FTB, @@ -236,6 +240,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': print_version(); exit(0); @@ -254,6 +259,10 @@ static int get_options(int *argc, char ***argv) if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (enclosed && opt_enclosed) { @@ -659,6 +668,6 @@ int main(int argc, char **argv) my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(argv_to_free); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); return(exitcode); } diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 649658d6223..a7f6cadf450 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -15,7 +15,7 @@ /* Show databases, tables or columns */ -#define SHOW_VERSION "9.6" +#define SHOW_VERSION "9.10" #include "client_priv.h" #include <my_sys.h> @@ -28,7 +28,9 @@ static char * host=0, *opt_password=0, *user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0; -static my_bool tty_password= 0, opt_table_type= 0, info_flag= 0; +static my_bool tty_password= 0, opt_table_type= 0; +static my_bool debug_info_flag= 0, debug_check_flag= 0; +static uint my_end_arg= 0; static uint opt_verbose=0; static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; @@ -150,7 +152,7 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(error ? 1 : 0); return 0; /* No compiler warnings */ } @@ -176,8 +178,12 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_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}, {"host", 'h', "Connect to host.", (uchar**) &host, (uchar**) &host, 0, GET_STR, @@ -293,6 +299,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': @@ -326,6 +333,10 @@ get_options(int *argc,char ***argv) */ opt_verbose= 2; } + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return; } diff --git a/client/mysqlslap.c b/client/mysqlslap.c index aa15141bfdc..a550dcae260 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -69,7 +69,7 @@ TODO: */ -#define SHOW_VERSION "0.9" +#define SLAP_VERSION "1.0" #define HUGE_STRING_LENGTH 8196 #define RAND_STRING_SIZE 126 @@ -131,10 +131,8 @@ const char *delimiter= "\n"; const char *create_schema_string= "mysqlslap"; -static my_bool opt_preserve; - +static my_bool opt_preserve= 0, debug_info_flag= 0, debug_check_flag= 0; static my_bool opt_only_print= FALSE; - static my_bool opt_compress= FALSE, tty_password= FALSE, opt_silent= FALSE, auto_generate_sql_autoincrement= FALSE, @@ -149,13 +147,14 @@ static uint commit_rate; static uint detach_rate; const char *num_int_cols_opt; const char *num_char_cols_opt; + /* Yes, we do set defaults here */ static unsigned int num_int_cols= 1; static unsigned int num_char_cols= 1; static unsigned int num_int_cols_index= 0; static unsigned int num_char_cols_index= 0; - static unsigned int iterations; +static uint my_end_arg= 0; static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; static ulonglong actual_queries= 0; static ulonglong auto_actual_queries; @@ -410,7 +409,7 @@ int main(int argc, char **argv) my_free(shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(defaults_argv); - my_end(0); + my_end(my_end_arg); return 0; } @@ -569,6 +568,11 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", 'F', "Delimiter to use in SQL statements supplied in file or command line.", (uchar**) &delimiter, (uchar**) &delimiter, 0, GET_STR, REQUIRED_ARG, @@ -672,7 +676,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION, + printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); } @@ -731,6 +735,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': @@ -1126,6 +1131,10 @@ get_options(int *argc,char ***argv) DBUG_ENTER("get_options"); if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (!user) user= (char *)"root"; diff --git a/client/mysqltest.c b/client/mysqltest.c index e5b9a2eaf12..7ba57f7515c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -31,7 +31,7 @@ Holyfoot */ -#define MTEST_VERSION "3.2" +#define MTEST_VERSION "3.3" #include "client_priv.h" #include <mysql_version.h> @@ -80,6 +80,7 @@ const char *opt_include= 0, *opt_charsets_dir; static int opt_port= 0; static int opt_max_connect_retries; static my_bool opt_compress= 0, silent= 0, verbose= 0; +static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; static my_bool opt_mark_progress= 0; static my_bool ps_protocol= 0, ps_protocol_enabled= 0; @@ -100,6 +101,7 @@ static const char *load_default_groups[]= { "mysqltest", "client", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static uint start_lineno= 0; /* Start line of current command */ +static uint my_end_arg= 0; static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -807,12 +809,10 @@ void free_used_memory() static void cleanup_and_exit(int exit_code) { free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); - if (!silent) - { - switch (exit_code) - { + if (!silent) { + switch (exit_code) { case 1: printf("not ok\n"); break; @@ -1084,8 +1084,7 @@ void check_result(DYNAMIC_STRING* ds) DBUG_ENTER("check_result"); DBUG_ASSERT(result_file_name); - switch (dyn_string_cmp(ds, result_file_name)) - { + switch (dyn_string_cmp(ds, result_file_name)) { case RESULT_OK: break; /* ok */ case RESULT_LENGTH_MISMATCH: @@ -1929,7 +1928,10 @@ void do_exec(struct st_command *command) command->first_argument, ds_cmd.str)); if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error) + { + dynstr_free(&ds_cmd); die("popen(\"%s\", \"r\") failed", command->first_argument); + } while (fgets(buf, sizeof(buf), res_file)) { @@ -1953,6 +1955,7 @@ void do_exec(struct st_command *command) { log_msg("exec of '%s failed, error: %d, status: %d, errno: %d", ds_cmd.str, error, status, errno); + dynstr_free(&ds_cmd); die("command \"%s\" failed", command->first_argument); } @@ -1971,8 +1974,11 @@ void do_exec(struct st_command *command) } } if (!ok) + { + dynstr_free(&ds_cmd); die("command \"%s\" failed with wrong error: %d", command->first_argument, status); + } } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) @@ -1980,6 +1986,7 @@ void do_exec(struct st_command *command) /* Error code we wanted was != 0, i.e. not an expected success */ log_msg("exec of '%s failed, error: %d, errno: %d", ds_cmd.str, error, errno); + dynstr_free(&ds_cmd); die("command \"%s\" succeeded - should have failed with errno %d...", command->first_argument, command->expected_errors.err[0].code.errnum); } @@ -4482,6 +4489,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (uchar**) &opt_host, (uchar**) &opt_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"include", 'i', "Include SQL before each test case.", (uchar**) &opt_include, @@ -4625,6 +4638,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case '#': #ifndef DBUG_OFF DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace"); + debug_check_flag= 1; #endif break; case 'r': @@ -4724,6 +4738,10 @@ int parse_args(int argc, char **argv) opt_db= *argv; if (tty_password) opt_pass= get_tty_password(NullS); /* purify tested */ + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return 0; } @@ -5377,11 +5395,8 @@ end: ds - dynamic string which is used for output buffer NOTE - If there is an unexpected error this function will abort mysqltest - immediately. - - RETURN VALUE - error - function will not return + If there is an unexpected error this function will abort mysqltest + immediately. */ void handle_error(struct st_command *command, diff --git a/configure.in b/configure.in index eb8e7b831db..7b86917b9fa 100644 --- a/configure.in +++ b/configure.in @@ -10,13 +10,13 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.21-beta) +AM_INIT_AUTOMAKE(mysql, 5.1.22-beta) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 # See the libtool docs for information on how to do shared lib versions. -SHARED_LIB_MAJOR_VERSION=15 +SHARED_LIB_MAJOR_VERSION=16 SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 NDB_SHARED_LIB_MAJOR_VERSION=3 NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 @@ -1922,8 +1922,9 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ - getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \ - localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \ + getpwuid getrlimit getrusage getwd index initgroups isnan \ + localtime_r gethrtime gmtime_r \ + locking longjmp lrand48 madvise mallinfo memcpy memmove \ mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \ pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \ diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt index 375fd19fb40..8b27f79dcf4 100644..100755 --- a/dbug/CMakeLists.txt +++ b/dbug/CMakeLists.txt @@ -13,8 +13,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -D__WIN32__") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/dbug) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) -ADD_LIBRARY(dbug dbug.c factorial.c sanity.c) +SET(DBUG_SOURCES dbug.c factorial.c sanity.c) + +IF(NOT SOURCE_SUBLIBS) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + ADD_LIBRARY(dbug ${DBUG_SOURCES}) +ENDIF(NOT SOURCE_SUBLIBS) diff --git a/dbug/dbug.c b/dbug/dbug.c index 83c9ea37de1..9d638c299d3 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1184,7 +1184,7 @@ void _db_dump_(uint _line_, const char *keyword, fprintf(cs->stack->out_file, "%s: ", cs->func); } sprintf(dbuff,"%s: Memory: 0x%lx Bytes: (%ld)\n", - keyword,(ulong) memory, length); + keyword, (ulong) memory, (long) length); (void) fputs(dbuff,cs->stack->out_file); pos=0; @@ -1449,6 +1449,7 @@ static void FreeState(CODE_STATE *cs, struct settings *state, int free_state) FreeList(state->p_functions); if (!is_shared(state, out_file)) DBUGCloseFile(cs, state->out_file); + (void) fflush(cs->stack->out_file); if (state->prof_file) DBUGCloseFile(cs, state->prof_file); if (free_state) @@ -1882,7 +1883,6 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) { (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); perror(""); - dbug_flush(0); (void) Delay(cs->stack->delay); } else @@ -1892,7 +1892,6 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) { (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); perror(""); - dbug_flush(0); } else { @@ -1931,7 +1930,7 @@ static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) pthread_mutex_lock(&THR_LOCK_dbug); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); perror(""); - dbug_flush(0); + dbug_flush(cs); } } diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 1722c9da5f2..42561a97888 100644..100755 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -20,7 +20,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) ADD_EXECUTABLE(comp_err comp_err.c) -TARGET_LINK_LIBRARIES(comp_err dbug mysys strings zlib wsock32) +TARGET_LINK_LIBRARIES(comp_err debug dbug mysys strings zlib wsock32) GET_TARGET_PROPERTY(COMP_ERR_EXE comp_err LOCATION) @@ -39,13 +39,13 @@ ADD_CUSTOM_TARGET(GenError DEPENDS ${PROJECT_SOURCE_DIR}/include/mysqld_error.h) ADD_EXECUTABLE(my_print_defaults my_print_defaults.c) -TARGET_LINK_LIBRARIES(my_print_defaults strings mysys dbug taocrypt wsock32) +TARGET_LINK_LIBRARIES(my_print_defaults strings mysys debug dbug taocrypt wsock32) ADD_EXECUTABLE(perror perror.c) -TARGET_LINK_LIBRARIES(perror strings mysys dbug wsock32) +TARGET_LINK_LIBRARIES(perror strings mysys debug dbug wsock32) ADD_EXECUTABLE(replace replace.c) -TARGET_LINK_LIBRARIES(replace strings mysys dbug wsock32) +TARGET_LINK_LIBRARIES(replace strings mysys debug dbug wsock32) IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("myTest" "asInvoker") diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt index 5cc97f22a36..26e682cbb0c 100644..100755 --- a/extra/yassl/CMakeLists.txt +++ b/extra/yassl/CMakeLists.txt @@ -13,9 +13,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -ADD_DEFINITIONS("-DWIN32 -D_LIB -DYASSL_PREFIX") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include + ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL) -INCLUDE_DIRECTORIES(include taocrypt/include taocrypt/mySTL) -ADD_LIBRARY(yassl src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp +ADD_DEFINITIONS("-D_LIB -DYASSL_PREFIX") + +SET(YASSL_SOURCES src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp src/log.cpp src/socket_wrapper.cpp src/ssl.cpp src/timer.cpp src/yassl_error.cpp src/yassl_imp.cpp src/yassl_int.cpp) +IF(NOT SOURCE_SUBLIBS) + ADD_LIBRARY(yassl ${YASSL_SOURCES}) +ENDIF(NOT SOURCE_SUBLIBS) diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt index baa8f97dff6..e91fa021de5 100644..100755 --- a/extra/yassl/taocrypt/CMakeLists.txt +++ b/extra/yassl/taocrypt/CMakeLists.txt @@ -13,9 +13,10 @@ # 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(mySTL include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL + ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include) -ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp +SET(TAOCRYPT_SOURCES src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp src/md4.cpp src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp include/aes.hpp include/algebra.hpp include/arc4.hpp include/asn.hpp include/block.hpp @@ -23,3 +24,6 @@ ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp include/error.hpp include/file.hpp include/hash.hpp include/hmac.hpp include/integer.hpp include/md2.hpp include/md5.hpp include/misc.hpp include/modarith.hpp include/modes.hpp include/random.hpp include/ripemd.hpp include/rsa.hpp include/sha.hpp) +IF(NOT SOURCE_SUBLIBS) + ADD_LIBRARY(taocrypt ${TAOCRYPT_SOURCES}) +ENDIF(NOT SOURCE_SUBLIBS) diff --git a/include/heap.h b/include/heap.h index d309fb4f162..4a1c7d419ed 100644 --- a/include/heap.h +++ b/include/heap.h @@ -189,11 +189,14 @@ typedef struct st_heap_create_info ulonglong max_table_size; ulonglong auto_increment; my_bool with_auto_increment; + my_bool internal_table; } HP_CREATE_INFO; /* Prototypes for heap-functions */ extern HP_INFO *heap_open(const char *name, int mode); +extern HP_INFO *heap_open_from_share(HP_SHARE *share, int mode); +extern HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode); extern int heap_close(HP_INFO *info); extern int heap_write(HP_INFO *info,const uchar *buff); extern int heap_update(HP_INFO *info,const uchar *old,const uchar *newdata); @@ -204,7 +207,7 @@ extern int heap_delete(HP_INFO *info,const uchar *buff); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info); + HP_CREATE_INFO *create_info, HP_SHARE **share); extern int heap_delete_table(const char *name); extern void heap_drop_table(HP_INFO *info); extern int heap_extra(HP_INFO *info,enum ha_extra_function function); diff --git a/include/keycache.h b/include/keycache.h index 7f4ce86cea0..a6005bae878 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -47,7 +47,7 @@ typedef struct st_key_cache my_bool in_resize; /* true during resize operation */ my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ - ulong key_cache_mem_size; /* specified size of the cache memory */ + size_t key_cache_mem_size; /* specified size of the cache memory */ uint key_cache_block_size; /* size of the page buffer of a cache block */ ulong min_warm_blocks; /* min number of warm blocks; */ ulong age_threshold; /* age threshold for hot blocks */ @@ -107,10 +107,10 @@ typedef struct st_key_cache extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache; extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold); extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold); extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, uint age_threshold); diff --git a/include/my_base.h b/include/my_base.h index 04127b81b78..339554979a8 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -48,6 +48,8 @@ #define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */ #define HA_OPEN_FROM_SQL_LAYER 64 #define HA_OPEN_MMAP 128 /* open memory mapped */ +/* Internal temp table, used for temporary results */ +#define HA_OPEN_INTERNAL_TABLE 256 /* The following is parameter to ha_rkey() how to use key */ diff --git a/include/my_getopt.h b/include/my_getopt.h index 115abf00618..c74f3ed672e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -31,6 +31,7 @@ C_MODE_START #define GET_DISABLED 11 #define GET_ENUM 12 #define GET_SET 13 +#define GET_DOUBLE 14 #define GET_ASK_ADDR 128 #define GET_TYPE_MASK 127 diff --git a/include/my_sys.h b/include/my_sys.h index fb949842e48..76c9a7f02c7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -150,7 +150,7 @@ extern ulonglong sf_malloc_mem_limit; #else #define my_checkmalloc() #undef TERMINATE -#define TERMINATE(A) {} +#define TERMINATE(A,B) {} #define QUICK_SAFEMALLOC #define NORMAL_SAFEMALLOC extern void *my_malloc(size_t Size,myf MyFlags); @@ -618,7 +618,7 @@ extern int nt_share_delete(const char *name,myf MyFlags); #endif #ifndef TERMINATE -extern void TERMINATE(FILE *file); +extern void TERMINATE(FILE *file, uint flag); #endif extern void init_glob_errs(void); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); @@ -833,7 +833,7 @@ extern my_bool my_compress(uchar *, size_t *, size_t *); extern my_bool my_uncompress(uchar *, size_t , size_t *); extern uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen); -extern int packfrm(const uchar *, size_t, uchar **, size_t *); +extern int packfrm(uchar *, size_t, uchar **, size_t *); extern int unpackfrm(uchar **, size_t *, const uchar *); extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem, @@ -846,7 +846,11 @@ extern void my_sleep(ulong m_seconds); extern uint my_set_max_open_files(uint files); void my_free_open_file_info(void); +extern time_t my_time(myf flags); extern ulonglong my_getsystime(void); +extern ulonglong my_micro_time(); +extern ulonglong my_micro_time_and_time(time_t *time_arg); +time_t my_time_possible_from_micro(ulonglong microtime); extern my_bool my_gethwaddr(uchar *to); extern int my_getncpus(); diff --git a/include/mysql.h b/include/mysql.h index da97531509f..68cce3196a0 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -113,6 +113,7 @@ typedef struct st_mysql_field { unsigned int decimals; /* Number of decimals in field */ unsigned int charsetnr; /* Character set */ enum enum_field_types type; /* Type of field. See mysql_com.h for types */ + void *extension; } MYSQL_FIELD; typedef char **MYSQL_ROW; /* return data as array of strings */ @@ -147,12 +148,13 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; typedef struct st_mysql_data { - my_ulonglong rows; - unsigned int fields; MYSQL_ROWS *data; + struct embedded_query_result *embedded_info; MEM_ROOT alloc; + my_ulonglong rows; + unsigned int fields; /* extra info for embedded library */ - struct embedded_query_result *embedded_info; + void *extension; } MYSQL_DATA; enum mysql_option @@ -215,6 +217,7 @@ struct st_mysql_options { void (*local_infile_end)(void *); int (*local_infile_error)(void *, char *, unsigned int); void *local_infile_userdata; + void *extension; }; enum mysql_status @@ -304,27 +307,28 @@ typedef struct st_mysql from mysql_stmt_close if close had to cancel result set of this object. */ my_bool *unbuffered_fetch_owner; -#if defined(EMBEDDED_LIBRARY) || defined(EMBEDDED_LIBRARY_COMPATIBLE) || MYSQL_VERSION_ID >= 50100 /* needed for embedded server - no net buffer to store the 'info' */ char *info_buffer; -#endif + void *extension; } MYSQL; + typedef struct st_mysql_res { - my_ulonglong row_count; + my_ulonglong row_count; MYSQL_FIELD *fields; MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ - MEM_ROOT field_alloc; - unsigned int field_count, current_field; + const struct st_mysql_methods *methods; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ + MEM_ROOT field_alloc; + unsigned int field_count, current_field; my_bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ my_bool unbuffered_fetch_cancelled; - const struct st_mysql_methods *methods; + void *extension; } MYSQL_RES; #define MAX_MYSQL_MANAGER_ERR 256 @@ -344,21 +348,23 @@ typedef struct st_mysql_res { typedef struct st_mysql_manager { NET net; - char *host,*user,*passwd; + char *host, *user, *passwd; + char *net_buf, *net_buf_pos, *net_data_end; unsigned int port; - my_bool free_me; - my_bool eof; int cmd_status; int last_errno; - char* net_buf,*net_buf_pos,*net_data_end; int net_buf_size; + my_bool free_me; + my_bool eof; char last_error[MAX_MYSQL_MANAGER_ERR]; + void *extension; } MYSQL_MANAGER; typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; unsigned long *p_net_buffer_length; + void *extension; } MYSQL_PARAMETERS; #if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) @@ -373,6 +379,7 @@ typedef struct st_mysql_parameters */ int STDCALL mysql_server_init(int argc, char **argv, char **groups); void STDCALL mysql_server_end(void); + /* mysql_server_init/end need to be called when using libmysqld or libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so @@ -661,23 +668,24 @@ typedef struct st_mysql_bind void *buffer; /* buffer to get/put data */ /* set this if you want to track data truncations happened during fetch */ my_bool *error; - enum enum_field_types buffer_type; /* buffer type */ + unsigned char *row_ptr; /* for the current data position */ + void (*store_param_func)(NET *net, struct st_mysql_bind *param); + void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); /* output buffer length, must be set when fetching str/binary */ unsigned long buffer_length; - unsigned char *row_ptr; /* for the current data position */ unsigned long offset; /* offset position for char/binary fetch */ unsigned long length_value; /* Used if length is 0 */ unsigned int param_number; /* For null count and error messages */ unsigned int pack_length; /* Internal length for packed data */ + enum enum_field_types buffer_type; /* buffer type */ my_bool error_value; /* used if error is 0 */ my_bool is_unsigned; /* set if integer type is unsigned */ my_bool long_data_used; /* If used with mysql_send_long_data */ my_bool is_null_value; /* Used if is_null is 0 */ - void (*store_param_func)(NET *net, struct st_mysql_bind *param); - void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, - unsigned char **row); - void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, - unsigned char **row); + void *extension; } MYSQL_BIND; @@ -692,15 +700,15 @@ typedef struct st_mysql_stmt MYSQL_FIELD *fields; /* result set metadata */ MYSQL_DATA result; /* cached result set */ MYSQL_ROWS *data_cursor; /* current row in cached result */ - /* copy of mysql->affected_rows after statement execution */ - my_ulonglong affected_rows; - my_ulonglong insert_id; /* copy of mysql->insert_id */ /* mysql_stmt_fetch() calls this function to fetch one row (it's different for buffered, unbuffered and cursor fetch). */ int (*read_row_func)(struct st_mysql_stmt *stmt, unsigned char **row); + /* copy of mysql->affected_rows after statement execution */ + my_ulonglong affected_rows; + my_ulonglong insert_id; /* copy of mysql->insert_id */ unsigned long stmt_id; /* Id for prepared statement */ unsigned long flags; /* i.e. type of cursor to open */ unsigned long prefetch_rows; /* number of rows per one COM_FETCH */ @@ -726,6 +734,7 @@ typedef struct st_mysql_stmt metadata fields when doing mysql_stmt_store_result. */ my_bool update_max_length; + void *extension; } MYSQL_STMT; enum enum_stmt_attr_type diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index b87fcc60692..541fa7dfbe6 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -110,7 +110,7 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE }; struct st_mysql_show_var { diff --git a/include/mysql_com.h b/include/mysql_com.h index ae57e84a696..5850d48fbf5 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -186,25 +186,25 @@ typedef struct st_vio Vio; typedef struct st_net { #if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY) - Vio* vio; + Vio *vio; unsigned char *buff,*buff_end,*write_pos,*read_pos; my_socket fd; /* For Perl DBI/dbd */ - unsigned long max_packet,max_packet_size; - unsigned int pkt_nr,compress_pkt_nr; - unsigned int write_timeout, read_timeout, retry_count; - int fcntl; - my_bool compress; /* The following variable is set if we are doing several queries in one command ( as in LOAD TABLE ... FROM MASTER ), and do not want to confuse the client with OK at the wrong time */ unsigned long remain_in_buf,length, buf_length, where_b; + unsigned long max_packet,max_packet_size; + unsigned int pkt_nr,compress_pkt_nr; + unsigned int write_timeout, read_timeout, retry_count; + int fcntl; unsigned int *return_status; unsigned char reading_or_writing; char save_char; my_bool no_send_ok; /* For SPs and other things that do multiple stmts */ my_bool no_send_eof; /* For SPs' first version read-only cursors */ + my_bool compress; /* Set if OK packet is already sent, and we do not need to send error messages @@ -215,20 +215,20 @@ typedef struct st_net { queries in cache that have not stored its results yet */ #endif - char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; - unsigned int last_errno; - unsigned char error; - /* 'query_cache_query' should be accessed only via query cache functions and methods to maintain proper locking. */ unsigned char *query_cache_query; - + unsigned int last_errno; + unsigned char error; my_bool report_error; /* We should report error (we have unreported error) */ my_bool return_errno; + char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; + void *extension; } NET; + #define packet_error (~(unsigned long) 0) enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, @@ -389,6 +389,7 @@ typedef struct st_udf_args char *maybe_null; /* Set to 1 for all maybe_null args */ char **attributes; /* Pointer to attribute name */ unsigned long *attribute_lengths; /* Length of attribute arguments */ + void *extension; } UDF_ARGS; /* This holds information about the result */ @@ -399,7 +400,9 @@ typedef struct st_udf_init unsigned int decimals; /* for real functions */ unsigned long max_length; /* For string functions */ char *ptr; /* free pointer for function data */ - my_bool const_item; /* 0 if result is independent of arguments */ + /* 0 if result is independent of arguments */ + my_bool const_item; + void *extension; } UDF_INIT; /* Constants when using compression */ diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 7d4dcc1e919..2e6ca55e618 100644..100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -12,24 +12,56 @@ # 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 - -# Need to set USE_TLS, since __declspec(thread) approach to thread local -# storage does not work properly in DLLs. INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS") +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +# Note that we don't link with the libraries "strings" or "mysys" +# here, instead we recompile the files needed and include them +# directly. This means we don't have to worry here about if these +# libraries are compiled defining USE_TLS or not. Not that it *should* +# have been a problem anyway, they don't use thread local storage. INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/zlib - ${CMAKE_SOURCE_DIR}/extra/yassl/include ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/strings) -ADD_LIBRARY(libmysql SHARED dll.c libmysql.def - ../mysys/array.c ../strings/bchange.c ../strings/bmove.c +# We include the source file listing instead of referencing the +# libraries. At least with CMake 2.4 and Visual Studio 2005 a static +# library created from other static libraries would not be complete, +# i.e. the libraries listed in TARGET_LINK_LIBRARIES() were just +# ignored. + + +# Include and add the directory path +SET(SOURCE_SUBLIBS TRUE) + +INCLUDE(${CMAKE_SOURCE_DIR}/zlib/CMakeLists.txt) +FOREACH(rpath ${ZLIB_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../zlib/${rpath}) +ENDFOREACH(rpath) + +# FIXME only needed if build type is "Debug", but CMAKE_BUILD_TYPE is +# not set during configure time. +INCLUDE(${CMAKE_SOURCE_DIR}/dbug/CMakeLists.txt) +FOREACH(rpath ${DBUG_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../dbug/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/CMakeLists.txt) +FOREACH(rpath ${TAOCRYPT_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/taocrypt/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/CMakeLists.txt) +FOREACH(rpath ${YASSL_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/${rpath}) +ENDFOREACH(rpath) + +SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c @@ -38,10 +70,11 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c - ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c - ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c - ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c - ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c + ../mysys/default.c errmsg.c ../mysys/errors.c + ../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c + get_password.c ../strings/int2str.c ../strings/is_prefix.c + libmysql.c ../mysys/list.c ../strings/llstr.c + ../strings/longlong2str.c manager.c ../mysys/mf_cache.c ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c @@ -63,13 +96,38 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c - ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) -ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt) -TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c + ../mysys/my_getsystime.c ${LIB_SOURCES}) + +# Need to set USE_TLS for building the DLL, since __declspec(thread) +# approach to thread local storage does not work properly in DLLs. +# +# The static library might be used to form another DLL, as is the case +# with the ODBC driver, so it has to be compiled with USE_TLS as well. +# +# We create a third library without USE_TLS for internal use. We can't +# be sure that some client application part of this build doesn't go +# beond the documented API, and try access the Thread Local Storage. +# The "_notls" means no Tls*() functions used, i.e. "static" TLS. + +ADD_LIBRARY(mysqlclient STATIC ${CLIENT_SOURCES}) +ADD_DEPENDENCIES(mysqlclient GenError) +TARGET_LINK_LIBRARIES(mysqlclient) -ADD_EXECUTABLE(myTest mytest.c) -TARGET_LINK_LIBRARIES(myTest libmysql) +ADD_LIBRARY(mysqlclient_notls STATIC ${CLIENT_SOURCES}) +ADD_DEPENDENCIES(mysqlclient_notls GenError) +TARGET_LINK_LIBRARIES(mysqlclient_notls) -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("myTest" "asInvoker") -ENDIF(EMBED_MANIFESTS) +IF(NOT EMBEDDED_ONLY) + ADD_LIBRARY(libmysql SHARED ${CLIENT_SOURCES} dll.c libmysql.def) + SET_TARGET_PROPERTIES(libmysql mysqlclient PROPERTIES COMPILE_FLAGS "-DUSE_TLS") + ADD_DEPENDENCIES(libmysql GenError) + TARGET_LINK_LIBRARIES(libmysql wsock32) + + ADD_EXECUTABLE(myTest mytest.c) + TARGET_LINK_LIBRARIES(myTest libmysql) + + IF(EMBED_MANIFESTS) + MYSQL_EMBED_MANIFEST("myTest" "asInvoker") + ENDIF(EMBED_MANIFESTS) +ENDIF(NOT EMBEDDED_ONLY) diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index c24c6ab52db..3a2559921f9 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ mf_iocache2.lo my_seek.lo my_sleep.lo \ my_pread.lo mf_cache.lo md5.lo sha1.lo \ my_getopt.lo my_gethostbyname.lo my_port.lo \ - my_rename.lo my_chsize.lo + my_rename.lo my_chsize.lo my_getsystime.lo sqlobjects = net.lo sql_cmn_objects = pack.lo client.lo my_time.lo diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 46d0c8f1037..b2f59ba2a5a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -215,7 +215,7 @@ void STDCALL mysql_server_end() } static MYSQL_PARAMETERS mysql_internal_parameters= -{&max_allowed_packet, &net_buffer_length}; +{&max_allowed_packet, &net_buffer_length, 0}; MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void) { diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index dd42bafcfe0..e8e5bebb5fc 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -20,21 +20,21 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") # storage does not work properly in DLLs. ADD_DEFINITIONS(-DUSE_TLS -DMYSQL_SERVER) -# The old Windows build method used renamed (.cc -> .cpp) source files, fails -# in #include in lib_sql.cc. So disable that using the USING_CMAKE define. -ADD_DEFINITIONS(-DUSING_CMAKE) - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/libmysqld - ${CMAKE_SOURCE_DIR}/libmysql + ${CMAKE_SOURCE_DIR}/libmysqld + ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/extra/yassl/include ${CMAKE_SOURCE_DIR}/zlib ) -SET_SOURCE_FILES_PROPERTIES(${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h +SET_SOURCE_FILES_PROPERTIES(sql_yacc.cc + sql_yacc.h + message.h + message.rc + ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc + lex_hash.h PROPERTIES GENERATED 1) ADD_LIBRARY(mysqldemb emb_qcache.cc libmysqld.c lib_sql.cc @@ -80,10 +80,54 @@ ADD_LIBRARY(mysqldemb emb_qcache.cc libmysqld.c lib_sql.cc ../sql/scheduler.cc ../vio/vio.c ../vio/viosocket.c ../vio/viossl.c ../vio/viosslfactories.c - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h) + sql_yacc.cc + sql_yacc.h + message.h + message.rc + lex_hash.h) ADD_DEPENDENCIES(mysqldemb GenError) +# Sql Parser custom command +ADD_CUSTOM_COMMAND( + SOURCE ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy + OUTPUT sql_yacc.cc + COMMAND bison.exe + ARGS -y -p MYSQL --defines=sql_yacc.h + --output=sql_yacc.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy + DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy +) + +ADD_CUSTOM_COMMAND( + OUTPUT sql_yacc.h + COMMAND echo + DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc +) + +# Windows message file +ADD_CUSTOM_COMMAND( + SOURCE ${CMAKE_SOURCE_DIR}/sql/message.mc + OUTPUT message.rc message.h + COMMAND mc + ARGS ${CMAKE_SOURCE_DIR}/sql/message.mc + DEPENDS ${CMAKE_SOURCE_DIR}/sql/message.mc +) + +# Gen_lex_hash +ADD_EXECUTABLE(gen_lex_hash ../sql/gen_lex_hash.cc) +TARGET_LINK_LIBRARIES(gen_lex_hash dbug mysqlclient wsock32) +GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION) +ADD_CUSTOM_COMMAND( + OUTPUT lex_hash.h + COMMAND ${GEN_LEX_HASH_EXE} ARGS > lex_hash.h + DEPENDS ${GEN_LEX_HASH_EXE} +) + +# Remove the auto-generated files as part of 'Clean Solution' +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES + "lex_hash.h;message.rc;message.h;sql_yacc.h;sql_yacc.cc") + +ADD_DEPENDENCIES(mysqldemb gen_lex_hash) + # Seems we cannot make a library without at least one source file. So use a # dummy empty file FILE(WRITE cmake_dummy.c " ") @@ -120,3 +164,6 @@ ENDIF(WITH_ARCHIVE_STORAGE_ENGINE) IF(WITH_BLACKHOLE_STORAGE_ENGINE) TARGET_LINK_LIBRARIES(libmysqld blackhole) ENDIF(WITH_BLACKHOLE_STORAGE_ENGINE) +IF(WITH_CSV_STORAGE_ENGINE) + TARGET_LINK_LIBRARIES(libmysqld csv) +ENDIF(WITH_CSV_STORAGE_ENGINE) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 024b85eed8e..6ecce474b50 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -22,7 +22,7 @@ MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) MYSQLLIBdir= $(libdir) -EXTRA_DIST = libmysqld.def +EXTRA_DIST = libmysqld.def CMakeLists.txt DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index 59fa390399d..13956fe0a10 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -23,11 +23,11 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include # Currently does not work with DBUG, there are missing symbols reported. ADD_DEFINITIONS(-DDBUG_OFF) ADD_DEFINITIONS(-DUSE_TLS) -ADD_EXECUTABLE(test_libmysqld ../../client/completion_hash.cc +ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ../../client/mysql.cc ../../client/readline.cc ../../client/sql_string.cc) -TARGET_LINK_LIBRARIES(test_libmysqld mysys yassl taocrypt zlib dbug regex strings wsock32) -ADD_DEPENDENCIES(test_libmysqld libmysqld) +TARGET_LINK_LIBRARIES(mysql_embedded mysys yassl taocrypt zlib dbug regex strings wsock32) +ADD_DEPENDENCIES(mysql_embedded libmysqld) ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.c) TARGET_LINK_LIBRARIES(mysqltest_embedded mysys yassl taocrypt zlib dbug regex strings wsock32) diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index ec5bbbb86e5..4a91724afee 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -19,6 +19,7 @@ client_sources = $(mysqltest_embedded_SOURCES) $(mysql_SOURCES) tests_sources = $(mysql_client_test_embedded_SOURCES) BUILT_SOURCES = link_sources CLEANFILES = $(client_sources) $(tests_sources) $(BUILT_SOURCES) +EXTRA_DIST = CMakeLists.txt link_sources: for f in $(client_sources); do \ diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 0ce9efca0cc..4a8387e9944 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -28,11 +28,7 @@ extern "C" extern unsigned long max_allowed_packet, net_buffer_length; } -#if defined(__WIN__) && !defined(USING_CMAKE) -#include "../sql/mysqld.cpp" -#else #include "../sql/mysqld.cc" -#endif C_MODE_START diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index c1025cd3846..78ff08e510a 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -1,6 +1,6 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 5.0 Embedded Server Library' -VERSION 5.0 +DESCRIPTION 'MySQL 5.1 Embedded Server Library' +VERSION 5.1 EXPORTS _dig_vec_upper _dig_vec_lower @@ -48,6 +48,7 @@ EXPORTS mysql_errno mysql_error mysql_escape_string + mysql_hex_string mysql_fetch_field mysql_fetch_field_direct mysql_fetch_fields @@ -62,11 +63,13 @@ EXPORTS mysql_get_host_info mysql_get_proto_info mysql_get_server_info + mysql_get_client_version mysql_get_ssl_cipher mysql_info mysql_init mysql_insert_id mysql_kill + mysql_set_server_option mysql_list_dbs mysql_list_fields mysql_list_processes @@ -172,4 +175,3 @@ EXPORTS my_charset_bin my_charset_same modify_defaults_file - mysql_set_server_option diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1effa7c878d..22b9499c37a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -693,6 +693,37 @@ sub command_line_setup () { $glob_timers= mtr_init_timers(); + # -------------------------------------------------------------------------- + # Embedded server flag + # -------------------------------------------------------------------------- + if ( $opt_embedded_server ) + { + $glob_use_embedded_server= 1; + # Add the location for libmysqld.dll to the path. + if ( $glob_win32 ) + { + my $lib_mysqld= + mtr_path_exists(vs_config_dirs('libmysqld','')); + $lib_mysqld= $glob_cygwin_perl ? ":".`cygpath "$lib_mysqld"` + : ";".$lib_mysqld; + chomp($lib_mysqld); + $ENV{'PATH'}="$ENV{'PATH'}".$lib_mysqld; + } + + push(@glob_test_mode, "embedded"); + $opt_skip_rpl= 1; # We never run replication with embedded + $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster + $opt_skip_ssl= 1; # Turn off use of SSL + + # Turn off use of bin log + push(@opt_extra_mysqld_opt, "--skip-log-bin"); + + if ( $opt_extern ) + { + mtr_error("Can't use --extern with --embedded-server"); + } + } + # # Find the mysqld executable to be able to find the mysqld version # number as early as possible @@ -717,6 +748,7 @@ sub command_line_setup () { if (!$opt_extern) { $exe_mysqld= mtr_exe_exists (vs_config_dirs('sql', 'mysqld'), + vs_config_dirs('sql', 'mysqld-debug'), "$glob_basedir/sql/mysqld", "$path_client_bindir/mysqld-max-nt", "$path_client_bindir/mysqld-max", @@ -1662,7 +1694,7 @@ sub generate_cmdline_mysqldump ($) { my($mysqld) = @_; return mtr_native_path($exe_mysqldump) . - " --no-defaults -uroot --debug-info " . + " --no-defaults -uroot --debug-check " . "--port=$mysqld->{'port'} " . "--socket=$mysqld->{'path_sock'} --password="; } @@ -1915,7 +1947,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlcheck= mtr_native_path($exe_mysqlcheck) . - " --no-defaults --debug-info -uroot " . + " --no-defaults --debug-check -uroot " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -1967,7 +1999,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlimport= mtr_native_path($exe_mysqlimport) . - " -uroot --debug-info " . + " -uroot --debug-check " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -1984,7 +2016,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlshow= mtr_native_path($exe_mysqlshow) . - " -uroot --debug-info " . + " -uroot --debug-check " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -2000,7 +2032,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlbinlog= mtr_native_path($exe_mysqlbinlog) . - " --no-defaults --disable-force-if-open --debug-info"; + " --no-defaults --disable-force-if-open --debug-check"; if ( !$opt_extern && $mysql_version_id >= 50000 ) { $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir"; @@ -2018,7 +2050,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysql= mtr_native_path($exe_mysql) . - " --no-defaults --debug-info --host=localhost --user=root --password= " . + " --no-defaults --debug-check --host=localhost --user=root --password= " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} ". "--character-sets-dir=$path_charsetsdir"; @@ -2449,6 +2481,7 @@ sub vs_config_dirs ($$) { } return ("$glob_basedir/$path_part/release/$exe", + "$glob_basedir/$path_part/relwithdebinfo/$exe", "$glob_basedir/$path_part/debug/$exe"); } diff --git a/mysql-test/r/binlog_unsafe.result b/mysql-test/r/binlog_unsafe.result index 624c7feec1f..fb89631f30b 100644 --- a/mysql-test/r/binlog_unsafe.result +++ b/mysql-test/r/binlog_unsafe.result @@ -5,9 +5,9 @@ CREATE TABLE t3 (b INT AUTO_INCREMENT PRIMARY KEY); CREATE VIEW v1(a,b) AS SELECT a,b FROM t2,t3; INSERT INTO t1 SELECT UUID(); Warnings: -Warning 1589 Statement is not safe to log in statement format. +Warning 1590 Statement is not safe to log in statement format. SHOW WARNINGS; Level Warning -Code 1589 +Code 1590 Message Statement is not safe to log in statement format. DROP TABLE t1,t2,t3; diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 002dbc6ccb5..795d8956a08 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -209,16 +209,16 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index explain SELECT distinct t1.a from t1 order by a desc limit 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index +1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using index explain SELECT distinct a from t3 order by a desc limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 index NULL a 5 NULL 204 Using index +1 SIMPLE t3 index NULL a 5 NULL 40 Using index explain SELECT distinct a,b from t3 order by a+1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort -explain SELECT distinct a,b from t3 order by a limit 10; +explain SELECT distinct a,b from t3 order by a limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 index NULL a 5 NULL 204 Using temporary +1 SIMPLE t3 index NULL a 5 NULL 2 Using temporary explain SELECT a,b from t3 group by a,b order by a+1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort diff --git a/mysql-test/r/endspace.result b/mysql-test/r/endspace.result index 6fb33dee826..9c8d12362c4 100644 --- a/mysql-test/r/endspace.result +++ b/mysql-test/r/endspace.result @@ -154,7 +154,7 @@ teststring teststring explain select * from t1 order by text1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL key1 34 NULL 3 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort alter table t1 modify text1 char(32) binary not null; select * from t1 order by text1; text1 diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 1bfa0e84f72..2557fcb3b28 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -31,7 +31,7 @@ create event e_55 on schedule at 10000101000000 do drop table t; ERROR HY000: Incorrect AT value: '10000101000000' create event e_55 on schedule at 20000101000000 do drop table t; Warnings: -Note 1585 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. +Note 1586 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. 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 create event e_55 on schedule at 20200101000000 starts 10000101000000 do drop table t; @@ -457,22 +457,22 @@ CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' DO SELECT 1; Warnings: -Note 1585 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. +Note 1586 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' ENDS '1999-01-02 00:00:00' DISABLE DO SELECT 1; Warnings: -Note 1585 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. +Note 1586 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DO SELECT 1; Warnings: -Note 1585 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. +Note 1586 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DISABLE DO SELECT 1; Warnings: -Note 1585 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. +Note 1586 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. 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 events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci @@ -482,19 +482,19 @@ The following should succeed giving a warning. ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE; Warnings: -Note 1541 Event execution time is in the past. Event has been disabled +Note 1542 Event execution time is in the past. Event has been disabled CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DO SELECT 1; Warnings: -Note 1541 Event execution time is in the past. Event has been disabled +Note 1542 Event execution time is in the past. Event has been disabled CREATE EVENT e5 ON SCHEDULE AT '1999-01-01 00:00:00' ON COMPLETION PRESERVE DO SELECT 1; Warnings: -Note 1541 Event execution time is in the past. Event has been disabled +Note 1542 Event execution time is in the past. Event has been disabled The following should succeed without warnings. ALTER EVENT e2 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'; ALTER EVENT e3 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' diff --git a/mysql-test/r/events_logs_tests.result b/mysql-test/r/events_logs_tests.result index 0d49060f4a9..b69a02c9819 100644 --- a/mysql-test/r/events_logs_tests.result +++ b/mysql-test/r/events_logs_tests.result @@ -41,7 +41,7 @@ SELECT user_host, query_time, db, sql_text FROM mysql.slow_log; user_host query_time db sql_text "Set new values" SET GLOBAL long_query_time=4; -SET SESSION long_query_time=1; +SET SESSION long_query_time=0.5; "Check that logging is working" SELECT SLEEP(2); SLEEP(2) diff --git a/mysql-test/r/events_trans.result b/mysql-test/r/events_trans.result index 1f87bcea68e..dce08d3b9f9 100644 --- a/mysql-test/r/events_trans.result +++ b/mysql-test/r/events_trans.result @@ -63,7 +63,7 @@ begin work; insert into t1 (a) values ("OK: create event if not exists"); create event if not exists e1 on schedule every 2 day do select 2; Warnings: -Note 1534 Event 'e1' already exists +Note 1535 Event 'e1' already exists rollback work; select * from t1; a diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index ca936cd5fde..8f1fe20ea3b 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -1920,6 +1920,20 @@ a b 2 Curly drop table federated.t1; drop table federated.t1; + +Bug#18287 create federated table always times out, error 1159 ' ' + +Test that self-references work + +create table federated.t1 (a int primary key); +create table federated.t2 (a int primary key) +ENGINE=FEDERATED +connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +insert into federated.t1 (a) values (1); +select * from federated.t2; +a +1 +drop table federated.t1, federated.t2; CREATE TABLE federated.t1 (a INT PRIMARY KEY) DEFAULT CHARSET=utf8; CREATE TABLE federated.t1 (a INT PRIMARY KEY) ENGINE=FEDERATED diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index faa1bc1d661..13ddccaee92 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -1161,7 +1161,7 @@ CREATE TABLE t2 (a INT, b INT, KEY(a)); INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4); EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL a 5 NULL 4 +1 SIMPLE t2 index NULL a 5 NULL 2 EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index b6bf7260dc2..02b1459afd0 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -1963,20 +1963,20 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using temporary; Using filesort explain select a1,a2,count(a2) from t1 group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 Using index +1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using index explain extended select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where (`test`.`t1`.`a1` > _latin1'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain extended select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 128 75.00 Using where; Using index +1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index Warnings: Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where (`test`.`t1`.`a1` > _latin1'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select distinct(a1) from t1 where ord(a2) = 98; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index +1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using where; Using index select distinct(a1) from t1 where ord(a2) = 98; a1 a @@ -2256,7 +2256,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index -2 DEPENDENT SUBQUERY t1 index NULL a 10 NULL 15 Using index +2 DEPENDENT SUBQUERY t1 index NULL a 10 NULL 1 Using index EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 804c15f6aa1..f81277b1ff9 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -289,8 +289,8 @@ explain select a.ROUTINE_NAME from information_schema.ROUTINES a, information_schema.SCHEMATA b where a.ROUTINE_SCHEMA = b.SCHEMA_NAME; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE # ALL NULL NULL NULL NULL 2 -1 SIMPLE # ALL NULL NULL NULL NULL 2 Using where; Using join buffer +1 SIMPLE # ALL NULL NULL NULL NULL NULL +1 SIMPLE # ALL NULL NULL NULL NULL NULL Using where; Using join buffer select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1; ROUTINE_NAME name @@ -355,7 +355,7 @@ mysql test explain select * from v0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE # ALL NULL NULL NULL NULL 2 +1 SIMPLE # ALL NULL NULL NULL NULL NULL create view v1 (c) as select table_name from information_schema.tables where table_name="v1"; select * from v1; @@ -679,17 +679,11 @@ where table_schema='test'; table_name v2 v3 -Warnings: -Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select table_name from information_schema.views where table_schema='test'; table_name v2 v3 -Warnings: -Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select column_name from information_schema.columns where table_schema='test'; column_name @@ -1337,11 +1331,11 @@ from information_schema.tables order by object_schema; explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tables ALL NULL NULL NULL NULL 2 Using filesort +1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort explain select * from (select table_name from information_schema.tables) as a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found -2 DERIVED tables ALL NULL NULL NULL NULL 2 +2 DERIVED tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases drop view v1; create table t1 (f1 int(11)); create table t2 (f1 int(11), f2 int(11)); @@ -1445,4 +1439,28 @@ ABORTED_CONNECTS BINLOG_CACHE_DISK_USE DROP TABLE server_status; SET GLOBAL event_scheduler=0; +explain select table_name from information_schema.views where +table_schema='test' and table_name='v1'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE views ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Open_frm_only; Scanned 0 databases +explain select * from information_schema.tables; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_full_table; Scanned all databases +explain select * from information_schema.collations; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE collations ALL NULL NULL NULL NULL NULL +explain select * from information_schema.tables where +table_schema='test' and table_name= 't1'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tables ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Open_full_table; Scanned 0 databases +explain select table_name, table_type from information_schema.tables +where table_schema='test'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tables ALL NULL TABLE_SCHEMA NULL NULL NULL Using where; Open_frm_only; Scanned 1 database +explain select b.table_name +from information_schema.tables a, information_schema.columns b +where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Skip_open_table; Scanned 0 databases +1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer End of 5.1 tests. diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index a0fd33ac068..e5a5a583de3 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -74,11 +74,11 @@ drop table t1; select table_name, table_type, table_comment from information_schema.tables where table_schema='inf%' and func2(); table_name table_type table_comment -v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define +v1 VIEW VIEW select table_name, table_type, table_comment from information_schema.tables where table_schema='inf%' and func2(); table_name table_type table_comment -v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define +v1 VIEW VIEW drop view v1; drop function func1; drop function func2; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 804c4b81c17..dce5e1a9a35 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -947,7 +947,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL # explain select * from t1 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 4 NULL # +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort explain select * from t1 order by c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 26000fa27b7..ae442acd1b9 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -879,13 +879,13 @@ EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; id 1 select_type SIMPLE table t1 -type range +type index possible_keys bkey -key bkey -key_len 5 +key PRIMARY +key_len 4 ref NULL -rows 16 -Extra Using where; Using index; Using filesort +rows 32 +Extra Using where SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; a b 1 2 @@ -974,13 +974,13 @@ EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; id 1 select_type SIMPLE table t2 -type ref +type index possible_keys bkey -key bkey -key_len 5 -ref const -rows 8 -Extra Using where; Using index; Using filesort +key PRIMARY +key_len 4 +ref NULL +rows 16 +Extra Using where; Using index SELECT * FROM t2 WHERE b=1 ORDER BY a; a b c 1 1 1 diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index e2000a9ec91..6152e403637 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -96,4 +96,74 @@ ERROR HY000: You can't combine write-locking of system tables with other tables LOCK TABLES mysql.time_zone READ, mysql.proc WRITE; ERROR HY000: You can't combine write-locking of system tables with other tables or lock types DROP TABLE t1; + +Bug#5719 impossible to lock VIEW + +Just covering existing behaviour with tests. +Consistency has not been found here. + +drop view if exists v_bug5719; +drop table if exists t1, t2, t3; +create table t1 (a int); +create temporary table t2 (a int); +create table t3 (a int); +create view v_bug5719 as select 1; +lock table v_bug5719 write; +select * from t1; +ERROR HY000: Table 't1' was not locked with LOCK TABLES + +Allowed to select from a temporary talbe under LOCK TABLES + +select * from t2; +a +select * from t3; +ERROR HY000: Table 't3' was not locked with LOCK TABLES +select * from v_bug5719; +1 +1 +drop view v_bug5719; + +sic: did not left LOCK TABLES mode automatically + +select * from t1; +ERROR HY000: Table 't1' was not locked with LOCK TABLES +unlock tables; +create view v_bug5719 as select * from t1; +lock tables v_bug5719 write; +select * from v_bug5719; +a + +Allowed to use an underlying table under LOCK TABLES <view> + +select * from t1; +a + +Allowed to select from a temporary table under LOCK TABLES + +select * from t2; +a +select * from t3; +ERROR HY000: Table 't3' was not locked with LOCK TABLES +drop table t1; + +sic: left LOCK TABLES mode + +select * from t3; +a +select * from v_bug5719; +ERROR HY000: View 'test.v_bug5719' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +unlock tables; +drop view v_bug5719; + +When limitation to use temporary tables in views is removed, please +add a test that shows what happens under LOCK TABLES when a view +references a temporary table, is locked, and the underlying table +is dropped. + +create view v_bug5719 as select * from t2; +ERROR HY000: View's SELECT refers to a temporary table 't2' + +Cleanup. + +drop table t2, t3; End of 5.1 tests. diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 2445b3e0c69..a3f7ab4505c 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -95,3 +95,13 @@ alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // unlock tables; drop table t1; +create table t1 (i int); +lock table t1 read; +update t1 set i= 10;; +select * from t1;; +kill query ID; +i +ERROR 70100: Query execution was interrupted +unlock tables; +drop table t1; +End of 5.1 tests diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 0c6be16b9b7..3a3ef584ce3 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -37,14 +37,14 @@ set session long_query_time=1; select sleep(2); sleep(2) 0 -select * from mysql.slow_log; +select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%'; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text set global slow_query_log= ON; set session long_query_time=1; select sleep(2); sleep(2) 0 -select * from mysql.slow_log; +select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%'; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2) show global variables diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index bb4fc654b38..5aa4288500c 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -86,7 +86,7 @@ a b 19 Testing explain select a from t3 order by a desc limit 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 index NULL a 4 NULL 1131 Using index +1 SIMPLE t3 index NULL a 4 NULL 10 Using index select a from t3 order by a desc limit 10; a 699 diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 57e1f2e4ef6..f5b369f246a 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -177,3 +177,4 @@ ERROR at line 1: DELIMITER cannot contain a backslash character 1 1 End of 5.0 tests +WARNING: --server-arg option not supported in this configuration. diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 25fbeadf21b..ff4882d6cd8 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1073,3 +1073,61 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY,b b 5 const 1 1 SIMPLE t2 ref a a 5 const 2 Using where; Using index DROP TABLE t1,t2; +CREATE TABLE t1( +id int auto_increment PRIMARY KEY, c2 int, c3 int, INDEX k2(c2), INDEX k3(c3)); +INSERT INTO t1 (c2,c3) VALUES +(31,34),(35,38),(34,31),(32,35),(31,39), +(11,14),(15,18),(14,11),(12,15),(11,19); +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +UPDATE t1 SET c2=20 WHERE id%100 = 0; +SELECT COUNT(*) FROM t1; +COUNT(*) +40960 +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * FROM t1 ORDER BY id; +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index k2 k3 5 NULL 111 Using where +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref k2 k2 5 const 7341 Using where; Using filesort +EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 10 AND 12 ORDER BY c3 LIMIT 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index k2 k3 5 NULL 73 Using where +EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range k2 k2 5 NULL 386 Using where; Using filesort +SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; +id c3 +6 14 +16 14 +26 14 +36 14 +46 14 +56 14 +66 14 +76 14 +86 14 +96 14 +106 14 +116 14 +126 14 +136 14 +146 14 +156 14 +166 14 +176 14 +186 14 +196 14 +DROP TABLE t1,t2; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index a148d1029df..1ebed6d17d5 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3980,4 +3980,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index 1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index DROP TABLE t1; +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (1,11), (2,22), (2,22); +EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2)))))))))))))))))))))))))))))))) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where +31 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +32 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0; +ERROR HY000: Too high level of nesting for select +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index 7abd65beb46..7896f8a9f4e 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -84,7 +84,7 @@ UNIQUE KEY e_n (email,name) EXPLAIN SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system PRIMARY,kid NULL NULL NULL 0 const row not found -1 SIMPLE t2 index NULL e_n 104 NULL 200 +1 SIMPLE t2 index NULL e_n 104 NULL 10 SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10; email email1 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ebdab4a3f89..163bbb4aab4 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5670,7 +5670,7 @@ drop function if exists pi; create function pi() returns varchar(50) return "pie, my favorite desert."; Warnings: -Note 1582 This function 'pi' has the same name as a native function +Note 1583 This function 'pi' has the same name as a native function SET @save_sql_mode=@@sql_mode; SET SQL_MODE='IGNORE_SPACE'; select pi(), pi (); @@ -5719,15 +5719,15 @@ use test; create function `database`() returns varchar(50) return "Stored function database"; Warnings: -Note 1582 This function 'database' has the same name as a native function +Note 1583 This function 'database' has the same name as a native function create function `current_user`() returns varchar(50) return "Stored function current_user"; Warnings: -Note 1582 This function 'current_user' has the same name as a native function +Note 1583 This function 'current_user' has the same name as a native function create function md5(x varchar(50)) returns varchar(50) return "Stored function md5"; Warnings: -Note 1582 This function 'md5' has the same name as a native function +Note 1583 This function 'md5' has the same name as a native function SET SQL_MODE='IGNORE_SPACE'; select database(), database (); database() database () diff --git a/mysql-test/r/sp_gis.result b/mysql-test/r/sp_gis.result index b4fe0872d64..c640e5c46f2 100644 --- a/mysql-test/r/sp_gis.result +++ b/mysql-test/r/sp_gis.result @@ -7,11 +7,11 @@ return 1; create function x() returns int return 2; Warnings: -Note 1582 This function 'x' has the same name as a native function +Note 1583 This function 'x' has the same name as a native function create function y() returns int return 3; Warnings: -Note 1582 This function 'y' has the same name as a native function +Note 1583 This function 'y' has the same name as a native function select a(); a() 1 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 40b9e489577..a25183a0e6d 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3419,7 +3419,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where -2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 9 Using filesort +2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1 Using filesort DROP TABLE t1; create table t1( f1 int,f2 int); insert into t1 values (1,1),(2,2); diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 8d7843cc0b1..e6641cab7f6 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -618,6 +618,30 @@ bit_field int_field 2 handler t1 close; drop table t1; +CREATE TABLE t1 (b BIT(2), a VARCHAR(5)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(5), b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +b+0 COUNT(DISTINCT a) +0 1 +1 1 +3 2 +DROP TABLE t1; End of 5.0 tests create table t1(a bit(7)); insert into t1 values(0x40); diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index ff43993cfdb..19b48efe6b4 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -444,7 +444,14 @@ set interactive_timeout=100; set join_buffer_size=100; set last_insert_id=1; set global local_infile=1; -set long_query_time=100; +set long_query_time=0.000001; +select @@long_query_time; +@@long_query_time +0.000001 +set long_query_time=100.000001; +select @@long_query_time; +@@long_query_time +100.000001 set low_priority_updates=1; set max_allowed_packet=100; set global max_binlog_cache_size=100; @@ -516,6 +523,7 @@ set tmp_table_size=100; set tx_isolation="READ-COMMITTED"; set wait_timeout=100; set log_warnings=1; +set global log_warnings=1; select @@session.insert_id; @@session.insert_id 1 diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 95ad19a886f..aac7c4e850a 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -647,32 +647,32 @@ select extractValue('<a>a','/a'); extractValue('<a>a','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 5: unexpected END-OF-INPUT' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 5: unexpected END-OF-INPUT' select extractValue('<a>a<','/a'); extractValue('<a>a<','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 6: END-OF-INPUT unexpected (ident or '/' wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 6: END-OF-INPUT unexpected (ident or '/' wanted)' select extractValue('<a>a</','/a'); extractValue('<a>a</','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 7: END-OF-INPUT unexpected (ident wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 7: END-OF-INPUT unexpected (ident wanted)' select extractValue('<a>a</a','/a'); extractValue('<a>a</a','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 8: END-OF-INPUT unexpected ('>' wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 8: END-OF-INPUT unexpected ('>' wanted)' select extractValue('<a>a</a></b>','/a'); extractValue('<a>a</a></b>','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 12: '</b>' unexpected (END-OF-INPUT wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 12: '</b>' unexpected (END-OF-INPUT wanted)' select extractValue('<a b=>a</a>','/a'); extractValue('<a b=>a</a>','/a') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 7: '>' unexpected (ident or string wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 7: '>' unexpected (ident or string wanted)' select extractValue('<e>1</e>','position()'); ERROR HY000: XPATH syntax error: '' select extractValue('<e>1</e>','last()'); @@ -723,17 +723,17 @@ select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//* extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 13: unknown token unexpected (ident or '/' wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 13: unknown token unexpected (ident or '/' wanted)' select extractValue('<.>test</.>','//*'); extractValue('<.>test</.>','//*') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)' select extractValue('<->test</->','//*'); extractValue('<->test</->','//*') NULL Warnings: -Warning 1522 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)' +Warning 1523 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)' select extractValue('<:>test</:>','//*'); extractValue('<:>test</:>','//*') test diff --git a/mysql-test/suite/ndb/r/ndb_alter_table.result b/mysql-test/suite/ndb/r/ndb_alter_table.result index 13c445b44ca..5798db73403 100644 --- a/mysql-test/suite/ndb/r/ndb_alter_table.result +++ b/mysql-test/suite/ndb/r/ndb_alter_table.result @@ -34,13 +34,13 @@ col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null, col6 int not null, to_be_deleted int) ENGINE=ndbcluster; show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 NDBCLUSTER 10 Dynamic 0 # # # 0 # 1 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 0 # # # 0 # 1 # # # latin1_swedish_ci NULL # SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO; insert into t1 values (0,4,3,5,"PENDING",1,7),(NULL,4,3,5,"PENDING",1,7),(31,4,3,5,"PENDING",1,7), (7,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7), (100,4,3,5,"PENDING",1,7), (99,4,3,5,"PENDING",1,7), (8,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 NDBCLUSTER 10 Dynamic 9 # # # 0 # 102 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 9 # # # 0 # 102 # # # latin1_swedish_ci NULL # select * from t1 order by col1; col1 col2 col3 col4 col5 col6 to_be_deleted 0 4 3 5 PENDING 1 7 @@ -60,7 +60,7 @@ change column col2 fourth varchar(30) not null after col3, modify column col6 int not null first; show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 NDBCLUSTER 10 Dynamic 9 # # # 0 # 102 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 9 # # # 0 # 102 # # # latin1_swedish_ci NULL # select * from t1 order by col1; col6 col1 col3 fourth col4 col4_5 col5 col7 col8 1 0 3 4 5 PENDING 0000-00-00 00:00:00 @@ -75,7 +75,7 @@ col6 col1 col3 fourth col4 col4_5 col5 col7 col8 insert into t1 values (2, NULL,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 NDBCLUSTER 10 Dynamic 10 # # # 0 # 103 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 10 # # # 0 # 103 # # # latin1_swedish_ci NULL # select * from t1 order by col1; col6 col1 col3 fourth col4 col4_5 col5 col7 col8 1 0 3 4 5 PENDING 0000-00-00 00:00:00 diff --git a/mysql-test/suite/ndb/r/ndb_dd_basic.result b/mysql-test/suite/ndb/r/ndb_dd_basic.result index bc1762ce407..b23d178acde 100644 --- a/mysql-test/suite/ndb/r/ndb_dd_basic.result +++ b/mysql-test/suite/ndb/r/ndb_dd_basic.result @@ -5,20 +5,20 @@ INITIAL_SIZE 16M UNDO_BUFFER_SIZE = 1M ENGINE=MYISAM; Warnings: -Error 1475 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1476 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' ALTER LOGFILE GROUP lg1 ADD UNDOFILE 'undofile02.dat' INITIAL_SIZE = 4M ENGINE=XYZ; Warnings: Warning 1286 Unknown table engine 'XYZ' -Error 1475 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1476 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 INITIAL_SIZE 12M; Warnings: -Error 1475 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1476 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' set storage_engine=ndb; CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' diff --git a/mysql-test/suite/ndb/r/ndb_dd_ddl.result b/mysql-test/suite/ndb/r/ndb_dd_ddl.result index 55f1f56fd0c..33536038b1b 100644 --- a/mysql-test/suite/ndb/r/ndb_dd_ddl.result +++ b/mysql-test/suite/ndb/r/ndb_dd_ddl.result @@ -16,7 +16,7 @@ ERROR HY000: Failed to create LOGFILE GROUP SHOW WARNINGS; Level Code Message Error 1296 Got error 1514 'Currently there is a limit of one logfile group' from NDB -Error 1525 Failed to create LOGFILE GROUP +Error 1526 Failed to create LOGFILE GROUP CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' INITIAL_SIZE 1M diff --git a/mysql-test/suite/ndb/r/ndb_gis.result b/mysql-test/suite/ndb/r/ndb_gis.result index 54f1fc23489..1d593f471d1 100644 --- a/mysql-test/suite/ndb/r/ndb_gis.result +++ b/mysql-test/suite/ndb/r/ndb_gis.result @@ -463,7 +463,7 @@ drop table t1; End of 4.1 tests CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); Warnings: -Error 1475 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' +Error 1476 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); @@ -1013,7 +1013,7 @@ drop table t1; End of 4.1 tests CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); Warnings: -Error 1475 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' +Error 1476 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); diff --git a/mysql-test/suite/ndb/r/ndb_row_format.result b/mysql-test/suite/ndb/r/ndb_row_format.result index 37c239986f6..44880e28c83 100644 --- a/mysql-test/suite/ndb/r/ndb_row_format.result +++ b/mysql-test/suite/ndb/r/ndb_row_format.result @@ -8,7 +8,7 @@ ENGINE=NDB; ERROR HY000: Can't create table 'test.t1' (errno: 138) SHOW WARNINGS; Level Code Message -Error 1475 Table storage engine 'ndbcluster' does not support the create option 'Row format FIXED incompatible with variable sized attribute' +Error 1476 Table storage engine 'ndbcluster' does not support the create option 'Row format FIXED incompatible with variable sized attribute' Error 1005 Can't create table 'test.t1' (errno: 138) CREATE TABLE t1 ( a INT KEY, diff --git a/mysql-test/suite/ndb/r/ndb_single_user.result b/mysql-test/suite/ndb/r/ndb_single_user.result index f916422a509..11e8f098416 100644 --- a/mysql-test/suite/ndb/r/ndb_single_user.result +++ b/mysql-test/suite/ndb/r/ndb_single_user.result @@ -11,7 +11,7 @@ ERROR HY000: Failed to create LOGFILE GROUP show warnings; Level Code Message Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB -Error 1525 Failed to create LOGFILE GROUP +Error 1526 Failed to create LOGFILE GROUP create table t1 (a int key, b int unique, c int) engine ndb; CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' @@ -27,14 +27,14 @@ ERROR HY000: Failed to create TABLESPACE show warnings; Level Code Message Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB -Error 1525 Failed to create TABLESPACE +Error 1526 Failed to create TABLESPACE DROP LOGFILE GROUP lg1 ENGINE =NDB; ERROR HY000: Failed to drop LOGFILE GROUP show warnings; Level Code Message Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB -Error 1526 Failed to drop LOGFILE GROUP +Error 1527 Failed to drop LOGFILE GROUP CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 @@ -47,7 +47,7 @@ ERROR HY000: Failed to alter: DROP DATAFILE show warnings; Level Code Message Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB -Error 1530 Failed to alter: DROP DATAFILE +Error 1531 Failed to alter: DROP DATAFILE ALTER TABLESPACE ts1 DROP DATAFILE 'datafile.dat' ENGINE NDB; @@ -57,7 +57,7 @@ ERROR HY000: Failed to drop TABLESPACE show warnings; Level Code Message Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB -Error 1526 Failed to drop TABLESPACE +Error 1527 Failed to drop TABLESPACE DROP TABLESPACE ts1 ENGINE NDB; DROP LOGFILE GROUP lg1 diff --git a/mysql-test/suite/ndb/r/ndb_temporary.result b/mysql-test/suite/ndb/r/ndb_temporary.result index 61fc1561e4f..7b7740003af 100644 --- a/mysql-test/suite/ndb/r/ndb_temporary.result +++ b/mysql-test/suite/ndb/r/ndb_temporary.result @@ -9,7 +9,7 @@ SET SESSION storage_engine=NDBCLUSTER; create table t1 (a int key); select engine from information_schema.tables where table_name = 't1'; engine -NDBCLUSTER +ndbcluster drop table t1; create temporary table t1 (a int key); show create table t1; diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result index bff391610a6..464c54d5850 100644 --- a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result @@ -139,7 +139,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -157,7 +157,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -201,7 +201,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -219,7 +219,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -263,7 +263,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 Skip_Counter 0 Exec_Master_Log_Pos # @@ -281,7 +281,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -324,7 +324,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -342,7 +342,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3; *** Drop t6 *** @@ -436,7 +436,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 Skip_Counter 0 Exec_Master_Log_Pos # @@ -454,7 +454,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -497,7 +497,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 Skip_Counter 0 Exec_Master_Log_Pos # @@ -515,7 +515,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -822,7 +822,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 Skip_Counter 0 Exec_Master_Log_Pos # @@ -840,7 +840,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result index 7613bb6aa12..5d2a5c1a80e 100644 --- a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result @@ -139,7 +139,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -157,7 +157,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -201,7 +201,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -219,7 +219,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -263,7 +263,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 Skip_Counter 0 Exec_Master_Log_Pos # @@ -281,7 +281,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -324,7 +324,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -342,7 +342,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3; *** Drop t6 *** @@ -436,7 +436,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 Skip_Counter 0 Exec_Master_Log_Pos # @@ -454,7 +454,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -497,7 +497,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 Skip_Counter 0 Exec_Master_Log_Pos # @@ -515,7 +515,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -822,7 +822,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 Skip_Counter 0 Exec_Master_Log_Pos # @@ -840,7 +840,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_incident.result b/mysql-test/suite/rpl/r/rpl_incident.result index 84fd9c0ee4f..c3cec758d89 100644 --- a/mysql-test/suite/rpl/r/rpl_incident.result +++ b/mysql-test/suite/rpl/r/rpl_incident.result @@ -44,7 +44,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1587 +Last_Errno 1588 Last_Error The incident LOST_EVENTS occured on the master. Message: <none> Skip_Counter 0 Exec_Master_Log_Pos # @@ -62,7 +62,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1587 +Last_SQL_Errno 1588 Last_SQL_Error The incident LOST_EVENTS occured on the master. Message: <none> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result index 6c73c275ff0..0216ef65570 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result @@ -65,7 +65,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1590 +Last_Errno 1591 Last_Error Fatal error: Not enough memory Skip_Counter 0 Exec_Master_Log_Pos 325 @@ -83,7 +83,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1590 +Last_SQL_Errno 1591 Last_SQL_Error Fatal error: Not enough memory SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index 816fba54bd8..07ac657584c 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -214,7 +214,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -232,7 +232,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -257,7 +257,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -275,7 +275,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -300,7 +300,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -318,7 +318,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index 0c5d57c1d00..a17d495a116 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -214,7 +214,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -232,7 +232,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -257,7 +257,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -275,7 +275,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -300,7 +300,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -318,7 +318,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_timezone.result b/mysql-test/suite/rpl/r/rpl_timezone.result index 47ef16b9d49..cd71dbe628e 100644 --- a/mysql-test/suite/rpl/r/rpl_timezone.result +++ b/mysql-test/suite/rpl/r/rpl_timezone.result @@ -105,3 +105,21 @@ t n 2005-01-01 08:00:00 17 drop table t1, t2; set global time_zone= @my_time_zone; +End of 4.1 tests +CREATE TABLE t1 (a INT, b TIMESTAMP); +INSERT INTO t1 VALUES (1, NOW()); +SET @@session.time_zone='Japan'; +UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1; +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT * FROM t1 ORDER BY a; +a b +1 0000-00-00 00:00:00 +SET @@session.time_zone='Japan'; +SELECT * FROM t1 ORDER BY a; +a b +1 0000-00-00 00:00:00 +SET @@session.time_zone = default; +DROP TABLE t1; +SET @@session.time_zone = default; +End of 5.0 tests diff --git a/mysql-test/suite/rpl/r/rpl_udf.result b/mysql-test/suite/rpl/r/rpl_udf.result index d21cfd2539b..1fa9cb3ffc2 100644 --- a/mysql-test/suite/rpl/r/rpl_udf.result +++ b/mysql-test/suite/rpl/r/rpl_udf.result @@ -182,19 +182,19 @@ CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM; affected rows: 0 INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00)); Warnings: -Warning 1589 Statement is not safe to log in statement format. +Warning 1590 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00)); Warnings: -Warning 1589 Statement is not safe to log in statement format. +Warning 1590 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00)); Warnings: -Warning 1589 Statement is not safe to log in statement format. +Warning 1590 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00)); Warnings: -Warning 1589 Statement is not safe to log in statement format. +Warning 1590 Statement is not safe to log in statement format. affected rows: 1 SELECT * FROM t1 ORDER BY sum; sum price diff --git a/mysql-test/suite/rpl/t/rpl_relayspace.test b/mysql-test/suite/rpl/t/rpl_relayspace.test index 70315c14f34..d4ef2fe59bd 100644 --- a/mysql-test/suite/rpl/t/rpl_relayspace.test +++ b/mysql-test/suite/rpl/t/rpl_relayspace.test @@ -14,6 +14,22 @@ connection slave; reset slave; start slave io_thread; # Give the I/O thread time to block. +let $run= 1; +let $counter= 300; +while ($run) +{ + let $io_state= query_get_value("SHOW SLAVE STATUS", Slave_IO_State, 1); + if (`SELECT '$io_state' = 'Waiting for the slave SQL thread to free enough relay log space'`){ + let $run= 0; + } + sleep 0.1; + if (!$counter){ + --echo "Failed while waiting for slave IO thread block" + SHOW SLAVE STATUS; + exit; + } + dec $counter; +} sleep 2; # A bug caused the I/O thread to refuse stopping. stop slave io_thread; diff --git a/mysql-test/suite/rpl/t/rpl_timezone.test b/mysql-test/suite/rpl/t/rpl_timezone.test index 4b8c8152c82..dac21000a62 100644 --- a/mysql-test/suite/rpl/t/rpl_timezone.test +++ b/mysql-test/suite/rpl/t/rpl_timezone.test @@ -140,3 +140,30 @@ sync_slave_with_master; # Restore original timezone connection master; set global time_zone= @my_time_zone; + +--echo End of 4.1 tests + +# +# Bug #29536: timestamp inconsistent in replication around 1970 +# +connection master; + +CREATE TABLE t1 (a INT, b TIMESTAMP); +INSERT INTO t1 VALUES (1, NOW()); + +SET @@session.time_zone='Japan'; +UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1; +SELECT * FROM t1 ORDER BY a; + +sync_slave_with_master; +SET @@session.time_zone='Japan'; +# must procdure the same result as the SELECT on the master +SELECT * FROM t1 ORDER BY a; + +SET @@session.time_zone = default; +connection master; +DROP TABLE t1; +SET @@session.time_zone = default; + + +--echo End of 5.0 tests diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result index ce1e5d69898..ccb7a9a15a3 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result @@ -139,7 +139,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -157,7 +157,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -201,7 +201,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -219,7 +219,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -263,7 +263,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 Skip_Counter 0 Exec_Master_Log_Pos # @@ -281,7 +281,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -324,7 +324,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 Skip_Counter 0 Exec_Master_Log_Pos # @@ -342,7 +342,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3; *** Drop t6 *** @@ -436,7 +436,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 Skip_Counter 0 Exec_Master_Log_Pos # @@ -454,7 +454,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -497,7 +497,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 Skip_Counter 0 Exec_Master_Log_Pos # @@ -515,7 +515,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -823,7 +823,7 @@ Replicate_Do_Table Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1532 +Last_Errno 1533 Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 Skip_Counter 0 Exec_Master_Log_Pos # @@ -841,7 +841,7 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno # Last_IO_Error # -Last_SQL_Errno 1532 +Last_SQL_Errno 1533 Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 7310f98cd16..bfdb5f8b9f8 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -97,7 +97,7 @@ explain SELECT t1.a from t1 group by a order by a desc; explain SELECT distinct t1.a from t1 order by a desc limit 1; explain SELECT distinct a from t3 order by a desc limit 2; explain SELECT distinct a,b from t3 order by a+1; -explain SELECT distinct a,b from t3 order by a limit 10; +explain SELECT distinct a,b from t3 order by a limit 2; explain SELECT a,b from t3 group by a,b order by a+1; drop table t1,t2,t3,t4; diff --git a/mysql-test/t/events_logs_tests.test b/mysql-test/t/events_logs_tests.test index 0c56f32beff..8617129b90c 100644 --- a/mysql-test/t/events_logs_tests.test +++ b/mysql-test/t/events_logs_tests.test @@ -58,7 +58,7 @@ TRUNCATE mysql.slow_log; SELECT user_host, query_time, db, sql_text FROM mysql.slow_log; --echo "Set new values" SET GLOBAL long_query_time=4; -SET SESSION long_query_time=1; +SET SESSION long_query_time=0.5; --echo "Check that logging is working" SELECT SLEEP(2); --replace_column 1 USER_HOST 2 SLEEPVAL diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 6597c77e798..90f1fa36bb4 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1725,6 +1725,20 @@ drop table federated.t1; connection slave; drop table federated.t1; +--echo +--echo Bug#18287 create federated table always times out, error 1159 ' ' +--echo +--echo Test that self-references work +--echo +connection slave; +create table federated.t1 (a int primary key); +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table federated.t2 (a int primary key) + ENGINE=FEDERATED + connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +insert into federated.t1 (a) values (1); +select * from federated.t2; +drop table federated.t1, federated.t2; # # BUG#29875 Disable support for transactions diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 6fa2a9ebc51..774e75a79fa 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1100,4 +1100,24 @@ SELECT variable_name FROM server_status; DROP TABLE server_status; SET GLOBAL event_scheduler=0; + +# +# WL#3732 Information schema optimization +# + +explain select table_name from information_schema.views where +table_schema='test' and table_name='v1'; + +explain select * from information_schema.tables; +explain select * from information_schema.collations; + +explain select * from information_schema.tables where +table_schema='test' and table_name= 't1'; +explain select table_name, table_type from information_schema.tables +where table_schema='test'; + +explain select b.table_name +from information_schema.tables a, information_schema.columns b +where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name; + --echo End of 5.1 tests. diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index 2b8b430f096..6069bbf7018 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -148,5 +148,70 @@ LOCK TABLES mysql.time_zone READ, mysql.proc WRITE; DROP TABLE t1; +--echo +--echo Bug#5719 impossible to lock VIEW +--echo +--echo Just covering existing behaviour with tests. +--echo Consistency has not been found here. +--echo +--disable_warnings +drop view if exists v_bug5719; +drop table if exists t1, t2, t3; +--enable_warnings +create table t1 (a int); +create temporary table t2 (a int); +create table t3 (a int); +create view v_bug5719 as select 1; +lock table v_bug5719 write; +--error ER_TABLE_NOT_LOCKED +select * from t1; +--echo +--echo Allowed to select from a temporary talbe under LOCK TABLES +--echo +select * from t2; +--error ER_TABLE_NOT_LOCKED +select * from t3; +select * from v_bug5719; +drop view v_bug5719; +--echo +--echo sic: did not left LOCK TABLES mode automatically +--echo +--error ER_TABLE_NOT_LOCKED +select * from t1; +unlock tables; +create view v_bug5719 as select * from t1; +lock tables v_bug5719 write; +select * from v_bug5719; +--echo +--echo Allowed to use an underlying table under LOCK TABLES <view> +--echo +select * from t1; +--echo +--echo Allowed to select from a temporary table under LOCK TABLES +--echo +select * from t2; +--error ER_TABLE_NOT_LOCKED +select * from t3; +drop table t1; +--echo +--echo sic: left LOCK TABLES mode +--echo +select * from t3; +--error ER_VIEW_INVALID +select * from v_bug5719; +unlock tables; +drop view v_bug5719; +--echo +--echo When limitation to use temporary tables in views is removed, please +--echo add a test that shows what happens under LOCK TABLES when a view +--echo references a temporary table, is locked, and the underlying table +--echo is dropped. +--echo +--error ER_VIEW_SELECT_TMPTABLE +create view v_bug5719 as select * from t2; +--echo +--echo Cleanup. +--echo +drop table t2, t3; --echo End of 5.1 tests. diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 4a6b4ff5e56..b7c406f9637 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -270,3 +270,38 @@ drop table t1; # End of 5.0 tests + +# +# Bug #21281 "Pending write lock is incorrectly removed when its +# statement being KILLed" +# +create table t1 (i int); +connection locker; +lock table t1 read; +connection writer; +--send update t1 set i= 10; +connection reader; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "update t1 set i= 10"; +--source include/wait_condition.inc +--send select * from t1; +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "select * from t1"; +--source include/wait_condition.inc +let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`; +--replace_result $ID ID +eval kill query $ID; +connection reader; +--reap +connection writer; +--error ER_QUERY_INTERRUPTED +--reap +connection locker; +unlock tables; +connection default; +drop table t1; + +--echo End of 5.1 tests diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test index b0bb818b783..c67da261ef1 100644 --- a/mysql-test/t/log_state.test +++ b/mysql-test/t/log_state.test @@ -28,7 +28,7 @@ connection con1; set session long_query_time=1; select sleep(2); --replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME -select * from mysql.slow_log; +select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%'; connection default; set global slow_query_log= ON; @@ -36,7 +36,7 @@ connection con1; set session long_query_time=1; select sleep(2); --replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME -select * from mysql.slow_log; +select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%'; connection default; show global variables where Variable_name = 'log' or Variable_name = 'log_slow_queries' or diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index e7131efa0f3..16f5fecf051 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -275,3 +275,10 @@ EOF --exec $MYSQL --character-sets-dir="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" 2>&1 --echo End of 5.0 tests + +# +# Bug #29903: The CMake build method does not produce the embedded library. +# +--disable_query_log +--exec $MYSQL --server-arg=no-defaults test -e "quit" +--enable_query_log diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 1e520da9f00..37398616299 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -739,3 +739,43 @@ INSERT INTO t2 VALUES (1,1),(1,2),(2,1),(2,2); EXPLAIN SELECT 1 FROM t1,t2 WHERE t1.b=2 AND t1.a=t2.a ORDER BY t2.b; DROP TABLE t1,t2; + +# End of 5.0 + +# +# Bug #28404: query with ORDER BY and ref access +# + +CREATE TABLE t1( + id int auto_increment PRIMARY KEY, c2 int, c3 int, INDEX k2(c2), INDEX k3(c3)); + +INSERT INTO t1 (c2,c3) VALUES + (31,34),(35,38),(34,31),(32,35),(31,39), + (11,14),(15,18),(14,11),(12,15),(11,19); + +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +INSERT INTO t1 (c2,c3) SELECT c2,c3 FROM t1; +UPDATE t1 SET c2=20 WHERE id%100 = 0; +SELECT COUNT(*) FROM t1; + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * FROM t1 ORDER BY id; + +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; +EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 10 AND 12 ORDER BY c3 LIMIT 20; +EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000; + +SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 1f8a00409e6..b513d17bfa0 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3359,4 +3359,34 @@ EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2 WHERE 1 AND f1.b NOT IN (100,2232,3343,51111); DROP TABLE t1; +# +# Bug #27352: Incorrect result of nested selects instead of error reporting +# + +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (1,11), (2,22), (2,22); + +let $n= 31; +let $q= COUNT(c2); +while ($n) +{ + let $q= (SELECT $q); + dec $n; +} +--disable_warnings +eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0; +--enable_warnings + +let $n= 64; +let $q= COUNT(c2); +while ($n) +{ + let $q= (SELECT $q); + dec $n; +} +--error ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT +eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index ae725b3b235..f51b2c1d612 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -272,6 +272,25 @@ handler t1 read a=(1); handler t1 close; drop table t1; +# +# Bug #30219: GROUP BY a column of the BIT type +# + +CREATE TABLE t1 (b BIT(2), a VARCHAR(5)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(5), b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z"); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b BIT(2)); +INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4); +SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b; +DROP TABLE t1; + --echo End of 5.0 tests # diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index efa2ce4a27c..81db143b518 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -268,7 +268,10 @@ set interactive_timeout=100; set join_buffer_size=100; set last_insert_id=1; set global local_infile=1; -set long_query_time=100; +set long_query_time=0.000001; +select @@long_query_time; +set long_query_time=100.000001; +select @@long_query_time; set low_priority_updates=1; set max_allowed_packet=100; set global max_binlog_cache_size=100; @@ -327,6 +330,7 @@ set tmp_table_size=100; set tx_isolation="READ-COMMITTED"; set wait_timeout=100; set log_warnings=1; +set global log_warnings=1; # # Bugs: #20392: INSERT_ID session variable has weird value diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 1ae625c4c03..9fb9a47dad3 100644..100755 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -13,18 +13,23 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -# Need to set USE_TLS, since mysys is linked into libmysql.dll and -# libmysqld.dll, and __declspec(thread) approach to thread local storage does -# not work properly in DLLs. -# Currently, USE_TLS crashes in Debug builds, so until that is fixed Debug -# .dlls cannot be loaded at runtime. -SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DUSE_TLS") -SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DUSE_TLS") +# Only the server link with this library, the client libraries and the client +# executables all link with recompiles of source found in the "mysys" directory. +# So we only need to create one version of this library, with the "static" +# Thread Local Storage model. +# +# Exception is the embedded server that needs this library compiled with +# dynamic TLS, i.e. define USE_TLS + +IF(EMBEDDED_ONLY) + ADD_DEFINITIONS(-DUSE_TLS) + ADD_DEFINITIONS(-DEMBEDDED_LIBRARY) +ENDIF(EMBEDDED_ONLY) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include) ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_modify.c errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c diff --git a/mysys/charset.c b/mysys/charset.c index a9b452b0a55..692d7867fe0 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -326,14 +326,14 @@ static int charset_initialized=0; static my_bool my_read_charset_file(const char *filename, myf myflags) { - char *buf; + uchar *buf; int fd; uint len, tmp_len; MY_STAT stat_info; if (!my_stat(filename, &stat_info, MYF(myflags)) || ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) || - !(buf= (char *)my_malloc(len,myflags))) + !(buf= (uchar*) my_malloc(len,myflags))) return TRUE; if ((fd=my_open(filename,O_RDONLY,myflags)) < 0) @@ -343,7 +343,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) if (tmp_len != len) goto error; - if (my_parse_charset_xml(buf,len,add_collation)) + if (my_parse_charset_xml((char*) buf,len,add_collation)) { #ifdef NOT_YET printf("ERROR at line %d pos %d '%s'\n", @@ -353,7 +353,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) #endif } - my_free(buf, myflags); + my_free(buf, myflags); return FALSE; error: diff --git a/mysys/default_modify.c b/mysys/default_modify.c index b2a43f511b9..78f6105b071 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -218,7 +218,7 @@ int modify_defaults_file(const char *file_location, const char *option, if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, MYF(MY_WME)) || my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || - my_fwrite(cnf_file, file_buffer, (size_t) (dst_ptr - file_buffer), + my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer), MYF(MY_NABP))) goto err; } diff --git a/mysys/hash.c b/mysys/hash.c index 47ddc5aa97d..4532b06b533 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -137,7 +137,7 @@ void my_hash_reset(HASH *hash) DBUG_VOID_RETURN; } - /* some helper functions */ +/* some helper functions */ /* This function is char* instead of uchar* as HPUX11 compiler can't @@ -149,9 +149,9 @@ hash_key(const HASH *hash, const uchar *record, size_t *length, my_bool first) { if (hash->get_key) - return (*hash->get_key)(record,length,first); + return (char*) (*hash->get_key)(record,length,first); *length=hash->key_length; - return (uchar*) record+hash->key_offset; + return (char*) record+hash->key_offset; } /* Calculate pos according to keys */ @@ -313,12 +313,14 @@ my_bool my_hash_insert(HASH *info,const uchar *record) uchar *ptr_to_rec,*ptr_to_rec2; HASH_LINK *data,*empty,*gpos,*gpos2,*pos; - LINT_INIT(gpos); LINT_INIT(gpos2); - LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2); + LINT_INIT(gpos); + LINT_INIT(gpos2); + LINT_INIT(ptr_to_rec); + LINT_INIT(ptr_to_rec2); if (HASH_UNIQUE & info->flags) { - char *key= (char*) hash_key(info, record, &idx, 1); + uchar *key= (uchar*) hash_key(info, record, &idx, 1); if (hash_search(info, key, idx)) return(TRUE); /* Duplicate entry */ } @@ -544,14 +546,16 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key, if (HASH_UNIQUE & hash->flags) { HASH_SEARCH_STATE state; - char *found, *new_key= hash_key(hash, record, &idx, 1); + uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1); if ((found= hash_first(hash, new_key, idx, &state))) + { do { - if (found != (char*) record) + if (found != record) DBUG_RETURN(1); /* Duplicate entry */ } while ((found= hash_next(hash, new_key, idx, &state))); + } } data=dynamic_element(&hash->array,0,HASH_LINK*); diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c index 2f08027a477..3a8e1be6a0b 100644 --- a/mysys/mf_getdate.c +++ b/mysys/mf_getdate.c @@ -42,7 +42,7 @@ void get_date(register char * to, int flag, time_t date) struct tm tm_tmp; #endif - skr=date ? (time_t) date : time((time_t*) 0); + skr=date ? (time_t) date : my_time(0); #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT) if (flag & GETDATE_GMT) localtime_r(&skr,&tm_tmp); diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index 8a5b91661c4..87ea995f518 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -246,7 +246,7 @@ size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length) for (;;) { - char *pos,*end; + uchar *pos, *end; if (length > max_length) length=max_length; for (pos=info->read_pos,end=pos+length ; pos < end ;) @@ -323,7 +323,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) length= (size_t) (fmt - start); out_length+=length; - if (my_b_write(info, start, length)) + if (my_b_write(info, (const uchar*) start, length)) goto err; if (*fmt == '\0') /* End of format */ @@ -378,14 +378,14 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) size_t length2 = strlen(par); /* TODO: implement minimum width and precision */ out_length+= length2; - if (my_b_write(info, par, length2)) + if (my_b_write(info, (uchar*) par, length2)) goto err; } else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */ { char *par = va_arg(args, char *); out_length+= precision; - if (my_b_write(info, par, precision)) + if (my_b_write(info, (uchar*) par, precision)) goto err; } else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ @@ -400,7 +400,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) else length2= (size_t) (int10_to_str((long) (uint) iarg,buff,10)- buff); out_length+= length2; - if (my_b_write(info, buff, length2)) + if (my_b_write(info, (uchar*) buff, length2)) goto err; } else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u') @@ -416,13 +416,13 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) else length2= (size_t) (int10_to_str(iarg,buff,10)- buff); out_length+= length2; - if (my_b_write(info, buff, length2)) + if (my_b_write(info, (uchar*) buff, length2)) goto err; } else { /* %% or unknown code */ - if (my_b_write(info, backtrack, fmt-backtrack)) + if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack))) goto err; out_length+= fmt-backtrack; } diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 1fef8aac170..c81da9a469a 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -366,10 +366,11 @@ static inline uint next_power(uint value) */ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold) { - uint blocks, hash_links, length; + ulong blocks, hash_links; + size_t length; int error; DBUG_ENTER("init_key_cache"); DBUG_ASSERT(key_cache_block_size >= 512); @@ -405,8 +406,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, DBUG_PRINT("info", ("key_cache_block_size: %u", key_cache_block_size)); - blocks= (uint) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + - sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); + blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + + sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); /* It doesn't make sense to have too few blocks (less than 8) */ if (blocks >= 8) { @@ -424,18 +425,18 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(sizeof(HASH_LINK*) * keycache->hash_entries))) + - ((ulong) blocks * keycache->key_cache_block_size) > use_mem) + ((size_t) blocks * keycache->key_cache_block_size) > use_mem) blocks--; /* Allocate memory for cache page buffers */ if ((keycache->block_mem= - my_large_malloc((ulong) blocks * keycache->key_cache_block_size, + my_large_malloc((size_t) blocks * keycache->key_cache_block_size, MYF(MY_WME)))) { /* Allocate memory for blocks, hash_links and hash entries; For each block 2 hash links are allocated */ - if ((keycache->block_root= (BLOCK_LINK*) my_malloc((uint) length, + if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length, MYF(0)))) break; my_large_free(keycache->block_mem, MYF(0)); @@ -448,7 +449,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, } blocks= blocks / 4*3; } - keycache->blocks_unused= (ulong) blocks; + keycache->blocks_unused= blocks; keycache->disk_blocks= (int) blocks; keycache->hash_links= hash_links; keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root + @@ -556,7 +557,7 @@ err: */ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold) { int blocks; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 99c0c959d94..a31b9595c85 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -56,7 +56,7 @@ void pack_dirname(char * to, const char *from) (buff_length == d_length && !bcmp(buff,start,d_length))) && *start != FN_LIBCHAR && *start) { /* Put current dir before */ - bchange(to,d_length,buff,buff_length,strlen(to)+1); + bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1); } } @@ -328,7 +328,7 @@ size_t unpack_dirname(char * to, const char *from) if (buff+h_length < suffix) bmove(buff+h_length,suffix,length); else - bmove_upp(buff+h_length+length,suffix+length,length); + bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length); bmove(buff,tilde_expansion,h_length); } } diff --git a/mysys/mf_path.c b/mysys/mf_path.c index 7baded9d715..73e73cb7f76 100644 --- a/mysys/mf_path.c +++ b/mysys/mf_path.c @@ -46,7 +46,7 @@ char * my_path(char * to, const char *progname, if (!test_if_hard_path(to)) { if (!my_getwd(curr_dir,FN_REFLEN,MYF(0))) - bchange(to,0,curr_dir, (uint) strlen(curr_dir), (uint) strlen(to)+1); + bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1); } } else diff --git a/mysys/my_append.c b/mysys/my_append.c index ddd3c91e832..35881a959d5 100644 --- a/mysys/my_append.c +++ b/mysys/my_append.c @@ -27,21 +27,22 @@ struct utimbuf { }; #endif - /* Append a file to another */ - -int my_append(const char *from, const char *to, myf MyFlags) +/* + Append a file to another + NOTES + Don't set MY_FNABP or MY_NABP bits on when calling this function +*/ - /* Dont set MY_FNABP or MY_NABP bits on - when calling this funktion */ +int my_append(const char *from, const char *to, myf MyFlags) { uint Count; File from_file,to_file; - char buff[IO_SIZE]; + uchar buff[IO_SIZE]; DBUG_ENTER("my_append"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); - from_file=to_file= -1; + from_file= to_file= -1; if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0) { diff --git a/mysys/my_compress.c b/mysys/my_compress.c index d495a1c1c6d..bc9f8317487 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -154,17 +154,20 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen) SYNOPSIS packfrm() - data Data reference to frm file data + data Data reference to frm file data. len Length of frm file data out:pack_data Reference to the pointer to the packed frm data out:pack_len Length of packed frm file data + NOTES + data is replaced with compressed content + RETURN VALUES 0 Success >0 Failure */ -int packfrm(const uchar *data, size_t len, +int packfrm(uchar *data, size_t len, uchar **pack_data, size_t *pack_len) { int error; @@ -178,8 +181,8 @@ int packfrm(const uchar *data, size_t len, if (my_compress((uchar*)data, &org_len, &comp_len)) goto err; - DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len)); - DBUG_DUMP("compressed", (char*)data, org_len); + DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len)); + DBUG_DUMP("compressed", data, org_len); error= 2; blob_len= BLOB_HEADER + org_len; @@ -235,7 +238,7 @@ int unpackfrm(uchar **unpack_data, size_t *unpack_len, complen= uint4korr(pack_data+8); DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu", - ver, complen, orglen)); + ver, (ulong) complen, (ulong) orglen)); DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen); if (ver != 1) diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 3f8b0695a25..cd741b1eb52 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -54,7 +54,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; - char buff[IO_SIZE]; + uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); @@ -80,10 +80,12 @@ int my_copy(const char *from, const char *to, myf MyFlags) MyFlags)) < 0) goto err; - while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0) + while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) + { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; + } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 01abc02058b..845b5aa4152 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -19,7 +19,7 @@ #include "mysys_priv.h" #include <m_string.h> -#ifndef MAIN +#if !defined(__FreeBSD__) || defined(__linux__) static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) { uint i, res=1; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 32a5452e451..3a5b130e067 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -32,6 +32,7 @@ my_bool getopt_compare_strings(const char *s, static longlong getopt_ll(char *arg, const struct my_option *optp, int *err); static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err); +static double getopt_double(char *arg, const struct my_option *optp, int *err); static void init_variables(const struct my_option *options); static int setval(const struct my_option *opts, uchar* *value, char *argument, my_bool set_maximum_value); @@ -611,6 +612,9 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument, case GET_ULL: *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err); break; + case GET_DOUBLE: + *((double*) result_pos)= getopt_double(argument, opts, &err); + break; case GET_STR: *((char**) result_pos)= argument; break; @@ -720,7 +724,7 @@ my_bool getopt_compare_strings(register const char *s, register const char *t, be k|K for kilo, m|M for mega or g|G for giga. */ -static longlong eval_num_suffix (char *argument, int *error, char *option_name) +static longlong eval_num_suffix(char *argument, int *error, char *option_name) { char *endchar; longlong num; @@ -802,6 +806,37 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) /* + Get double value withing ranges + + Evaluates and returns the value that user gave as an argument to a variable. + + RETURN + decimal value of arg + + In case of an error, prints an error message and sets *err to + EXIT_ARGUMENT_INVALID. Otherwise err is not touched +*/ + +static double getopt_double(char *arg, const struct my_option *optp, int *err) +{ + double num; + int error; + char *end= arg + 1000; /* Big enough as *arg is \0 terminated */ + num= my_strtod(arg, &end, &error); + if (end[0] != 0 || error) + { + fprintf(stderr, + "%s: ERROR: Invalid decimal value for option '%s'\n", + my_progname, optp->name); + *err= EXIT_ARGUMENT_INVALID; + return 0.0; + } + if (optp->max_value && num > (double) optp->max_value) + num= (double) optp->max_value; + return max(num, (double) optp->min_value); +} + +/* Init one value to it's default values SYNOPSIS @@ -838,6 +873,9 @@ static void init_one_value(const struct my_option *option, uchar* *variable, case GET_SET: *((ulonglong*) variable)= (ulonglong) value; break; + case GET_DOUBLE: + *((double*) variable)= (double) value; + break; case GET_STR: /* Do not clear variable value if it has no default value. @@ -1052,6 +1090,9 @@ void my_print_variables(const struct my_option *options) longlong2str(*((ulonglong*) value), buff, 10); printf("%s\n", buff); break; + case GET_DOUBLE: + printf("%g\n", *(double*) value); + break; default: printf("(Disabled)\n"); break; diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index 2fd7eed7778..43bb6c08af9 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -17,11 +17,13 @@ /* thus to get the current time we should use the system function with the highest possible resolution */ +#include "mysys_priv.h" +#include "my_static.h" + #ifdef __NETWARE__ #include <nks/time.h> #endif -#include "mysys_priv.h" ulonglong my_getsystime() { #ifdef HAVE_CLOCK_GETTIME @@ -29,28 +31,15 @@ ulonglong my_getsystime() clock_gettime(CLOCK_REALTIME, &tp); return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; #elif defined(__WIN__) -#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) - static __int64 offset=0, freq; LARGE_INTEGER t_cnt; - if (!offset) + if (query_performance_frequency) { - /* strictly speaking there should be a mutex to protect - initialization section. But my_getsystime() is called from - UUID() code, and UUID() calls are serialized with a mutex anyway - */ - LARGE_INTEGER li; - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - li.LowPart=ft.dwLowDateTime; - li.HighPart=ft.dwHighDateTime; - offset=li.QuadPart-OFFSET_TO_EPOC; - QueryPerformanceFrequency(&li); - freq=li.QuadPart; QueryPerformanceCounter(&t_cnt); - offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq; + return (t_cnt.QuadPart / query_performance_frequency * 10000000+ + t_cnt.QuadPart % query_performance_frequency * 10000000/ + query_performance_frequency+query_performance_offset); } - QueryPerformanceCounter(&t_cnt); - return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset; + return 0; #elif defined(__NETWARE__) NXTime_t tm; NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm); @@ -62,3 +51,176 @@ ulonglong my_getsystime() return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10; #endif } + + +/* + Return current time + + SYNOPSIS + my_time() + flags If MY_WME is set, write error if time call fails + +*/ + +time_t my_time(myf flags __attribute__((unused))) +{ + time_t t; +#ifdef HAVE_GETHRTIME + (void) my_micro_time_and_time(&t); + return t; +#else + /* The following loop is here beacuse time() may fail on some systems */ + while ((t= time(0)) == (time_t) -1) + { + if (flags & MY_WME) + fprintf(stderr, "%s: Warning: time() call failed\n", my_progname); + } + return t; +#endif +} + + +/* + Return time in micro seconds + + SYNOPSIS + my_micro_time() + + NOTES + This function is to be used to measure performance in micro seconds. + As it's not defined whats the start time for the clock, this function + us only useful to measure time between two moments. + + For windows platforms we need the frequency value of the CUP. This is + initalized in my_init.c through QueryPerformanceFrequency(). + + If Windows platform doesn't support QueryPerformanceFrequency() we will + obtain the time via GetClockCount, which only supports milliseconds. + + RETURN + Value in microseconds from some undefined point in time +*/ + +ulonglong my_micro_time() +{ + ulonglong newtime; +#if defined(__WIN__) + if (query_performance_frequency) + { + QueryPerformanceCounter((LARGE_INTEGER*) &newtime); + newtime/= (query_performance_frequency * 1000000); + } + else + newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */ + return newtime; +#elif defined(HAVE_GETHRTIME) + return gethrtime()/1000; +#else + struct timeval t; + /* The following loop is here because gettimeofday may fail on some systems */ + while (gettimeofday(&t, NULL) != 0) + {} + newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; + return newtime; +#endif /* defined(__WIN__) */ +} + + +/* + Return time in seconds and timer in microseconds (not different start!) + + SYNOPSIS + my_micro_time_and_time() + time_arg Will be set to seconds since epoch (00:00:00 UTC, January 1, + 1970) + + NOTES + This function is to be useful when we need both the time and microtime. + For example in MySQL this is used to get the query time start of a query and + to measure the time of a query (for the slow query log) + + IMPLEMENTATION + Value of time is as in time() call. + Value of microtime is same as my_micro_time(), which may be totally unrealated + to time() + + RETURN + Value in microseconds from some undefined point in time +*/ + +#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */ + +ulonglong my_micro_time_and_time(time_t *time_arg) +{ + ulonglong newtime; +#if defined(__WIN__) + if (query_performance_frequency) + { + QueryPerformanceCounter((LARGE_INTEGER*) &newtime); + newtime/= (query_performance_frequency * 1000000); + } + else + newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */ + (void) time(time_arg); + return newtime; +#elif defined(HAVE_GETHRTIME) + /* + Solaris has a very slow time() call. We optimize this by using the very fast + gethrtime() call and only calling time() every 1/2 second + */ + static hrtime_t prev_gethrtime= 0; + static time_t cur_time= 0; + hrtime_t cur_gethrtime; + + pthread_mutex_lock(&THR_LOCK_time); + cur_gethrtime= gethrtime(); + if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS) + { + cur_time= time(0); + prev_gethrtime= cur_gethrtime; + } + *time_arg= cur_time; + pthread_mutex_unlock(&THR_LOCK_time); + return cur_gethrtime/1000; +#else + struct timeval t; + /* The following loop is here because gettimeofday may fail on some systems */ + while (gettimeofday(&t, NULL) != 0) + {} + *time_arg= t.tv_sec; + newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; + return newtime; +#endif /* defined(__WIN__) */ +} + + +/* + Returns current time + + SYNOPSIS + my_time_possible_from_micro() + microtime Value from very recent my_micro_time() + + NOTES + This function returns the current time. The microtime argument is only used + if my_micro_time() uses a function that can safely be converted to the current + time. + + RETURN + current time +*/ + +time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused))) +{ +#if defined(__WIN__) + time_t t; + while ((t= time(0)) == (time_t) -1) + {} + return t; +#elif defined(HAVE_GETHRTIME) + return my_time(0); /* Cached time */ +#else + return (time_t) (microtime / 1000000); +#endif /* defined(__WIN__) */ +} + diff --git a/mysys/my_init.c b/mysys/my_init.c index c1337205eb4..257edb351b4 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -130,17 +130,18 @@ void my_end(int infoflag) */ FILE *info_file= DBUG_FILE; my_bool print_info= (info_file != stderr); - /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer - operational, so we cannot use DBUG_RETURN. + /* + We do not use DBUG_ENTER here, as after cleanup DBUG is no longer + operational, so we cannot use DBUG_RETURN. */ - DBUG_PRINT("info",("Shutting down")); + DBUG_PRINT("info",("Shutting down: infoflag: %d print_info: %d", + infoflag, print_info)); if (!info_file) { info_file= stderr; print_info= 0; } - DBUG_PRINT("info",("Shutting down: print_info: %d", print_info)); if ((infoflag & MY_CHECK_ERROR) || print_info) { /* Test if some file is left open */ @@ -185,7 +186,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC); #endif #if defined(SAFEMALLOC) - TERMINATE(stderr); /* Give statistic on screen */ + TERMINATE(stderr, (infoflag & MY_GIVE_INFO) != 0); #elif defined(__WIN__) && defined(_MSC_VER) _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); @@ -197,6 +198,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", _CrtDumpMemoryLeaks(); #endif } + else if (infoflag & MY_CHECK_ERROR) + { + TERMINATE(stderr, 0); /* Print memory leaks on screen */ + } if (!(infoflag & MY_DONT_FREE_DBUG)) { @@ -371,6 +376,28 @@ static void my_win_init(void) /* chiude la chiave */ RegCloseKey(hSoftMysql) ; + + /* The following is used by time functions */ +#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) +#define MS 10000000 + { + FILETIME ft; + LARGE_INTEGER li, t_cnt; + DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); + if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency)) + query_performance_frequency= 0; + else + { + GetSystemTimeAsFileTime(&ft); + li.LowPart= ft.dwLowDateTime; + li.HighPart= ft.dwHighDateTime; + query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; + QueryPerformanceCounter(&t_cnt); + query_performance_offset-= (t_cnt.QuadPart / query_performance_frequency * MS + + t_cnt.QuadPart % query_performance_frequency * MS / + query_performance_frequency); + } + } DBUG_VOID_RETURN ; } diff --git a/mysys/my_static.c b/mysys/my_static.c index 472cf3b5084..b8bff0e9810 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -18,11 +18,9 @@ a shared library */ -#if !defined(stdin) #include "mysys_priv.h" #include "my_static.h" #include "my_alarm.h" -#endif my_bool timed_mutexes= 0; @@ -93,6 +91,11 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)= int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)= my_message_no_curses; +#ifdef __WIN__ +/* from my_getsystime.c */ +ulonglong query_performance_frequency, query_performance_offset; +#endif + /* How to disable options */ my_bool NEAR my_disable_locking=0; my_bool NEAR my_disable_async_io=0; diff --git a/mysys/my_static.h b/mysys/my_static.h index 66e6ea1c280..0eca196c1c9 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -66,6 +66,8 @@ extern struct st_irem *sf_malloc_root; extern struct st_my_file_info my_file_info_default[MY_NFILE]; +extern ulonglong query_performance_frequency, query_performance_offset; + #if defined(THREAD) && !defined(__WIN__) extern sigset_t my_signals; /* signals blocked by mf_brkhant */ #endif diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index cc33ac3f21c..8b935c895c8 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -30,7 +30,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys); #endif /* USE_TLS */ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, - THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads; + THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time; pthread_cond_t THR_COND_threads; uint THR_thread_count= 0; uint my_thread_end_wait_time= 5; @@ -146,6 +146,7 @@ my_bool my_thread_global_init(void) pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); + pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST); pthread_cond_init(&THR_COND_threads, NULL); #if defined( __WIN__) || defined(OS2) win_pthread_init(); @@ -202,6 +203,7 @@ void my_thread_global_end(void) pthread_mutex_destroy(&THR_LOCK_myisam); pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_net); + pthread_mutex_destroy(&THR_LOCK_time); pthread_mutex_destroy(&THR_LOCK_charset); if (all_threads_killed) { diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 709cfed969a..6e0959ae08c 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -28,7 +28,7 @@ #include <my_pthread.h> extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; -extern pthread_mutex_t THR_LOCK_charset; +extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; #else #include <my_no_pthread.h> #endif diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 30c501c54ee..7a2f448b2dc 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -51,7 +51,7 @@ (equivalent to realloc()) FREE( pPtr ) Free memory allocated by NEW (equivalent to free()) - TERMINATE(file) End system, report errors and stats on file + TERMINATE(file,flag) End system, report errors and stats on file I personally use two more functions, but have not included them here: char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory char *RENEW( pPtr, uSize ) @@ -352,12 +352,15 @@ static int check_ptr(const char *where, uchar *ptr, const char *filename, /* - TERMINATE(FILE *file) - Report on all the memory pieces that have not been - free'ed as well as the statistics. + Report on all the memory pieces that have not been free'ed + + SYNOPSIS + TERMINATE() + file Write output to this file + flag If <> 0, also write statistics */ -void TERMINATE(FILE *file) +void TERMINATE(FILE *file, uint flag) { struct st_irem *irem; DBUG_ENTER("TERMINATE"); @@ -373,8 +376,7 @@ void TERMINATE(FILE *file) { if (file) { - fprintf(file, "Warning: Not freed memory segments: %u\n", - sf_malloc_count); + fprintf(file, "Warning: Not freed memory segments: %u\n", sf_malloc_count); (void) fflush(file); } DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count)); @@ -414,7 +416,7 @@ void TERMINATE(FILE *file) } } /* Report the memory usage statistics */ - if (file) + if (file && flag) { fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n", sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L); diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 81093be3678..2934e724724 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -157,7 +157,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) DBUG_ENTER("thr_alarm"); DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec)); - now=(ulong) time((time_t*) 0); + now=(ulong) my_time(0); pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ if (alarm_aborted > 0) @@ -351,7 +351,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) } else { - ulong now=(ulong) time((time_t*) 0); + ulong now=(ulong) my_time(0); ulong next=now+10-(now%10); while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now) { @@ -480,7 +480,7 @@ void thr_alarm_info(ALARM_INFO *info) info->max_used_alarms= max_used_alarms; if ((info->active_alarms= alarm_queue.elements)) { - ulong now=(ulong) time((time_t*) 0); + ulong now=(ulong) my_time(0); long time_diff; ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue); time_diff= (long) (alarm_data->expire_time - now); @@ -528,7 +528,7 @@ static void *alarm_handler(void *arg __attribute__((unused))) { if (alarm_queue.elements) { - ulong sleep_time,now=time((time_t*) 0); + ulong sleep_time,now= my_time(0); if (alarm_aborted) sleep_time=now+1; else @@ -685,7 +685,7 @@ static void *test_thread(void *arg) for (i=1 ; i <= 10 ; i++) { wait_time=param ? 11-i : i; - start_time=time((time_t*) 0); + start_time= my_time(0); if (thr_alarm(&got_alarm,wait_time,0)) { printf("Thread: %s Alarms aborted\n",my_thread_name()); @@ -747,7 +747,7 @@ static void *test_thread(void *arg) } } printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(), - (int) (time((time_t*) 0)-start_time), wait_time); fflush(stdout); + (int) (my_time(0)-start_time), wait_time); fflush(stdout); thr_end_alarm(&got_alarm); fflush(stdout); } diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 20edffb49c2..a81ed925562 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -384,6 +384,9 @@ static inline my_bool have_specific_lock(THR_LOCK_DATA *data, } +static void wake_up_waiters(THR_LOCK *lock); + + static enum enum_thr_lock_result wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, my_bool in_wait_list) @@ -445,8 +448,13 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, else wait->last=data->prev; data->type= TL_UNLOCK; /* No lock */ + check_locks(data->lock, "killed or timed out wait_for_lock", 1); + wake_up_waiters(data->lock); + } + else + { + check_locks(data->lock, "aborted wait_for_lock", 0); } - check_locks(data->lock,"failed wait_for_lock",0); } else { @@ -776,6 +784,26 @@ void thr_unlock(THR_LOCK_DATA *data) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ check_locks(lock,"after releasing lock",1); + wake_up_waiters(lock); + pthread_mutex_unlock(&lock->mutex); + DBUG_VOID_RETURN; +} + + +/** + @brief Wake up all threads which pending requests for the lock + can be satisfied. + + @param lock Lock for which threads should be woken up + +*/ + +static void wake_up_waiters(THR_LOCK *lock) +{ + THR_LOCK_DATA *data; + enum thr_lock_type lock_type; + + DBUG_ENTER("wake_up_waiters"); if (!lock->write.data) /* If no active write locks */ { @@ -827,11 +855,7 @@ void thr_unlock(THR_LOCK_DATA *data) data=lock->write_wait.data; /* Free this too */ } if (data->type >= TL_WRITE_LOW_PRIORITY) - { - check_locks(lock,"giving write lock",0); - pthread_mutex_unlock(&lock->mutex); - DBUG_VOID_RETURN; - } + goto end; /* Release possible read locks together with the write lock */ } if (lock->read_wait.data) @@ -886,8 +910,7 @@ void thr_unlock(THR_LOCK_DATA *data) free_all_read_locks(lock,0); } end: - check_locks(lock,"thr_unlock",0); - pthread_mutex_unlock(&lock->mutex); + check_locks(lock, "after waking up waiters", 0); DBUG_VOID_RETURN; } @@ -1101,6 +1124,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) lock->write_wait.last= data->prev; } } + wake_up_waiters(lock); pthread_mutex_unlock(&lock->mutex); DBUG_RETURN(found); } diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt index 9b95c9d2bc6..9b95c9d2bc6 100644..100755 --- a/regex/CMakeLists.txt +++ b/regex/CMakeLists.txt diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index e9113b098da..6fbfcab72d4 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -24,7 +24,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tabl # Build comp_sql - used for embedding SQL in C or C++ programs ADD_EXECUTABLE(comp_sql comp_sql.c) -TARGET_LINK_LIBRARIES(comp_sql dbug mysys strings) +TARGET_LINK_LIBRARIES(comp_sql debug dbug mysys strings) # Use comp_sql to build mysql_fix_privilege_tables_sql.c GET_TARGET_PROPERTY(COMP_SQL_EXE comp_sql LOCATION) diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 480ea39b2cf..957a5a6768d 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -127,6 +127,8 @@ if [ -e $DESTDIR ] ; then usage fi +trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR + # ---------------------------------------------------------------------- # Adjust target name if needed, release with debug info has another name # ---------------------------------------------------------------------- @@ -137,19 +139,16 @@ then fi # ---------------------------------------------------------------------- -# Copy executables, and client DLL (FIXME why?) +# Copy executables, and client DLL # ---------------------------------------------------------------------- -trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR - mkdir $DESTDIR mkdir $DESTDIR/bin cp client/$TARGET/*.exe $DESTDIR/bin/ cp extra/$TARGET/*.exe $DESTDIR/bin/ cp storage/myisam/$TARGET/*.exe $DESTDIR/bin/ cp server-tools/instance-manager/$TARGET/*.{exe,map} $DESTDIR/bin/ -if [ x"$TARGET" != x"release" ] -then +if [ x"$TARGET" != x"release" ] ; then cp server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/ fi cp tests/$TARGET/*.exe $DESTDIR/bin/ @@ -161,8 +160,7 @@ mv $DESTDIR/bin/comp_err.exe $DESTDIR/bin/comp-err.exe cp sql/$TARGET/mysqld.exe $DESTDIR/bin/mysqld$EXE_SUFFIX.exe cp sql/$TARGET/mysqld.map $DESTDIR/bin/mysqld$EXE_SUFFIX.map -if [ x"$TARGET" != x"release" ] -then +if [ x"$TARGET" != x"release" ] ; then cp sql/$TARGET/mysqld.pdb $DESTDIR/bin/mysqld$EXE_SUFFIX.pdb fi @@ -177,9 +175,8 @@ fi # Copy data directory, readme files etc # ---------------------------------------------------------------------- -# FIXME is there ever a data directory to copy? if [ -d win/data ] ; then - cp -pR win/data $DESTDIR/data + cp -pR win/data $DESTDIR/ fi # FIXME maybe a flag to define "release build", or do the @@ -209,16 +206,22 @@ copy_embedded() $DESTDIR/include cp libmysqld/libmysqld.def $DESTDIR/include/ cp libmysqld/$TARGET/mysqlserver.lib $DESTDIR/Embedded/static/release/ + cp libmysqld/$TARGET/mysqlserver.pdb $DESTDIR/Embedded/static/release/ cp libmysqld/$TARGET/libmysqld.dll $DESTDIR/Embedded/DLL/release/ cp libmysqld/$TARGET/libmysqld.exp $DESTDIR/Embedded/DLL/release/ cp libmysqld/$TARGET/libmysqld.lib $DESTDIR/Embedded/DLL/release/ + cp libmysqld/$TARGET/libmysqld.pdb $DESTDIR/Embedded/DLL/release/ if [ x"$PACK_DEBUG" = x"" -a -f "libmysqld/debug/libmysqld.lib" -o \ x"$PACK_DEBUG" = x"yes" ] ; then - mkdir -p $DESTDIR/Embedded/DLL/debug + mkdir -p $DESTDIR/Embedded/DLL/debug \ + $DESTDIR/Embedded/static/debug + cp libmysqld/debug/mysqlserver.lib $DESTDIR/Embedded/static/debug/ + cp libmysqld/debug/mysqlserver.pdb $DESTDIR/Embedded/static/debug/ cp libmysqld/debug/libmysqld.dll $DESTDIR/Embedded/DLL/debug/ cp libmysqld/debug/libmysqld.exp $DESTDIR/Embedded/DLL/debug/ cp libmysqld/debug/libmysqld.lib $DESTDIR/Embedded/DLL/debug/ + cp libmysqld/debug/libmysqld.pdb $DESTDIR/Embedded/DLL/debug/ fi } @@ -230,45 +233,47 @@ if [ x"$PACK_EMBEDDED" = x"" -a \ fi # ---------------------------------------------------------------------- -# FIXME test stuff that is useless garbage? -# ---------------------------------------------------------------------- - -mkdir -p $DESTDIR/examples/libmysqltest/release -cp libmysql/mytest.c libmysql/myTest.vcproj libmysql/$TARGET/myTest.exe \ - $DESTDIR/examples/libmysqltest/ -cp libmysql/$TARGET/myTest.exe $DESTDIR/examples/libmysqltest/release/ - -if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/myTest.exe" -o \ - x"$PACK_DEBUG" = x"yes" ] ; then - mkdir -p $DESTDIR/examples/libmysqltest/debug - cp libmysql/debug/myTest.exe $DESTDIR/examples/libmysqltest/debug/ -fi - -mkdir -p $DESTDIR/examples/tests -cp tests/*.res tests/*.tst tests/*.pl tests/*.c $DESTDIR/examples/tests/ - -mkdir -p $DESTDIR/examples/udf_example -cp sql/udf_example.def sql/udf_example.vcproj sql/udf_example.c $DESTDIR/examples/udf_example/ - -# ---------------------------------------------------------------------- -# FIXME why not copy it all in "include"?! +# Note: Make sure to sync with include/Makefile.am and WiX installer +# XML specifications # ---------------------------------------------------------------------- mkdir -p $DESTDIR/include -cp include/conf*.h \ - include/mysql*.h \ - include/errmsg.h \ - include/my_alloc.h \ - include/my_getopt.h \ - include/my_sys.h \ +cp include/mysql.h \ + include/mysql_com.h \ + include/mysql_time.h \ include/my_list.h \ - include/my_pthread.h \ + include/my_alloc.h \ + include/typelib.h \ include/my_dbug.h \ include/m_string.h \ - include/m_ctype.h \ + include/my_sys.h \ + include/my_xml.h \ + include/mysql_embed.h \ + include/my_pthread.h \ + include/my_no_pthread.h \ + include/decimal.h \ + include/errmsg.h \ include/my_global.h \ - include/typelib.h $DESTDIR/include/ -cp libmysql/libmysql.def $DESTDIR/include/ + include/my_net.h \ + include/my_getopt.h \ + include/sslopt-longopts.h \ + include/my_dir.h \ + include/sslopt-vars.h \ + include/sslopt-case.h \ + include/sql_common.h \ + include/keycache.h \ + include/m_ctype.h \ + include/my_attribute.h \ + include/mysqld_error.h \ + include/sql_state.h \ + include/mysqld_ername.h \ + include/mysql_version.h \ + include/config-win.h \ + libmysql/libmysql.def \ + $DESTDIR/include/ + +mkdir -p $DESTDIR/include/mysql +cp include/mysql/plugin.h $DESTDIR/include/mysql/ # ---------------------------------------------------------------------- # Client libraries, and other libraries @@ -278,7 +283,8 @@ cp libmysql/libmysql.def $DESTDIR/include/ mkdir -p $DESTDIR/lib/opt cp libmysql/$TARGET/libmysql.dll \ libmysql/$TARGET/libmysql.lib \ - client/$TARGET/mysqlclient.lib \ + libmysql/$TARGET/mysqlclient.lib \ + mysys/$TARGET/mysys.lib \ regex/$TARGET/regex.lib \ strings/$TARGET/strings.lib \ zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/ @@ -288,59 +294,28 @@ if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \ mkdir -p $DESTDIR/lib/debug cp libmysql/debug/libmysql.dll \ libmysql/debug/libmysql.lib \ - client/debug/mysqlclient.lib \ + libmysql/debug/mysqlclient.lib \ mysys/debug/mysys.lib \ regex/debug/regex.lib \ strings/debug/strings.lib \ zlib/debug/zlib.lib $DESTDIR/lib/debug/ fi -# FIXME sort this out... -cp mysys/$TARGET/mysys.lib $DESTDIR/lib/opt/mysys_tls.lib - # ---------------------------------------------------------------------- # Copy the test directory # ---------------------------------------------------------------------- -mkdir -p $DESTDIR/mysql-test/include $DESTDIR/mysql-test/lib \ - $DESTDIR/mysql-test/r $DESTDIR/mysql-test/std_data \ - $DESTDIR/mysql-test/t $DESTDIR/mysql-test/suite +mkdir $DESTDIR/mysql-test cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/ cp mysql-test/README $DESTDIR/mysql-test/ -cp mysql-test/install_test_db.sh $DESTDIR/mysql-test/install_test_db -cp mysql-test/include/*.inc $DESTDIR/mysql-test/include/ -cp mysql-test/lib/*.pl $DESTDIR/mysql-test/lib/ -cp mysql-test/r/*.require $DESTDIR/mysql-test/r/ -# Need this trick, or we get "argument list too long". -ABS_DST=`pwd`/$DESTDIR -(cd mysql-test/r/ && cp *.result $ABS_DST/mysql-test/r/) -cp mysql-test/std_data/Moscow_leap $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/des_key_file $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.000001 $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.cnf $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.dat $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.frm $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.pem $DESTDIR/mysql-test/std_data/ -cp mysql-test/std_data/*.MY* $DESTDIR/mysql-test/std_data/ -cp mysql-test/t/*.opt $DESTDIR/mysql-test/t/ -cp mysql-test/t/*.sh $DESTDIR/mysql-test/t/ -cp mysql-test/t/*.slave-mi $DESTDIR/mysql-test/t/ || /bin/true -cp mysql-test/t/*.sql $DESTDIR/mysql-test/t/ -cp mysql-test/t/*.def $DESTDIR/mysql-test/t/ -(cd mysql-test/t/ && cp *.test $ABS_DST/mysql-test/t/) +cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/ # Note that this will not copy "extra" if a soft link if [ -d mysql-test/extra ] ; then - mkdir -p $DESTDIR/mysql-test/extra + mkdir $DESTDIR/mysql-test/extra cp -pR mysql-test/extra/* $DESTDIR/mysql-test/extra/ fi -# Copy all directories in mysql-test/suite/ -for i in `cd mysql-test/suite && ls`; do \ - mkdir -p $DESTDIR/mysql-test/suite/$i; \ - cp -R mysql-test/suite/$i $DESTDIR/mysql-test/suite/; \ -done - # ---------------------------------------------------------------------- # Copy what could be usable in the "scripts" directory. Currently # only SQL files, others are Bourne shell scripts or Perl scripts @@ -366,11 +341,19 @@ for i in `cd scripts && ls`; do \ done cp -pR sql/share $DESTDIR/ +cp -pR sql-bench $DESTDIR/ +rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile* # The SQL initialisation code is really expected to be in "share" mv $DESTDIR/scripts/*.sql $DESTDIR/share/ || true # ---------------------------------------------------------------------- +# Clean up from possibly copied SCCS directories +# ---------------------------------------------------------------------- + +rm -rf `find $DISTDIR -type d -name SCCS -print` + +# ---------------------------------------------------------------------- # Copy other files specified on command line DEST=SOURCE # ---------------------------------------------------------------------- diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt index f8a8a7e57d0..d11507229bf 100644..100755 --- a/server-tools/instance-manager/CMakeLists.txt +++ b/server-tools/instance-manager/CMakeLists.txt @@ -31,7 +31,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc ../../libmysql/errmsg.c) ADD_DEPENDENCIES(mysqlmanager GenError) -TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32) +TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32) IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker") diff --git a/sql-common/client.c b/sql-common/client.c index cdf9eed8574..ce891a37b21 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -232,7 +232,7 @@ static int wait_for_data(my_socket fd, uint timeout) implementations of select that don't adjust tv upon failure to reflect the time remaining */ - start_time = time(NULL); + start_time= my_time(0); for (;;) { tv.tv_sec = (long) timeout; @@ -246,7 +246,7 @@ static int wait_for_data(my_socket fd, uint timeout) #endif if (res == 0) /* timeout */ return -1; - now_time=time(NULL); + now_time= my_time(0); timeout-= (uint) (now_time - start_time); if (errno != EINTR || (int) timeout <= 0) return -1; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index c792e10c3af..1400c1487d0 100644..100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -84,26 +84,26 @@ ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX} ${PROJECT_SOURCE_DIR}/sql/sql_builtin.cc ${PROJECT_SOURCE_DIR}/sql/lex_hash.h) TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} - heap myisam myisammrg mysys yassl zlib dbug yassl + heap myisam myisammrg mysys yassl zlib debug dbug yassl taocrypt strings vio regex wsock32 ws2_32) IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("mysqld" "asInvoker") ENDIF(EMBED_MANIFESTS) IF(WITH_ARCHIVE_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld archive) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} archive) ENDIF(WITH_ARCHIVE_STORAGE_ENGINE) IF(WITH_BLACKHOLE_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld blackhole) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} blackhole) ENDIF(WITH_BLACKHOLE_STORAGE_ENGINE) IF(WITH_CSV_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld csv) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} csv) ENDIF(WITH_CSV_STORAGE_ENGINE) IF(WITH_EXAMPLE_STORAGE_ENGINE) TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} example) ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) IF(WITH_FEDERATED_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld federated) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} federated) ENDIF(WITH_FEDERATED_STORAGE_ENGINE) IF(WITH_INNOBASE_STORAGE_ENGINE) TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} innobase) diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 144a87e13f6..2ab77ad6b11 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1645,7 +1645,7 @@ err: void Event_queue_element::mark_last_executed(THD *thd) { - thd->end_time(); + thd->set_current_time(); last_executed= (my_time_t) thd->query_start(); last_executed_changed= TRUE; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 04449dd48a1..95f207844fc 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -550,7 +550,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, top= ((Event_queue_element*) queue_element(&queue, 0)); - thd->end_time(); /* Get current time */ + thd->set_current_time(); /* Get current time */ next_activation_at= top->execute_at; if (next_activation_at > thd->query_start()) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index c552b22e942..3092521fd4c 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -283,8 +283,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) res= post_init_event_thread(thd); DBUG_ENTER("Event_worker_thread::run"); - DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", - (long) time(NULL), (long) thd)); + DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd)); if (res) goto end; diff --git a/sql/field.cc b/sql/field.cc index b1b89d16bbb..e3333c14573 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4704,15 +4704,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; } } - -#ifdef WORDS_BIGENDIAN - if (table && table->s->db_low_byte_first) - { - int4store(ptr,tmp); - } - else -#endif - longstore(ptr,tmp); + store_timestamp(tmp); return error; } @@ -4772,19 +4764,10 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATETIME, 1); -#ifdef WORDS_BIGENDIAN - if (table && table->s->db_low_byte_first) - { - int4store(ptr,timestamp); - } - else -#endif - longstore(ptr,(uint32) timestamp); - + store_timestamp(timestamp); return error; } - double Field_timestamp::val_real(void) { ASSERT_COLUMN_MARKED_FOR_READ; @@ -4798,6 +4781,7 @@ longlong Field_timestamp::val_int(void) MYSQL_TIME time_tmp; THD *thd= table ? table->in_use : current_thd; + thd->time_zone_used= 1; #ifdef WORDS_BIGENDIAN if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); @@ -4809,7 +4793,6 @@ longlong Field_timestamp::val_int(void) return(0); /* purecov: inspected */ thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp); - thd->time_zone_used= 1; return time_tmp.year * LL(10000000000) + time_tmp.month * LL(100000000) + time_tmp.day * 1000000L + time_tmp.hour * 10000L + @@ -4829,6 +4812,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) to= (char*) val_buffer->ptr(); val_buffer->length(field_length); + thd->time_zone_used= 1; #ifdef WORDS_BIGENDIAN if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); @@ -4844,7 +4828,6 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) val_buffer->set_charset(&my_charset_bin); // Safety thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp); - thd->time_zone_used= 1; temp= time_tmp.year % 100; if (temp < YY_PART_YEAR - 1) @@ -4894,6 +4877,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate) { long temp; THD *thd= table ? table->in_use : current_thd; + thd->time_zone_used= 1; #ifdef WORDS_BIGENDIAN if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); @@ -4909,7 +4893,6 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate) else { thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp); - thd->time_zone_used= 1; } return 0; } @@ -4979,14 +4962,7 @@ void Field_timestamp::set_time() THD *thd= table ? table->in_use : current_thd; long tmp= (long) thd->query_start(); set_notnull(); -#ifdef WORDS_BIGENDIAN - if (table && table->s->db_low_byte_first) - { - int4store(ptr,tmp); - } - else -#endif - longstore(ptr,tmp); + store_timestamp(tmp); } /**************************************************************************** @@ -10080,4 +10056,3 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, field_name); } } - diff --git a/sql/field.h b/sql/field.h index 55a95d3bb66..f784ed82ecc 100644 --- a/sql/field.h +++ b/sql/field.h @@ -293,9 +293,9 @@ public: if (null_ptr) null_ptr=ADD_TO_PTR(null_ptr,ptr_diff,uchar*); } - inline void get_image(uchar *buff,uint length, CHARSET_INFO *cs) + virtual void get_image(uchar *buff, uint length, CHARSET_INFO *cs) { memcpy(buff,ptr,length); } - inline void set_image(const uchar *buff,uint length, CHARSET_INFO *cs) + virtual void set_image(const uchar *buff,uint length, CHARSET_INFO *cs) { memcpy(ptr,buff,length); } @@ -996,6 +996,17 @@ public: longget(tmp,ptr); return tmp; } + inline void store_timestamp(my_time_t timestamp) + { +#ifdef WORDS_BIGENDIAN + if (table && table->s->db_low_byte_first) + { + int4store(ptr,timestamp); + } + else +#endif + longstore(ptr,(uint32) timestamp); + } bool get_date(MYSQL_TIME *ltime,uint fuzzydate); bool get_time(MYSQL_TIME *ltime); timestamp_auto_set_type get_auto_set_type() const; @@ -1481,6 +1492,8 @@ public: { return charset() == &my_charset_bin ? FALSE : TRUE; } uint32 max_display_length(); uint is_equal(Create_field *new_field); + inline bool in_read_set() { return bitmap_is_set(table->read_set, field_index); } + inline bool in_write_set() { return bitmap_is_set(table->write_set, field_index); } private: int do_save_field_metadata(uchar *first_byte); }; @@ -1632,7 +1645,10 @@ public: virtual bool str_needs_quotes() { return TRUE; } my_decimal *val_decimal(my_decimal *); int cmp(const uchar *a, const uchar *b) - { return cmp_binary(a, b); } + { + DBUG_ASSERT(ptr == a); + return Field_bit::key_cmp(b, bytes_in_rec+test(bit_len)); + } int cmp_binary_offset(uint row_offset) { return cmp_offset(row_offset); } int cmp_max(const uchar *a, const uchar *b, uint max_length); @@ -1640,6 +1656,10 @@ public: { return cmp_binary((uchar *) a, (uchar *) b); } int key_cmp(const uchar *str, uint length); int cmp_offset(uint row_offset); + void get_image(uchar *buff, uint length, CHARSET_INFO *cs) + { get_key_image(buff, length, itRAW); } + void set_image(const uchar *buff,uint length, CHARSET_INFO *cs) + { Field_bit::store((char *) buff, length, cs); } uint get_key_image(uchar *buff, uint length, imagetype type); void set_key_image(const uchar *buff, uint length) { Field_bit::store((char*) buff, length, &my_charset_bin); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 48712600e79..3b68b3828d2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6883,7 +6883,7 @@ int ndbcluster_find_all_files(THD *thd) int ndbcluster_find_files(handlerton *hton, THD *thd, const char *db, const char *path, - const char *wild, bool dir, List<char> *files) + const char *wild, bool dir, List<LEX_STRING> *files) { DBUG_ENTER("ndbcluster_find_files"); DBUG_PRINT("enter", ("db: %s", db)); @@ -6950,21 +6950,22 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, my_hash_insert(&ndb_tables, (uchar*)thd->strdup(elmt.name)); } - char *file_name; - List_iterator<char> it(*files); + LEX_STRING *file_name; + List_iterator<LEX_STRING> it(*files); List<char> delete_list; + char *file_name_str; while ((file_name=it++)) { bool file_on_disk= FALSE; - DBUG_PRINT("info", ("%s", file_name)); - if (hash_search(&ndb_tables, (uchar*) file_name, strlen(file_name))) + DBUG_PRINT("info", ("%s", file_name->str)); + if (hash_search(&ndb_tables, (uchar*) file_name->str, file_name->length)) { - DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name)); + DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name->str)); file_on_disk= TRUE; } // Check for .ndb file with this name - build_table_filename(name, sizeof(name), db, file_name, ha_ndb_ext, 0); + build_table_filename(name, sizeof(name), db, file_name->str, ha_ndb_ext, 0); DBUG_PRINT("info", ("Check access for %s", name)); if (my_access(name, F_OK)) { @@ -6972,33 +6973,34 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, // .ndb file did not exist on disk, another table type if (file_on_disk) { - // Ignore this ndb table - uchar *record= hash_search(&ndb_tables, (uchar*) file_name, - strlen(file_name)); + // Ignore this ndb table + uchar *record= hash_search(&ndb_tables, (uchar*) file_name->str, + file_name->length); DBUG_ASSERT(record); hash_delete(&ndb_tables, record); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TABLE_EXISTS_ERROR, "Local table %s.%s shadows ndb table", - db, file_name); + db, file_name->str); } continue; } if (file_on_disk) { // File existed in NDB and as frm file, put in ok_tables list - my_hash_insert(&ok_tables, (uchar*)file_name); + my_hash_insert(&ok_tables, (uchar*) file_name->str); continue; } DBUG_PRINT("info", ("%s existed on disk", name)); // The .ndb file exists on disk, but it's not in list of tables in ndb // Verify that handler agrees table is gone. - if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name) == HA_ERR_NO_SUCH_TABLE) + if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name->str) == + HA_ERR_NO_SUCH_TABLE) { - DBUG_PRINT("info", ("NDB says %s does not exists", file_name)); + DBUG_PRINT("info", ("NDB says %s does not exists", file_name->str)); it.remove(); // Put in list of tables to remove from disk - delete_list.push_back(thd->strdup(file_name)); + delete_list.push_back(thd->strdup(file_name->str)); } } @@ -7009,12 +7011,12 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, build_table_filename(name, sizeof(name), db, "", "", 0); for (i= 0; i < ok_tables.records; i++) { - file_name= (char*)hash_element(&ok_tables, i); + file_name_str= (char*)hash_element(&ok_tables, i); end= end1 + - tablename_to_filename(file_name, end1, sizeof(name) - (end1 - name)); + tablename_to_filename(file_name_str, end1, sizeof(name) - (end1 - name)); pthread_mutex_lock(&LOCK_open); ndbcluster_create_binlog_setup(ndb, name, end-name, - db, file_name, TRUE); + db, file_name_str, TRUE); pthread_mutex_unlock(&LOCK_open); } } @@ -7025,16 +7027,16 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, List<char> create_list; for (i= 0 ; i < ndb_tables.records ; i++) { - file_name= (char*) hash_element(&ndb_tables, i); - if (!hash_search(&ok_tables, (uchar*) file_name, strlen(file_name))) + file_name_str= (char*) hash_element(&ndb_tables, i); + if (!hash_search(&ok_tables, (uchar*) file_name_str, strlen(file_name_str))) { - build_table_filename(name, sizeof(name), db, file_name, reg_ext, 0); + build_table_filename(name, sizeof(name), db, file_name_str, reg_ext, 0); if (my_access(name, F_OK)) { - DBUG_PRINT("info", ("%s must be discovered", file_name)); + DBUG_PRINT("info", ("%s must be discovered", file_name_str)); // File is in list of ndb tables and not in ok_tables // This table need to be created - create_list.push_back(thd->strdup(file_name)); + create_list.push_back(thd->strdup(file_name_str)); } } } @@ -7043,14 +7045,14 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, { // Delete old files List_iterator_fast<char> it3(delete_list); - while ((file_name=it3++)) + while ((file_name_str= it3++)) { - DBUG_PRINT("info", ("Remove table %s/%s", db, file_name)); + DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str)); // Delete the table and all related files TABLE_LIST table_list; bzero((char*) &table_list,sizeof(table_list)); table_list.db= (char*) db; - table_list.alias= table_list.table_name= (char*)file_name; + table_list.alias= table_list.table_name= (char*)file_name_str; (void)mysql_rm_table_part2(thd, &table_list, FALSE, /* if_exists */ FALSE, /* drop_temporary */ @@ -7065,11 +7067,16 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, pthread_mutex_lock(&LOCK_open); // Create new files List_iterator_fast<char> it2(create_list); - while ((file_name=it2++)) + while ((file_name_str=it2++)) { - DBUG_PRINT("info", ("Table %s need discovery", file_name)); - if (ndb_create_table_from_engine(thd, db, file_name) == 0) - files->push_back(thd->strdup(file_name)); + DBUG_PRINT("info", ("Table %s need discovery", file_name_str)); + if (ndb_create_table_from_engine(thd, db, file_name_str) == 0) + { + LEX_STRING *tmp_file_name= 0; + tmp_file_name= thd->make_lex_string(tmp_file_name, file_name_str, + strlen(file_name_str), TRUE); + files->push_back(tmp_file_name); + } } pthread_mutex_unlock(&LOCK_open); @@ -7083,8 +7090,8 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, uint count = 0; while (count++ < files->elements) { - file_name = (char *)files->pop(); - if (!strcmp(file_name, NDB_SCHEMA_TABLE)) + file_name = (LEX_STRING *)files->pop(); + if (!strcmp(file_name->str, NDB_SCHEMA_TABLE)) { DBUG_PRINT("info", ("skip %s.%s table, it should be hidden to user", NDB_REP_DB, NDB_SCHEMA_TABLE)); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 4f5a1359d2d..a6f992226c2 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -563,7 +563,7 @@ extern SHOW_VAR ndb_status_variables[]; int ndbcluster_discover(THD* thd, const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ndbcluster_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir, List<char> *files); + const char *wild, bool dir, List<LEX_STRING> *files); int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name); void ndbcluster_print_error(int error, const NdbOperation *error_op); diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index f388b60f3d5..c91faac388f 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -2480,8 +2480,8 @@ ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname) { DBUG_ENTER("ndbcluster_check_if_local_tables_in_db"); DBUG_PRINT("info", ("Looking for files in directory %s", dbname)); - char *tabname; - List<char> files; + LEX_STRING *tabname; + List<LEX_STRING> files; char path[FN_REFLEN]; build_table_filename(path, sizeof(path), dbname, "", "", 0); @@ -2493,8 +2493,8 @@ ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname) DBUG_PRINT("info",("found: %d files", files.elements)); while ((tabname= files.pop())) { - DBUG_PRINT("info", ("Found table %s", tabname)); - if (ndbcluster_check_if_local_table(dbname, tabname)) + DBUG_PRINT("info", ("Found table %s", tabname->str)); + if (ndbcluster_check_if_local_table(dbname, tabname->str)) DBUG_RETURN(true); } diff --git a/sql/handler.cc b/sql/handler.cc index e828c9cdde8..3e9524e9821 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2834,7 +2834,7 @@ struct st_find_files_args const char *path; const char *wild; bool dir; - List<char> *files; + List<LEX_STRING> *files; }; static my_bool find_files_handlerton(THD *thd, plugin_ref plugin, @@ -2854,7 +2854,7 @@ static my_bool find_files_handlerton(THD *thd, plugin_ref plugin, int ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir, List<char> *files) + const char *wild, bool dir, List<LEX_STRING> *files) { int error= 0; DBUG_ENTER("ha_find_files"); @@ -3467,8 +3467,7 @@ namespace { if (table->s->cached_row_logging_check == -1) { int const check(table->s->tmp_table == NO_TMP_TABLE && - binlog_filter->db_ok(table->s->db.str) && - !table->no_replicate); + binlog_filter->db_ok(table->s->db.str)); table->s->cached_row_logging_check= check; } @@ -3476,9 +3475,9 @@ namespace { table->s->cached_row_logging_check == 1); return (thd->current_stmt_binlog_row_based && + table->s->cached_row_logging_check && (thd->options & OPTION_BIN_LOG) && - mysql_bin_log.is_open() && - table->s->cached_row_logging_check); + mysql_bin_log.is_open()); } } @@ -3556,7 +3555,7 @@ namespace const uchar *before_record, const uchar *after_record) { - if (table->file->ha_table_flags() & HA_HAS_OWN_BINLOGGING) + if (table->no_replicate) return 0; bool error= 0; THD *const thd= table->in_use; diff --git a/sql/handler.h b/sql/handler.h index ddea6c3a34c..60e936bef5b 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -700,7 +700,7 @@ struct handlerton int (*find_files)(handlerton *hton, THD *thd, const char *db, const char *path, - const char *wild, bool dir, List<char> *files); + const char *wild, bool dir, List<LEX_STRING> *files); int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db, const char *name); uint32 license; /* Flag for Engine License */ @@ -1860,7 +1860,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name); int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); int ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir,List<char>* files); + const char *wild, bool dir, List<LEX_STRING>* files); int ha_table_exists_in_engine(THD* thd, const char* db, const char* name); /* key cache */ diff --git a/sql/item.cc b/sql/item.cc index 006595a39a9..76aad708d22 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1705,7 +1705,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field) tmp_field->type=field->type(); tmp_field->flags= field->table->maybe_null ? (field->flags & ~NOT_NULL_FLAG) : field->flags; - tmp_field->decimals= 0; + tmp_field->decimals= field->decimals(); } /**********************************************/ diff --git a/sql/item.h b/sql/item.h index cc3ba961820..21c4560c6bc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1743,8 +1743,11 @@ public: max_length=length; fixed= 1; } - Item_float(double value_par) :presentation(0), value(value_par) { fixed= 1; } - + Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par) + { + decimals= (uint8) decimal_par; + fixed= 1; + } int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index fcbacc32d88..47914c59b4c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -853,6 +853,7 @@ public: friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b); }; + class in_double :public in_vector { double tmp; @@ -862,16 +863,16 @@ public: uchar *get_value(Item *item); Item *create_item() { - return new Item_float(0.0); + return new Item_float(0.0, 0); } void value_to_item(uint pos, Item *item) { ((Item_float*)item)->value= ((double*) base)[pos]; } Item_result result_type() { return REAL_RESULT; } - }; + class in_decimal :public in_vector { my_decimal val; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 23d55dad531..0af98b5d987 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1594,7 +1594,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time) { THD *thd= current_thd; - thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) time(NULL)); + thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0)); thd->time_zone_used= 1; } diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index f8457a1ae50..067af930d6f 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2769,7 +2769,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf) char buf[128]; my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %lu: %s", my_xml_error_lineno(&p) + 1, - my_xml_error_pos(&p) + 1, + (ulong) my_xml_error_pos(&p) + 1, my_xml_error_string(&p)); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_VALUE, diff --git a/sql/lock.cc b/sql/lock.cc index 08ff90ce983..20fb7d73c1c 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -290,6 +290,10 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, } else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) { + /* + Thread was killed or lock aborted. Let upper level close all + used tables and retry or give error. + */ thd->locked=0; break; } @@ -326,7 +330,7 @@ retry: } } - thd->lock_time(); + thd->set_time_after_lock(); DBUG_RETURN (sql_lock); } diff --git a/sql/log.cc b/sql/log.cc index 00ef726f037..ed1a8bdb7f7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -320,23 +320,18 @@ bool Log_to_csv_event_handler:: uint field_index; Silence_log_table_errors error_handler; Open_tables_state open_tables_backup; - Field_timestamp *field0; ulonglong save_thd_options; - bool save_query_start_used; - time_t save_start_time; - time_t save_time_after_lock; - time_t save_user_time; bool save_time_zone_used; + /* + CSV uses TIME_to_timestamp() internally if table needs to be repaired + which will set thd->time_zone_used + */ + save_time_zone_used= thd->time_zone_used; + save_thd_options= thd->options; thd->options&= ~OPTION_BIN_LOG; - save_query_start_used= thd->query_start_used; - save_start_time= thd->start_time; - save_time_after_lock= thd->time_after_lock; - save_user_time= thd->user_time; - save_time_zone_used= thd->time_zone_used; - bzero(& table_list, sizeof(TABLE_LIST)); table_list.alias= table_list.table_name= GENERAL_LOG_NAME.str; table_list.table_name_length= GENERAL_LOG_NAME.length; @@ -346,12 +341,13 @@ bool Log_to_csv_event_handler:: table_list.db= MYSQL_SCHEMA_NAME.str; table_list.db_length= MYSQL_SCHEMA_NAME.length; - table= open_performance_schema_table(thd, & table_list, - & open_tables_backup); + if (!(table= open_performance_schema_table(thd, & table_list, + & open_tables_backup))) + goto err; + need_close= TRUE; - if (!table || - table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || + if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || table->file->ha_rnd_init(0)) goto err; @@ -384,8 +380,8 @@ bool Log_to_csv_event_handler:: DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP); - field0= (Field_timestamp*) (table->field[0]); - field0->set_time(); + ((Field_timestamp*) table->field[0])->store_timestamp((my_time_t) + event_time); /* do a write */ if (table->field[1]->store(user_host, user_host_len, client_cs) || @@ -395,7 +391,8 @@ bool Log_to_csv_event_handler:: table->field[5]->store(sql_text, sql_text_len, client_cs)) goto err; - /* mark tables as not null */ + + /* mark all fields as not null */ table->field[1]->set_notnull(); table->field[2]->set_notnull(); table->field[3]->set_notnull(); @@ -434,11 +431,6 @@ err: close_performance_schema_table(thd, & open_tables_backup); thd->options= save_thd_options; - - thd->query_start_used= save_query_start_used; - thd->start_time= save_start_time; - thd->time_after_lock= save_time_after_lock; - thd->user_time= save_user_time; thd->time_zone_used= save_time_zone_used; return result; } @@ -455,8 +447,8 @@ err: user_host the pointer to the string with user@host info user_host_len length of the user_host string. this is computed once and passed to all general log event handlers - query_time Amount of time the query took to execute (in seconds) - lock_time Amount of time the query was locked (in seconds) + query_time Amount of time the query took to execute (in microseconds) + lock_time Amount of time the query was locked (in microseconds) is_command The flag, which determines, whether the sql_text is a query or an administrator command (these are treated differently by the old logging routines) @@ -476,7 +468,7 @@ err: bool Log_to_csv_event_handler:: log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { TABLE_LIST table_list; @@ -485,15 +477,16 @@ bool Log_to_csv_event_handler:: bool need_close= FALSE; bool need_rnd_end= FALSE; Open_tables_state open_tables_backup; - bool save_query_start_used; - time_t save_start_time; - time_t save_time_after_lock; - time_t save_user_time; - bool save_time_zone_used; CHARSET_INFO *client_cs= thd->variables.character_set_client; - + bool save_time_zone_used; DBUG_ENTER("Log_to_csv_event_handler::log_slow"); + /* + CSV uses TIME_to_timestamp() internally if table needs to be repaired + which will set thd->time_zone_used + */ + save_time_zone_used= thd->time_zone_used; + bzero(& table_list, sizeof(TABLE_LIST)); table_list.alias= table_list.table_name= SLOW_LOG_NAME.str; table_list.table_name_length= SLOW_LOG_NAME.length; @@ -503,18 +496,13 @@ bool Log_to_csv_event_handler:: table_list.db= MYSQL_SCHEMA_NAME.str; table_list.db_length= MYSQL_SCHEMA_NAME.length; - save_query_start_used= thd->query_start_used; - save_start_time= thd->start_time; - save_time_after_lock= thd->time_after_lock; - save_user_time= thd->user_time; - save_time_zone_used= thd->time_zone_used; + if (!(table= open_performance_schema_table(thd, & table_list, + & open_tables_backup))) + goto err; - table= open_performance_schema_table(thd, & table_list, - & open_tables_backup); need_close= TRUE; - if (!table || - table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || + if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || table->file->ha_rnd_init(0)) goto err; @@ -529,17 +517,17 @@ bool Log_to_csv_event_handler:: if (table->s->fields < 11) goto err; - /* - We do not set a value for table->field[0], as it will use - default value. - */ - - /* store the value */ + /* store the time and user values */ + DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP); + ((Field_timestamp*) table->field[0])->store_timestamp((my_time_t) + current_time); if (table->field[1]->store(user_host, user_host_len, client_cs)) goto err; if (query_start_arg) { + longlong query_time= (longlong) (query_utime/1000000); + longlong lock_time= (longlong) (lock_utime/1000000); /* A TIME field can not hold the full longlong range; query_time or lock_time may be truncated without warning here, if greater than @@ -633,11 +621,6 @@ err: } if (need_close) close_performance_schema_table(thd, & open_tables_backup); - - thd->query_start_used= save_query_start_used; - thd->start_time= save_start_time; - thd->time_after_lock= save_time_after_lock; - thd->user_time= save_user_time; thd->time_zone_used= save_time_zone_used; DBUG_RETURN(result); } @@ -705,12 +688,12 @@ void Log_to_file_event_handler::init_pthread_objects() bool Log_to_file_event_handler:: log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { return mysql_slow_log.write(thd, current_time, query_start_arg, user_host, user_host_len, - query_time, lock_time, is_command, + query_utime, lock_utime, is_command, sql_text, sql_text_len); } @@ -785,10 +768,10 @@ bool LOGGER::error_log_print(enum loglevel level, const char *format, va_list args) { bool error= FALSE; - Log_event_handler **current_handler= error_log_handler_list; + Log_event_handler **current_handler; /* currently we don't need locking here as there is no error_log table */ - while (*current_handler) + for (current_handler= error_log_handler_list ; *current_handler ;) error= (*current_handler++)->log_error(level, format, args) || error; return error; @@ -878,28 +861,27 @@ bool LOGGER::flush_logs(THD *thd) SYNOPSIS slow_log_print() - thd THD of the query being logged - query The query being logged - query_length The length of the query string - query_start_arg Query start timestamp + thd THD of the query being logged + query The query being logged + query_length The length of the query string + current_utime Current time in microseconds (from undefined start) RETURN - FALSE - OK - TRUE - error occured + FALSE OK + TRUE error occured */ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg) + ulonglong current_utime) + { bool error= FALSE; - Log_event_handler **current_handler= slow_log_handler_list; + Log_event_handler **current_handler; bool is_command= FALSE; char user_host_buff[MAX_USER_HOST_SIZE]; - - time_t current_time; Security_context *sctx= thd->security_ctx; uint user_host_len= 0; - longlong query_time= 0, lock_time= 0; + ulonglong query_utime, lock_utime; /* Print the message to the buffer if we have slow log enabled @@ -907,10 +889,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, if (*slow_log_handler_list) { - current_time= time(NULL); + time_t current_time; /* do not log slow queries from replication threads */ - if (thd->slave_thread) + if (thd->slave_thread && !opt_log_slow_slave_statements) return 0; lock_shared(); @@ -921,17 +903,22 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, } /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */ - user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE, - sctx->priv_user ? sctx->priv_user : "", "[", - sctx->user ? sctx->user : "", "] @ ", - sctx->host ? sctx->host : "", " [", - sctx->ip ? sctx->ip : "", "]", NullS) - - user_host_buff; - - if (query_start_arg) + user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE, + sctx->priv_user ? sctx->priv_user : "", "[", + sctx->user ? sctx->user : "", "] @ ", + sctx->host ? sctx->host : "", " [", + sctx->ip ? sctx->ip : "", "]", NullS) - + user_host_buff); + + current_time= my_time_possible_from_micro(current_utime); + if (thd->start_utime) { - query_time= (longlong) (current_time - query_start_arg); - lock_time= (longlong) (thd->time_after_lock - query_start_arg); + query_utime= (current_utime - thd->start_utime); + lock_utime= (thd->utime_after_lock - thd->start_utime); + } + else + { + query_utime= lock_utime= 0; } if (!query) @@ -941,10 +928,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, query_length= command_name[thd->command].length; } - while (*current_handler) - error= (*current_handler++)->log_slow(thd, current_time, query_start_arg, + for (current_handler= slow_log_handler_list; *current_handler ;) + error= (*current_handler++)->log_slow(thd, current_time, thd->start_time, user_host_buff, user_host_len, - query_time, lock_time, is_command, + query_utime, lock_utime, is_command, query, query_length) || error; unlock(); @@ -969,7 +956,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, Security_context *sctx= thd->security_ctx; ulong id; uint message_buff_len= 0, user_host_len= 0; - + time_t current_time; if (thd) { /* Normal thread */ if ((thd->options & OPTION_LOG_OFF) @@ -991,8 +978,6 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, unlock(); return 0; } - time_t current_time= time(NULL); - user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE, sctx->priv_user ? sctx->priv_user : "", "[", sctx->user ? sctx->user : "", "] @ ", @@ -1007,6 +992,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, else message_buff[0]= '\0'; + current_time= my_time(0); while (*current_handler) error+= (*current_handler++)-> log_general(thd, current_time, user_host_buff, @@ -2024,8 +2010,8 @@ err: user_host the pointer to the string with user@host info user_host_len length of the user_host string. this is computed once and passed to all general log event handlers - query_time Amount of time the query took to execute (in seconds) - lock_time Amount of time the query was locked (in seconds) + query_utime Amount of time the query took to execute (in microseconds) + lock_utime Amount of time the query was locked (in microseconds) is_command The flag, which determines, whether the sql_text is a query or an administrator command. sql_text the very text of the query or administrator command @@ -2043,8 +2029,8 @@ err: bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { bool error= 0; @@ -2062,6 +2048,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, { // Safety agains reopen int tmp_errno= 0; char buff[80], *end; + char query_time_buff[22+7], lock_time_buff[22+7]; uint buff_len; end= buff; @@ -2092,10 +2079,12 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, tmp_errno= errno; } /* For slow query log */ + sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0); + sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0); if (my_b_printf(&log_file, - "# Query_time: %lu Lock_time: %lu" + "# Query_time: %s Lock_time: %s" " Rows_sent: %lu Rows_examined: %lu\n", - (ulong) query_time, (ulong) lock_time, + query_time_buff, lock_time_buff, (ulong) thd->sent_row_count, (ulong) thd->examined_row_count) == (uint) -1) tmp_errno= errno; @@ -3737,9 +3726,9 @@ int error_log_print(enum loglevel level, const char *format, bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg) + ulonglong current_utime) { - return logger.slow_log_print(thd, query, query_length, query_start_arg); + return logger.slow_log_print(thd, query, query_length, current_utime); } @@ -3767,7 +3756,7 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags) #ifdef HAVE_REPLICATION if (expire_logs_days) { - time_t purge_time= time(0) - expire_logs_days*24*60*60; + time_t purge_time= my_time(0) - expire_logs_days*24*60*60; if (purge_time >= 0) purge_logs_before_date(purge_time); } @@ -4365,7 +4354,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer) VOID(pthread_mutex_lock(&LOCK_error_log)); - skr=time(NULL); + skr= my_time(0); localtime_r(&skr, &tm_tmp); start=&tm_tmp; diff --git a/sql/log.h b/sql/log.h index 3b1a0950daa..c116c4a93f7 100644 --- a/sql/log.h +++ b/sql/log.h @@ -198,7 +198,7 @@ public: const char *sql_text, uint sql_text_len); bool write(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); bool open_slow_log(const char *log_name) { @@ -394,8 +394,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len)= 0; virtual bool log_error(enum loglevel level, const char *format, va_list args)= 0; @@ -423,8 +423,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); virtual bool log_error(enum loglevel level, const char *format, va_list args); @@ -455,8 +455,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); virtual bool log_error(enum loglevel level, const char *format, va_list args); @@ -515,7 +515,7 @@ public: bool error_log_print(enum loglevel level, const char *format, va_list args); bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg); + ulonglong current_utime); bool general_log_print(THD *thd,enum enum_server_command command, const char *format, va_list args); diff --git a/sql/log_event.cc b/sql/log_event.cc index fbb925fa98f..19b1d941c78 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -456,7 +456,7 @@ Log_event::Log_event() thd(0) { server_id= ::server_id; - when= time(NULL); + when= my_time(0); log_pos= 0; } #endif /* !MYSQL_CLIENT */ @@ -2073,7 +2073,7 @@ int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli, /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); - + log_slow_statement(thd); } else { @@ -4350,7 +4350,7 @@ int User_var_log_event::do_apply_event(RELAY_LOG_INFO const *rli) switch (type) { case REAL_RESULT: float8get(real_val, val); - it= new Item_float(real_val); + it= new Item_float(real_val, 0); val= (char*) &real_val; // Pointer to value in native format val_len= 8; break; @@ -6183,7 +6183,7 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) problem. When WL#2975 is implemented, just remove the member st_relay_log_info::last_event_start_time and all its occurences. */ - const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= time(0); + const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= my_time(0); } DBUG_RETURN(0); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2fe70980ea8..34d92a13945 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -167,6 +167,7 @@ public: void restore_env(THD *thd, Object_creation_ctx *backup_ctx); protected: + Object_creation_ctx() {} virtual Object_creation_ctx *create_backup_ctx(THD *thd) = 0; virtual void change_env(THD *thd) const = 0; @@ -734,7 +735,7 @@ int error_log_print(enum loglevel level, const char *format, va_list args); bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg); + ulonglong current_utime); bool general_log_print(THD *thd, enum enum_server_command command, const char *format,...); @@ -1802,7 +1803,7 @@ extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; extern char* opt_secure_file_priv; -extern my_bool opt_log_slow_admin_statements; +extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements; extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool opt_old_style_user_limits, trust_function_creators; extern uint opt_crash_binlog_innodb; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 536d3d95933..6c8fa7e7ac3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -338,6 +338,7 @@ static char *default_collation_name; static char *default_storage_engine_str; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; +static double long_query_time; static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; @@ -406,6 +407,7 @@ my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; char* opt_secure_file_priv= 0; my_bool opt_log_slow_admin_statements= 0; +my_bool opt_log_slow_slave_statements= 0; my_bool lower_case_file_system= 0; my_bool opt_large_pages= 0; my_bool opt_myisam_use_mmap= 0; @@ -1143,7 +1145,7 @@ extern "C" void unireg_abort(int exit_code) sql_print_error("Aborting\n"); else if (opt_help) usage(); - clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */ + clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); wait_for_signal_thread_to_end(); clean_up_mutexes(); @@ -1240,12 +1242,12 @@ void clean_up(bool print_message) my_regex_end(); #endif - if (print_message && errmesg) - sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); #if !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif + if (print_message && errmesg && server_start_time) + sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); thread_scheduler.end(); finish_client_errs(); my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST), @@ -1797,7 +1799,7 @@ static bool cache_thread() this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; - thd->thr_create_time= time(NULL); + thd->thr_create_utime= my_micro_time(); threads.append(thd); return(1); } @@ -2174,7 +2176,7 @@ extern "C" sig_handler handle_segfault(int sig) segfaulted = 1; - curr_time= time(NULL); + curr_time= my_time(0); localtime_r(&curr_time, &tm); fprintf(stderr,"\ @@ -2717,7 +2719,7 @@ static int init_common_variables(const char *conf_file_name, int argc, tzset(); // Set tzname max_system_variables.pseudo_thread_id= (ulong)~0; - server_start_time= time((time_t*) 0); + server_start_time= my_time(0); rpl_filter= new Rpl_filter; binlog_filter= new Rpl_filter; if (!rpl_filter || !binlog_filter) @@ -2952,7 +2954,7 @@ static int init_common_variables(const char *conf_file_name, int argc, && !(log_output_options & LOG_NONE)) sql_print_warning("Although a path was specified for the " "--log-slow-queries option, log tables are used. " - "To enable logging to files use the --log-output option."); + "To enable logging to files use the --log-output=file option."); s= opt_logname ? opt_logname : make_default_log_name(buff, ".log"); sys_var_general_log_path.value= my_strdup(s, MYF(0)); @@ -3540,7 +3542,7 @@ server."); #ifdef HAVE_REPLICATION if (opt_bin_log && expire_logs_days) { - time_t purge_time= time(0) - expire_logs_days*24*60*60; + time_t purge_time= server_start_time - expire_logs_days*24*60*60; if (purge_time >= 0) mysql_bin_log.purge_logs_before_date(purge_time); } @@ -4289,7 +4291,7 @@ void create_thread_to_handle_connection(THD *thd) thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->connect_time = time(NULL); + thd->connect_utime= thd->start_utime= my_micro_time(); if ((error=pthread_create(&thd->real_id,&connection_attrib, handle_one_connection, (void*) thd))) @@ -5071,11 +5073,14 @@ enum options_mysqld OPT_PLUGIN_DIR, OPT_LOG_OUTPUT, OPT_PORT_OPEN_TIMEOUT, + OPT_KEEP_FILES_ON_CREATE, OPT_GENERAL_LOG, OPT_SLOW_LOG, OPT_THREAD_HANDLING, OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_SECURE_FILE_PRIV, + OPT_MIN_EXAMINED_ROW_LIMIT, + OPT_LOG_SLOW_SLAVE_STATEMENTS, OPT_OLD_MODE }; @@ -5377,8 +5382,13 @@ Disable with --skip-large-pages.", (uchar**) &opt_log_slow_admin_statements, (uchar**) &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS, + "Log slow statements executed by slave thread to the slow log if it is open.", + (uchar**) &opt_log_slow_slave_statements, + (uchar**) &opt_log_slow_slave_statements, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-slow-queries", OPT_SLOW_QUERY_LOG, - "Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options.", + "Log slow queries to a table or log file. Defaults logging to table mysql.slow_log or hostname-slow.log if --log-output=file is used. Must be enabled to activate other slow log options.", (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-tc", OPT_LOG_TC, @@ -5941,6 +5951,11 @@ log and this option does nothing anymore.", (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG, REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE, + "Don't overwrite stale .MYD and .MYI even if no directory is specified.", + (uchar**) &global_system_variables.keep_files_on_create, + (uchar**) &max_system_variables.keep_files_on_create, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"key_buffer_size", OPT_KEY_BUFFER_SIZE, "The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.", (uchar**) &dflt_key_cache_var.param_buff_size, @@ -5967,10 +5982,10 @@ log and this option does nothing anymore.", 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, - "Log all queries that have taken more than long_query_time seconds to execute to file.", - (uchar**) &global_system_variables.long_query_time, - (uchar**) &max_system_variables.long_query_time, 0, GET_ULONG, - REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, + "Log all queries that have taken more than long_query_time seconds to execute to file. " + "The argument will be treated as a decimal value with microsecond precission.", + (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE, + REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system", (uchar**) &lower_case_table_names, @@ -6068,6 +6083,11 @@ The minimum value for this variable is 4096.", "After this many write locks, allow some read locks to run in between.", (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT, + "Don't log queries which examine less than min_examined_row_limit rows to file.", + (uchar**) &global_system_variables.min_examined_row_limit, + (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, {"multi_range_count", OPT_MULTI_RANGE_COUNT, "Number of key ranges to request at once.", (uchar**) &global_system_variables.multi_range_count, @@ -6960,7 +6980,7 @@ Starts the MySQL database server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) - puts("\nFor more help options (several pages), use mysqld --verbose --help\n"); + puts("\nFor more help options (several pages), use mysqld --verbose --help"); else { #ifdef __WIN__ @@ -6985,7 +7005,7 @@ Starts the MySQL database server\n"); puts("\n\ To see what values a running MySQL server is using, type\n\ -'mysqladmin variables' instead of 'mysqld --verbose --help'.\n"); +'mysqladmin variables' instead of 'mysqld --verbose --help'."); } } #endif /*!EMBEDDED_LIBRARY*/ @@ -7720,7 +7740,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } return 0; } - /* Initiates DEBUG - but no debugging here ! */ + + +/* Handle arguments for multiple key caches */ static uchar* * mysql_getopt_value(const char *keyname, uint key_length, @@ -7778,9 +7800,10 @@ static void get_options(int *argc,char **argv) (*argc)++; /* add back one for the progname handle_options removes */ /* no need to do this for argv as we are discarding it. */ - if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) && + if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes || + opt_log_slow_slave_statements) && !opt_slow_log) - sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set"); + sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log-slow-queries is not set"); #if defined(HAVE_BROKEN_REALPATH) my_use_symdir=0; @@ -7824,6 +7847,10 @@ static void get_options(int *argc,char **argv) /* Set global variables based on startup options */ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); + /* long_query_time is in microseconds */ + global_system_variables.long_query_time= max_system_variables.long_query_time= + (longlong) (long_query_time * 1000000.0); + if (opt_short_log_format) opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bd273145782..1f75d7ab1d7 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -437,7 +437,7 @@ net_write_command(NET *net,uchar command, uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; DBUG_ENTER("net_write_command"); - DBUG_PRINT("enter",("length: %lu", len)); + DBUG_PRINT("enter",("length: %lu", (ulong) len)); buff[4]=command; /* For first packet */ diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 5ea49396cb4..19fb11ac0cc 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -135,7 +135,7 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, { /* string have to be allocated already */ LEX_STRING *val_s= (LEX_STRING *)(base + parameter->offset); - time_t tm= time(NULL); + time_t tm= my_time(0); get_date(val_s->str, GETDATE_DATE_TIME|GETDATE_GMT|GETDATE_FIXEDLENGTH, tm); diff --git a/sql/set_var.cc b/sql/set_var.cc index a18d45627dc..ace3bee8342 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -250,8 +250,8 @@ static sys_var_bool_ptr sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes", &opt_log_queries_not_using_indexes); static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings); -static sys_var_thd_ulong sys_long_query_time(&vars, "long_query_time", - &SV::long_query_time); +static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time", + &SV::long_query_time); static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates", &SV::low_priority_updates, fix_low_priority_updates); @@ -315,6 +315,8 @@ static sys_var_thd_ulong sys_max_tmp_tables(&vars, "max_tmp_tables", &SV::max_tmp_tables); static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count", &max_write_lock_count); +static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit", + &SV::min_examined_row_limit); static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count", &SV::multi_range_count); static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size", @@ -1473,6 +1475,15 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) pthread_mutex_unlock(&LOCK_global_system_variables); return new Item_int(value); } + case SHOW_DOUBLE: + { + double value; + pthread_mutex_lock(&LOCK_global_system_variables); + value= *(double*) value_ptr(thd, var_type, base); + pthread_mutex_unlock(&LOCK_global_system_variables); + /* 6, as this is for now only used with microseconds */ + return new Item_float(value, 6); + } case SHOW_HA_ROWS: { ha_rows value; @@ -2527,6 +2538,60 @@ void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type) } /* + Handling of microseoncds given as seconds.part_seconds + + NOTES + The argument to long query time is in seconds in decimal + which is converted to ulonglong integer holding microseconds for storage. + This is used for handling long_query_time +*/ + +bool sys_var_microseconds::update(THD *thd, set_var *var) +{ + double num= var->value->val_real(); + longlong microseconds; + if (num > (double) option_limits->max_value) + num= (double) option_limits->max_value; + if (num < (double) option_limits->min_value) + num= (double) option_limits->min_value; + microseconds= (longlong) (num * 1000000.0 + 0.5); + if (var->type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + (global_system_variables.*offset)= microseconds; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= microseconds; + return 0; +} + + +void sys_var_microseconds::set_default(THD *thd, enum_var_type type) +{ + longlong microseconds= (longlong) (option_limits->def_value * 1000000.0); + if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.*offset= microseconds; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= microseconds; +} + + +uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ? + global_system_variables.*offset : + thd->variables.*offset) / 1000000.0; + return (uchar*) &thd->tmp_double_value; +} + + +/* Functions to update thd->options bits */ diff --git a/sql/set_var.h b/sql/set_var.h index a998dc93b84..67ec449a02f 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -113,9 +113,10 @@ class sys_var_long_ptr_global: public sys_var_global { public: ulong *value; - sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg, - pthread_mutex_t *guard_arg, - sys_after_update_func after_update_arg= NULL) + sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, + ulong *value_ptr_arg, + pthread_mutex_t *guard_arg, + sys_after_update_func after_update_arg= NULL) :sys_var_global(name_arg, after_update_arg, guard_arg), value(value_ptr_arg) { chain_sys_var(chain); } @@ -911,6 +912,27 @@ public: uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; + +class sys_var_microseconds :public sys_var_thd +{ + ulonglong SV::*offset; +public: + sys_var_microseconds(sys_var_chain *chain, const char *name_arg, + ulonglong SV::*offset_arg): + sys_var_thd(name_arg), offset(offset_arg) + { chain_sys_var(chain); } + bool check(THD *thd, set_var *var) {return 0;} + bool update(THD *thd, set_var *var); + void set_default(THD *thd, enum_var_type type); + SHOW_TYPE show_type() { return SHOW_DOUBLE; } + bool check_update_type(Item_result type) + { + return (type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT); + } + uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); +}; + + class sys_var_trust_routine_creators :public sys_var_bool_ptr { /* We need a derived class only to have a warn_deprecated() */ diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 966e841ccbf..8ecba1d4be0 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5654,6 +5654,8 @@ ER_NON_INSERTABLE_TABLE ger "Die Zieltabelle %-.100s von %s ist nicht einfügbar" ER_ADMIN_WRONG_MRG_TABLE eng "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist" +ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT + eng "Too high level of nesting for select" ER_FOREIGN_SERVER_EXISTS eng "The foreign server, %s, you are trying to create already exists." ER_FOREIGN_SERVER_DOESNT_EXIST diff --git a/sql/slave.cc b/sql/slave.cc index 96a105b06e4..0854bc123f9 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1460,6 +1460,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ thd->slave_thread = 1; + thd->enable_slow_log= opt_log_slow_slave_statements; set_slave_thread_options(thd); thd->client_capabilities = CLIENT_LOCAL_FILES; pthread_mutex_lock(&LOCK_thread_count); @@ -1491,7 +1492,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, DBUG_ENTER("safe_sleep"); thr_alarm_init(&alarmed); - time_t start_time= time((time_t*) 0); + time_t start_time= my_time(0); time_t end_time= start_time+sec; while ((nap_time= (int) (end_time - start_time)) > 0) @@ -1508,7 +1509,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, if ((*thread_killed)(thd,thread_killed_arg)) DBUG_RETURN(1); - start_time=time((time_t*) 0); + start_time= my_time(0); } DBUG_RETURN(0); } @@ -1796,7 +1797,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) thd->set_time(); // time the query thd->lex->current_select= 0; if (!ev->when) - ev->when = time(NULL); + ev->when= my_time(0); ev->thd = thd; // because up to this point, ev->thd == 0 int reason= ev->shall_skip(rli); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3e594d4da4b..24c6979c0f6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1314,24 +1314,20 @@ void close_temporary_tables(THD *thd) { TABLE *table; TABLE *next; - /* - TODO: 5.1 maintains prev link in temporary_tables - double-linked list so we could fix it. But it is not necessary - at this time when the list is being destroyed - */ TABLE *prev_table; /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */ bool was_quote_show= TRUE; + LINT_INIT(next); if (!thd->temporary_tables) return; if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based) { - TABLE *next; - for (table= thd->temporary_tables; table; table= next) + TABLE *tmp_next; + for (table= thd->temporary_tables; table; table= tmp_next) { - next=table->next; + tmp_next= table->next; close_temporary(table, 1, 1); } thd->temporary_tables= 0; @@ -1344,13 +1340,12 @@ void close_temporary_tables(THD *thd) char buf[256]; String s_query= String(buf, sizeof(buf), system_charset_info); bool found_user_tables= FALSE; - LINT_INIT(next); memcpy(buf, stub, stub_len); /* - insertion sort of temp tables by pseudo_thread_id to build ordered list - of sublists of equal pseudo_thread_id + Insertion sort of temp tables by pseudo_thread_id to build ordered list + of sublists of equal pseudo_thread_id */ for (prev_table= thd->temporary_tables, table= prev_table->next; @@ -2759,11 +2754,10 @@ bool reopen_table(TABLE *table) sql_print_error("Table %s had a open data handler in reopen_table", table->alias); #endif + bzero((char*) &table_list, sizeof(TABLE_LIST)); table_list.db= table->s->db.str; table_list.table_name= table->s->table_name.str; table_list.table= table; - table_list.belong_to_view= 0; - table_list.next_local= 0; if (wait_for_locked_table_names(thd, &table_list)) DBUG_RETURN(1); // Thread was killed @@ -3295,15 +3289,19 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, DBUG_ENTER("open_unireg_entry"); safe_mutex_assert_owner(&LOCK_open); - retry: if (!(share= get_table_share_with_create(thd, table_list, cache_key, cache_key_length, - OPEN_VIEW, &error))) + OPEN_VIEW | + table_list->i_s_requested_object, + &error))) DBUG_RETURN(1); if (share->is_view) { + if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + goto err; + /* Open view */ error= (int) open_new_frm(thd, share, alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | @@ -3319,6 +3317,9 @@ retry: DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0); } + if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) + goto err; + while ((error= open_table_from_share(thd, share, alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | @@ -7197,6 +7198,12 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, else if (in_use != thd) { DBUG_PRINT("info", ("Table was in use by other thread")); + /* + Mark that table is going to be deleted from cache. This will + force threads that are in mysql_lock_tables() (but not yet + in thr_multi_lock()) to abort it's locks, close all tables and retry + */ + in_use->some_tables_deleted= 1; if (table->is_name_opened()) { DBUG_PRINT("info", ("Found another active instance of the table")); @@ -7724,23 +7731,30 @@ TABLE * open_performance_schema_table(THD *thd, TABLE_LIST *one_table, Open_tables_state *backup) { - uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK - | MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY - | MYSQL_LOCK_PERF_SCHEMA ); - + uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK | + MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | + MYSQL_LOCK_IGNORE_FLUSH | + MYSQL_LOCK_PERF_SCHEMA); + TABLE *table; + /* Save value that is changed in mysql_lock_tables() */ + ulonglong save_utime_after_lock= thd->utime_after_lock; DBUG_ENTER("open_performance_schema_table"); thd->reset_n_backup_open_tables_state(backup); - TABLE *table= open_ltable(thd, one_table, one_table->lock_type, flags); - if (table) + if ((table= open_ltable(thd, one_table, one_table->lock_type, flags))) { DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_PERFORMANCE); /* Make sure all columns get assigned to a default value */ table->use_all_columns(); table->no_replicate= 1; + /* + Don't set automatic timestamps as we may want to use time of logging, + not from query start + */ + table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; } - + thd->utime_after_lock= save_utime_after_lock; DBUG_RETURN(table); } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 39a7aebcc5d..f6b48afc10b 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -862,6 +862,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg, ulong Query_cache::resize(ulong query_cache_size_arg) { + ulong new_query_cache_size; DBUG_ENTER("Query_cache::resize"); DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size, query_cache_size_arg)); @@ -876,17 +877,13 @@ ulong Query_cache::resize(ulong query_cache_size_arg) free_cache(); query_cache_size= query_cache_size_arg; - ulong new_query_cache_size= init_cache(); + new_query_cache_size= init_cache(); STRUCT_LOCK(&structure_guard_mutex); m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; - /* - Must not call check_integrity() with - m_cache_status != Query_cache::NO_FLUSH_IN_PROGRESS. - It would wait forever. - */ - DBUG_EXECUTE("check_querycache",check_integrity(1);); pthread_cond_signal(&COND_cache_status_changed); + if (new_query_cache_size) + DBUG_EXECUTE("check_querycache",check_integrity(1);); STRUCT_UNLOCK(&structure_guard_mutex); DBUG_RETURN(new_query_cache_size); diff --git a/sql/sql_cache.h b/sql/sql_cache.h index c4c7e1dbc5e..645807eecbf 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -142,6 +142,7 @@ struct Query_cache_query uint8 tbls_type; unsigned int last_pkt_nr; + Query_cache_query() {} /* Remove gcc warning */ inline void init_n_lock(); void unlock_n_destroy(); inline ulonglong found_rows() { return limit_found_rows; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0135acddd8c..a08d1abe438 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -410,7 +410,8 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; - time_after_lock=(time_t) 0; + start_utime= 0L; + utime_after_lock= 0L; current_linfo = 0; slave_thread = 0; bzero(&variables, sizeof(variables)); diff --git a/sql/sql_class.h b/sql/sql_class.h index 996009f3f5d..df79d82732f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -249,18 +249,19 @@ struct system_variables ulonglong myisam_max_sort_file_size; ulonglong max_heap_table_size; ulonglong tmp_table_size; + ulonglong long_query_time; ha_rows select_limit; ha_rows max_join_size; ulong auto_increment_increment, auto_increment_offset; ulong bulk_insert_buff_size; ulong join_buff_size; - ulong long_query_time; ulong max_allowed_packet; ulong max_error_count; ulong max_length_for_sort_data; ulong max_sort_length; ulong max_tmp_tables; ulong max_insert_delayed_threads; + ulong min_examined_row_limit; ulong multi_range_count; ulong myisam_repair_threads; ulong myisam_sort_buff_size; @@ -423,6 +424,8 @@ typedef struct system_status_var #define last_system_status_var com_stmt_close +void mark_transaction_to_rollback(THD *thd, bool all); + #ifdef MYSQL_SERVER void free_tmp_table(THD *thd, TABLE *entry); @@ -1037,8 +1040,6 @@ public: Security_context main_security_ctx; Security_context *security_ctx; - /* remote (peer) port */ - uint16 peer_port; /* Points to info-string that we show in SHOW PROCESSLIST You are supposed to update thd->proc_info only if you have coded @@ -1046,6 +1047,14 @@ public: */ const char *proc_info; + /* + Used in error messages to tell user in what part of MySQL we found an + error. E. g. when where= "having clause", if fix_fields() fails, user + will know that the error was in having clause. + */ + const char *where; + + double tmp_double_value; /* Used in set_var.cc */ ulong client_capabilities; /* What the client supports */ ulong max_client_packet_length; @@ -1067,14 +1076,12 @@ public: enum enum_server_command command; uint32 server_id; uint32 file_id; // for LOAD DATA INFILE - /* - Used in error messages to tell user in what part of MySQL we found an - error. E. g. when where= "having clause", if fix_fields() fails, user - will know that the error was in having clause. - */ - const char *where; - time_t start_time,time_after_lock,user_time; - time_t connect_time,thr_create_time; // track down slow pthread_create + /* remote (peer) port */ + uint16 peer_port; + time_t start_time, user_time; + ulonglong connect_utime, thr_create_utime; // track down slow pthread_create + ulonglong start_utime, utime_after_lock; + thr_lock_type update_lock_default; Delayed_insert *di; @@ -1606,27 +1613,25 @@ public: proc_info = old_msg; pthread_mutex_unlock(&mysys_var->mutex); } - - static inline void safe_time(time_t *t) + inline time_t query_start() { query_start_used=1; return start_time; } + inline void set_time() { - /** - Wrapper around time() which retries on error (-1) - - @details - This is needed because, despite the documentation, time() may fail - in some circumstances. Here we retry time() until it succeeds, and - log the failure so that performance problems related to this can be - identified. - */ - while(unlikely(time(t) == ((time_t) -1))) - sql_print_information("time() failed with %d", errno); + if (user_time) + { + start_time= user_time; + start_utime= utime_after_lock= my_micro_time(); + } + else + start_utime= utime_after_lock= my_micro_time_and_time(&start_time); } - - inline time_t query_start() { query_start_used=1; return start_time; } - inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }} - inline void end_time() { safe_time(&start_time); } - inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; } - inline void lock_time() { safe_time(&time_after_lock); } + inline void set_current_time() { start_time= my_time(MY_WME); } + inline void set_time(time_t t) + { + start_time= user_time= t; + start_utime= utime_after_lock= my_micro_time(); + } + void set_time_after_lock() { utime_after_lock= my_micro_time(); } + ulonglong current_utime() { return my_micro_time(); } inline ulonglong found_rows(void) { return limit_found_rows; @@ -2479,6 +2484,7 @@ public: /* Functions in sql_class.cc */ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); + void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, STATUS_VAR *dec_var); void mark_transaction_to_rollback(THD *thd, bool all); diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 26b7098e27c..03b9908c1ad 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -97,7 +97,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, uc->len= temp_len; uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0; uc->user_resources= *mqh; - uc->intime= thd->thr_create_time; + uc->reset_utime= thd->thr_create_utime; if (my_hash_insert(&hash_user_connections, (uchar*) uc)) { my_free((char*) uc,0); @@ -223,16 +223,16 @@ void decrease_user_connections(USER_CONN *uc) void time_out_user_resource_limits(THD *thd, USER_CONN *uc) { - time_t check_time = thd->start_time ? thd->start_time : time(NULL); + ulonglong check_time= thd->start_utime; DBUG_ENTER("time_out_user_resource_limits"); /* If more than a hour since last check, reset resource checking */ - if (check_time - uc->intime >= 3600) + if (check_time - uc->reset_utime >= LL(3600000000)) { uc->questions=1; uc->updates=0; uc->conn_per_hour=0; - uc->intime=check_time; + uc->reset_utime= check_time; } DBUG_VOID_RETURN; @@ -1053,8 +1053,8 @@ void prepare_new_connection_state(THD* thd) pthread_handler_t handle_one_connection(void *arg) { THD *thd= (THD*) arg; - uint launch_time = - (uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time); + ulong launch_time= (ulong) ((thd->thr_create_utime= my_micro_time()) - + thd->connect_utime); if (thread_scheduler.init_new_connection_thread()) { @@ -1063,7 +1063,7 @@ pthread_handler_t handle_one_connection(void *arg) thread_scheduler.end_thread(thd,0); return 0; } - if (launch_time >= slow_launch_time) + if (launch_time >= slow_launch_time*1000000L) statistic_increment(slow_launch_threads,&LOCK_status); /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6c6a4721369..36623c1a10f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -426,7 +426,6 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, client connection and the delayed thread. */ if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) || - thd->slave_thread || thd->variables.max_insert_delayed_threads == 0 || thd->prelocked_mode || thd->lex->uses_stored_routines()) @@ -434,6 +433,14 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, *lock_type= TL_WRITE; return; } + if (thd->slave_thread) + { + /* Try concurrent insert */ + *lock_type= (duplic == DUP_UPDATE || duplic == DUP_REPLACE) ? + TL_WRITE : TL_WRITE_CONCURRENT_INSERT; + return; + } + bool log_on= (thd->options & OPTION_BIN_LOG || ! (thd->security_ctx->master_access & SUPER_ACL)); if (global_system_variables.binlog_format == BINLOG_FORMAT_STMT && @@ -2226,7 +2233,7 @@ pthread_handler_t handle_delayed_insert(void *arg) /* Add thread to THD list so that's it's visible in 'show processlist' */ pthread_mutex_lock(&LOCK_thread_count); thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - thd->end_time(); + thd->set_current_time(); threads.append(thd); thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 737ec320a69..0d7158a4eee 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1341,7 +1341,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, void log_slow_statement(THD *thd) { - time_t start_of_query; DBUG_ENTER("log_slow_statement"); /* @@ -1352,26 +1351,25 @@ void log_slow_statement(THD *thd) if (unlikely(thd->in_sub_stmt)) DBUG_VOID_RETURN; // Don't set time for sub stmt - start_of_query= thd->start_time; - thd->end_time(); // Set start time - /* Do not log administrative statements unless the appropriate option is set; do not log into slow log if reading from backup. */ if (thd->enable_slow_log && !thd->user_time) { - thd->proc_info="logging slow query"; + ulonglong end_utime_of_query= thd->current_utime(); - if ((ulong) (thd->start_time - thd->time_after_lock) > - thd->variables.long_query_time || - ((thd->server_status & - (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - opt_log_queries_not_using_indexes && - !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) + thd->proc_info="logging slow query"; + if (((end_utime_of_query - thd->utime_after_lock) > + thd->variables.long_query_time || + ((thd->server_status & + (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && + opt_log_queries_not_using_indexes && + !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) && + thd->examined_row_count >= thd->variables.min_examined_row_limit) { thd->status_var.long_query_count++; - slow_log_print(thd, thd->query, thd->query_length, start_of_query); + slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query); } } DBUG_VOID_RETURN; @@ -5253,6 +5251,11 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->init_query(); select_lex->init_select(); 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); + DBUG_RETURN(1); + } select_lex->nest_level= lex->nest_level; /* Don't evaluate this subquery during statement prepare even if diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9ea67af1bf9..6f3851b66a1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1625,6 +1625,10 @@ JOIN::exec() DBUG_VOID_RETURN; } + if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && + get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) + DBUG_VOID_RETURN; + if (select_options & SELECT_DESCRIBE) { /* @@ -1670,13 +1674,6 @@ JOIN::exec() */ curr_join->examined_rows= 0; - if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) && - !thd->lex->describe && - get_schema_tables_result(curr_join, PROCESSED_BY_JOIN_EXEC)) - { - DBUG_VOID_RETURN; - } - /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) { @@ -6451,6 +6448,7 @@ void JOIN_TAB::cleanup() quick= 0; x_free(cache.buff); cache.buff= 0; + limit= 0; if (table) { if (table->key_read) @@ -10199,7 +10197,7 @@ static bool open_tmp_table(TABLE *table) { int error; if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR, - HA_OPEN_TMP_TABLE))) + HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -10437,8 +10435,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, /* remove heap table and change to use myisam table */ (void) table->file->ha_rnd_end(); - (void) table->file->close(); - (void) table->file->delete_table(table->s->table_name.str); + (void) table->file->close(); // This deletes the table ! delete table->file; table->file=0; plugin_unlock(0, table->s->db_plugin); @@ -12590,9 +12587,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, { int ref_key; uint ref_key_parts; + int order_direction; + uint used_key_parts; TABLE *table=tab->table; SQL_SELECT *select=tab->select; key_map usable_keys; + QUICK_SELECT_I *save_quick= 0; DBUG_ENTER("test_if_skip_sort_order"); LINT_INIT(ref_key_parts); @@ -12627,6 +12627,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, else if (select && select->quick) // Range found by opt_range { int quick_type= select->quick->get_type(); + save_quick= select->quick; /* assume results are not ordered when index merge is used TODO: sergeyp: Results of all index merge selects actually are ordered @@ -12646,8 +12647,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, /* We come here when there is a REF key. */ - int order_direction; - uint used_key_parts; if (!usable_keys.is_set(ref_key)) { /* @@ -12708,63 +12707,33 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } /* Check if we get the rows in requested sorted order by using the key */ if (usable_keys.is_set(ref_key) && - (order_direction = test_if_order_by_key(order,table,ref_key, - &used_key_parts))) - { - if (order_direction == -1) // If ORDER BY ... DESC - { - if (select && select->quick) - { - /* - Don't reverse the sort order, if it's already done. - (In some cases test_if_order_by_key() can be called multiple times - */ - if (!select->quick->reverse_sorted()) - { - QUICK_SELECT_DESC *tmp; - int quick_type= select->quick->get_type(); - if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || - quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || - quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) - DBUG_RETURN(0); // Use filesort - - /* ORDER BY range_key DESC */ - tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick), - used_key_parts); - if (!tmp || tmp->error) - { - delete tmp; - DBUG_RETURN(0); // Reverse sort not supported - } - select->quick=tmp; - } - DBUG_RETURN(1); - } - if (tab->ref.key_parts < used_key_parts) - { - /* - SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC - - Use a traversal function that starts by reading the last row - with key part (A) and then traverse the index backwards. - */ - tab->read_first_record= join_read_last_key; - tab->read_record.read_record= join_read_prev_same; - /* fall through */ - } - } - else if (select && select->quick) - select->quick->sorted= 1; - DBUG_RETURN(1); /* No need to sort */ - } + (order_direction= test_if_order_by_key(order,table,ref_key, + &used_key_parts))) + goto check_reverse_order; } - else { - /* check if we can use a key to resolve the group */ - /* Tables using JT_NEXT are handled here */ + /* + Check whether there is an index compatible with the given order + usage of which is cheaper than usage of the ref_key index (ref_key>=0) + or a table scan. + It may be the case if ORDER/GROUP BY is used with LIMIT. + */ uint nr; key_map keys; + uint best_key_parts; + int best_key_direction; + ha_rows best_records; + double read_time; + int best_key= -1; + bool is_best_covering= FALSE; + double fanout= 1; + JOIN *join= tab->join; + uint tablenr= tab - join->join_tab; + ha_rows table_records= table->file->stats.records; + bool group= join->group && order == join->group_list; + LINT_INIT(best_key_parts); + LINT_INIT(best_key_direction); + LINT_INIT(best_records); /* filesort() and join cache are usually faster than reading in @@ -12777,7 +12746,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, resolved with a key; This is because filesort() is usually faster than retrieving all rows through an index. */ - if (select_limit >= table->file->stats.records) + if (select_limit >= table_records) { keys= *table->file->keys_to_use_for_scanning(); keys.merge(table->covering_keys); @@ -12788,38 +12757,227 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, This is to allow users to use index in ORDER BY. */ if (table->force_index) - keys.merge(table->keys_in_use_for_query); + keys.merge(group ? table->keys_in_use_for_group_by : + table->keys_in_use_for_order_by); keys.intersect(usable_keys); } else keys= usable_keys; + read_time= join->best_positions[tablenr].read_time; + for (uint i= tablenr+1; i < join->tables; i++) + fanout*= join->best_positions[i].records_read; // fanout is always >= 1 + for (nr=0; nr < table->s->keys ; nr++) { - uint not_used; - if (keys.is_set(nr)) + int direction; + if (keys.is_set(nr) && + (direction= test_if_order_by_key(order, table, nr, &used_key_parts))) + { + bool is_covering= table->covering_keys.is_set(nr) || + nr == table->s->primary_key && + table->file->primary_key_is_clustered(); + + /* + Don't use an index scan with ORDER BY without limit. + For GROUP BY without limit always use index scan + if there is a suitable index. + Why we hold to this asymmetry hardly can be explained + rationally. It's easy to demonstrate that using + temporary table + filesort could be cheaper for grouping + queries too. + */ + if (is_covering || + select_limit != HA_POS_ERROR || + ref_key < 0 && (group || table->force_index)) + { + double rec_per_key; + double index_scan_time; + KEY *keyinfo= tab->table->key_info+nr; + if (select_limit == HA_POS_ERROR) + select_limit= table_records; + if (group) + { + rec_per_key= keyinfo->rec_per_key[used_key_parts-1]; + set_if_bigger(rec_per_key, 1); + /* + With a grouping query each group containing on average + rec_per_key records produces only one row that will + be included into the result set. + */ + if (select_limit > table_records/rec_per_key) + select_limit= table_records; + else + select_limit= (ha_rows) (select_limit*rec_per_key); + } + /* + If tab=tk is not the last joined table tn then to get first + L records from the result set we can expect to retrieve + only L/fanout(tk,tn) where fanout(tk,tn) says how many + rows in the record set on average will match each row tk. + Usually our estimates for fanouts are too pessimistic. + So the estimate for L/fanout(tk,tn) will be too optimistic + and as result we'll choose an index scan when using ref/range + access + filesort will be cheaper. + */ + select_limit= (ha_rows) (select_limit < fanout ? + 1 : select_limit/fanout); + /* + We assume that each of the tested indexes is not correlated + with ref_key. Thus, to select first N records we have to scan + N/selectivity(ref_key) index entries. + selectivity(ref_key) = #scanned_records/#table_records = + table->quick_condition_rows/table_records. + In any case we can't select more than #table_records. + N/(table->quick_condition_rows/table_records) > table_records + <=> N > table->quick_condition_rows. + */ + if (select_limit > table->quick_condition_rows) + select_limit= table_records; + else + select_limit= (ha_rows) (select_limit * + (double) table_records / + table->quick_condition_rows); + rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1]; + set_if_bigger(rec_per_key, 1); + /* + Here we take into account the fact that rows are + accessed in sequences rec_per_key records in each. + Rows in such a sequence are supposed to be ordered + by rowid/primary key. When reading the data + in a sequence we'll touch not more pages than the + table file contains. + TODO. Use the formula for a disk sweep sequential access + to calculate the cost of accessing data rows for one + index entry. + */ + index_scan_time= select_limit/rec_per_key * + min(rec_per_key, table->file->scan_time()); + if (is_covering || + ref_key < 0 && (group || table->force_index) || + index_scan_time < read_time) + { + ha_rows quick_records= table_records; + if (is_best_covering && !is_covering) + continue; + if (table->quick_keys.is_set(nr)) + quick_records= table->quick_rows[nr]; + if (best_key < 0 || + (select_limit <= min(quick_records,best_records) ? + keyinfo->key_parts < best_key_parts : + quick_records < best_records)) + { + best_key= nr; + best_key_parts= keyinfo->key_parts; + best_records= quick_records; + is_best_covering= is_covering; + best_key_direction= direction; + } + } + } + } + } + if (best_key >= 0) + { + bool quick_created= FALSE; + if (table->quick_keys.is_set(best_key) && best_key != ref_key) + { + key_map map; + map.clear_all(); // Force the creation of quick select + map.set_bit(best_key); // only best_key. + quick_created= + select->test_quick_select(join->thd, map, 0, + join->select_options & OPTION_FOUND_ROWS ? + HA_POS_ERROR : + join->unit->select_limit_cnt, + 0) > 0; + } + if (!no_changes) { - int flag; - if ((flag= test_if_order_by_key(order, table, nr, ¬_used))) + if (!quick_created) { - if (!no_changes) - { - tab->index=nr; - tab->read_first_record= (flag > 0 ? join_read_first: - join_read_last); - tab->type=JT_NEXT; // Read with index_first(), index_next() - if (table->covering_keys.is_set(nr)) - { - table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); - } - } - DBUG_RETURN(1); + tab->index= best_key; + tab->read_first_record= best_key_direction > 0 ? + join_read_first:join_read_last; + tab->type=JT_NEXT; // Read with index_first(), index_next() + if (table->covering_keys.is_set(best_key)) + { + table->key_read=1; + table->file->extra(HA_EXTRA_KEYREAD); + } + table->file->ha_index_or_rnd_end(); + if (join->select_options & SELECT_DESCRIBE) + { + tab->ref.key= -1; + tab->ref.key_parts= 0; + if (select && select->quick) + { + delete select->quick; + select->quick= 0; + } + if (select_limit < table_records) + tab->limit= select_limit; + } + } + } + used_key_parts= best_key_parts; + order_direction= best_key_direction; + } + else + DBUG_RETURN(0); + } + +check_reverse_order: + if (order_direction == -1) // If ORDER BY ... DESC + { + if (select && select->quick) + { + /* + Don't reverse the sort order, if it's already done. + (In some cases test_if_order_by_key() can be called multiple times + */ + if (!select->quick->reverse_sorted()) + { + QUICK_SELECT_DESC *tmp; + int quick_type= select->quick->get_type(); + if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || + quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || + quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) + { + tab->limit= 0; + select->quick= save_quick; + DBUG_RETURN(0); // Use filesort + } + + /* ORDER BY range_key DESC */ + tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick), + used_key_parts); + if (!tmp || tmp->error) + { + delete tmp; + select->quick= save_quick; + tab->limit= 0; + DBUG_RETURN(0); // Reverse sort not supported } + select->quick=tmp; } } + else if (tab->ref.key >= 0 && tab->ref.key_parts < used_key_parts) + { + /* + SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC + + Use a traversal function that starts by reading the last row + with key part (A) and then traverse the index backwards. + */ + tab->read_first_record= join_read_last_key; + tab->read_record.read_record= join_read_prev_same; + } } - DBUG_RETURN(0); // Can't use index. + else if (select && select->quick) + select->quick->sorted= 1; + DBUG_RETURN(1); } @@ -12929,7 +13087,6 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, /* Fill schema tables with data before filesort if it's necessary */ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && - !thd->lex->describe && get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX)) goto err; @@ -15382,6 +15539,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { JOIN_TAB *tab=join->join_tab+i; TABLE *table=tab->table; + TABLE_LIST *table_list= tab->table->pos_in_table_list; char buff[512]; char buff1[512], buff2[512], buff3[512]; char keylen_str_buf[64]; @@ -15517,37 +15675,64 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } else { - item_list.push_back(item_null); + if (table_list->schema_table && + table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE) + { + const char *tmp_buff; + int f_idx; + if (table_list->has_db_lookup_value) + { + f_idx= table_list->schema_table->idx_field1; + tmp_buff= table_list->schema_table->fields_info[f_idx].field_name; + tmp2.append(tmp_buff, strlen(tmp_buff), cs); + } + if (table_list->has_table_lookup_value) + { + if (table_list->has_db_lookup_value) + tmp2.append(','); + f_idx= table_list->schema_table->idx_field2; + tmp_buff= table_list->schema_table->fields_info[f_idx].field_name; + tmp2.append(tmp_buff, strlen(tmp_buff), cs); + } + if (tmp2.length()) + item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs)); + else + item_list.push_back(item_null); + } + else + item_list.push_back(item_null); item_list.push_back(item_null); item_list.push_back(item_null); } /* Add "rows" field to item_list. */ - ha_rows examined_rows; - if (tab->select && tab->select->quick) - examined_rows= tab->select->quick->records; - else if (tab->type == JT_NEXT || tab->type == JT_ALL) - examined_rows= tab->table->file->records(); + if (table_list->schema_table) + { + item_list.push_back(item_null); + } else - examined_rows=(ha_rows)join->best_positions[i].records_read; - - item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, - MY_INT64_NUM_DECIMAL_DIGITS)); - - /* Add "filtered" field to item_list. */ - if (join->thd->lex->describe & DESCRIBE_EXTENDED) { - Item_float *filtered; - float f; - if (examined_rows) - f= (float) (100.0 * join->best_positions[i].records_read / - examined_rows); + ha_rows examined_rows; + if (tab->select && tab->select->quick) + examined_rows= tab->select->quick->records; + else if (tab->type == JT_NEXT || tab->type == JT_ALL) + examined_rows= tab->limit ? tab->limit : tab->table->file->records(); else - f= 0.0; - item_list.push_back((filtered= new Item_float(f))); - filtered->decimals= 2; - } + examined_rows=(ha_rows)join->best_positions[i].records_read; + + item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, + MY_INT64_NUM_DECIMAL_DIGITS)); + /* Add "filtered" field to item_list. */ + if (join->thd->lex->describe & DESCRIBE_EXTENDED) + { + float f= 0.0; + if (examined_rows) + f= (float) (100.0 * join->best_positions[i].records_read / + examined_rows); + item_list.push_back(new Item_float(f, 2)); + } + } /* Build "Extra" field and add it to item_list. */ my_bool key_read=table->key_read; @@ -15615,6 +15800,24 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, extra.append(STRING_WITH_LEN("; Using where")); } } + if (table_list->schema_table && + table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE) + { + if (!table_list->table_open_method) + extra.append(STRING_WITH_LEN("; Skip_open_table")); + else if (table_list->table_open_method == OPEN_FRM_ONLY) + extra.append(STRING_WITH_LEN("; Open_frm_only")); + else + extra.append(STRING_WITH_LEN("; Open_full_table")); + if (table_list->has_db_lookup_value && + table_list->has_table_lookup_value) + extra.append(STRING_WITH_LEN("; Scanned 0 databases")); + else if (table_list->has_db_lookup_value || + table_list->has_table_lookup_value) + extra.append(STRING_WITH_LEN("; Scanned 1 database")); + else + extra.append(STRING_WITH_LEN("; Scanned all databases")); + } if (key_read) { if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) diff --git a/sql/sql_select.h b/sql/sql_select.h index d1acad1c5d6..efa92432e2b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -194,6 +194,12 @@ typedef struct st_join_table { enum join_type type; bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; bool sorted; + /* + If it's not 0 the number stored this field indicates that the index + scan has been chosen to access the table data and we expect to scan + this number of rows for the table. + */ + ha_rows limit; TABLE_REF ref; JOIN_CACHE cache; JOIN *join; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a0c3355b49a..5a1619aa5cf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -443,13 +443,15 @@ bool mysqld_show_column_types(THD *thd) find_files_result -find_files(THD *thd, List<char> *files, const char *db, +find_files(THD *thd, List<LEX_STRING> *files, const char *db, const char *path, const char *wild, bool dir) { uint i; char *ext; MY_DIR *dirp; FILEINFO *file; + LEX_STRING *file_name= 0; + uint file_name_len; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif @@ -498,10 +500,16 @@ find_files(THD *thd, List<char> *files, const char *db, #endif if (!MY_S_ISDIR(file->mystat->st_mode)) continue; - VOID(filename_to_tablename(file->name, uname, sizeof(uname))); + + file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); if (wild && wild_compare(uname, wild, 0)) continue; - file->name= uname; + if (!(file_name= + thd->make_lex_string(file_name, uname, file_name_len, TRUE))) + { + my_dirend(dirp); + DBUG_RETURN(FIND_FILES_OOM); + } } else { @@ -510,16 +518,15 @@ find_files(THD *thd, List<char> *files, const char *db, is_prefix(file->name, tmp_file_prefix)) continue; *ext=0; - VOID(filename_to_tablename(file->name, uname, sizeof(uname))); - file->name= uname; + file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); if (wild) { if (lower_case_table_names) { - if (wild_case_compare(files_charset_info, file->name, wild)) + if (wild_case_compare(files_charset_info, uname, wild)) continue; } - else if (wild_compare(file->name,wild,0)) + else if (wild_compare(uname, wild, 0)) continue; } } @@ -529,14 +536,16 @@ find_files(THD *thd, List<char> *files, const char *db, { table_list.db= (char*) db; table_list.db_length= strlen(db); - table_list.table_name= file->name; - table_list.table_name_length= strlen(file->name); + table_list.table_name= uname; + table_list.table_name_length= file_name_len; table_list.grant.privilege=col_access; if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1)) continue; } #endif - if (files->push_back(thd->strdup(file->name))) + if (!(file_name= + thd->make_lex_string(file_name, uname, file_name_len, TRUE)) || + files->push_back(file_name)) { my_dirend(dirp); DBUG_RETURN(FIND_FILES_OOM); @@ -545,7 +554,7 @@ find_files(THD *thd, List<char> *files, const char *db, DBUG_PRINT("info",("found: %d files", files->elements)); my_dirend(dirp); - VOID(ha_find_files(thd,db,path,wild,dir,files)); + VOID(ha_find_files(thd, db, path, wild, dir, files)); DBUG_RETURN(FIND_FILES_OK); } @@ -1663,11 +1672,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) if (mysys_var) pthread_mutex_unlock(&mysys_var->mutex); -#ifdef EXTRA_DEBUG - thd_info->start_time= tmp->time_after_lock; -#else thd_info->start_time= tmp->start_time; -#endif thd_info->query=0; if (tmp->query) { @@ -1686,7 +1691,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) VOID(pthread_mutex_unlock(&LOCK_thread_count)); thread_info *thd_info; - time_t now= time(0); + time_t now= my_time(0); while ((thd_info=thread_infos.get())) { protocol->prepare_for_resend(); @@ -1716,7 +1721,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; char *user; - time_t now= time(0); + time_t now= my_time(0); DBUG_ENTER("fill_process_list"); user= thd->security_ctx->master_access & PROCESS_ACL ? @@ -2069,11 +2074,11 @@ static bool show_status_array(THD *thd, const char *wild, */ switch (show_type) { case SHOW_DOUBLE_STATUS: - { value= ((char *) status_var + (ulong) value); - end= buff + sprintf(buff, "%f", *(double*) value); + /* fall through */ + case SHOW_DOUBLE: + end= buff + my_sprintf(buff, (buff, "%f", *(double*) value)); break; - } case SHOW_LONG_STATUS: value= ((char *) status_var + (ulong) value); /* fall through */ @@ -2083,6 +2088,7 @@ static bool show_status_array(THD *thd, const char *wild, break; case SHOW_LONGLONG_STATUS: value= ((char *) status_var + (ulonglong) value); + /* fall through */ case SHOW_LONGLONG: end= longlong10_to_str(*(longlong*) value, buff, 10); break; @@ -2179,10 +2185,11 @@ void calc_sum_of_all_status(STATUS_VAR *to) /* This is only used internally, but we need it here as a forward reference */ extern ST_SCHEMA_TABLE schema_tables[]; -typedef struct st_index_field_values +typedef struct st_lookup_field_values { - const char *db_value, *table_value; -} INDEX_FIELD_VALUES; + LEX_STRING db_value, table_value; + bool wild_db_value, wild_table_value; +} LOOKUP_FIELD_VALUES; /* @@ -2213,38 +2220,11 @@ bool schema_table_store_record(THD *thd, TABLE *table) } -void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values) -{ - const char *wild= lex->wild ? lex->wild->ptr() : NullS; - switch (lex->sql_command) { - case SQLCOM_SHOW_DATABASES: - index_field_values->db_value= wild; - break; - case SQLCOM_SHOW_TABLES: - case SQLCOM_SHOW_TABLE_STATUS: - case SQLCOM_SHOW_TRIGGERS: - case SQLCOM_SHOW_EVENTS: - index_field_values->db_value= lex->select_lex.db; - index_field_values->table_value= wild; - break; - default: - index_field_values->db_value= NullS; - index_field_values->table_value= NullS; - break; - } -} - - int make_table_list(THD *thd, SELECT_LEX *sel, - char *db, char *table) + LEX_STRING *db_name, LEX_STRING *table_name) { Table_ident *table_ident; - LEX_STRING ident_db, ident_table; - ident_db.str= db; - ident_db.length= strlen(db); - ident_table.str= table; - ident_table.length= strlen(table); - table_ident= new Table_ident(thd, ident_db, ident_table, 1); + 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)) return 1; @@ -2252,6 +2232,127 @@ int make_table_list(THD *thd, SELECT_LEX *sel, } +/** + @brief Get lookup value from the part of 'WHERE' condition + + @details This function gets lookup value from + the part of 'WHERE' condition if it's possible and + fill appropriate lookup_field_vals struct field + with this value. + + @param[in] thd thread handler + @param[in] item_func part of WHERE condition + @param[in] table I_S table + @param[in, out] lookup_field_vals Struct which holds lookup values + + @return void +*/ + +void get_lookup_value(THD *thd, Item_func *item_func, + TABLE_LIST *table, + LOOKUP_FIELD_VALUES *lookup_field_vals) +{ + ST_SCHEMA_TABLE *schema_table= table->schema_table; + ST_FIELD_INFO *field_info= schema_table->fields_info; + const char *field_name1= schema_table->idx_field1 >= 0 ? + field_info[schema_table->idx_field1].field_name : ""; + const char *field_name2= schema_table->idx_field2 >= 0 ? + field_info[schema_table->idx_field2].field_name : ""; + + if (item_func->functype() == Item_func::EQ_FUNC || + item_func->functype() == Item_func::EQUAL_FUNC) + { + int idx_field, idx_val; + char tmp[MAX_FIELD_WIDTH]; + String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info); + Item_field *item_field; + CHARSET_INFO *cs= system_charset_info; + + if (item_func->arguments()[0]->type() == Item::FIELD_ITEM && + item_func->arguments()[1]->const_item()) + { + idx_field= 0; + idx_val= 1; + } + else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM && + item_func->arguments()[0]->const_item()) + { + idx_field= 1; + idx_val= 0; + } + else + return; + + item_field= (Item_field*) item_func->arguments()[idx_field]; + if (table->table != item_field->field->table) + return; + tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff); + + /* Lookup value is database name */ + if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1), + (uchar *) item_field->field_name, + strlen(item_field->field_name), 0)) + { + thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(), + tmp_str->length(), FALSE); + } + /* Lookup value is table name */ + else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2, + strlen(field_name2), + (uchar *) item_field->field_name, + strlen(item_field->field_name), 0)) + { + thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(), + tmp_str->length(), FALSE); + } + } + return; +} + + +/** + @brief Calculates lookup values from 'WHERE' condition + + @details This function calculates lookup value(database name, table name) + from 'WHERE' condition if it's possible and + fill lookup_field_vals struct fields with these values. + + @param[in] thd thread handler + @param[in] cond WHERE condition + @param[in] table I_S table + @param[in, out] lookup_field_vals Struct which holds lookup values + + @return void +*/ + +void calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table, + LOOKUP_FIELD_VALUES *lookup_field_vals) +{ + if (!cond) + return; + + if (cond->type() == Item::COND_ITEM) + { + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item= li++)) + { + if (item->type() == Item::FUNC_ITEM) + get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals); + else + calc_lookup_values_from_cond(thd, item, table, lookup_field_vals); + } + } + return; + } + else if (cond->type() == Item::FUNC_ITEM) + get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals); + return; +} + + bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) { if (item->type() == Item::FUNC_ITEM) @@ -2269,21 +2370,23 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) CHARSET_INFO *cs= system_charset_info; ST_SCHEMA_TABLE *schema_table= table->schema_table; ST_FIELD_INFO *field_info= schema_table->fields_info; - const char *field_name1= schema_table->idx_field1 >= 0 ? field_info[schema_table->idx_field1].field_name : ""; - const char *field_name2= schema_table->idx_field2 >= 0 ? field_info[schema_table->idx_field2].field_name : ""; + const char *field_name1= schema_table->idx_field1 >= 0 ? + field_info[schema_table->idx_field1].field_name : ""; + const char *field_name2= schema_table->idx_field2 >= 0 ? + field_info[schema_table->idx_field2].field_name : ""; if (table->table != item_field->field->table || (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1), - (uchar *) item_field->field_name, + (uchar *) item_field->field_name, strlen(item_field->field_name), 0) && cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2), - (uchar *) item_field->field_name, + (uchar *) item_field->field_name, strlen(item_field->field_name), 0))) return 0; } else if (item->type() == Item::REF_ITEM) return uses_only_table_name_fields(item->real_item(), table); - if (item->type() == Item::SUBSELECT_ITEM && - !item->const_item()) + + if (item->type() == Item::SUBSELECT_ITEM && !item->const_item()) return 0; return 1; @@ -2346,6 +2449,61 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table) } +/** + @brief Calculate lookup values(database name, table name) + + @details This function calculates lookup values(database name, table name) + from 'WHERE' condition or wild values (for 'SHOW' commands only) + from LEX struct and fill lookup_field_vals struct field + with these values. + + @param[in] thd thread handler + @param[in] cond WHERE condition + @param[in] table I_S table + @param[in, out] lookup_field_vals Struct which holds lookup values + + @return void +*/ + +void get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, + LOOKUP_FIELD_VALUES *lookup_field_values) +{ + LEX *lex= thd->lex; + const char *wild= lex->wild ? lex->wild->ptr() : NullS; + bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES)); + switch (lex->sql_command) { + case SQLCOM_SHOW_DATABASES: + if (wild) + { + lookup_field_values->db_value.str= (char*) wild; + lookup_field_values->db_value.length= strlen(wild); + lookup_field_values->wild_db_value= 1; + } + break; + case SQLCOM_SHOW_TABLES: + case SQLCOM_SHOW_TABLE_STATUS: + case SQLCOM_SHOW_TRIGGERS: + case SQLCOM_SHOW_EVENTS: + lookup_field_values->db_value.str= lex->select_lex.db; + lookup_field_values->db_value.length=strlen(lex->select_lex.db); + if (wild) + { + lookup_field_values->table_value.str= (char*)wild; + lookup_field_values->table_value.length= strlen(wild); + lookup_field_values->wild_table_value= 1; + } + break; + default: + /* + The "default" is for queries over I_S. + All previous cases handle SHOW commands. + */ + calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values); + break; + } +} + + enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) { return (enum enum_schema_tables) (schema_table - &schema_tables[0]); @@ -2363,81 +2521,87 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) idx_field_vals idx_field_vals->db_name contains db name or wild string with_i_schema returns 1 if we added 'IS' name to list - otherwise returns 0 - is_wild_value if value is 1 then idx_field_vals->db_name is - wild string otherwise it's db name; + otherwise returns 0 RETURN zero success non-zero error */ -int make_db_list(THD *thd, List<char> *files, - INDEX_FIELD_VALUES *idx_field_vals, - bool *with_i_schema, bool is_wild_value) +int make_db_list(THD *thd, List<LEX_STRING> *files, + LOOKUP_FIELD_VALUES *lookup_field_vals, + bool *with_i_schema) { - LEX *lex= thd->lex; + LEX_STRING *i_s_name_copy= 0; + i_s_name_copy= thd->make_lex_string(i_s_name_copy, + INFORMATION_SCHEMA_NAME.str, + INFORMATION_SCHEMA_NAME.length, TRUE); *with_i_schema= 0; - get_index_field_values(lex, idx_field_vals); - - if (is_wild_value) + if (lookup_field_vals->wild_db_value) { /* This part of code is only for SHOW DATABASES command. idx_field_vals->db_value can be 0 when we don't use LIKE clause (see also get_index_field_values() function) */ - if (!idx_field_vals->db_value || + if (!lookup_field_vals->db_value.str || !wild_case_compare(system_charset_info, INFORMATION_SCHEMA_NAME.str, - idx_field_vals->db_value)) + lookup_field_vals->db_value.str)) { *with_i_schema= 1; - if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str))) + if (files->push_back(i_s_name_copy)) return 1; } return (find_files(thd, files, NullS, mysql_data_home, - idx_field_vals->db_value, 1) != FIND_FILES_OK); + lookup_field_vals->db_value.str, 1) != FIND_FILES_OK); } + /* - This part of code is for SHOW TABLES, SHOW TABLE STATUS commands. - idx_field_vals->db_value can't be 0 (see get_index_field_values() - function). + If we have db lookup vaule we just add it to list and + exit from the function */ - if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) + if (lookup_field_vals->db_value.str) { if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, - idx_field_vals->db_value)) + lookup_field_vals->db_value.str)) { *with_i_schema= 1; - return files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str)); + if (files->push_back(i_s_name_copy)) + return 1; + return 0; } - return files->push_back(thd->strdup(idx_field_vals->db_value)); + if (files->push_back(&lookup_field_vals->db_value)) + return 1; + return 0; } /* Create list of existing databases. It is used in case of select from information schema table */ - if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str))) + if (files->push_back(i_s_name_copy)) return 1; *with_i_schema= 1; return (find_files(thd, files, NullS, mysql_data_home, NullS, 1) != FIND_FILES_OK); } + struct st_add_schema_table { - List<char> *files; + List<LEX_STRING> *files; const char *wild; }; + static my_bool add_schema_table(THD *thd, plugin_ref plugin, void* p_data) { + LEX_STRING *file_name= 0; st_add_schema_table *data= (st_add_schema_table *)p_data; - List<char> *file_list= data->files; + List<LEX_STRING> *file_list= data->files; const char *wild= data->wild; ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("add_schema_table"); @@ -2457,14 +2621,18 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, DBUG_RETURN(0); } - if (file_list->push_back(thd->strdup(schema_table->table_name))) - DBUG_RETURN(1); - - DBUG_RETURN(0); + if ((file_name= thd->make_lex_string(file_name, schema_table->table_name, + strlen(schema_table->table_name), + TRUE)) && + !file_list->push_back(file_name)) + DBUG_RETURN(0); + DBUG_RETURN(1); } -int schema_tables_add(THD *thd, List<char> *files, const char *wild) + +int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild) { + LEX_STRING *file_name= 0; ST_SCHEMA_TABLE *tmp_schema_table= schema_tables; st_add_schema_table add_data; DBUG_ENTER("schema_tables_add"); @@ -2485,8 +2653,12 @@ int schema_tables_add(THD *thd, List<char> *files, const char *wild) else if (wild_compare(tmp_schema_table->table_name, wild, 0)) continue; } - if (files->push_back(thd->strdup(tmp_schema_table->table_name))) - DBUG_RETURN(1); + if ((file_name= + thd->make_lex_string(file_name, tmp_schema_table->table_name, + strlen(tmp_schema_table->table_name), TRUE)) && + !files->push_back(file_name)) + continue; + DBUG_RETURN(1); } add_data.files= files; @@ -2499,37 +2671,380 @@ int schema_tables_add(THD *thd, List<char> *files, const char *wild) } +/** + @brief Create table names list + + @details The function creates the list of table names in + database + + @param[in] thd thread handler + @param[in] table_names List of table names in database + @param[in] lex pointer to LEX struct + @param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct + @param[in] with_i_schema TRUE means that we add I_S tables to list + @param[in] db_name database name + + @return Operation status + @retval 0 ok + @retval 1 fatal error + @retval 2 Not fatal error; Safe to ignore this file list +*/ + +static int +make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex, + LOOKUP_FIELD_VALUES *lookup_field_vals, + bool with_i_schema, LEX_STRING *db_name) +{ + char path[FN_REFLEN]; + build_table_filename(path, sizeof(path), db_name->str, "", "", 0); + if (!lookup_field_vals->wild_table_value && + lookup_field_vals->table_value.str) + { + if (with_i_schema) + { + if (find_schema_table(thd, lookup_field_vals->table_value.str)) + { + if (table_names->push_back(&lookup_field_vals->table_value)) + return 1; + } + } + else + { + if (table_names->push_back(&lookup_field_vals->table_value)) + return 1; + /* + Check that table is relevant in current transaction. + (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc) + */ + VOID(ha_find_files(thd, db_name->str, path, + lookup_field_vals->table_value.str, 0, + table_names)); + } + return 0; + } + + /* + This call will add all matching the wildcards (if specified) IS tables + to the list + */ + if (with_i_schema) + return (schema_tables_add(thd, table_names, + lookup_field_vals->table_value.str)); + + find_files_result res= find_files(thd, table_names, db_name->str, path, + lookup_field_vals->table_value.str, 0); + if (res != FIND_FILES_OK) + { + /* + Downgrade errors about problems with database directory to + warnings if this is not a 'SHOW' command. Another thread + may have dropped database, and we may still have a name + for that directory. + */ + if (res == FIND_FILES_DIR) + { + if (lex->sql_command != SQLCOM_SELECT) + return 1; + thd->clear_error(); + return 2; + } + return 1; + } + return 0; +} + + +/** + @brief Fill I_S table for SHOW COLUMNS|INDEX commands + + @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] open_tables_state_backup pointer to Open_tables_state object + which is used to save|restore original + status of variables related to + open tables state + + @return Operation status + @retval 0 success + @retval 1 error +*/ + +static int +fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables, + ST_SCHEMA_TABLE *schema_table, + Open_tables_state *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= (TABLE_LIST*) tables->schema_select_lex-> + table_list.first; + TABLE *table= tables->table; + int error= 1; + DBUG_ENTER("fill_schema_show"); + + 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. + */ + thd->temporary_tables= open_tables_state_backup->temporary_tables; + /* + 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()' + */ + lex->sql_command= SQLCOM_SHOW_FIELDS; + res= open_normal_and_derived_tables(thd, show_table_list, + MYSQL_LOCK_IGNORE_FLUSH); + lex->sql_command= save_sql_command; + /* + 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). + */ + 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); + DBUG_RETURN(error); +} + + +/** + @brief Fill I_S table for SHOW TABLE NAMES commands + + @param[in] thd thread handler + @param[in] table TABLE struct for I_S table + @param[in] db_name database name + @param[in] table_name table name + @param[in] with_i_schema I_S table if TRUE + + @return Operation status + @retval 0 success + @retval 1 error +*/ + +static int fill_schema_table_names(THD *thd, TABLE *table, + LEX_STRING *db_name, LEX_STRING *table_name, + bool with_i_schema) +{ + if (with_i_schema) + { + table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), + system_charset_info); + } + else + { + enum legacy_db_type not_used; + char path[FN_REFLEN]; + (void) build_table_filename(path, sizeof(path), db_name->str, + table_name->str, reg_ext, 0); + switch (mysql_frm_type(thd, path, ¬_used)) { + case FRMTYPE_ERROR: + table->field[3]->store(STRING_WITH_LEN("ERROR"), + system_charset_info); + break; + case FRMTYPE_TABLE: + table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), + system_charset_info); + break; + case FRMTYPE_VIEW: + table->field[3]->store(STRING_WITH_LEN("VIEW"), + system_charset_info); + break; + default: + DBUG_ASSERT(0); + } + if (thd->net.last_errno == ER_NO_SUCH_TABLE) + { + thd->clear_error(); + return 0; + } + } + if (schema_table_store_record(thd, table)) + return 1; + return 0; +} + + +/** + @brief Get open table method + + @details The function calculates the method which will be used + for table opening: + SKIP_OPEN_TABLE - do not open table + OPEN_FRM_ONLY - open FRM file only + OPEN_FULL_TABLE - open FRM, data, index files + @param[in] tables I_S table table_list + @param[in] schema_table I_S table struct + @param[in] schema_table_idx I_S table index + + @return return a set of flags + @retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE +*/ + +static uint get_table_open_method(TABLE_LIST *tables, + ST_SCHEMA_TABLE *schema_table, + enum enum_schema_tables schema_table_idx) +{ + /* + determine which method will be used for table opening + */ + if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE) + { + Field **ptr, *field; + int table_open_method= 0, field_indx= 0; + for (ptr=tables->table->field; (field= *ptr) ; ptr++) + { + if (bitmap_is_set(tables->table->read_set, field->field_index)) + table_open_method|= schema_table->fields_info[field_indx].open_method; + field_indx++; + } + return table_open_method; + } + /* I_S tables which use get_all_tables but can not be optimized */ + return (uint) OPEN_FULL_TABLE; +} + + +/** + @brief Fill I_S table with data from FRM file only + + @param[in] thd thread handler + @param[in] table TABLE struct for I_S table + @param[in] schema_table I_S table struct + @param[in] db_name database name + @param[in] table_name table name + @param[in] schema_table_idx I_S table index + + @return Operation status + @retval 0 Table is processed and we can continue + with new table + @retval 1 It's view and we have to use + open_tables function for this table +*/ + +static int fill_schema_table_from_frm(THD *thd,TABLE *table, + ST_SCHEMA_TABLE *schema_table, + LEX_STRING *db_name, + LEX_STRING *table_name, + enum enum_schema_tables schema_table_idx) +{ + TABLE_SHARE share; + TABLE tbl; + TABLE_LIST table_list; + char path[FN_REFLEN]; + uint res; + bzero((char*) &table_list, sizeof(TABLE_LIST)); + bzero((char*) &tbl, sizeof(TABLE)); + (void) build_table_filename(path, sizeof(path), db_name->str, + table_name->str, "", 0); + init_tmp_table_share(&share, "", 0, "", path); + if (!(res= open_table_def(thd, &share, OPEN_VIEW))) + { + share.tmp_table= NO_TMP_TABLE; + tbl.s= &share; + table_list.table= &tbl; + if (schema_table->i_s_requested_object & OPEN_TABLE_FROM_SHARE) + { + if (share.is_view || + open_table_from_share(thd, &share, table_name->str, 0, + (READ_KEYINFO | COMPUTE_TYPES | + EXTRA_RECORD | OPEN_FRM_FILE_ONLY), + thd->open_options, &tbl, FALSE)) + { + share.tmp_table= INTERNAL_TMP_TABLE; + free_table_share(&share); + return (share.is_view && + !(schema_table->i_s_requested_object & + ~(OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE))); + } + } + table_list.view= (st_lex*) share.is_view; + res= schema_table->process_table(thd, &table_list, table, + res, db_name, table_name); + share.tmp_table= INTERNAL_TMP_TABLE; + if (schema_table->i_s_requested_object & OPEN_TABLE_FROM_SHARE) + closefrm(&tbl, true); + else + free_table_share(&share); + } + + if (res) + thd->clear_error(); + return 0; +} + + + +/** + @brief Fill I_S tables whose data are retrieved + from frm files and storage engine + + @details The information schema tables are internally represented as + temporary tables that are filled at query execution time. + Those I_S tables whose data are retrieved + from frm files and storage engine are filled by the function + get_all_tables(). + + @param[in] thd thread handler + @param[in] tables I_S table + @param[in] cond 'WHERE' condition + + @return Operation status + @retval 0 success + @retval 1 error +*/ + int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; TABLE *table= tables->table; - SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX *old_all_select_lex= lex->all_selects_list; enum_sql_command save_sql_command= lex->sql_command; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; SELECT_LEX sel; - INDEX_FIELD_VALUES idx_field_vals; - char path[FN_REFLEN], *base_name, *orig_base_name, *file_name; - uint len; + LOOKUP_FIELD_VALUES lookup_field_vals; + LEX_STRING *db_name, *table_name; bool with_i_schema; enum enum_schema_tables schema_table_idx; - List<char> bases; - List_iterator_fast<char> it(bases); + List<LEX_STRING> db_names; + List_iterator_fast<LEX_STRING> it(db_names); COND *partial_cond; uint derived_tables= lex->derived_tables; int error= 1; - enum legacy_db_type not_used; Open_tables_state open_tables_state_backup; bool save_view_prepare_mode= lex->view_prepare_mode; Query_tables_list query_tables_list_backup; #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; #endif + uint table_open_method; DBUG_ENTER("get_all_tables"); - LINT_INIT(len); - lex->view_prepare_mode= TRUE; lex->reset_n_backup_query_tables_list(&query_tables_list_backup); @@ -2540,183 +3055,145 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ thd->reset_n_backup_open_tables_state(&open_tables_state_backup); + /* + this branch processes SHOW FIELDS, SHOW INDEXES commands. + see sql_parse.cc, prepare_schema_table() function where + this values are initialized + */ if (lsel && lsel->table_list.first) { - TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first; - bool res; - - lex->all_selects_list= lsel; - /* - 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; - /* - 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()' - */ - lex->sql_command= SQLCOM_SHOW_FIELDS; - res= open_normal_and_derived_tables(thd, show_table_list, - MYSQL_LOCK_IGNORE_FLUSH); - lex->sql_command= save_sql_command; - /* - 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). - */ - error= test(schema_table->process_table(thd, show_table_list, - table, res, - (show_table_list->view ? - show_table_list->view_db.str : - show_table_list->db), - show_table_list->alias)); - thd->temporary_tables= 0; - close_tables_for_reopen(thd, &show_table_list); + error= fill_schema_show_cols_or_idxs(thd, tables, schema_table, + &open_tables_state_backup); goto err; } schema_table_idx= get_schema_table_idx(schema_table); + get_lookup_field_values(thd, cond, tables, &lookup_field_vals); + DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'", + lookup_field_vals.db_value.str, + lookup_field_vals.table_value.str)); + if (lookup_field_vals.db_value.length && + !lookup_field_vals.wild_db_value && + lookup_field_vals.table_value.length && + !lookup_field_vals.wild_table_value) + partial_cond= 0; + else + partial_cond= make_cond_for_info_schema(cond, tables); - if (make_db_list(thd, &bases, &idx_field_vals, - &with_i_schema, 0)) + if (lookup_field_vals.db_value.length && !lookup_field_vals.wild_db_value) + tables->has_db_lookup_value= TRUE; + if (lookup_field_vals.table_value.length && + !lookup_field_vals.wild_table_value) + tables->has_table_lookup_value= TRUE; + + tables->table_open_method= table_open_method= + get_table_open_method(tables, schema_table, schema_table_idx); + + if (lex->describe) + { + /* EXPLAIN SELECT */ + error= 0; goto err; + } - partial_cond= make_cond_for_info_schema(cond, tables); + if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema)) + goto err; it.rewind(); /* To get access to new elements in basis list */ - - /* - Below we generate error for non existing database. - (to save old behaviour for SHOW TABLES FROM db) - */ - while ((orig_base_name= base_name= it++) || - ((sql_command_flags[save_sql_command] & CF_SHOW_TABLE_COMMAND) && - (base_name= select_lex->db) && !bases.elements)) + while ((db_name= it++)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!check_access(thd,SELECT_ACL, base_name, + if (!check_access(thd,SELECT_ACL, db_name->str, &thd->col_access, 0, 1, with_i_schema) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) || - !check_grant_db(thd, base_name)) + acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) || + !check_grant_db(thd, db_name->str)) #endif { - List<char> files; - if (with_i_schema) // information schema table names - { - if (schema_tables_add(thd, &files, idx_field_vals.table_value)) - goto err; - } - else + thd->no_warnings_for_error= 1; + List<LEX_STRING> table_names; + int res= make_table_name_list(thd, &table_names, lex, + &lookup_field_vals, + with_i_schema, db_name); + if (res == 2) /* Not fatal error, continue */ + continue; + if (res) + goto err; + + List_iterator_fast<LEX_STRING> it_files(table_names); + while ((table_name= it_files++)) { - len= build_table_filename(path, sizeof(path), base_name, "", "", 0); - len= FN_LEN - len; - find_files_result res= find_files(thd, &files, base_name, - path, idx_field_vals.table_value, 0); - if (res != FIND_FILES_OK) + restore_record(table, s->default_values); + table->field[schema_table->idx_field1]-> + store(db_name->str, db_name->length, system_charset_info); + table->field[schema_table->idx_field2]-> + store(table_name->str, table_name->length, system_charset_info); + + if (!partial_cond || partial_cond->val_int()) { /* - Downgrade errors about problems with database directory to - warnings if this is not a 'SHOW' command. Another thread - may have dropped database, and we may still have a name - for that directory. + If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN) + we can skip table opening and we don't have lookup value for + table name or lookup value is wild string(table name list is + already created by make_table_name_list() function). */ - if (res == FIND_FILES_DIR && lex->sql_command == SQLCOM_END) + if (!table_open_method && schema_table_idx == SCH_TABLES && + (!lookup_field_vals.table_value.length || + lookup_field_vals.wild_table_value)) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->net.last_errno, thd->net.last_error); - thd->clear_error(); + if (schema_table_store_record(thd, table)) + goto err; /* Out of space in temporary table */ continue; } - else - { - goto err; - } - } - if (lower_case_table_names) - orig_base_name= thd->strdup(base_name); - } - List_iterator_fast<char> it_files(files); - while ((file_name= it_files++)) - { - restore_record(table, s->default_values); - table->field[schema_table->idx_field1]-> - store(base_name, strlen(base_name), system_charset_info); - table->field[schema_table->idx_field2]-> - store(file_name, strlen(file_name),system_charset_info); - if (!partial_cond || partial_cond->val_int()) - { + /* SHOW TABLE NAMES command */ if (schema_table_idx == SCH_TABLE_NAMES) { - if (lex->verbose || - (sql_command_flags[save_sql_command] & CF_STATUS_COMMAND) == 0) - { - if (with_i_schema) - { - table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), - system_charset_info); - } - else - { - build_table_filename(path, sizeof(path), - base_name, file_name, reg_ext, 0); - - switch (mysql_frm_type(thd, path, ¬_used)) { - case FRMTYPE_ERROR: - table->field[3]->store(STRING_WITH_LEN("ERROR"), - system_charset_info); - break; - case FRMTYPE_TABLE: - table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), - system_charset_info); - break; - case FRMTYPE_VIEW: - table->field[3]->store(STRING_WITH_LEN("VIEW"), - system_charset_info); - break; - default: - DBUG_ASSERT(0); - } - } - } - if (schema_table_store_record(thd, table)) - goto err; + if (fill_schema_table_names(thd, tables->table, db_name, + table_name, with_i_schema)) + continue; } else { + if (!(table_open_method & ~OPEN_FRM_ONLY) && + !with_i_schema) + { + if (!fill_schema_table_from_frm(thd, table, schema_table, db_name, + table_name, schema_table_idx)) + continue; + } + int res; + LEX_STRING tmp_lex_string, orig_db_name; /* Set the parent lex of 'sel' because it is needed by sel.init_query() which is called inside make_table_list. */ + thd->no_warnings_for_error= 1; sel.parent_lex= lex; - if (make_table_list(thd, &sel, base_name, file_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; + if (make_table_list(thd, &sel, db_name, table_name)) goto err; TABLE_LIST *show_table_list= (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; res= open_normal_and_derived_tables(thd, show_table_list, MYSQL_LOCK_IGNORE_FLUSH); lex->sql_command= save_sql_command; - /* - They can drop table after table names list creation and - before table opening. We open non existing table and - get ER_NO_SUCH_TABLE error. In this case we do not store - the record into I_S table and clear error. - */ + if (thd->net.last_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(); } @@ -2729,12 +3206,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) 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_base_name, - show_table_list->alias); + res, &orig_db_name, + &tmp_lex_string); close_tables_for_reopen(thd, &show_table_list); - DBUG_ASSERT(!lex->query_tables_own_last); } + DBUG_ASSERT(!lex->query_tables_own_last); if (res) goto err; } @@ -2760,11 +3239,11 @@ err: } -bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name, +bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name, CHARSET_INFO *cs) { restore_record(table, s->default_values); - table->field[1]->store(db_name, strlen(db_name), system_charset_info); + table->field[1]->store(db_name->str, db_name->length, system_charset_info); table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info); table->field[3]->store(cs->name, strlen(cs->name), system_charset_info); return schema_table_store_record(thd, table); @@ -2778,9 +3257,9 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) Returning error status in this case leads to client hangup. */ - INDEX_FIELD_VALUES idx_field_vals; - List<char> files; - char *file_name; + LOOKUP_FIELD_VALUES lookup_field_vals; + List<LEX_STRING> db_names; + LEX_STRING *db_name; bool with_i_schema; HA_CREATE_INFO create; TABLE *table= tables->table; @@ -2789,16 +3268,20 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) #endif DBUG_ENTER("fill_schema_shemata"); - if (make_db_list(thd, &files, &idx_field_vals, - &with_i_schema, 1)) + get_lookup_field_values(thd, cond, tables, &lookup_field_vals); + DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'", + lookup_field_vals.db_value.str, + lookup_field_vals.table_value.str)); + if (make_db_list(thd, &db_names, &lookup_field_vals, + &with_i_schema)) DBUG_RETURN(1); - List_iterator_fast<char> it(files); - while ((file_name=it++)) + List_iterator_fast<LEX_STRING> it(db_names); + while ((db_name=it++)) { if (with_i_schema) // information schema name is always first in list { - if (store_schema_shemata(thd, table, file_name, + if (store_schema_shemata(thd, table, db_name, system_charset_info)) DBUG_RETURN(1); with_i_schema= 0; @@ -2806,13 +3289,12 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) } #ifndef NO_EMBEDDED_ACCESS_CHECKS if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) || - !check_grant_db(thd, file_name)) + acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) || + !check_grant_db(thd, db_name->str)) #endif { - load_db_opt_by_name(thd, file_name, &create); - - if (store_schema_shemata(thd, table, file_name, + load_db_opt_by_name(thd, db_name->str, &create); + if (store_schema_shemata(thd, table, db_name, create.default_table_charset)) DBUG_RETURN(1); } @@ -2823,8 +3305,8 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { const char *tmp_buff; MYSQL_TIME time; @@ -2832,8 +3314,8 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, DBUG_ENTER("get_schema_tables_record"); restore_record(table, s->default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(file_name, strlen(file_name), cs); + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[2]->store(table_name->str, table_name->length, cs); if (res) { /* @@ -2856,12 +3338,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } else { + char option_buff[350],*ptr; TABLE *show_table= tables->table; TABLE_SHARE *share= show_table->s; handler *file= show_table->file; - - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO | - HA_STATUS_NO_LOCK); + handlerton *tmp_db_type= share->db_type(); if (share->tmp_table == SYSTEM_TMP_TABLE) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else if (share->tmp_table) @@ -2875,89 +3356,15 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, continue; table->field[i]->set_notnull(); } - tmp_buff= file->table_type(); +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (share->db_type() == partition_hton && + share->partition_info_len) + tmp_db_type= share->default_part_db_type; +#endif + tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type); table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); table->field[5]->store((longlong) share->frm_version, TRUE); - enum row_type row_type = file->get_row_type(); - switch (row_type) { - case ROW_TYPE_NOT_USED: - case ROW_TYPE_DEFAULT: - tmp_buff= ((share->db_options_in_use & - HA_OPTION_COMPRESS_RECORD) ? "Compressed" : - (share->db_options_in_use & HA_OPTION_PACK_RECORD) ? - "Dynamic" : "Fixed"); - break; - case ROW_TYPE_FIXED: - tmp_buff= "Fixed"; - break; - case ROW_TYPE_DYNAMIC: - tmp_buff= "Dynamic"; - break; - case ROW_TYPE_COMPRESSED: - tmp_buff= "Compressed"; - break; - case ROW_TYPE_REDUNDANT: - tmp_buff= "Redundant"; - break; - case ROW_TYPE_COMPACT: - tmp_buff= "Compact"; - break; - case ROW_TYPE_PAGES: - tmp_buff= "Paged"; - break; - } - table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); - if (!tables->schema_table) - { - table->field[7]->store((longlong) file->stats.records, TRUE); - table->field[7]->set_notnull(); - } - table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE); - table->field[9]->store((longlong) file->stats.data_file_length, TRUE); - if (file->stats.max_data_file_length) - { - table->field[10]->store((longlong) file->stats.max_data_file_length, - TRUE); - } - table->field[11]->store((longlong) file->stats.index_file_length, TRUE); - table->field[12]->store((longlong) file->stats.delete_length, TRUE); - if (show_table->found_next_number_field) - { - table->field[13]->store((longlong) file->stats.auto_increment_value, - TRUE); - table->field[13]->set_notnull(); - } - if (file->stats.create_time) - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, - (my_time_t) file->stats.create_time); - table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - table->field[14]->set_notnull(); - } - if (file->stats.update_time) - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, - (my_time_t) file->stats.update_time); - table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - table->field[15]->set_notnull(); - } - if (file->stats.check_time) - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, - (my_time_t) file->stats.check_time); - table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - table->field[16]->set_notnull(); - } - tmp_buff= (share->table_charset ? - share->table_charset->name : "default"); - table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); - if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM) - { - table->field[18]->store((longlong) file->checksum(), TRUE); - table->field[18]->set_notnull(); - } - char option_buff[350],*ptr; ptr=option_buff; if (share->min_rows) { @@ -2995,17 +3402,91 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, table->field[19]->store(option_buff+1, (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1), cs); + + if (share->comment.str) + table->field[20]->store(share->comment.str, share->comment.length, cs); + + if(file) { - char *comment; - comment= show_table->file->update_table_comment(share->comment.str); - if (comment) + file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO | + HA_STATUS_NO_LOCK); + enum row_type row_type = file->get_row_type(); + switch (row_type) { + case ROW_TYPE_NOT_USED: + case ROW_TYPE_DEFAULT: + tmp_buff= ((share->db_options_in_use & + HA_OPTION_COMPRESS_RECORD) ? "Compressed" : + (share->db_options_in_use & HA_OPTION_PACK_RECORD) ? + "Dynamic" : "Fixed"); + break; + case ROW_TYPE_FIXED: + tmp_buff= "Fixed"; + break; + case ROW_TYPE_DYNAMIC: + tmp_buff= "Dynamic"; + break; + case ROW_TYPE_COMPRESSED: + tmp_buff= "Compressed"; + break; + case ROW_TYPE_REDUNDANT: + tmp_buff= "Redundant"; + break; + case ROW_TYPE_COMPACT: + tmp_buff= "Compact"; + break; + case ROW_TYPE_PAGES: + tmp_buff= "Paged"; + break; + } + table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); + if (!tables->schema_table) + { + table->field[7]->store((longlong) file->stats.records, TRUE); + table->field[7]->set_notnull(); + } + table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE); + table->field[9]->store((longlong) file->stats.data_file_length, TRUE); + if (file->stats.max_data_file_length) + { + table->field[10]->store((longlong) file->stats.max_data_file_length, + TRUE); + } + table->field[11]->store((longlong) file->stats.index_file_length, TRUE); + table->field[12]->store((longlong) file->stats.delete_length, TRUE); + if (show_table->found_next_number_field) + { + table->field[13]->store((longlong) file->stats.auto_increment_value, + TRUE); + table->field[13]->set_notnull(); + } + if (file->stats.create_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + (my_time_t) file->stats.create_time); + table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[14]->set_notnull(); + } + if (file->stats.update_time) { - table->field[20]->store(comment, - (comment == share->comment.str ? - share->comment.length : - strlen(comment)), cs); - if (comment != share->comment.str) - my_free(comment, MYF(0)); + thd->variables.time_zone->gmt_sec_to_TIME(&time, + (my_time_t) file->stats.update_time); + table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[15]->set_notnull(); + } + if (file->stats.check_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + (my_time_t) file->stats.check_time); + table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[16]->set_notnull(); + } + tmp_buff= (share->table_charset ? + share->table_charset->name : "default"); + table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); + if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM) + { + table->field[18]->store((longlong) file->checksum(), TRUE); + table->field[18]->set_notnull(); } } } @@ -3015,17 +3496,15 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, static int get_schema_column_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; CHARSET_INFO *cs= system_charset_info; TABLE *show_table; - handler *file; Field **ptr,*field; int count; - uint base_name_length, file_name_length; DBUG_ENTER("get_schema_column_record"); if (res) @@ -3045,15 +3524,11 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, } show_table= tables->table; - file= show_table->file; count= 0; - file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); restore_record(show_table, s->default_values); - base_name_length= strlen(base_name); - file_name_length= strlen(file_name); show_table->use_all_columns(); // Required for default - for (ptr=show_table->field; (field= *ptr) ; ptr++) + for (ptr= show_table->field; (field= *ptr) ; ptr++) { const char *tmp_buff; uchar *pos; @@ -3076,10 +3551,10 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access; - check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, + check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str, &tables->grant.privilege, 0, 0, test(tables->schema_table)); col_access= get_column_grant(thd, &tables->grant, - base_name, file_name, + db_name->str, table_name->str, field->field_name) & COL_ACLS; if (lex->sql_command != SQLCOM_SHOW_FIELDS && !tables->schema_table && !col_access) @@ -3096,8 +3571,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); #endif - table->field[1]->store(base_name, base_name_length, cs); - table->field[2]->store(file_name, file_name_length, cs); + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[2]->store(table_name->str, table_name->length, cs); table->field[3]->store(field->field_name, strlen(field->field_name), cs); table->field[4]->store((longlong) count, TRUE); @@ -3522,8 +3997,8 @@ err: static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_stat_record"); @@ -3535,7 +4010,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS rather than in SHOW KEYS */ - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -3546,10 +4021,11 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, else if (!tables->view) { TABLE *show_table= tables->table; - KEY *key_info=show_table->key_info; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | - HA_STATUS_TIME); + KEY *key_info=show_table->s->key_info; + if (show_table->file) + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); for (uint i=0 ; i < show_table->s->keys ; i++,key_info++) { KEY_PART_INFO *key_part= key_info->key_part; @@ -3557,35 +4033,40 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) { restore_record(table, s->default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(file_name, strlen(file_name), cs); + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[2]->store(table_name->str, table_name->length, cs); table->field[3]->store((longlong) ((key_info->flags & HA_NOSAME) ? 0 : 1), TRUE); - table->field[4]->store(base_name, strlen(base_name), cs); + table->field[4]->store(db_name->str, db_name->length, cs); table->field[5]->store(key_info->name, strlen(key_info->name), cs); table->field[6]->store((longlong) (j+1), TRUE); str=(key_part->field ? key_part->field->field_name : "?unknown field?"); table->field[7]->store(str, strlen(str), cs); - if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER) - { - table->field[8]->store(((key_part->key_part_flag & - HA_REVERSE_SORT) ? - "D" : "A"), 1, cs); - table->field[8]->set_notnull(); - } - KEY *key=show_table->key_info+i; - if (key->rec_per_key[j]) + if (show_table->file) { - ha_rows records=(show_table->file->stats.records / - key->rec_per_key[j]); - table->field[9]->store((longlong) records, TRUE); - table->field[9]->set_notnull(); + if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER) + { + table->field[8]->store(((key_part->key_part_flag & + HA_REVERSE_SORT) ? + "D" : "A"), 1, cs); + table->field[8]->set_notnull(); + } + KEY *key=show_table->key_info+i; + if (key->rec_per_key[j]) + { + ha_rows records=(show_table->file->stats.records / + key->rec_per_key[j]); + table->field[9]->store((longlong) records, TRUE); + table->field[9]->set_notnull(); + } + str= show_table->file->index_type(i); + table->field[13]->store(str, strlen(str), cs); } if (!(key_info->flags & HA_FULLTEXT) && (key_part->field && key_part->length != - show_table->field[key_part->fieldnr-1]->key_length())) + show_table->s->field[key_part->fieldnr-1]->key_length())) { table->field[10]->store((longlong) key_part->length / key_part->field->charset()->mbmaxlen, TRUE); @@ -3594,8 +4075,6 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, uint flags= key_part->field ? key_part->field->flags : 0; const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); table->field[12]->store(pos, strlen(pos), cs); - pos= show_table->file->index_type(i); - table->field[13]->store(pos, strlen(pos), cs); if (!show_table->s->keys_in_use.is_set(i)) table->field[14]->store(STRING_WITH_LEN("disabled"), cs); else @@ -3612,19 +4091,28 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, static int get_schema_views_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_views_record"); + LEX_STRING *tmp_db_name, *tmp_table_name; char definer[USER_HOST_BUFF_SIZE]; uint definer_len; bool updatable_view; + /* + if SELECT FROM I_S.VIEWS uses only fields + which have OPEN_FRM_ONLY flag then 'tables' + structure is zeroed and only tables->view is set. + (see fill_schema_table_from_frm() function). + So we should disable other fields filling. + */ + bool only_share= !tables->definer.user.str; if (tables->view) { Security_context *sctx= thd->security_ctx; - if (!tables->allowed_show) + if (!only_share && !tables->allowed_show) { if (!my_strcasecmp(system_charset_info, tables->definer.user.str, sctx->priv_user) && @@ -3633,79 +4121,88 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, tables->allowed_show= TRUE; } restore_record(table, s->default_values); - table->field[1]->store(tables->view_db.str, tables->view_db.length, cs); - table->field[2]->store(tables->view_name.str, tables->view_name.length, cs); - if (tables->allowed_show) + tmp_db_name= &tables->view_db; + tmp_table_name= &tables->view_name; + if (only_share) { - table->field[3]->store(tables->view_body_utf8.str, - tables->view_body_utf8.length, - cs); + tmp_db_name= db_name; + tmp_table_name= table_name; } - - if (tables->with_check != VIEW_CHECK_NONE) + table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs); + table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs); + if (!only_share) { - if (tables->with_check == VIEW_CHECK_LOCAL) - table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs); + if (tables->allowed_show) + { + table->field[3]->store(tables->view_body_utf8.str, + tables->view_body_utf8.length, + cs); + } + + if (tables->with_check != VIEW_CHECK_NONE) + { + if (tables->with_check == VIEW_CHECK_LOCAL) + table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs); + else + table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs); + } else - table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs); - } - else - table->field[4]->store(STRING_WITH_LEN("NONE"), cs); + table->field[4]->store(STRING_WITH_LEN("NONE"), cs); - updatable_view= 0; - if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) - { - /* - We should use tables->view->select_lex.item_list here and - can not use Field_iterator_view because the view always uses - temporary algorithm during opening for I_S and - TABLE_LIST fields 'field_translation' & 'field_translation_end' - are uninitialized is this case. - */ - List<Item> *fields= &tables->view->select_lex.item_list; - List_iterator<Item> it(*fields); - Item *item; - Item_field *field; - /* - check that at least one column in view is updatable - */ - while ((item= it++)) + updatable_view= 0; + if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) { - if ((field= item->filed_for_view_update()) && field->field && - !field->field->table->pos_in_table_list->schema_table) + /* + We should use tables->view->select_lex.item_list here and + can not use Field_iterator_view because the view always uses + temporary algorithm during opening for I_S and + TABLE_LIST fields 'field_translation' & 'field_translation_end' + are uninitialized is this case. + */ + List<Item> *fields= &tables->view->select_lex.item_list; + List_iterator<Item> it(*fields); + Item *item; + Item_field *field; + /* + check that at least one column in view is updatable + */ + while ((item= it++)) { - updatable_view= 1; - break; + if ((field= item->filed_for_view_update()) && field->field && + !field->field->table->pos_in_table_list->schema_table) + { + updatable_view= 1; + break; + } } + if (updatable_view && !tables->view->can_be_merged()) + updatable_view= 0; } - if (updatable_view && !tables->view->can_be_merged()) - updatable_view= 0; - } - if (updatable_view) - table->field[5]->store(STRING_WITH_LEN("YES"), cs); - else - table->field[5]->store(STRING_WITH_LEN("NO"), cs); - definer_len= (strxmov(definer, tables->definer.user.str, "@", - tables->definer.host.str, NullS) - definer); - table->field[6]->store(definer, definer_len, cs); - if (tables->view_suid) - table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs); - else - table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs); + if (updatable_view) + table->field[5]->store(STRING_WITH_LEN("YES"), cs); + else + table->field[5]->store(STRING_WITH_LEN("NO"), cs); + definer_len= (strxmov(definer, tables->definer.user.str, "@", + tables->definer.host.str, NullS) - definer); + table->field[6]->store(definer, definer_len, cs); + if (tables->view_suid) + table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs); + else + table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs); - table->field[8]->store( - tables->view_creation_ctx->get_client_cs()->csname, - strlen(tables->view_creation_ctx->get_client_cs()->csname), - cs); + table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname, + strlen(tables->view_creation_ctx-> + get_client_cs()->csname), cs); - table->field[9]->store( - tables->view_creation_ctx->get_connection_cl()->name, - strlen(tables->view_creation_ctx->get_connection_cl()->name), - cs); + table->field[9]->store(tables->view_creation_ctx-> + get_connection_cl()->name, + strlen(tables->view_creation_ctx-> + get_connection_cl()->name), cs); + } if (schema_table_store_record(thd, table)) DBUG_RETURN(1); - if (res) + if (res && thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); } @@ -3715,16 +4212,16 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, } -bool store_constraints(THD *thd, TABLE *table, const char *db, - const char *tname, const char *key_name, +bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name, + LEX_STRING *table_name, const char *key_name, uint key_len, const char *con_type, uint con_len) { CHARSET_INFO *cs= system_charset_info; restore_record(table, s->default_values); - table->field[1]->store(db, strlen(db), cs); + table->field[1]->store(db_name->str, db_name->length, cs); table->field[2]->store(key_name, key_len, cs); - table->field[3]->store(db, strlen(db), cs); - table->field[4]->store(tname, strlen(tname), cs); + table->field[3]->store(db_name->str, db_name->length, cs); + table->field[4]->store(table_name->str, table_name->length, cs); table->field[5]->store(con_type, con_len, cs); return schema_table_store_record(thd, table); } @@ -3732,13 +4229,13 @@ bool store_constraints(THD *thd, TABLE *table, const char *db, static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { DBUG_ENTER("get_schema_constraints_record"); if (res) { - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -3760,14 +4257,14 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, if (i == primary_key && !strcmp(key_info->name, primary_key_name)) { - if (store_constraints(thd, table, base_name, file_name, key_info->name, + if (store_constraints(thd, table, db_name, table_name, key_info->name, strlen(key_info->name), STRING_WITH_LEN("PRIMARY KEY"))) DBUG_RETURN(1); } else if (key_info->flags & HA_NOSAME) { - if (store_constraints(thd, table, base_name, file_name, key_info->name, + if (store_constraints(thd, table, db_name, table_name, key_info->name, strlen(key_info->name), STRING_WITH_LEN("UNIQUE"))) DBUG_RETURN(1); @@ -3779,7 +4276,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list); while ((f_key_info=it++)) { - if (store_constraints(thd, table, base_name, file_name, + if (store_constraints(thd, table, db_name, table_name, f_key_info->forein_id->str, strlen(f_key_info->forein_id->str), "FOREIGN KEY", 11)) @@ -3790,8 +4287,8 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, } -static bool store_trigger(THD *thd, TABLE *table, const char *db, - const char *tname, LEX_STRING *trigger_name, +static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name, + LEX_STRING *table_name, LEX_STRING *trigger_name, enum trg_event_type event, enum trg_action_time_type timing, LEX_STRING *trigger_stmt, @@ -3805,12 +4302,12 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db, LEX_STRING sql_mode_rep; restore_record(table, s->default_values); - table->field[1]->store(db, strlen(db), cs); + table->field[1]->store(db_name->str, db_name->length, cs); table->field[2]->store(trigger_name->str, trigger_name->length, cs); table->field[3]->store(trg_event_type_names[event].str, trg_event_type_names[event].length, cs); - table->field[5]->store(db, strlen(db), cs); - table->field[6]->store(tname, strlen(tname), cs); + table->field[5]->store(db_name->str, db_name->length, cs); + table->field[6]->store(table_name->str, table_name->length, cs); table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs); table->field[10]->store(STRING_WITH_LEN("ROW"), cs); table->field[11]->store(trg_action_time_type_names[timing].str, @@ -3833,8 +4330,8 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db, static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { DBUG_ENTER("get_schema_triggers_record"); /* @@ -3843,7 +4340,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, */ if (res) { - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -3877,7 +4374,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, &db_cl_name)) continue; - if (store_trigger(thd, table, base_name, file_name, &trigger_name, + if (store_trigger(thd, table, db_name, table_name, &trigger_name, (enum trg_event_type) event, (enum trg_action_time_type) timing, &trigger_stmt, sql_mode, @@ -3893,15 +4390,16 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, } -void store_key_column_usage(TABLE *table, const char*db, const char *tname, - const char *key_name, uint key_len, - const char *con_type, uint con_len, longlong idx) +void store_key_column_usage(TABLE *table, LEX_STRING *db_name, + LEX_STRING *table_name, const char *key_name, + uint key_len, const char *con_type, uint con_len, + longlong idx) { CHARSET_INFO *cs= system_charset_info; - table->field[1]->store(db, strlen(db), cs); + table->field[1]->store(db_name->str, db_name->length, cs); table->field[2]->store(key_name, key_len, cs); - table->field[4]->store(db, strlen(db), cs); - table->field[5]->store(tname, strlen(tname), cs); + table->field[4]->store(db_name->str, db_name->length, cs); + table->field[5]->store(table_name->str, table_name->length, cs); table->field[6]->store(con_type, con_len, cs); table->field[7]->store((longlong) idx, TRUE); } @@ -3910,13 +4408,13 @@ void store_key_column_usage(TABLE *table, const char*db, const char *tname, static int get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { DBUG_ENTER("get_schema_key_column_usage_record"); if (res) { - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -3943,7 +4441,7 @@ static int get_schema_key_column_usage_record(THD *thd, { f_idx++; restore_record(table, s->default_values); - store_key_column_usage(table, base_name, file_name, + store_key_column_usage(table, db_name, table_name, key_info->name, strlen(key_info->name), key_part->field->field_name, @@ -3970,7 +4468,7 @@ static int get_schema_key_column_usage_record(THD *thd, r_info= it1++; f_idx++; restore_record(table, s->default_values); - store_key_column_usage(table, base_name, file_name, + store_key_column_usage(table, db_name, table_name, f_key_info->forein_id->str, f_key_info->forein_id->length, f_info->str, f_info->length, @@ -4095,8 +4593,8 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table, static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, - const char *file_name) + LEX_STRING *db_name, + LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; char buff[61]; @@ -4111,7 +4609,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, if (res) { - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -4127,8 +4625,8 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, uint part_pos= 0, part_id= 0; restore_record(table, s->default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(file_name, strlen(file_name), cs); + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[2]->store(table_name->str, table_name->length, cs); /* Partition method*/ @@ -4641,14 +5139,14 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) static int get_referential_constraints_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, - const char *base_name, const char *file_name) + LEX_STRING *db_name, LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_referential_constraints_record"); if (res) { - if (!tables->view) + if (thd->net.last_errno) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -4668,8 +5166,8 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, while ((f_key_info= it++)) { restore_record(table, s->default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[9]->store(file_name, strlen(file_name), cs); + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[9]->store(table_name->str, table_name->length, cs); table->field[2]->store(f_key_info->forein_id->str, f_key_info->forein_id->length, cs); table->field[4]->store(f_key_info->referenced_db->str, @@ -4739,7 +5237,7 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin, RETURN 0 table not found - # pointer to 'shema_tables' element + # pointer to 'schema_tables' element */ ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name) @@ -4882,6 +5380,12 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, table_list->alias))) DBUG_RETURN(0); + my_bitmap_map* bitmaps= + (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); + bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, + FALSE); + table->read_set= &table->def_read_set; + bitmap_clear_all(table->read_set); table_list->schema_table_param= tmp_table_param; DBUG_RETURN(table); } @@ -5225,6 +5729,13 @@ bool get_schema_tables_result(JOIN *join, { bool is_subselect= (&lex->unit != lex->current_select->master_unit() && lex->current_select->master_unit()->item); + + + /* skip I_S optimizations specific to get_all_tables */ + if (thd->lex->describe && + (table_list->schema_table->fill_table != get_all_tables)) + continue; + /* If schema table is already processed and the statement is not a subselect then @@ -5304,479 +5815,537 @@ int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond) ST_FIELD_INFO schema_fields_info[]= { - {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"}, - {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0}, - {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0}, - {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database", + SKIP_OPEN_TABLE}, + {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, + {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO tables_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, - {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", + SKIP_OPEN_TABLE}, + {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY}, {"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version"}, - {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY}, + {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE}, {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE}, {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE}, {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE}, {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE}, {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE}, {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE}, {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment"}, - {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time"}, - {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time"}, - {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time"}, - {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE}, + {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE}, + {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE}, + {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE}, + {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY}, {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum"}, - {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options"}, - {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE}, + {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options", + OPEN_FRM_ONLY}, + {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO columns_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field", + OPEN_FRM_ONLY}, {"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, - MY_I_S_UNSIGNED, 0}, + MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY}, {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, - 1, "Default"}, - {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"}, - {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + 1, "Default", OPEN_FRM_ONLY}, + {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY}, + {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, - 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, {"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, - 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, {"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, - 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, - 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0}, - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"}, - {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type"}, - {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"}, - {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra"}, - {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges"}, - {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, + {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY}, + {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY}, + {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY}, + {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY}, + {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY}, + {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO charsets_fields_info[]= { - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"}, - {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation"}, - {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description"}, - {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", + SKIP_OPEN_TABLE}, + {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation", + SKIP_OPEN_TABLE}, + {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description", + SKIP_OPEN_TABLE}, + {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO collation_fields_info[]= { - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation"}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"}, - {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id"}, - {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default"}, - {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled"}, - {"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE}, + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", + SKIP_OPEN_TABLE}, + {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id", + SKIP_OPEN_TABLE}, + {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE}, + {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE}, + {"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO engines_fields_info[]= { - {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine"}, - {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support"}, - {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"}, - {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions"}, - {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA"}, - {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE}, + {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE}, + {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE}, + {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions", SKIP_OPEN_TABLE}, + {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA", SKIP_OPEN_TABLE}, + {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO events_fields_info[]= { - {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"}, - {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"}, - {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone"}, - {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0}, - {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, - {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"}, - {"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at"}, - {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value"}, - {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field"}, - {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, - {"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts"}, - {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends"}, - {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status"}, - {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0}, - {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0}, - {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator"}, + {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db", + SKIP_OPEN_TABLE}, + {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", + SKIP_OPEN_TABLE}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, + {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE}, + {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, + {"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE}, + {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value", + SKIP_OPEN_TABLE}, + {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field", + SKIP_OPEN_TABLE}, + {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE}, + {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE}, + {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, + {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE}, + {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE}, + {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE}, + {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "character_set_client"}, + "character_set_client", SKIP_OPEN_TABLE}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "collation_connection"}, + "collation_connection", SKIP_OPEN_TABLE}, {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "Database Collation"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + "Database Collation", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO coll_charset_app_fields_info[]= { - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO proc_fields_info[]= { - {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"}, - {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, - {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"}, - {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"}, - {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created"}, - {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified"}, - {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"}, + {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db", + SKIP_OPEN_TABLE}, + {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", + SKIP_OPEN_TABLE}, + {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, + {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + SKIP_OPEN_TABLE}, + {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, + {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type", + SKIP_OPEN_TABLE}, + {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE}, + {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE}, + {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment", + SKIP_OPEN_TABLE}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "character_set_client"}, + "character_set_client", SKIP_OPEN_TABLE}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "collation_connection"}, + "collation_connection", SKIP_OPEN_TABLE}, {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "Database Collation"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + "Database Collation", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO stat_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"}, - {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique"}, - {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name"}, - {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index"}, - {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name"}, - {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation"}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY}, + {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY}, + {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name", + OPEN_FRM_ONLY}, + {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY}, + {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name", + OPEN_FRM_ONLY}, + {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY}, {"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1, - "Cardinality"}, - {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part"}, - {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed"}, - {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"}, - {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type"}, - {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + "Cardinality", OPEN_FULL_TABLE}, + {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY}, + {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY}, + {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY}, + {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE}, + {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO view_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0}, - {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0}, - {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO user_privileges_fields_info[]= { - {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO schema_privileges_fields_info[]= { - {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO table_privileges_fields_info[]= { - {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO column_privileges_fields_info[]= { - {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO table_constraints_fields_info[]= { - {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO key_column_usage_fields_info[]= { - {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0}, - {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE}, + {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0, + OPEN_FULL_TABLE}, + {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO table_names_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_"}, - {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_", + SKIP_OPEN_TABLE}, + {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type", + OPEN_FRM_ONLY}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO open_tables_fields_info[]= { - {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"}, - {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"}, - {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use"}, - {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database", + SKIP_OPEN_TABLE}, + {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE}, + {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE}, + {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO triggers_fields_info[]= { - {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger"}, - {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event"}, - {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"}, - {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0}, - {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement"}, - {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing"}, - {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created"}, - {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"}, - {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"}, + {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger", + OPEN_FULL_TABLE}, + {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE}, + {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", + OPEN_FULL_TABLE}, + {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE}, + {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement", + OPEN_FULL_TABLE}, + {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE}, + {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE}, + {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE}, + {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "character_set_client"}, + "character_set_client", OPEN_FULL_TABLE}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "collation_connection"}, + "collation_connection", OPEN_FULL_TABLE}, {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "Database Collation"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + "Database Collation", OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO partitions_fields_info[]= { - {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE}, {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, - {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0}, - {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0}, - {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE}, + {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, + OPEN_FULL_TABLE}, + {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, + OPEN_FULL_TABLE}, + {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, + OPEN_FULL_TABLE}, {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, - {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0}, - {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0}, - {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE}, + {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, + OPEN_FULL_TABLE}, + {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, + OPEN_FULL_TABLE}, + {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE}, + {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE}, + {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE}, {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, - {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0}, - {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE}, + {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO variables_fields_info[]= { - {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"}, - {"VARIABLE_VALUE", 20480, MYSQL_TYPE_STRING, 0, 1, "Value"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name", + SKIP_OPEN_TABLE}, + {"VARIABLE_VALUE", 20480, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO processlist_fields_info[]= { - {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id"}, - {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User"}, - {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host"}, - {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"}, - {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"}, - {"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time"}, - {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State"}, - {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE}, + {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE}, + {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host", + SKIP_OPEN_TABLE}, + {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE}, + {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE}, + {"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE}, + {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE}, + {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info", + SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO plugin_fields_info[]= { - {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, - {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status"}, - {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type"}, - {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0}, - {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"}, - {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, - {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License"}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", + SKIP_OPEN_TABLE}, + {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, + {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, + {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library", + SKIP_OPEN_TABLE}, + {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; ST_FIELD_INFO files_fields_info[]= { - {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0}, - {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0}, + {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE}, + {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + SKIP_OPEN_TABLE}, + {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, + SKIP_OPEN_TABLE}, + {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE}, {"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE}, {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE}, {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0}, - {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0}, - {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, - {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE}, + {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE}, + {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE}, + {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE}, + {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE}, {"VERSION", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version"}, - {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", SKIP_OPEN_TABLE}, + {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE}, {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE}, {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE}, {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE}, {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE}, {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE}, {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free"}, - {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time"}, - {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time"}, - {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time"}, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE}, + {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE}, + {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE}, + {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE}, {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0, - (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum"}, - {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0}, - {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE}, + {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; void init_fill_schema_files_row(TABLE* table) @@ -5791,18 +6360,24 @@ void init_fill_schema_files_row(TABLE* table) ST_FIELD_INFO referential_constraints_fields_info[]= { - {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FULL_TABLE}, + {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -5816,69 +6391,75 @@ ST_FIELD_INFO referential_constraints_fields_info[]= ST_SCHEMA_TABLE schema_tables[]= { {"CHARACTER_SETS", charsets_fields_info, create_schema_table, - fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0}, + fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, {"COLLATIONS", collation_fields_info, create_schema_table, - fill_schema_collation, make_old_format, 0, -1, -1, 0}, + fill_schema_collation, make_old_format, 0, -1, -1, 0, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, - create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0}, + create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0}, {"COLUMNS", columns_fields_info, create_schema_table, - get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0}, + get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0, + OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE}, {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, - fill_schema_column_privileges, 0, 0, -1, -1, 0}, + fill_schema_column_privileges, 0, 0, -1, -1, 0, 0}, {"ENGINES", engines_fields_info, create_schema_table, - fill_schema_engines, make_old_format, 0, -1, -1, 0}, + fill_schema_engines, make_old_format, 0, -1, -1, 0, 0}, {"EVENTS", events_fields_info, create_schema_table, - Events::fill_schema_events, make_old_format, 0, -1, -1, 0}, + Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0}, {"FILES", files_fields_info, create_schema_table, - fill_schema_files, 0, 0, -1, -1, 0}, + fill_schema_files, 0, 0, -1, -1, 0, 0}, {"GLOBAL_STATUS", variables_fields_info, create_schema_table, - fill_status, make_old_format, 0, -1, -1, 0}, + fill_status, make_old_format, 0, -1, -1, 0, 0}, {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, - fill_variables, make_old_format, 0, -1, -1, 0}, + fill_variables, make_old_format, 0, -1, -1, 0, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, - get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0}, + get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0, + OPEN_TABLE_ONLY}, {"OPEN_TABLES", open_tables_fields_info, create_schema_table, - fill_open_tables, make_old_format, 0, -1, -1, 1}, + fill_open_tables, make_old_format, 0, -1, -1, 1, 0}, {"PARTITIONS", partitions_fields_info, create_schema_table, - get_all_tables, 0, get_schema_partitions_record, 1, 2, 0}, + get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY}, {"PLUGINS", plugin_fields_info, create_schema_table, - fill_plugins, make_old_format, 0, -1, -1, 0}, + fill_plugins, make_old_format, 0, -1, -1, 0, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, - fill_schema_processlist, make_old_format, 0, -1, -1, 0}, + fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info, create_schema_table, get_all_tables, 0, get_referential_constraints_record, - 1, 9, 0}, + 1, 9, 0, OPEN_TABLE_ONLY}, {"ROUTINES", proc_fields_info, create_schema_table, - fill_schema_proc, make_proc_old_format, 0, -1, -1, 0}, + fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0}, {"SCHEMATA", schema_fields_info, create_schema_table, - fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0}, + fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0, 0}, {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, - fill_schema_schema_privileges, 0, 0, -1, -1, 0}, + fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0}, {"SESSION_STATUS", variables_fields_info, create_schema_table, - fill_status, make_old_format, 0, -1, -1, 0}, + fill_status, make_old_format, 0, -1, -1, 0, 0}, {"SESSION_VARIABLES", variables_fields_info, create_schema_table, - fill_variables, make_old_format, 0, -1, -1, 0}, + fill_variables, make_old_format, 0, -1, -1, 0, 0}, {"STATISTICS", stat_fields_info, create_schema_table, - get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0}, + get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0, + OPEN_TABLE_ONLY|OPEN_TABLE_FROM_SHARE|OPTIMIZE_I_S_TABLE}, {"STATUS", variables_fields_info, create_schema_table, fill_status, - make_old_format, 0, -1, -1, 1}, + make_old_format, 0, -1, -1, 1, 0}, {"TABLES", tables_fields_info, create_schema_table, - get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0}, + get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, + OPTIMIZE_I_S_TABLE}, {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, - get_all_tables, 0, get_schema_constraints_record, 3, 4, 0}, + get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY}, {"TABLE_NAMES", table_names_fields_info, create_schema_table, - get_all_tables, make_table_names_old_format, 0, 1, 2, 1}, + get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0}, {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, - fill_schema_table_privileges, 0, 0, -1, -1, 0}, + fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, {"TRIGGERS", triggers_fields_info, create_schema_table, - get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0}, + get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0, + OPEN_TABLE_ONLY}, {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, - fill_schema_user_privileges, 0, 0, -1, -1, 0}, + fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, - make_old_format, 0, -1, -1, 1}, + make_old_format, 0, -1, -1, 1, 0}, {"VIEWS", view_fields_info, create_schema_table, - get_all_tables, 0, get_schema_views_record, 1, 2, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0} + get_all_tables, 0, get_schema_views_record, 1, 2, 0, + OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/sql_show.h b/sql/sql_show.h index 57004323ca9..d63217584b2 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -29,7 +29,7 @@ enum find_files_result { FIND_FILES_DIR }; -find_files_result find_files(THD *thd, List<char> *files, const char *db, +find_files_result find_files(THD *thd, List<LEX_STRING> *files, const char *db, const char *path, const char *wild, bool dir); int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dd92c47d29b..eb81e7647eb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,6 +54,20 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); +#ifndef DBUG_OFF + +/* Wait until we get a 'mysql_kill' signal */ + +static void wait_for_kill_signal(THD *thd) +{ + while (thd->killed == 0) + sleep(1); + // Reset signal and continue as if nothing happend + thd->killed= THD::NOT_KILLED; +} +#endif + + /* Translate a file name to a table name (WL #1324). @@ -4096,6 +4110,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG); thd->exit_cond(old_message); + DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd);); if (thd->killed) goto err; /* Flush entries in the query cache involving this table. */ diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 5bd01eea68c..0fe299d4505 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -509,7 +509,7 @@ Next alarm time: %lu\n", fflush(stdout); my_checkmalloc(); fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite - TERMINATE(stdout); // Write malloc information + TERMINATE(stdout, 1); // Write malloc information fprintf(stdout,"\nEnd safemalloc memory dump.\n"); #ifdef HAVE_MALLINFO diff --git a/sql/structs.h b/sql/structs.h index da2339d27f8..09a3c4d7285 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -209,6 +209,11 @@ typedef struct user_conn { char *user; /* Pointer to host part of the key. */ char *host; + /* + The moment of time when per hour counters were reset last time + (i.e. start of "hour" for conn_per_hour, updates, questions counters). + */ + ulonglong reset_utime; /* Total length of the key. */ uint len; /* Current amount of concurrent connections for this account. */ @@ -220,11 +225,6 @@ typedef struct user_conn { uint conn_per_hour, updates, questions; /* Maximum amount of resources which account is allowed to consume. */ USER_RESOURCES user_resources; - /* - The moment of time when per hour counters were reset last time - (i.e. start of "hour" for conn_per_hour, updates, questions counters). - */ - time_t intime; } USER_CONN; /* Bits in form->update */ diff --git a/sql/table.cc b/sql/table.cc index 5e036abe6b1..27f9ccc418e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -572,7 +572,15 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) { if (head[2] == FRM_VER || head[2] == FRM_VER+1 || (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) + { + /* Open view only */ + if (db_flags & OPEN_VIEW_ONLY) + { + error_given= 1; + goto err; + } table_type= 1; + } else { error= 6; // Unkown .frm version @@ -1612,9 +1620,17 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, outparam->keys_in_use_for_query.init(); /* Allocate handler */ - if (!(outparam->file= get_new_handler(share, &outparam->mem_root, - share->db_type()))) - goto err; + outparam->file= 0; + if (!(prgflag & OPEN_FRM_FILE_ONLY)) + { + if (!(outparam->file= get_new_handler(share, &outparam->mem_root, + share->db_type()))) + goto err; + } + else + { + DBUG_ASSERT(!db_stat); + } error= 4; outparam->reginfo.lock_type= TL_UNLOCK; @@ -1862,6 +1878,9 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, bzero((char*) bitmaps, bitmap_size*3); #endif + outparam->no_replicate= outparam->file && + test(outparam->file->ha_table_flags() & + HA_HAS_OWN_BINLOGGING); thd->status_var.opened_tables++; DBUG_RETURN (0); @@ -2465,6 +2484,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->row_type= share->row_type; create_info->default_table_charset= share->table_charset; create_info->table_charset= 0; + create_info->comment= share->comment; DBUG_VOID_RETURN; } diff --git a/sql/table.h b/sql/table.h index e46036f3ee9..ffe7350f250 100644 --- a/sql/table.h +++ b/sql/table.h @@ -719,6 +719,10 @@ enum enum_schema_tables #define MY_I_S_UNSIGNED 2 +#define SKIP_OPEN_TABLE 0 // do not open table +#define OPEN_FRM_ONLY 1 // open FRM file only +#define OPEN_FULL_TABLE 2 // open FRM,MYD, MYI files + typedef struct st_field_info { const char* field_name; @@ -727,6 +731,7 @@ typedef struct st_field_info int value; uint field_flags; // Field atributes(maybe_null, signed, unsigned etc.) const char* old_name; + uint open_method; } ST_FIELD_INFO; @@ -743,11 +748,11 @@ typedef struct st_schema_table int (*fill_table) (THD *thd, TABLE_LIST *tables, COND *cond); /* Handle fileds for old SHOW */ int (*old_format) (THD *thd, struct st_schema_table *schema_table); - int (*process_table) (THD *thd, TABLE_LIST *tables, - TABLE *table, bool res, const char *base_name, - const char *file_name); + int (*process_table) (THD *thd, TABLE_LIST *tables, TABLE *table, + bool res, LEX_STRING *db_name, LEX_STRING *table_name); int idx_field1, idx_field2; bool hidden; + uint i_s_requested_object; /* the object we need to open(TABLE | VIEW) */ } ST_SCHEMA_TABLE; @@ -1091,6 +1096,10 @@ struct TABLE_LIST */ uint8 trg_event_map; + uint i_s_requested_object; + bool has_db_lookup_value; + bool has_table_lookup_value; + uint table_open_method; enum enum_schema_table_state schema_table_state; void calc_md5(char *buffer); void set_underlying_merge(); diff --git a/sql/time.cc b/sql/time.cc index c552d085f5e..a6619cf4cee 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -263,11 +263,11 @@ my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_ my_time_t timestamp; *in_dst_time_gap= 0; + thd->time_zone_used= 1; timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap); if (timestamp) { - thd->time_zone_used= 1; return timestamp; } diff --git a/sql/unireg.h b/sql/unireg.h index 6c26f30f116..b368eee6f0e 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -85,6 +85,8 @@ #define MAX_FIELDS 4096 /* Limit in the .frm file */ #define MAX_PARTITIONS 1024 +#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1) + #define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD) #define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD) @@ -153,6 +155,11 @@ #define OPEN_VIEW 8192 /* Allow open on view */ #define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view, but do not parse view itself */ +#define OPEN_FRM_FILE_ONLY 32768 /* Open frm file only */ +#define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2 /* Open view only */ +#define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2 /* Open table only */ +#define OPEN_TABLE_FROM_SHARE OPEN_VIEW_ONLY*2 /* For I_S tables*/ +#define OPTIMIZE_I_S_TABLE OPEN_TABLE_FROM_SHARE*2 /* For I_S tables*/ #define SC_INFO_LENGTH 4 /* Form format constant */ #define TE_INFO_LENGTH 3 #define MTYP_NOEMPTY_BIT 128 diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt index f4732397cc4..f4732397cc4 100644..100755 --- a/storage/heap/CMakeLists.txt +++ b/storage/heap/CMakeLists.txt diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index f2b67f20c57..2e7c47e17b4 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -22,7 +22,7 @@ #include "mysql_priv.h" #include <mysql/plugin.h> #include "ha_heap.h" - +#include "heapdef.h" static handler *heap_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -61,8 +61,8 @@ static handler *heap_create_handler(handlerton *hton, *****************************************************************************/ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg) - :handler(hton, table_arg), file(0), records_changed(0), - key_stat_version(0) + :handler(hton, table_arg), file(0), records_changed(0), internal_table(0), + key_stat_version(0) {} @@ -90,13 +90,25 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - if (!(file= heap_open(name, mode)) && my_errno == ENOENT) + if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || + !(file= heap_open(name, mode)) && my_errno == ENOENT) { HA_CREATE_INFO create_info; + internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); bzero(&create_info, sizeof(create_info)); + file= 0; if (!create(name, table, &create_info)) { - file= heap_open(name, mode); + file= internal_table ? + heap_open_from_share(internal_share, mode) : + heap_open_from_share_and_register(internal_share, mode); + if (!file) + { + /* Couldn't open table; Remove the newly created table */ + pthread_mutex_lock(&THR_LOCK_heap); + hp_free(internal_share); + pthread_mutex_unlock(&THR_LOCK_heap); + } implicit_emptied= 1; } } @@ -120,7 +132,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) int ha_heap::close(void) { - return heap_close(file); + return internal_table ? hp_close(file) : heap_close(file); } @@ -542,7 +554,7 @@ int ha_heap::delete_table(const char *name) void ha_heap::drop_table(const char *name) { - heap_drop_table(file); + file->s->delete_on_close= 1; close(); } @@ -681,16 +693,16 @@ int ha_heap::create(const char *name, TABLE *table_arg, create_info->auto_increment_value - 1 : 0); hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; hp_create_info.with_auto_increment= found_real_auto_increment; + hp_create_info.internal_table= internal_table; max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(name, keys, keydef, share->reclength, (ulong) ((share->max_rows < max_rows && share->max_rows) ? share->max_rows : max_rows), - (ulong) share->min_rows, &hp_create_info); + (ulong) share->min_rows, &hp_create_info, &internal_share); my_free((uchar*) keydef, MYF(0)); - if (file) - info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); + DBUG_ASSERT(file == 0); return (error); } diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index c414383a4aa..7db775ca15a 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -25,10 +25,12 @@ class ha_heap: public handler { HP_INFO *file; + HP_SHARE *internal_share; key_map btree_keys; /* number of records changed since last statistics update */ uint records_changed; uint key_stat_version; + my_bool internal_table; public: ha_heap(handlerton *hton, TABLE_SHARE *table); ~ha_heap() {} diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h index c43d73eb96d..3fc94062303 100644 --- a/storage/heap/heapdef.h +++ b/storage/heap/heapdef.h @@ -16,6 +16,7 @@ /* This file is included in all heap-files */ #include <my_base.h> /* This includes global */ +C_MODE_START #ifdef THREAD #include <my_pthread.h> #endif @@ -107,3 +108,4 @@ extern pthread_mutex_t THR_LOCK_heap; #define pthread_mutex_lock(A) #define pthread_mutex_unlock(A) #endif +C_MODE_END diff --git a/storage/heap/hp_close.c b/storage/heap/hp_close.c index 79fed859487..d571815980c 100644 --- a/storage/heap/hp_close.c +++ b/storage/heap/hp_close.c @@ -42,7 +42,8 @@ int hp_close(register HP_INFO *info) } #endif info->s->changed=0; - heap_open_list=list_delete(heap_open_list,&info->open_list); + if (info->open_list.data) + heap_open_list=list_delete(heap_open_list,&info->open_list); if (!--info->s->open_count && info->s->delete_on_close) hp_free(info->s); /* Table was deleted */ my_free((uchar*) info,MYF(0)); diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index b910b89ffcd..b6814fc1614 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -19,23 +19,27 @@ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2); static void init_block(HP_BLOCK *block,uint reclength,ulong min_records, ulong max_records); +/* Create a heap table */ + int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info) + HP_CREATE_INFO *create_info, HP_SHARE **res) { uint i, j, key_segs, max_length, length; - HP_SHARE *share; + HP_SHARE *share= 0; HA_KEYSEG *keyseg; - DBUG_ENTER("heap_create"); - pthread_mutex_lock(&THR_LOCK_heap); - if ((share= hp_find_named_heap(name)) && share->open_count == 0) + if (!create_info->internal_table) { - hp_free(share); - share= NULL; - } - + pthread_mutex_lock(&THR_LOCK_heap); + if ((share= hp_find_named_heap(name)) && share->open_count == 0) + { + hp_free(share); + share= 0; + } + } + if (!share) { HP_KEYDEF *keyinfo; @@ -131,10 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keys*sizeof(HP_KEYDEF)+ key_segs*sizeof(HA_KEYSEG), MYF(MY_ZEROFILL)))) - { - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(1); - } + goto err; share->keydef= (HP_KEYDEF*) (share + 1); share->key_stat_version= 1; keyseg= (HA_KEYSEG*) (share->keydef + keys); @@ -189,20 +190,33 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, if (!(share->name= my_strdup(name,MYF(0)))) { my_free((uchar*) share,MYF(0)); - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(1); + goto err; } #ifdef THREAD thr_lock_init(&share->lock); VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); #endif - share->open_list.data= (void*) share; - heap_share_list= list_add(heap_share_list,&share->open_list); + if (!create_info->internal_table) + { + share->open_list.data= (void*) share; + heap_share_list= list_add(heap_share_list,&share->open_list); + } + else + share->delete_on_close= 1; } - pthread_mutex_unlock(&THR_LOCK_heap); + if (!create_info->internal_table) + pthread_mutex_unlock(&THR_LOCK_heap); + + *res= share; DBUG_RETURN(0); + +err: + if (!create_info->internal_table) + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(1); } /* heap_create */ + static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) { uint not_used[2]; @@ -279,7 +293,8 @@ void heap_drop_table(HP_INFO *info) void hp_free(HP_SHARE *share) { - heap_share_list= list_delete(heap_share_list, &share->open_list); + if (share->open_list.data) /* If not internal table */ + heap_share_list= list_delete(heap_share_list, &share->open_list); hp_clear(share); /* Remove blocks from memory */ #ifdef THREAD thr_lock_delete(&share->lock); diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c index d252704a11b..4d5ec6e27ac 100644 --- a/storage/heap/hp_open.c +++ b/storage/heap/hp_open.c @@ -22,43 +22,34 @@ #include "my_sys.h" -HP_INFO *heap_open(const char *name, int mode) +/* + Open heap table based on HP_SHARE structure + + NOTE + This doesn't register the table in the open table list. +*/ + +HP_INFO *heap_open_from_share(HP_SHARE *share, int mode) { HP_INFO *info; - HP_SHARE *share; + DBUG_ENTER("heap_open_from_share"); - DBUG_ENTER("heap_open"); - pthread_mutex_lock(&THR_LOCK_heap); - if (!(share= hp_find_named_heap(name))) - { - my_errno= ENOENT; - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(0); - } if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) + 2 * share->max_key_length, MYF(MY_ZEROFILL)))) { - pthread_mutex_unlock(&THR_LOCK_heap); DBUG_RETURN(0); } share->open_count++; #ifdef THREAD thr_lock_data_init(&share->lock,&info->lock,NULL); #endif - info->open_list.data= (void*) info; - heap_open_list= list_add(heap_open_list,&info->open_list); - pthread_mutex_unlock(&THR_LOCK_heap); - info->s= share; info->lastkey= (uchar*) (info + 1); info->recbuf= (uchar*) (info->lastkey + share->max_key_length); info->mode= mode; info->current_record= (ulong) ~0L; /* No current record */ - info->current_ptr= 0; - info->current_hash_ptr= 0; info->lastinx= info->errkey= -1; - info->update= 0; #ifndef DBUG_OFF info->opt_flag= READ_CHECK_USED; /* Check when changing */ #endif @@ -68,7 +59,59 @@ HP_INFO *heap_open(const char *name, int mode) DBUG_RETURN(info); } - /* map name to a heap-nr. If name isn't found return 0 */ + +/* + Open heap table based on HP_SHARE structure and register it +*/ + +HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode) +{ + HP_INFO *info; + DBUG_ENTER("heap_open_from_share_and_register"); + + pthread_mutex_lock(&THR_LOCK_heap); + if ((info= heap_open_from_share(share, mode))) + { + info->open_list.data= (void*) info; + heap_open_list= list_add(heap_open_list,&info->open_list); + } + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(info); +} + + +/* + Open heap table based on name + + NOTE + This register the table in the open table list. so that it can be + found by future heap_open() calls. +*/ + +HP_INFO *heap_open(const char *name, int mode) +{ + HP_INFO *info; + HP_SHARE *share; + DBUG_ENTER("heap_open"); + + pthread_mutex_lock(&THR_LOCK_heap); + if (!(share= hp_find_named_heap(name))) + { + my_errno= ENOENT; + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(0); + } + if ((info= heap_open_from_share(share, mode))) + { + info->open_list.data= (void*) info; + heap_open_list= list_add(heap_open_list,&info->open_list); + } + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(info); +} + + +/* map name to a heap-nr. If name isn't found return 0 */ HP_SHARE *hp_find_named_heap(const char *name) { diff --git a/storage/heap/hp_test1.c b/storage/heap/hp_test1.c index aad5677db69..24eea141ad9 100644 --- a/storage/heap/hp_test1.c +++ b/storage/heap/hp_test1.c @@ -37,6 +37,7 @@ int main(int argc, char **argv) HP_KEYDEF keyinfo[10]; HA_KEYSEG keyseg[4]; HP_CREATE_INFO hp_create_info; + HP_SHARE *tmp_share; MY_INIT(argv[0]); filename= "test1"; @@ -52,6 +53,7 @@ int main(int argc, char **argv) keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].charset= &my_charset_latin1; + keyinfo[0].seg[0].null_bit= 0; keyinfo[0].flag = HA_NOSAME; deleted=0; @@ -59,7 +61,7 @@ int main(int argc, char **argv) printf("- Creating heap-file\n"); if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L, - &hp_create_info) || + &hp_create_info, &tmp_share) || !(file= heap_open(filename, 2))) goto err; printf("- Writing records:s\n"); diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 46b1fd61d46..e2a8e2f6926 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -59,6 +59,7 @@ int main(int argc, char *argv[]) char record[128],record2[128],record3[128],key[10]; const char *filename,*filename2; HP_INFO *file,*file2; + HP_SHARE *tmp_share; HP_KEYDEF keyinfo[MAX_KEYS]; HA_KEYSEG keyseg[MAX_KEYS*5]; HEAP_PTR position; @@ -126,7 +127,7 @@ int main(int argc, char *argv[]) printf("- Creating heap-file\n"); if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L, - (ulong) recant/2, &hp_create_info) || + (ulong) recant/2, &hp_create_info, &tmp_share) || !(file= heap_open(filename, 2))) goto err; signal(SIGINT,endprog); @@ -562,8 +563,9 @@ int main(int argc, char *argv[]) heap_close(file2); printf("- Creating output heap-file 2\n"); - if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) || - !(file2= heap_open(filename2, 2))) + if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info, + &tmp_share) || + !(file2= heap_open_from_share_and_register(tmp_share, 2))) goto err; printf("- Copying and removing records\n"); diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index d2b6162ba26..d2b6162ba26 100644..100755 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f606134578a..05447f75e95 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -604,7 +604,6 @@ convert_error_code_to_mysql( thd_mark_transaction_to_rollback(thd, TRUE); return(HA_ERR_LOCK_DEADLOCK); - } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) { /* Starting from 5.0.13, we let MySQL just roll back the diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt index ec7cde9a789..de2880298b5 100644..100755 --- a/storage/myisam/CMakeLists.txt +++ b/storage/myisam/CMakeLists.txt @@ -38,16 +38,16 @@ ADD_LIBRARY(myisam ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c f rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c) ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c) -TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys debug dbug strings zlib wsock32) ADD_EXECUTABLE(myisamchk myisamchk.c) -TARGET_LINK_LIBRARIES(myisamchk myisam mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(myisamchk myisam mysys debug dbug strings zlib wsock32) ADD_EXECUTABLE(myisamlog myisamlog.c) -TARGET_LINK_LIBRARIES(myisamlog myisam mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(myisamlog myisam mysys debug dbug strings zlib wsock32) ADD_EXECUTABLE(myisampack myisampack.c) -TARGET_LINK_LIBRARIES(myisampack myisam mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(myisampack myisam mysys debug dbug strings zlib wsock32) IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("myisam_ftdump" "asInvoker") diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index 3dcaa27d3ca..856bb07b2e7 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -94,42 +94,63 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, myisam_read_vec[search_flag], info->s->state.key_root[inx])) { /* - If we searching for a partial key (or using >, >=, < or <=) and - the data is outside of the data file, we need to continue searching - for the first key inside the data file + Found a key, but it might not be usable. We cannot use rows that + are inserted by other threads after we got our table lock + ("concurrent inserts"). The record may not even be present yet. + Keys are inserted into the index(es) before the record is + inserted into the data file. When we got our table lock, we + saved the current data_file_length. Concurrent inserts always go + to the end of the file. So we can test if the found key + references a new record. */ - if (info->lastpos >= info->state->data_file_length && - (search_flag != HA_READ_KEY_EXACT || - last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) + if (info->lastpos >= info->state->data_file_length) { - do + /* The key references a concurrently inserted record. */ + if (search_flag == HA_READ_KEY_EXACT && + last_used_keyseg == keyinfo->seg + keyinfo->keysegs) + { + /* Simply ignore the key if it matches exactly. (Bug #29838) */ + my_errno= HA_ERR_KEY_NOT_FOUND; + info->lastpos= HA_OFFSET_ERROR; + } + else { - uint not_used[2]; - /* - Skip rows that are inserted by other threads since we got a lock - Note that this can only happen if we are not searching after an - full length exact key, because the keys are sorted - according to position - */ - if (_mi_search_next(info, keyinfo, info->lastkey, - info->lastkey_length, - myisam_readnext_vec[search_flag], - info->s->state.key_root[inx])) - break; /* - Check that the found key does still match the search. - _mi_search_next() delivers the next key regardless of its - value. + If searching for a partial key (or using >, >=, < or <=) and + the data is outside of the data file, we need to continue + searching for the first key inside the data file. */ - if (search_flag == HA_READ_KEY_EXACT && - ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length, - SEARCH_FIND, not_used)) + do { - my_errno= HA_ERR_KEY_NOT_FOUND; - info->lastpos= HA_OFFSET_ERROR; - break; - } - } while (info->lastpos >= info->state->data_file_length); + uint not_used[2]; + /* + Skip rows that are inserted by other threads since we got + a lock. Note that this can only happen if we are not + searching after a full length exact key, because the keys + are sorted according to position. + */ + if (_mi_search_next(info, keyinfo, info->lastkey, + info->lastkey_length, + myisam_readnext_vec[search_flag], + info->s->state.key_root[inx])) + break; /* purecov: inspected */ + /* + Check that the found key does still match the search. + _mi_search_next() delivers the next key regardless of its + value. + */ + if (search_flag == HA_READ_KEY_EXACT && + ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, + use_key_length, SEARCH_FIND, not_used)) + { + /* purecov: begin inspected */ + my_errno= HA_ERR_KEY_NOT_FOUND; + info->lastpos= HA_OFFSET_ERROR; + break; + /* purecov: end */ + } + } while (info->lastpos >= info->state->data_file_length); + } } } } diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 3700251ab15..567e1057e5d 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -329,7 +329,7 @@ static struct my_option my_long_options[] = (uchar**) &ft_stopword_file, (uchar**) &ft_stopword_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"stats_method", OPT_STATS_METHOD, - "Specifies how index statistics collection code should threat NULLs. " + "Specifies how index statistics collection code should treat NULLs. " "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), " "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".", (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0, @@ -444,7 +444,7 @@ static void usage(void) MySQL faster. You can check the calculated distribution\n\ by using '--description --verbose table_name'.\n\ --stats_method=name Specifies how index statistics collection code should\n\ - threat NULLs. Possible values of name are \"nulls_unequal\"\n\ + treat NULLs. Possible values of name are \"nulls_unequal\"\n\ (default for 4.1/5.0), \"nulls_equal\" (emulate 4.0), and \n\ \"nulls_ignored\".\n\ -d, --description Prints some information about table.\n\ diff --git a/storage/myisammrg/CMakeLists.txt b/storage/myisammrg/CMakeLists.txt index b35638ac91d..b35638ac91d 100644..100755 --- a/storage/myisammrg/CMakeLists.txt +++ b/storage/myisammrg/CMakeLists.txt diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt index ac7c75ec56c..ac7c75ec56c 100644..100755 --- a/strings/CMakeLists.txt +++ b/strings/CMakeLists.txt diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7559ca9ec6b..2093fc0da36 100644..100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,15 +13,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +# About "mysqlclient_notls", see note in "client/CMakeLists.txt" +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") ADD_DEFINITIONS("-DMYSQL_CLIENT") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) -ADD_EXECUTABLE(mysql_client_test mysql_client_test.c) -TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32) +ADD_EXECUTABLE(mysql_client_test mysql_client_test.c ../mysys/my_memmem.c) +TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient_notls wsock32) ADD_EXECUTABLE(bug25714 bug25714.c) -TARGET_LINK_LIBRARIES(bug25714 dbug mysys mysqlclient yassl taocrypt zlib wsock32) +TARGET_LINK_LIBRARIES(bug25714 mysqlclient_notls wsock32) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index eac1ad413ea..3656364820e 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16077,7 +16077,6 @@ static void test_bug24179() /* Bug#28075 "COM_DEBUG crashes mysqld" - Note: Test disabled because of failure in PushBuild. */ static void test_bug28075() @@ -16106,7 +16105,7 @@ static void test_bug27876() int rc; MYSQL_RES *result; - char utf8_func[] = + unsigned char utf8_func[] = { 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba, @@ -16114,7 +16113,7 @@ static void test_bug27876() 0x00 }; - char utf8_param[] = + unsigned char utf8_param[] = { 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a, @@ -16334,7 +16333,54 @@ static void test_bug29692() mysql_close(conn); } +/** + Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW +*/ + +static void test_bug29306() +{ + MYSQL_FIELD *field; + int rc; + MYSQL_RES *res; + + DBUG_ENTER("test_bug29306"); + myheader("test_bug29306"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))"); + myquery(rc); + rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557"); + myquery(rc); + rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)"); + myquery(rc); + + /* Checking the view */ + res= mysql_list_fields(mysql, "view17557", NULL); + while ((field= mysql_fetch_field(res))) + { + if (! opt_silent) + { + printf("field name %s\n", field->name); + printf("field table %s\n", field->table); + printf("field decimals %d\n", field->decimals); + if (field->decimals < 1) + printf("Error! No decimals! \n"); + printf("\n\n"); + } + DIE_UNLESS(field->decimals == 1); + } + mysql_free_result(res); + + rc= mysql_query(mysql, "DROP TABLE tab17557"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW view17557"); + myquery(rc); + DBUG_VOID_RETURN; +} /* Read and parse arguments and MySQL options from my.cnf */ @@ -16626,6 +16672,7 @@ static struct my_tests_st my_tests[]= { { "test_bug27592", test_bug27592 }, { "test_bug29687", test_bug29687 }, { "test_bug29692", test_bug29692 }, + { "test_bug29306", test_bug29306 }, { 0, 0 } }; diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c index 7e4afbb3128..1622fe22b4d 100644 --- a/unittest/mysys/base64-t.c +++ b/unittest/mysys/base64-t.c @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <my_global.h> +#include <my_sys.h> #include <base64.h> #include <tap.h> #include <string.h> @@ -26,6 +27,7 @@ main(void) { int i, cmp; size_t j, k, l, dst_len, needed_length; + MY_INIT("base64-t"); plan(BASE64_LOOP_COUNT * BASE64_ROWS); diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 779508ee228..069a14ff553 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -18,12 +18,11 @@ library. */ -#include <tap.h> - #include <my_global.h> +#include <my_sys.h> #include <my_bitmap.h> - -#include <string.h> +#include <tap.h> +#include <m_string.h> uint get_rand_bit(uint bitsize) { @@ -379,6 +378,8 @@ int main() int i; int const min_size = 1; int const max_size = 1024; + MY_INIT("bitmap-t"); + plan(max_size - min_size); for (i= min_size; i < max_size; i++) ok(do_test(i) == 0, "bitmap size %d", i); diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index 8280aff5422..a9e98a95cdb 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -14,9 +14,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <my_global.h> -#include <tap.h> #include <my_sys.h> #include <my_atomic.h> +#include <tap.h> int32 a32,b32,c32; my_atomic_rwlock_t rwl; @@ -160,6 +160,7 @@ err: int main() { int err; + MY_INIT("my_atomic-t.c"); diag("N CPUs: %d", my_getncpus()); err= my_atomic_initialize(); diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt index e4940d54da8..e4940d54da8 100644..100755 --- a/vio/CMakeLists.txt +++ b/vio/CMakeLists.txt diff --git a/win/README b/win/README index afa4bd65163..d4b6ee1e3df 100644 --- a/win/README +++ b/win/README @@ -65,6 +65,8 @@ The options right now are: EMBED_MANIFESTS Embed custom manifests into final exes, otherwise VS default will be used. (Note - This option should only be used by MySQL AB.) + EMBEDDED_ONLY Configure solution to produce libmysqld.dll + default will be used. So the command line could look like: @@ -98,3 +100,16 @@ may be necessary to clean the build tree to remove any stale objects. Please see this link: http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/ At step 5 you only need to add the libraries advapi32.lib and user32.lib to the file "corewin_express.vsprops" in order to avoid link errors. + +3. Testing the Windows embedded library requires a two step process. The extra +step is necessary because the testsuite requires mysqld to run properly but both +the embedded library and the mysqld executable cannot be built at the same time. +Here's the process for building and testing the embedded library: + + A. Follow steps 1 - 7 listed above to produce the Release configuration. + B. Perform step 5 from above again adding "--EMBEDDED-ONLY" to previously + supplied options. + C. Complete the build steps above to produce the Release configuration. Make + sure to Rebuild the solution so that all libraries are re-built. + D. Run the testsuite as usual. + diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index ac315b0dd85..43235b631f6 100644..100755 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -13,11 +13,18 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") +# Note that this library is not using any "Thread Local Storage" (TLS), +# i.e. no data declared "__declspec(thread)" or allocated with TlsAlloc(). +# Not directly and indirectly using any of the macros for creating and +# using the storage, pthread_key*(), {,my_}{set,get}_specific*() .... + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") -ADD_DEFINITIONS(-DUSE_TLS -DMYSQL_CLIENT -D__WIN32__) -ADD_LIBRARY(zlib adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.c infback.c inffast.c inffast.h +SET(ZLIB_SOURCES adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.c infback.c inffast.c inffast.h inffixed.h inflate.c inflate.h inftrees.c inftrees.h trees.c trees.h uncompr.c zconf.h zlib.h zutil.c zutil.h) -
\ No newline at end of file +IF(NOT SOURCE_SUBLIBS) + ADD_LIBRARY(zlib ${ZLIB_SOURCES}) +ENDIF(NOT SOURCE_SUBLIBS) |