diff --git a/.bzrignore b/.bzrignore index 2369d922ddf..a851f547392 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3132,3 +3132,4 @@ VERSION.dep info_macros.cmake Docs/INFO_BIN Docs/INFO_SRC +Testing diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index ca77dfb84d7..9791ac04f22 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -293,7 +293,8 @@ extended_usage() version string suffix: [none] All packages except Classic include support for user-defined - partitioning. + partitioning. All packages include support for Performance + Schema. If --with-debug is used, an additional "-debug" is appended to the version string. diff --git a/CMakeLists.txt b/CMakeLists.txt index 235a65a6437..6766f76c665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,6 +172,13 @@ IF(ENABLE_DEBUG_SYNC) SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC") ENDIF() +OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF) +IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE) + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov") +ENDIF() + OPTION(ENABLED_LOCAL_INFILE "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE) diff --git a/VERSION b/VERSION index 796544a7013..f0a5c1203ed 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=15 +MYSQL_VERSION_PATCH=14 MYSQL_VERSION_EXTRA= diff --git a/include/my_compiler.h b/include/my_compiler.h index 5f898621159..e3ff80fad40 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -140,6 +140,14 @@ struct my_aligned_storage #endif /* __cplusplus */ +# ifndef MY_ALIGNED +/* + Make sure MY_ALIGNED can be used also on platforms where we don't + have a way of aligning data structures. +*/ +#define MY_ALIGNED(size) +#endif + #include #endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_sys.h b/include/my_sys.h index f0b2c1a0636..e13ef1af067 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -627,6 +627,8 @@ extern FILE *my_freopen(const char *path, const char *mode, FILE *stream); extern int my_fclose(FILE *fd,myf MyFlags); extern File my_fileno(FILE *fd); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); +extern void thr_set_sync_wait_callback(void (*before_sync)(void), + void (*after_sync)(void)); extern int my_sync(File fd, myf my_flags); extern int my_sync_dir(const char *dir_name, myf my_flags); extern int my_sync_dir_by_file(const char *file_name, myf my_flags); diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 0e5b97d8717..732503e176a 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include struct scheduler_functions; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 88588d03b9e..e65278c518e 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include struct scheduler_functions; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 2c2c1adbf88..c29eac45b19 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -33,16 +33,23 @@ MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, int allocate_lex_string); #include typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(void*, thd_wait_type); + void (*thd_wait_begin_func)(void*, int); void (*thd_wait_end_func)(void*); } *thd_wait_service; -void thd_wait_begin(void* thd, thd_wait_type wait_type); +void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); #include struct scheduler_functions; diff --git a/include/mysql/service_thd_wait.h b/include/mysql/service_thd_wait.h index 2a8f5e610a3..f5d2a75f5fc 100644 --- a/include/mysql/service_thd_wait.h +++ b/include/mysql/service_thd_wait.h @@ -50,15 +50,35 @@ extern "C" { #endif +/* + One should only report wait events that could potentially block for a + long time. A mutex wait is too short of an event to report. The reason + is that an event which is reported leads to a new thread starts + executing a query and this has a negative impact of usage of CPU caches + and thus the expected gain of starting a new thread must be higher than + the expected cost of lost performance due to starting a new thread. + + Good examples of events that should be reported are waiting for row locks + that could easily be for many milliseconds or even seconds and the same + holds true for global read locks, table locks and other meta data locks. + Another event of interest is going to sleep for an extended time. +*/ typedef enum _thd_wait_type_e { - THD_WAIT_MUTEX= 1, + THD_WAIT_SLEEP= 1, THD_WAIT_DISKIO= 2, - THD_WAIT_ROW_TABLE_LOCK= 3, - THD_WAIT_GLOBAL_LOCK= 4 + THD_WAIT_ROW_LOCK= 3, + THD_WAIT_GLOBAL_LOCK= 4, + THD_WAIT_META_DATA_LOCK= 5, + THD_WAIT_TABLE_LOCK= 6, + THD_WAIT_USER_LOCK= 7, + THD_WAIT_BINLOG= 8, + THD_WAIT_GROUP_COMMIT= 9, + THD_WAIT_SYNC= 10, + THD_WAIT_LAST= 11 } thd_wait_type; extern struct thd_wait_service_st { - void (*thd_wait_begin_func)(MYSQL_THD, thd_wait_type); + void (*thd_wait_begin_func)(MYSQL_THD, int); void (*thd_wait_end_func)(MYSQL_THD); } *thd_wait_service; @@ -70,7 +90,7 @@ extern struct thd_wait_service_st { #else -void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type); +void thd_wait_begin(MYSQL_THD thd, int wait_type); void thd_wait_end(MYSQL_THD thd); #endif diff --git a/include/mysql/thread_pool_priv.h b/include/mysql/thread_pool_priv.h new file mode 100644 index 00000000000..b0b0aadc7ff --- /dev/null +++ b/include/mysql/thread_pool_priv.h @@ -0,0 +1,119 @@ +/* + Copyright (C) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef THREAD_POOL_PRIV_INCLUDED +#define THREAD_POOL_PRIV_INCLUDED + +/* + The thread pool requires access to some MySQL server error codes, this is + accessed from mysqld_error.h. + We need access to the struct that defines the thread pool plugin interface + which is accessed through scheduler.h. + All accesses to THD variables and functions are defined in this header file. + A thread pool can also use DEBUG_SYNC and must thus include + debug_sync.h + To handle definitions of Information Schema plugins it is also required + to include sql_profile.h and table.h. +*/ +#include /* To get ER_ERROR_ON_READ */ +#define MYSQL_SERVER 1 +#include +#include +#include +#include + +/* Needed to get access to scheduler variables */ +void* thd_get_scheduler_data(THD *thd); +void thd_set_scheduler_data(THD *thd, void *data); +PSI_thread* thd_get_psi(THD *thd); +void thd_set_psi(THD *thd, PSI_thread *psi); + +/* Interface to THD variables and functions */ +void thd_set_killed(THD *thd); +void thd_clear_errors(THD *thd); +void thd_set_thread_stack(THD *thd, char *stack_start); +void thd_lock_thread_count(THD *thd); +void thd_unlock_thread_count(THD *thd); +void thd_close_connection(THD *thd); +THD *thd_get_current_thd(); +void thd_new_connection_setup(THD *thd, char *stack_start); +void thd_lock_data(THD *thd); +void thd_unlock_data(THD *thd); +bool thd_is_transaction_active(THD *thd); +int thd_connection_has_data(THD *thd); +void thd_set_net_read_write(THD *thd, uint val); +void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var); +my_socket thd_get_fd(THD *thd); + +/* Print to the MySQL error log */ +void sql_print_error(const char *format, ...); + +/* Store a table record */ +bool schema_table_store_record(THD *thd, TABLE *table); + +/* + The thread pool must be able to execute statements using the connection + state in THD object. This is the main objective of the thread pool to + schedule the start of these commands. +*/ +bool do_command(THD *thd); + +/* + The thread pool requires an interface to the connection logic in the + MySQL Server since the thread pool will maintain the event logic on + the TCP connection of the MySQL Server. Thus new connections, dropped + connections will be discovered by the thread pool and it needs to + ensure that the proper MySQL Server logic attached to these events is + executed. +*/ +/* Initialise a new connection handler thread */ +bool init_new_connection_handler_thread(); +/* Set up connection thread before use as execution thread */ +bool setup_connection_thread_globals(THD *thd); +/* Prepare connection as part of connection set-up */ +bool thd_prepare_connection(THD *thd); +/* Release auditing before executing statement */ +void mysql_audit_release(THD *thd); +/* Check if connection is still alive */ +bool thd_is_connection_alive(THD *thd); +/* Close connection with possible error code */ +void close_connection(THD *thd, uint errcode); +/* End the connection before closing it */ +void end_connection(THD *thd); +/* Decrement connection counter */ +void dec_connection_count(); +/* Destroy THD object */ +void delete_thd(THD *thd); + +/* + thread_created is maintained by thread pool when activated since + user threads are created by the thread pool (and also special + threads to maintain the thread pool). This is done through + inc_thread_created. + + max_connections is needed to calculate the maximum number of threads + that is allowed to be started by the thread pool. The method + get_max_connections() gets reference to this variable. + + connection_attrib is the thread attributes for connection threads, + the method get_connection_attrib provides a reference to these + attributes. +*/ +void inc_thread_created(void); +ulong get_max_connections(void); +pthread_attr_t *get_connection_attrib(void); +#endif diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index b07ae1de96b..34f8f685e45 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -50,6 +50,23 @@ extern "C" void unireg_clear(int exit_code) DBUG_VOID_RETURN; } +/* + Wrapper error handler for embedded server to call client/server error + handler based on whether thread is in client/server context +*/ + +static void embedded_error_handler(uint error, const char *str, myf MyFlags) +{ + DBUG_ENTER("embedded_error_handler"); + + /* + If current_thd is NULL, it means restore_global has been called and + thread is in client context, then call client error handler else call + server error handler. + */ + DBUG_RETURN(current_thd ? my_message_sql(error, str, MyFlags): + my_message_stderr(error, str, MyFlags)); +} /* Reads error information from the MYSQL_DATA and puts @@ -106,7 +123,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql->status != MYSQL_STATUS_READY) { set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); - return 1; + result= 1; + goto end; } /* Clear result variables */ @@ -147,6 +165,9 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, #if defined(ENABLED_PROFILING) thd->profiling.finish_current_query(); #endif + +end: + thd->restore_globals(); return result; } @@ -545,7 +566,10 @@ int init_embedded_server(int argc, char **argv, char **groups) return 1; } - error_handler_hook = my_message_sql; + /* + set error_handler_hook to embedded_error_handler wrapper. + */ + error_handler_hook= embedded_error_handler; acl_error= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 5ecc8ef8c64..22505701ac1 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -28,6 +28,7 @@ sys_vars.wait_timeout_func # Bug#41255 2010-04-26 alik wait_t sys_vars.ndb_log_update_as_write_basic sys_vars.have_ndbcluster_basic sys_vars.ndb_log_updated_only_basic +sys_vars.rpl_init_slave_func # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5 main.gis-rtree # svoj: due to BUG#38965 main.type_float # svoj: due to BUG#38965 diff --git a/mysql-test/include/have_archive_plugin.inc b/mysql-test/include/have_archive_plugin.inc index 98e146ca20b..03b382d6344 100644 --- a/mysql-test/include/have_archive_plugin.inc +++ b/mysql-test/include/have_archive_plugin.inc @@ -1,5 +1,10 @@ +disable_query_log; if (`select plugin_library IS NULL from information_schema.plugins where plugin_name LIKE '%archive%'`) { --skip archive plugin not available } +if (`SELECT @@plugin_dir != '$ARCHIVE_PLUGIN_DIR'`) { + --skip Archive plugin requires that --plugin-dir is set to the archive plugin dir (either the .opt file does not contain \$ARCHIVE_PLUGIN_OPT or another plugin is in use) +} +enable_query_log; \ No newline at end of file diff --git a/mysql-test/include/have_blackhole_plugin.inc b/mysql-test/include/have_blackhole_plugin.inc index 749efd343d6..bd1c1ac8af7 100644 --- a/mysql-test/include/have_blackhole_plugin.inc +++ b/mysql-test/include/have_blackhole_plugin.inc @@ -1,5 +1,11 @@ +disable_query_log; if (`select plugin_library IS NULL from information_schema.plugins where plugin_name LIKE '%blackhole%'`) { --skip blackhole plugin not available; } +if (`SELECT @@plugin_dir != '$BLACKHOLE_PLUGIN_DIR'`) { + --skip Blackhole plugin requires that --plugin-dir is set to the blackhole plugin dir (either the .opt file does not contain \$BLACKHOLE_PLUGIN_OPT or another plugin is in use) +} +enable_query_log; + diff --git a/mysql-test/include/not_threadpool.inc b/mysql-test/include/not_threadpool.inc new file mode 100644 index 00000000000..a49c8cfcc32 --- /dev/null +++ b/mysql-test/include/not_threadpool.inc @@ -0,0 +1,5 @@ +if (`SELECT count(*) FROM information_schema.GLOBAL_VARIABLES WHERE + VARIABLE_NAME = 'THREAD_HANDLING' AND + VARIABLE_VALUE = 'loaded-dynamically'`){ + skip Test requires: 'not_threadpool'; +} diff --git a/mysql-test/include/plugin.defs b/mysql-test/include/plugin.defs index e07c603c8e5..2b840d9f438 100644 --- a/mysql-test/include/plugin.defs +++ b/mysql-test/include/plugin.defs @@ -39,3 +39,4 @@ ha_archive storage/archive ARCHIVE_PLUGIN ha_blackhole storage/blackhole BLACKHOLE_PLUGIN ha_federated storage/federated FEDERATED_PLUGIN mypluglib plugin/fulltext SIMPLE_PARSER +thread_pool plugin/thread_pool THREADPOOL_PLUGIN thread_pool,TP_THREAD_STATE,TP_THREAD_GROUP_STATE,TP_THREAD_GROUP_STATS diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index b1bf0a6a830..e6ef9bdfe61 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1389,6 +1389,15 @@ NULL SELECT DATE_FORMAT('0000-00-11', '%w'); DATE_FORMAT('0000-00-11', '%w') NULL +# +# Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +# +SELECT MAKEDATE(11111111,1); +MAKEDATE(11111111,1) +NULL +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); +WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1) +NULL End of 5.1 tests # # Bug#57039: constant subtime expression returns incorrect result. diff --git a/mysql-test/r/implicit_char_to_num_conversion.result b/mysql-test/r/implicit_char_to_num_conversion.result new file mode 100644 index 00000000000..8f24a6b293c --- /dev/null +++ b/mysql-test/r/implicit_char_to_num_conversion.result @@ -0,0 +1,366 @@ +DROP TABLE IF EXISTS t5; +CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +HEX(c1) +0 +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +HEX(c1) +0 +2 +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +HEX(c1) +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +HEX(c1) +0 +1 +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +HEX(c1) +0 +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +HEX(c1) +1 +2 +DROP TABLE t5; +CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +95.95 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +c1 +-10.10 +0.00 +95.95 +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +c1 +-10.10 +0.00 +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +c1 +1.00 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95 +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +c1 +-8 +10 +11 +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +c1 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +c1 +-8 +10 +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +c1 +11 +95 +DROP TABLE t5; +CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-200 +100 +111 +395 +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +c1 +395 +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +c1 +-200 +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +c1 +-200 +111 +395 +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +c1 +-200 +100 +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +c1 +395 +DROP TABLE t5; +CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +c1 +-8388607 +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +c1 +311 +88608 +DROP TABLE t5; +CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-2147483647 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +c1 +-2147483647 +15 +1011 +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +c1 +-2147483647 +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +c1 +1011 +9388607 +DROP TABLE t5; +CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +c1 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +c1 +3372036854775808 +DROP TABLE t5; +CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = ; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index c0cd0f7bc1a..ce3acba9b8a 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -238,11 +238,5 @@ SELECT 9; 9 DROP PROCEDURE p1; DROP FUNCTION f1; -DROP VIEW IF EXISTS v1; -CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; -SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; -SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; -NAME -DROP VIEW v1; set @@global.concurrent_insert= @old_concurrent_insert; SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/r/status_bug17954.result b/mysql-test/r/status_bug17954.result new file mode 100644 index 00000000000..5c244cd8aca --- /dev/null +++ b/mysql-test/r/status_bug17954.result @@ -0,0 +1,13 @@ +set @old_concurrent_insert= @@global.concurrent_insert; +set @@global.concurrent_insert= 0; +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; +flush status; +DROP VIEW IF EXISTS v1; +CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; +SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; +SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; +NAME +DROP VIEW v1; +set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/suite/binlog/r/binlog_innodb_row.result b/mysql-test/suite/binlog/r/binlog_innodb_row.result index 093628c29cc..61f961f16da 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb_row.result +++ b/mysql-test/suite/binlog/r/binlog_innodb_row.result @@ -59,3 +59,20 @@ show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */ ############################################### +# +# Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED +# +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb; +CREATE TABLE t2(a INT) engine=myisam; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +INSERT INTO t2 VALUES (1); +INSERT IGNORE INTO t1 VALUES (1); +COMMIT; +INSERT INTO t1 VALUES (2); +START TRANSACTION; +INSERT INTO t2 VALUES (2); +UPDATE IGNORE t1 SET a=1 WHERE a=2; +COMMIT; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/t/binlog_innodb_row.test b/mysql-test/suite/binlog/t/binlog_innodb_row.test index b491510c9c9..f4ad1058a7e 100644 --- a/mysql-test/suite/binlog/t/binlog_innodb_row.test +++ b/mysql-test/suite/binlog/t/binlog_innodb_row.test @@ -77,3 +77,29 @@ DROP TEMPORARY TABLE t1; -- echo ############################################### -- source include/show_binlog_events.inc -- echo ############################################### + + +--echo # +--echo # Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb; +CREATE TABLE t2(a INT) engine=myisam; + +INSERT INTO t1 VALUES (1); +START TRANSACTION; +INSERT INTO t2 VALUES (1); +INSERT IGNORE INTO t1 VALUES (1); +COMMIT; + +INSERT INTO t1 VALUES (2); +START TRANSACTION; +INSERT INTO t2 VALUES (2); +UPDATE IGNORE t1 SET a=1 WHERE a=2; +COMMIT; + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/perfschema/t/no_threads.test b/mysql-test/suite/perfschema/t/no_threads.test index f98aa8abdb7..dd0bd076dfc 100644 --- a/mysql-test/suite/perfschema/t/no_threads.test +++ b/mysql-test/suite/perfschema/t/no_threads.test @@ -17,6 +17,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/not_threadpool.inc # Setup : in this main thread diff --git a/mysql-test/suite/perfschema/t/one_thread_per_con.test b/mysql-test/suite/perfschema/t/one_thread_per_con.test index 5393152f7d2..fc4d17e34c7 100644 --- a/mysql-test/suite/perfschema/t/one_thread_per_con.test +++ b/mysql-test/suite/perfschema/t/one_thread_per_con.test @@ -17,6 +17,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/not_threadpool.inc # Setup diff --git a/mysql-test/suite/rpl/r/rpl_relayspace.result b/mysql-test/suite/rpl/r/rpl_relayspace.result index 2815974c78f..fb21540aa31 100644 --- a/mysql-test/suite/rpl/r/rpl_relayspace.result +++ b/mysql-test/suite/rpl/r/rpl_relayspace.result @@ -1,7 +1,6 @@ include/master-slave.inc [connection master] -stop slave; -include/wait_for_slave_to_stop.inc +include/stop_slave.inc create table t1 (a int); drop table t1; create table t1 (a int); @@ -9,10 +8,8 @@ drop table t1; reset slave; start slave io_thread; include/wait_for_slave_param.inc [Slave_IO_State] -stop slave io_thread; +include/stop_slave_io.inc reset slave; -start slave; -select master_pos_wait('master-bin.001',200,6)=-1; -master_pos_wait('master-bin.001',200,6)=-1 -0 +include/start_slave.inc +include/assert.inc [Assert that master_pos_wait does not timeout nor it returns NULL] include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_relayspace.test b/mysql-test/suite/rpl/t/rpl_relayspace.test index 2ad6936dd50..fc33d6bc0ba 100644 --- a/mysql-test/suite/rpl/t/rpl_relayspace.test +++ b/mysql-test/suite/rpl/t/rpl_relayspace.test @@ -2,9 +2,9 @@ # to force the deadlock after one event. source include/master-slave.inc; +--let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1) connection slave; -stop slave; ---source include/wait_for_slave_to_stop.inc +--source include/stop_slave.inc connection master; # This will generate a master's binlog > 10 bytes create table t1 (a int); @@ -20,20 +20,33 @@ let $slave_param_value= Waiting for the slave SQL thread to free enough relay lo source include/wait_for_slave_param.inc; # A bug caused the I/O thread to refuse stopping. -stop slave io_thread; +--source include/stop_slave_io.inc reset slave; -start slave; -# The I/O thread stops filling the relay log when -# it's >10b. And the SQL thread cannot purge this relay log -# as purge is done only when the SQL thread switches to another -# relay log, which does not exist here. -# So we should have a deadlock. -# if it is not resolved automatically we'll detect -# it with master_pos_wait that waits for farther than 1Ob; -# it will timeout after 10 seconds; -# also the slave will probably not cooperate to shutdown -# (as 2 threads are locked) -select master_pos_wait('master-bin.001',200,6)=-1; +--source include/start_slave.inc + +# The I/O thread stops filling the relay log when it's >10b. And the +# SQL thread cannot purge this relay log as purge is done only when +# the SQL thread switches to another relay log, which does not exist +# here. So we should have a deadlock. If it is not resolved +# automatically we'll detect it with master_pos_wait that waits for +# farther than 1Ob; it will timeout after 300 seconds (which is inline +# with the default used for sync_slave_with_master and will protect us +# against slow test envs); also the slave will probably not cooperate +# to shutdown (as 2 threads are locked) +--let $outcome= `SELECT MASTER_POS_WAIT('$master_log_file',200,300) AS mpw;` + +# master_pos_wait returns: +# +# * >= 0, the number of events the slave had to wait to advance to the +# position +# +# * -1, if there was a timeout +# +# * NULL, if an error occurred, or the SQL thread was not started, +# slave master info is not initialized, the arguments are incorrect +--let $assert_text= Assert that master_pos_wait does not timeout nor it returns NULL +--let $assert_cond= $outcome IS NOT NULL AND $outcome <> -1 +--source include/assert.inc # End of 4.1 tests --source include/rpl_end.inc diff --git a/mysql-test/suite/sys_vars/t/all_vars.test b/mysql-test/suite/sys_vars/t/all_vars.test index a00b7d5fbb9..5e8ce6d8abf 100644 --- a/mysql-test/suite/sys_vars/t/all_vars.test +++ b/mysql-test/suite/sys_vars/t/all_vars.test @@ -14,6 +14,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --source include/not_embedded.inc +--source include/not_threadpool.inc # 2010-01-28 OBN Added support to load 'innodb' and 'semisync' if possible. # As we need to have there variables loaded if the components exist but do diff --git a/mysql-test/suite/sys_vars/t/slow_launch_time_func.test b/mysql-test/suite/sys_vars/t/slow_launch_time_func.test index 1f384888f81..c9fc357b10f 100644 --- a/mysql-test/suite/sys_vars/t/slow_launch_time_func.test +++ b/mysql-test/suite/sys_vars/t/slow_launch_time_func.test @@ -31,6 +31,7 @@ # --source include/not_embedded.inc +--source include/not_threadpool.inc SET @global_slow_launch_time = @@GLOBAL.slow_launch_time; diff --git a/mysql-test/suite/sys_vars/t/thread_cache_size_func.test b/mysql-test/suite/sys_vars/t/thread_cache_size_func.test index fe9f4242c0d..9bffa32ca2b 100644 --- a/mysql-test/suite/sys_vars/t/thread_cache_size_func.test +++ b/mysql-test/suite/sys_vars/t/thread_cache_size_func.test @@ -28,6 +28,7 @@ # --source include/not_embedded.inc +--source include/not_threadpool.inc SET @global_thread_cache_size = @@GLOBAL.thread_cache_size; diff --git a/mysql-test/suite/sys_vars/t/wait_timeout_func.test b/mysql-test/suite/sys_vars/t/wait_timeout_func.test index e33c39016cc..313d9e8191d 100644 --- a/mysql-test/suite/sys_vars/t/wait_timeout_func.test +++ b/mysql-test/suite/sys_vars/t/wait_timeout_func.test @@ -22,6 +22,7 @@ ############################################################################### --source include/not_embedded.inc +--source include/not_threadpool.inc SET @start_value= @@global.wait_timeout; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index add741e12a7..86f465b3a6e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -902,6 +902,13 @@ SELECT DATE_FORMAT('0000-00-11', '%W'); SELECT DATE_FORMAT('0000-00-11', '%a'); SELECT DATE_FORMAT('0000-00-11', '%w'); +--echo # +--echo # Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +--echo # + +SELECT MAKEDATE(11111111,1); +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); + --echo End of 5.1 tests --echo # diff --git a/mysql-test/t/implicit_char_to_num_conversion.test b/mysql-test/t/implicit_char_to_num_conversion.test new file mode 100644 index 00000000000..f3da83ff2c1 --- /dev/null +++ b/mysql-test/t/implicit_char_to_num_conversion.test @@ -0,0 +1,174 @@ +########### implicit_char_to_num_conversion.test ####################### +# # +# This test aims at using string/char literal in comparison operators # +# without explicit type-cast. This is a bug test for Bug#11766521 # +# - Incorrect result is returned if string/char literal is used with # +# comparision operator and bit data type column. Test is extended to # +# include numeric data type comparison with string/char literal # +# # +# # +# Creation: # +# 2011-05-10 vfisrekar Implement this test as part of Bug#11766521 # +# # +######################################################################## + +--disable_warnings +DROP TABLE IF EXISTS t5; +--enable_warnings + +let $default_engine = `select @@SESSION.default_storage_engine`; + +# Bug#11766521 - BIT Datatype comparison in where clause return incorrect +# result for '=' , '<=>' operators +--replace_result $default_engine +eval CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +# Enable Following two select after Bug#11766521 fix +# SELECT HEX(c1) FROM t5 WHERE c1 = '1' ORDER BY c1; +# SELECT HEX(c1) FROM t5 WHERE c1 <=> '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# FLOAT Data-type +--replace_result $default_engine +eval CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +# Following two queries does not return result may be due to Bug#11766521. +# Enable them after Bug#11766521 fix. +# SELECT c1 FROM t5 WHERE c1 = '10.10' ORDER BY c1; +# SELECT c1 FROM t5 WHERE c2 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# TINYINT Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +DROP TABLE t5; + +# SMALLINT Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +DROP TABLE t5; + +# MEDIUMINT Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +DROP TABLE t5; + +# INT Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +DROP TABLE t5; + +# BIGINT Data-type +--replace_result $default_engine +eval CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +DROP TABLE t5; + +# DOUBLE Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# NUMERIC Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# DECIMAL Datatype +--replace_result $default_engine +eval CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index bc73e8411ca..589bb898d6a 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1,6 +1,9 @@ # This test uses grants, which can't get tested for embedded server -- source include/not_embedded.inc +#Don't run this test when thread_pool active +--source include/not_threadpool.inc + # check that CSV engine was compiled in, as the result of the test depends # on the presence of the log tables (which are CSV-based). --source include/have_csv.inc diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test index 7326f33b113..f1aebfa4bed 100644 --- a/mysql-test/t/information_schema_db.test +++ b/mysql-test/t/information_schema_db.test @@ -2,6 +2,9 @@ # in the embedded server by default). So skip the test in embedded-server mode. -- source include/not_embedded.inc +#Don't run this test when thread_pool active +--source include/not_threadpool.inc + -- source include/testdb_only.inc --disable_warnings diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 9e94bb44171..f36d5a2169d 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -9,6 +9,7 @@ -- source include/not_embedded.inc -- source include/have_debug_sync.inc +-- source include/not_threadpool.inc --disable_warnings SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 66ec8e22ab1..515e2bcf325 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -2,6 +2,8 @@ -- source include/not_embedded.inc # Test lists tables in Information_schema, and InnoDB adds some -- source include/have_innodb.inc +# Don't test when thread_pool active +--source include/not_threadpool.inc --disable_warnings DROP TABLE IF EXISTS t1,t2,test1,test2; diff --git a/mysql-test/t/named_pipe.test b/mysql-test/t/named_pipe.test index 0e6c963024f..23a11d61222 100644 --- a/mysql-test/t/named_pipe.test +++ b/mysql-test/t/named_pipe.test @@ -3,6 +3,9 @@ # other platforms --source include/windows.inc +# thread pool causes different results +-- source include/not_threadpool.inc + # Only run this test if named pipe is avaliable let $nmp= query_get_value("SHOW VARIABLES LIKE 'named_pipe'", Value, 1); if ($nmp != ON){ diff --git a/mysql-test/t/no-threads.test b/mysql-test/t/no-threads.test index fd8365e5678..c2b326897f8 100644 --- a/mysql-test/t/no-threads.test +++ b/mysql-test/t/no-threads.test @@ -1,3 +1,4 @@ +--source include/not_threadpool.inc # # Test the --thread-handler=no-threads option # diff --git a/mysql-test/t/shm.test b/mysql-test/t/shm.test index 0f880e58741..4c765c43c1b 100644 --- a/mysql-test/t/shm.test +++ b/mysql-test/t/shm.test @@ -2,6 +2,9 @@ # to optimize things we skip this test on all other platforms --source include/windows.inc +# thread pool causes different results +-- source include/not_threadpool.inc + # Only run this test if shared memory is avaliable let $shm= query_get_value("SHOW VARIABLES LIKE 'shared_memory'", Value, 1); if ($shm != ON){ diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 9965875af55..26c7a89bf5c 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -354,21 +354,6 @@ DROP FUNCTION f1; # End of 5.1 tests -# -# Bug#17954 Threads_connected > Threads_created -# - ---disable_warnings -DROP VIEW IF EXISTS v1; ---enable_warnings - -CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; - -SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; -SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; - -DROP VIEW v1; - # Restore global concurrent_insert value. Keep in the end of the test file. --connection default set @@global.concurrent_insert= @old_concurrent_insert; diff --git a/mysql-test/t/status_bug17954.test b/mysql-test/t/status_bug17954.test new file mode 100644 index 00000000000..36430cceeff --- /dev/null +++ b/mysql-test/t/status_bug17954.test @@ -0,0 +1,54 @@ +# This test requires that --log-output includes 'table', and the general +# log is on + +# embedded server causes different stat +-- source include/not_embedded.inc + +# thread pool causes different results +-- source include/not_threadpool.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# Disable concurrent inserts to avoid sporadic test failures as it might +# affect the the value of variables used throughout the test case. +set @old_concurrent_insert= @@global.concurrent_insert; +set @@global.concurrent_insert= 0; + +# Disable logging to table, since this will also cause table locking and unlocking, which will +# show up in SHOW STATUS and may cause sporadic failures + +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; + +# PS causes different statistics +--disable_ps_protocol + +flush status; + +# +# Bug#17954 Threads_connected > Threads_created +# + +--disable_warnings +DROP VIEW IF EXISTS v1; +--enable_warnings + +CREATE VIEW v1 AS SELECT VARIABLE_NAME AS NAME, CONVERT(VARIABLE_VALUE, UNSIGNED) AS VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS; + +SELECT VALUE INTO @tc FROM v1 WHERE NAME = 'Threads_connected'; +SELECT NAME FROM v1 WHERE NAME = 'Threads_created' AND VALUE < @tc; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS where variable_name like '%thread%'; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS; +#SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES; + +DROP VIEW v1; + +# Restore global concurrent_insert value. Keep in the end of the test file. +--connection default +set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index 4ed01ac8083..127d7807761 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -146,6 +146,7 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox) */ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) { + struct st_my_thread_var *var; uint32 pins, next, top_ver; LF_PINS *el; /* @@ -188,7 +189,12 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) el->link= pins; el->purgatory_count= 0; el->pinbox= pinbox; - el->stack_ends_here= & my_thread_var->stack_ends_here; + var= my_thread_var; + /* + Threads that do not call my_thread_init() should still be + able to use the LF_HASH. + */ + el->stack_ends_here= (var ? & var->stack_ends_here : NULL); return el; } @@ -327,34 +333,36 @@ static int match_pins(LF_PINS *el, void *addr) */ static void _lf_pinbox_real_free(LF_PINS *pins) { - int npins, alloca_size; - void *list, **addr; + int npins; + void *list; + void **addr= NULL; void *first= NULL, *last= NULL; LF_PINBOX *pinbox= pins->pinbox; npins= pinbox->pins_in_array+1; #ifdef HAVE_ALLOCA - alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; - /* create a sorted list of pinned addresses, to speed up searches */ - if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + if (pins->stack_ends_here != NULL) { - struct st_harvester hv; - addr= (void **) alloca(alloca_size); - hv.granary= addr; - hv.npins= npins; - /* scan the dynarray and accumulate all pinned addresses */ - _lf_dynarray_iterate(&pinbox->pinarray, - (lf_dynarray_func)harvest_pins, &hv); + int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; + /* create a sorted list of pinned addresses, to speed up searches */ + if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + { + struct st_harvester hv; + addr= (void **) alloca(alloca_size); + hv.granary= addr; + hv.npins= npins; + /* scan the dynarray and accumulate all pinned addresses */ + _lf_dynarray_iterate(&pinbox->pinarray, + (lf_dynarray_func)harvest_pins, &hv); - npins= hv.granary-addr; - /* and sort them */ - if (npins) - qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + npins= hv.granary-addr; + /* and sort them */ + if (npins) + qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + } } - else #endif - addr= 0; list= pins->purgatory; pins->purgatory= 0; diff --git a/mysys/my_sync.c b/mysys/my_sync.c index e33a9342afa..076b9b40642 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -17,6 +17,16 @@ #include "mysys_err.h" #include +static void (*before_sync_wait)(void)= 0; +static void (*after_sync_wait)(void)= 0; + +void thr_set_sync_wait_callback(void (*before_wait)(void), + void (*after_wait)(void)) +{ + before_sync_wait= before_wait; + after_sync_wait= after_wait; +} + /* Sync data in file to disk @@ -46,6 +56,8 @@ int my_sync(File fd, myf my_flags) DBUG_ENTER("my_sync"); DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags)); + if (before_sync_wait) + (*before_sync_wait)(); do { #if defined(F_FULLFSYNC) @@ -75,6 +87,8 @@ int my_sync(File fd, myf my_flags) int er= errno; if (!(my_errno= er)) my_errno= -1; /* Unknown error */ + if (after_sync_wait) + (*after_sync_wait)(); if ((my_flags & MY_IGNORE_BADFD) && (er == EBADF || er == EINVAL || er == EROFS)) { @@ -84,6 +98,11 @@ int my_sync(File fd, myf my_flags) else if (my_flags & MY_WME) my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno); } + else + { + if (after_sync_wait) + (*after_sync_wait)(); + } DBUG_RETURN(res); } /* my_sync */ diff --git a/packaging/WiX/ca/CMakeLists.txt b/packaging/WiX/ca/CMakeLists.txt index a03ceb9a5d2..6872dc99d94 100644 --- a/packaging/WiX/ca/CMakeLists.txt +++ b/packaging/WiX/ca/CMakeLists.txt @@ -13,15 +13,43 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) -LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) +INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc ${WIX_DIR}/SDK/inc) +LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - LINK_LIBRARIES(wcautil_x64 dutil_x64 msi version) + SET(WIX_ARCH_SUFFIX "_x64") ELSE() - LINK_LIBRARIES(wcautil dutil msi version) + SET(WIX_ARCH_SUFFIX) ENDIF() - -ADD_LIBRARY(wixca SHARED ${WIXCA_SOURCES}) + +IF(MSVC_VERSION EQUAL 1400) + SET(WIX35_MSVC_SUFFIX "_2005") +ELSEIF(MSVC_VERSION EQUAL 1500) + SET(WIX35_MSVC_SUFFIX "_2008") +ELSEIF(MSVC_VERSION EQUAL 1600) + SET(WIX35_MSVC_SUFFIX "_2010") +ELSE() + # When next VS is out, add the correct version here + MESSAGE(FATAL_ERROR "Unknown VS version") +ENDIF() + +MESSAGE(STATUS "Searching for wcautil${WIX_ARCH_SUFFIX} or wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} in ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib") +MESSAGE(STATUS "Searching for dutil${WIX_ARCH_SUFFIX} or dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} in ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib") + +FIND_LIBRARY(WIX_WCAUTIL_LIBRARY + NAMES wcautil${WIX_ARCH_SUFFIX} wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + HINTS ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) + +FIND_LIBRARY(WIX_DUTIL_LIBRARY + NAMES dutil${WIX_ARCH_SUFFIX} dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + PATHS ${WIX_DIR}/../SDK/lib ${WIX_DIR}/SDK/lib) + +MESSAGE(STATUS "Found: ${WIX_WCAUTIL_LIBRARY}") +MESSAGE(STATUS "Found: ${WIX_DUTIL_LIBRARY}") + +ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) +ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES}) +TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} + msi version ) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index a1899b701fd..dd2e9fd9d85 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -15,6 +15,28 @@ SET(COPYING_RTF "@COPYING_RTF@") SET(CPACK_WIX_CONFIG "@CPACK_WIX_CONFIG@") SET(CPACK_WIX_INCLUDE "@CPACK_WIX_INCLUDE@") +LIST(APPEND EXCLUDE_DIRS + bin/debug + data/test + lib/plugin/debug + mysql-test + scripts + sql-bench +) + +LIST(APPEND EXCLUDE_FILES + bin/echo.exe + bin/mysql_client_test_embedded.exe + bin/mysqld-debug.exe + bin/mysqltest_embedded.exe + bin/replace.exe + lib/debug/mysqlserver.lib + lib/libmysqld.dll + lib/libmysqld.lib + lib/mysqlserver.lib + lib/mysqlservices.lib +) + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) SET(Win64 " Win64='yes'") SET(Platform x64) @@ -197,11 +219,18 @@ ENDMACRO() FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) + FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) + IF(dir_rel) + LIST(FIND EXCLUDE_DIRS ${dir_rel} TO_EXCLUDE) + IF(NOT TO_EXCLUDE EQUAL -1) + MESSAGE(STATUS "excluding directory: ${dir_rel}") + RETURN() + ENDIF() + ENDIF() FILE(GLOB all_files ${dir}/*) IF(NOT all_files) RETURN() ENDIF() - FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) IF(dir_rel) MAKE_DIRECTORY(${dir_root}/${dir_rel}) MAKE_WIX_IDENTIFIER("${dir_rel}" id) @@ -215,18 +244,31 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FOREACH(f ${all_files}) IF(NOT IS_DIRECTORY ${f}) FILE(RELATIVE_PATH rel ${topdir} ${f}) - MAKE_WIX_IDENTIFIER("${rel}" id) - FILE(TO_NATIVE_PATH ${f} f_native) - GET_FILENAME_COMPONENT(f_ext "${f}" EXT) - # According to MSDN each DLL or EXE should be in the own component - IF(f_ext MATCHES ".exe" OR f_ext MATCHES ".dll") + SET(TO_EXCLUDE) + IF(rel MATCHES "\\.pdb$") + SET(TO_EXCLUDE TRUE) + ELSE() + LIST(FIND EXCLUDE_FILES ${rel} RES) + IF(NOT RES EQUAL -1) + SET(TO_EXCLUDE TRUE) + ENDIF() + ENDIF() + IF(TO_EXCLUDE) + MESSAGE(STATUS "excluding file: ${rel}") + ELSE() + MAKE_WIX_IDENTIFIER("${rel}" id) + FILE(TO_NATIVE_PATH ${f} f_native) + GET_FILENAME_COMPONENT(f_ext "${f}" EXT) + # According to MSDN each DLL or EXE should be in the own component + IF(f_ext MATCHES ".exe" OR f_ext MATCHES ".dll") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file_comp} " \n") - ELSE() - SET(NONEXEFILES "${NONEXEFILES}\n" ) + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file_comp} " \n") + ELSE() + SET(NONEXEFILES "${NONEXEFILES}\n" ) + ENDIF() ENDIF() ENDIF() ENDFOREACH() @@ -247,18 +289,18 @@ ENDFUNCTION() FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) FILE(RELATIVE_PATH rel ${topdir} ${dir}) - IF(rel AND IS_DIRECTORY "${f}") + IF(rel) MAKE_WIX_IDENTIFIER("${rel}" id) GET_FILENAME_COMPONENT(name ${dir} NAME) FILE(APPEND ${file} "${prefix}\n") ENDIF() FILE(GLOB all_files ${dir}/*) - FOREACH(f ${all_files}) + FOREACH(f ${all_files}) IF(IS_DIRECTORY ${f}) TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ") ENDIF() ENDFOREACH() - IF(rel AND IS_DIRECTORY "${f}") + IF(rel) FILE(APPEND ${file} "${prefix}\n") ENDIF() ENDFUNCTION() @@ -317,16 +359,25 @@ ENDIF() FILE(REMOVE mysql_server.wixobj) EXECUTE_PROCESS( COMMAND ${CANDLE_EXECUTABLE} -ext WixUtilExtension mysql_server.wxs ${EXTRA_CANDLE_ARGS} + RESULT_VARIABLE CANDLE_RESULT ) + +IF(CANDLE_RESULT) + MESSAGE(FATAL_ERROR "ERROR: can't run candle") +ENDIF() + EXECUTE_PROCESS( COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension mysql_server.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi ${EXTRA_LIGHT_ARGS} + RESULT_VARIABLE LIGHT_RESULT ) +IF(LIGHT_RESULT) + MESSAGE(FATAL_ERROR "ERROR: can't run light") +ENDIF() + # Switch monolithic install on again EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=1 ${CMAKE_BINARY_DIR} - OUTPUT_QUIET ) - diff --git a/packaging/WiX/custom_ui.wxs b/packaging/WiX/custom_ui.wxs index 90db5c416fe..1dc1ef28e4f 100644 --- a/packaging/WiX/custom_ui.wxs +++ b/packaging/WiX/custom_ui.wxs @@ -1,7 +1,22 @@ - + + + 1 + + + NOT OLDERVERSIONBEINGUPGRADED + OLDERVERSIONBEINGUPGRADED + + + + + + + + + 1]]> @@ -47,10 +62,7 @@ 1 - NOT OLDERVERSIONBEINGUPGRADED - OLDERVERSIONBEINGUPGRADED - - 1 + 1 LicenseAccepted = "1" 1 @@ -74,7 +86,11 @@ 1 1 - 1 + 1 + + + NOT Installed + diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 4f353597d6d..7f69ae54037 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1745,11 +1745,20 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) We don't use enter_cond()/exit_cond(). They do not save old mutex and cond. This would prohibit the use of DEBUG_SYNC between other places of enter_cond() and exit_cond(). + + We need to check for existence of thd->mysys_var to also make + it possible to use DEBUG_SYNC framework in scheduler when this + variable has been set to NULL. */ - old_mutex= thd->mysys_var->current_mutex; - old_cond= thd->mysys_var->current_cond; - thd->mysys_var->current_mutex= &debug_sync_global.ds_mutex; - thd->mysys_var->current_cond= &debug_sync_global.ds_cond; + if (thd->mysys_var) + { + old_mutex= thd->mysys_var->current_mutex; + old_cond= thd->mysys_var->current_cond; + thd->mysys_var->current_mutex= &debug_sync_global.ds_mutex; + thd->mysys_var->current_cond= &debug_sync_global.ds_cond; + } + else + old_mutex= NULL; set_timespec(abstime, action->timeout); DBUG_EXECUTE("debug_sync_exec", { @@ -1804,11 +1813,16 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) is locked. (See comment in THD::exit_cond().) */ mysql_mutex_unlock(&debug_sync_global.ds_mutex); - mysql_mutex_lock(&thd->mysys_var->mutex); - thd->mysys_var->current_mutex= old_mutex; - thd->mysys_var->current_cond= old_cond; - thd_proc_info(thd, old_proc_info); - mysql_mutex_unlock(&thd->mysys_var->mutex); + if (old_mutex) + { + mysql_mutex_lock(&thd->mysys_var->mutex); + thd->mysys_var->current_mutex= old_mutex; + thd->mysys_var->current_cond= old_cond; + thd_proc_info(thd, old_proc_info); + mysql_mutex_unlock(&thd->mysys_var->mutex); + } + else + thd_proc_info(thd, old_proc_info); } else { diff --git a/sql/debug_sync.h b/sql/debug_sync.h index 9ac7da39d4d..ba3739e8ad5 100644 --- a/sql/debug_sync.h +++ b/sql/debug_sync.h @@ -39,7 +39,7 @@ class THD; } while (0) /* Command line option --debug-sync-timeout. See mysqld.cc. */ -extern uint opt_debug_sync_timeout; +extern MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout; /* Default WAIT_FOR timeout if command line option is given without argument. */ #define DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT 300 diff --git a/sql/item_func.cc b/sql/item_func.cc index 24d0d94c6c5..a7e9ed43cb4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -52,6 +52,8 @@ #include "sp.h" #include "set_var.h" #include "debug_sync.h" +#include +#include #ifdef NO_EMBEDDED_ACCESS_CHECKS #define sp_restore_security_context(A,B) while (0) {} @@ -3890,6 +3892,7 @@ longlong Item_func_get_lock::val_int() timed_cond.set_timeout(timeout * ULL(1000000000)); error= 0; + thd_wait_begin(thd, THD_WAIT_USER_LOCK); while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); @@ -3901,6 +3904,7 @@ longlong Item_func_get_lock::val_int() } error= 0; } + thd_wait_end(thd); if (ull->locked) { @@ -4118,6 +4122,7 @@ longlong Item_func_sleep::val_int() thd->mysys_var->current_cond= &cond; error= 0; + thd_wait_begin(thd, THD_WAIT_SLEEP); while (!thd->killed) { error= timed_cond.wait(&cond, &LOCK_user_locks); @@ -4125,6 +4130,7 @@ longlong Item_func_sleep::val_int() break; error= 0; } + thd_wait_end(thd); thd_proc_info(thd, 0); mysql_mutex_unlock(&LOCK_user_locks); mysql_mutex_lock(&thd->mysys_var->mutex); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0952a5448e4..b31a388bea4 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1591,6 +1591,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 1; bzero(ltime, sizeof(MYSQL_TIME)); get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); + + if ((null_value= (fuzzy_date & TIME_NO_ZERO_DATE) && + (ltime->year == 0 || ltime->month == 0 || ltime->day == 0))) + return TRUE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } @@ -2779,7 +2784,7 @@ String *Item_func_makedate::val_str(String *str) long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) @@ -2822,7 +2827,7 @@ longlong Item_func_makedate::val_int() long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) diff --git a/sql/log.cc b/sql/log.cc index fe782c5d621..ce6b0f0a5a2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -5993,7 +5993,7 @@ int TC_LOG_MMAP::open(const char *opt_name) { pg->next=pg+1; pg->waiters=0; - pg->state=POOL; + pg->state=PS_POOL; mysql_mutex_init(key_PAGE_lock, &pg->lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_PAGE_cond, &pg->cond, 0); pg->start=(my_xid *)(data + i*tc_log_page_size); @@ -6167,7 +6167,7 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid) cookie= (ulong)((uchar *)p->ptr - data); // can never be zero *p->ptr++= xid; p->free--; - p->state= DIRTY; + p->state= PS_DIRTY; /* to sync or not to sync - this is the question */ mysql_mutex_unlock(&LOCK_active); @@ -6179,13 +6179,13 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid) p->waiters++; /* note - it must be while (), not do ... while () here - as p->state may be not DIRTY when we come here + as p->state may be not PS_DIRTY when we come here */ - while (p->state == DIRTY && syncing) + while (p->state == PS_DIRTY && syncing) mysql_cond_wait(&p->cond, &LOCK_sync); p->waiters--; - err= p->state == ERROR; - if (p->state != DIRTY) // page was synced + err= p->state == PS_ERROR; + if (p->state != PS_DIRTY) // page was synced { if (p->waiters == 0) mysql_cond_signal(&COND_pool); // in case somebody's waiting @@ -6223,7 +6223,7 @@ int TC_LOG_MMAP::sync() pool_last->next=syncing; pool_last=syncing; syncing->next=0; - syncing->state= err ? ERROR : POOL; + syncing->state= err ? PS_ERROR : PS_POOL; mysql_cond_broadcast(&syncing->cond); // signal "sync done" mysql_cond_signal(&COND_pool); // in case somebody's waiting mysql_mutex_unlock(&LOCK_pool); @@ -6506,8 +6506,11 @@ int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) { DBUG_ENTER("TC_LOG_BINLOG::unlog"); mysql_mutex_lock(&LOCK_prep_xids); - DBUG_ASSERT(prepared_xids > 0); - if (--prepared_xids == 0) { + // prepared_xids can be 0 if the transaction had ignorable errors. + DBUG_ASSERT(prepared_xids >= 0); + if (prepared_xids > 0) + prepared_xids--; + if (prepared_xids == 0) { DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids)); mysql_cond_signal(&COND_prep_xids); } diff --git a/sql/log.h b/sql/log.h index 7f7d1a1cf3a..5d6c5b00012 100644 --- a/sql/log.h +++ b/sql/log.h @@ -63,9 +63,9 @@ class TC_LOG_MMAP: public TC_LOG { public: // only to keep Sun Forte on sol9x86 happy typedef enum { - POOL, // page is in pool - ERROR, // last sync failed - DIRTY // new xids added since last sync + PS_POOL, // page is in pool + PS_ERROR, // last sync failed + PS_DIRTY // new xids added since last sync } PAGE_STATE; private: diff --git a/sql/mdl.cc b/sql/mdl.cc index 3aed54ce12d..21410db2d22 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -18,6 +18,8 @@ #include "debug_sync.h" #include #include +#include +#include #ifdef HAVE_PSI_INTERFACE static PSI_mutex_key key_MDL_map_mutex; @@ -973,10 +975,14 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, old_msg= thd_enter_cond(thd, &m_COND_wait_status, &m_LOCK_wait_status, wait_state_name); + thd_wait_begin(thd, THD_WAIT_META_DATA_LOCK); while (!m_wait_status && !thd_killed(thd) && wait_result != ETIMEDOUT && wait_result != ETIME) + { wait_result= mysql_cond_timedwait(&m_COND_wait_status, &m_LOCK_wait_status, abs_timeout); + } + thd_wait_end(thd); if (m_wait_status == EMPTY) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 52df837f193..d67a04bcc23 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -422,7 +422,7 @@ my_bool opt_super_large_pages= 0; my_bool opt_myisam_use_mmap= 0; uint opt_large_page_size= 0; #if defined(ENABLED_DEBUG_SYNC) -uint opt_debug_sync_timeout= 0; +MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout= 0; #endif /* defined(ENABLED_DEBUG_SYNC) */ my_bool opt_old_style_user_limits= 0, trust_function_creators= 0; /* @@ -2008,6 +2008,36 @@ extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) } +/* + Decrease number of connections + + SYNOPSIS + dec_connection_count() +*/ + +void dec_connection_count() +{ + mysql_mutex_lock(&LOCK_connection_count); + --connection_count; + mysql_mutex_unlock(&LOCK_connection_count); +} + + +/* + Delete the THD object and decrease number of threads + + SYNOPSIS + delete_thd() + thd Thread handler +*/ + +void delete_thd(THD *thd) +{ + thread_count--; + delete thd; +} + + /* Unlink thd from global list of available connections and free thd @@ -2023,15 +2053,10 @@ void unlink_thd(THD *thd) { DBUG_ENTER("unlink_thd"); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); - thd->cleanup(); - - mysql_mutex_lock(&LOCK_connection_count); - --connection_count; - mysql_mutex_unlock(&LOCK_connection_count); + dec_connection_count(); mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - delete thd; + delete_thd(thd); DBUG_VOID_RETURN; } @@ -4923,6 +4948,14 @@ static bool read_init_file(char *file_name) } +/** + Increment number of created threads +*/ +void inc_thread_created(void) +{ + thread_created++; +} + #ifndef EMBEDDED_LIBRARY /* diff --git a/sql/mysqld.h b/sql/mysqld.h index 303ee5bec0f..d2366224b3f 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -216,6 +216,10 @@ extern char err_shared_dir[]; extern TYPELIB thread_handling_typelib; extern my_decimal decimal_zero; +/* + THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(MEM_ROOT**,THR_MALLOC); #ifdef HAVE_PSI_INTERFACE @@ -503,6 +507,10 @@ get_thread_running() extern "C" THD *_current_thd_noinline(); #define _current_thd() _current_thd_noinline() #else +/* + THR_THD is a key which will be used to set/get THD* for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(THD*, THR_THD); inline THD *_current_thd(void) { diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f2653894ea7..9a5c7521752 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -26,6 +26,8 @@ #include "rpl_utility.h" #include "transaction.h" #include "sql_parse.h" // end_trans, ROLLBACK +#include +#include static int count_relay_log_space(Relay_log_info* rli); @@ -799,6 +801,7 @@ int Relay_log_info::wait_for_pos(THD* thd, String* log_name, We are going to mysql_cond_(timed)wait(); if the SQL thread stops it will wake us up. */ + thd_wait_begin(thd, THD_WAIT_BINLOG); if (timeout > 0) { /* @@ -816,6 +819,7 @@ int Relay_log_info::wait_for_pos(THD* thd, String* log_name, } else mysql_cond_wait(&data_cond, &data_lock); + thd_wait_end(thd); DBUG_PRINT("info",("Got signal of master update or timed out")); if (error == ETIMEDOUT || error == ETIME) { diff --git a/sql/scheduler.cc b/sql/scheduler.cc index d61a452b99e..a3848e20be5 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -80,14 +80,26 @@ scheduler_functions *thread_scheduler= NULL; */ /**@{*/ -static void scheduler_wait_begin(void) { +extern "C" +{ +static void scheduler_wait_lock_begin(void) { MYSQL_CALLBACK(thread_scheduler, - thd_wait_begin, (current_thd, THD_WAIT_ROW_TABLE_LOCK)); + thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK)); } -static void scheduler_wait_end(void) { +static void scheduler_wait_lock_end(void) { MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd)); } + +static void scheduler_wait_sync_begin(void) { + MYSQL_CALLBACK(thread_scheduler, + thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK)); +} + +static void scheduler_wait_sync_end(void) { + MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd)); +} +}; /**@}*/ /** @@ -98,7 +110,10 @@ static void scheduler_wait_end(void) { mysqld.cc, so this init function will always be called. */ static void scheduler_init() { - thr_set_lock_wait_callback(scheduler_wait_begin, scheduler_wait_end); + thr_set_lock_wait_callback(scheduler_wait_lock_begin, + scheduler_wait_lock_end); + thr_set_sync_wait_callback(scheduler_wait_sync_begin, + scheduler_wait_sync_end); } /* @@ -137,10 +152,6 @@ void one_thread_scheduler() thd_scheduler::thd_scheduler() : m_psi(NULL), data(NULL) { -#ifndef DBUG_OFF - dbug_explain[0]= '\0'; - set_explain= FALSE; -#endif } diff --git a/sql/scheduler.h b/sql/scheduler.h index b5a175434b6..7cf54dec004 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -72,11 +72,6 @@ enum scheduler_types void one_thread_per_connection_scheduler(); void one_thread_scheduler(); -enum pool_command_op -{ - NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP -}; - /* To be used for pool-of-threads (implemeneted differently on various OSs) */ @@ -97,15 +92,15 @@ public: void *data; /* scheduler-specific data structure */ -# ifndef DBUG_OFF - char dbug_explain[512]; - bool set_explain; -# endif - thd_scheduler(); ~thd_scheduler(); }; +void *thd_get_scheduler_data(THD *thd); +void thd_set_scheduler_data(THD *thd, void *data); +PSI_thread* thd_get_psi(THD *thd); +void thd_set_psi(THD *thd, PSI_thread *psi); + extern scheduler_functions *thread_scheduler; #endif diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3affee4058d..5841091a976 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -550,7 +550,7 @@ sp_head::operator delete(void *ptr, size_t size) throw() sp_head::sp_head() - :Query_arena(&main_mem_root, INITIALIZED_FOR_SP), + :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP), m_flags(0), m_sp_cache_version(0), unsafe_flags(0), @@ -1208,7 +1208,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) Query_arena *old_arena; /* per-instruction arena */ MEM_ROOT execute_mem_root; - Query_arena execute_arena(&execute_mem_root, INITIALIZED_FOR_SP), + Query_arena execute_arena(&execute_mem_root, STMT_INITIALIZED_FOR_SP), backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; @@ -1489,7 +1489,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->m_reprepare_observer= save_reprepare_observer; thd->stmt_arena= old_arena; - state= EXECUTED; + state= STMT_EXECUTED; /* Restore the caller's original warning information area: @@ -1647,7 +1647,7 @@ sp_head::execute_trigger(THD *thd, sp_rcontext *nctx = NULL; bool err_status= FALSE; MEM_ROOT call_mem_root; - Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); Query_arena backup_arena; DBUG_ENTER("sp_head::execute_trigger"); @@ -1788,7 +1788,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, String binlog_buf(buf, sizeof(buf), &my_charset_bin); bool err_status= FALSE; MEM_ROOT call_mem_root; - Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); Query_arena backup_arena; DBUG_ENTER("sp_head::execute_function"); DBUG_PRINT("info", ("function %s", m_name.str)); @@ -2545,7 +2545,7 @@ sp_head::restore_thd_mem_root(THD *thd) DBUG_ENTER("sp_head::restore_thd_mem_root"); Item *flist= free_list; // The old list set_query_arena(thd); // Get new free_list and mem_root - state= INITIALIZED_FOR_SP; + state= STMT_INITIALIZED_FOR_SP; DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx", (ulong) &mem_root, (ulong) &thd->mem_root)); @@ -3009,7 +3009,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, (thd->stmt_da->sql_errno() != ER_CANT_REOPEN_TABLE && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE && thd->stmt_da->sql_errno() != ER_UPDATE_TABLE_USED)) - thd->stmt_arena->state= Query_arena::EXECUTED; + thd->stmt_arena->state= Query_arena::STMT_EXECUTED; /* Merge here with the saved parent's values diff --git a/sql/sp_head.h b/sql/sp_head.h index 5efd48fc7c6..4d5e2dd95ab 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -560,7 +560,7 @@ public: /// Should give each a name or type code for debugging purposes? sp_instr(uint ip, sp_pcontext *ctx) - :Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) + :Query_arena(0, STMT_INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) {} virtual ~sp_instr() diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 18758130767..0eb05489015 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3644,6 +3644,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { // Should never happen /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); + thd->lex->restore_backup_query_tables_list(&backup); if (save_binlog_row_based) thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(TRUE); /* purecov: deadcode */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4af038bb4e0..9636dc50ee4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -216,6 +216,252 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ +/** + Get reference to scheduler data object + + @param thd THD object + + @retval Scheduler data object on THD +*/ +void *thd_get_scheduler_data(THD *thd) +{ + return thd->scheduler.data; +} + +/** + Set reference to Scheduler data object for THD object + + @param thd THD object + @param psi Scheduler data object to set on THD +*/ +void thd_set_scheduler_data(THD *thd, void *data) +{ + thd->scheduler.data= data; +} + +/** + Get reference to Performance Schema object for THD object + + @param thd THD object + + @retval Performance schema object for thread on THD +*/ +PSI_thread *thd_get_psi(THD *thd) +{ + return thd->scheduler.m_psi; +} + +/** + Set reference to Performance Schema object for THD object + + @param thd THD object + @param psi Performance schema object for thread +*/ +void thd_set_psi(THD *thd, PSI_thread *psi) +{ + thd->scheduler.m_psi= psi; +} + +/** + Set the state on connection to killed + + @param thd THD object +*/ +void thd_set_killed(THD *thd) +{ + thd->killed= THD::KILL_CONNECTION; +} + +/** + Clear errors from the previous THD + + @param thd THD object +*/ +void thd_clear_errors(THD *thd) +{ + my_errno= 0; + thd->mysys_var->abort= 0; +} + +/** + Set thread stack in THD object + + @param thd Thread object + @param stack_start Start of stack to set in THD object +*/ +void thd_set_thread_stack(THD *thd, char *stack_start) +{ + thd->thread_stack= stack_start; +} + +/** + Lock connection data for the set of connections this connection + belongs to + + @param thd THD object +*/ +void thd_lock_thread_count(THD *) +{ + mysql_mutex_lock(&LOCK_thread_count); +} + +/** + Lock connection data for the set of connections this connection + belongs to + + @param thd THD object +*/ +void thd_unlock_thread_count(THD *) +{ + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); +} + +/** + Close the socket used by this connection + + @param thd THD object +*/ +void thd_close_connection(THD *thd) +{ + if (thd->net.vio) + vio_close(thd->net.vio); +} + +/** + Get current THD object from thread local data + + @retval The THD object for the thread, NULL if not connection thread +*/ +THD *thd_get_current_thd() +{ + return current_thd; +} + +/** + Set up various THD data for a new connection + + thd_new_connection_setup + + @param thd THD object + @param stack_start Start of stack for connection +*/ +void thd_new_connection_setup(THD *thd, char *stack_start) +{ +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + thd_set_psi(thd, + PSI_server->new_thread(key_thread_one_connection, + thd, + thd_get_thread_id((MYSQL_THD)thd))); +#endif + thd->set_time(); + thd->prior_thr_create_utime= thd->thr_create_utime= thd->start_utime= + my_micro_time(); + threads.append(thd); + thd_unlock_thread_count(thd); + DBUG_PRINT("info", ("init new connection. thd: 0x%lx fd: %d", + (ulong)thd, thd->net.vio->sd)); + thd_set_thread_stack(thd, stack_start); +} + +/** + Lock data that needs protection in THD object + + @param thd THD object +*/ +void thd_lock_data(THD *thd) +{ + mysql_mutex_lock(&thd->LOCK_thd_data); +} + +/** + Unlock data that needs protection in THD object + + @param thd THD object +*/ +void thd_unlock_data(THD *thd) +{ + mysql_mutex_unlock(&thd->LOCK_thd_data); +} + +/** + Support method to check if connection has already started transcaction + + @param client_cntx Low level client context + + @retval TRUE if connection already started transaction +*/ +bool thd_is_transaction_active(THD *thd) +{ + return thd->transaction.is_active(); +} + +/** + Check if there is buffered data on the socket representing the connection + + @param thd THD object +*/ +int thd_connection_has_data(THD *thd) +{ + Vio *vio= thd->net.vio; + return vio->has_data(vio); +} + +/** + Set reading/writing on socket, used by SHOW PROCESSLIST + + @param thd THD object + @param val Value to set it to (0 or 1) +*/ +void thd_set_net_read_write(THD *thd, uint val) +{ + thd->net.reading_or_writing= val; +} + +/** + Set reference to mysys variable in THD object + + @param thd THD object + @param mysys_var Reference to set +*/ +void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var) +{ + thd->set_mysys_var(mysys_var); +} + +/** + Get socket file descriptor for this connection + + @param thd THD object + + @retval Socket of the connection +*/ +my_socket thd_get_fd(THD *thd) +{ + return thd->net.vio->sd; +} + +/** + Get thread attributes for connection threads + + @retval Reference to thread attribute for connection threads +*/ +pthread_attr_t *get_connection_attrib(void) +{ + return &connection_attrib; +} + +/** + Get max number of connections + + @retval Max number of connections for MySQL Server +*/ +ulong get_max_connections(void) +{ + return max_connections; +} + /* The following functions form part of the C plugin API */ @@ -493,7 +739,7 @@ bool Drop_table_error_handler::handle_condition(THD *thd, THD::THD() - :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, + :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, /* statement id */ 0), rli_fake(0), user_time(0), in_sub_stmt(0), @@ -1354,6 +1600,25 @@ bool THD::store_globals() return 0; } +/* + Remove the thread specific info (THD and mem_root pointer) stored during + store_global call for this thread. +*/ +bool THD::restore_globals() +{ + /* + Assert that thread_stack is initialized: it's necessary to be able + to track stack overrun. + */ + DBUG_ASSERT(thread_stack); + + /* Undocking the thread specific data. */ + my_pthread_setspecific_ptr(THR_THD, NULL); + my_pthread_setspecific_ptr(THR_MALLOC, NULL); + + return 0; +} + /* Cleanup after query. @@ -3297,7 +3562,7 @@ extern "C" void thd_pool_wait_end(MYSQL_THD thd); thd_wait_end MUST be called immediately after waking up again. */ -extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type) +extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type) { MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type)); } @@ -3313,7 +3578,7 @@ extern "C" void thd_wait_end(MYSQL_THD thd) MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (thd)); } #else -extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type) +extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type) { /* do NOTHING for the embedded library */ return; diff --git a/sql/sql_class.h b/sql/sql_class.h index 56d85e7cb6d..a2c622b2326 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -624,14 +624,14 @@ public: /* The states relfects three diffrent life cycles for three different types of statements: - Prepared statement: INITIALIZED -> PREPARED -> EXECUTED. - Stored procedure: INITIALIZED_FOR_SP -> EXECUTED. - Other statements: CONVENTIONAL_EXECUTION never changes. + Prepared statement: STMT_INITIALIZED -> STMT_PREPARED -> STMT_EXECUTED. + Stored procedure: STMT_INITIALIZED_FOR_SP -> STMT_EXECUTED. + Other statements: STMT_CONVENTIONAL_EXECUTION never changes. */ enum enum_state { - INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2, - CONVENTIONAL_EXECUTION= 3, EXECUTED= 4, ERROR= -1 + STMT_INITIALIZED= 0, STMT_INITIALIZED_FOR_SP= 1, STMT_PREPARED= 2, + STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, STMT_ERROR= -1 }; enum_state state; @@ -654,13 +654,13 @@ public: virtual Type type() const; virtual ~Query_arena() {}; - inline bool is_stmt_prepare() const { return state == INITIALIZED; } + inline bool is_stmt_prepare() const { return state == STMT_INITIALIZED; } inline bool is_stmt_prepare_or_first_sp_execute() const - { return (int)state < (int)PREPARED; } + { return (int)state < (int)STMT_PREPARED; } inline bool is_stmt_prepare_or_first_stmt_execute() const - { return (int)state <= (int)PREPARED; } + { return (int)state <= (int)STMT_PREPARED; } inline bool is_conventional() const - { return state == CONVENTIONAL_EXECUTION; } + { return state == STMT_CONVENTIONAL_EXECUTION; } inline void* alloc(size_t size) { return alloc_root(mem_root,size); } inline void* calloc(size_t size) @@ -2199,6 +2199,7 @@ public: void cleanup(void); void cleanup_after_query(); bool store_globals(); + bool restore_globals(); #ifdef SIGNAL_WITH_VIO_CLOSE inline void set_active_vio(Vio* vio) { diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 9d7e20c1d6e..42a14cda21d 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -708,6 +708,32 @@ pthread_handler_t handle_one_connection(void *arg) return 0; } +bool thd_prepare_connection(THD *thd) +{ + bool rc; + lex_start(thd); + rc= login_connection(thd); + MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + if (rc) + return rc; + + MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0], + (char *) thd->security_ctx->host_or_ip); + + prepare_new_connection_state(thd); + return FALSE; +} + +bool thd_is_connection_alive(THD *thd) +{ + NET *net= &thd->net; + if (!net->error && + net->vio != 0 && + !(thd->killed == THD::KILL_CONNECTION)) + return TRUE; + return FALSE; +} + void do_handle_one_connection(THD *thd_arg) { THD *thd= thd_arg; @@ -750,22 +776,13 @@ void do_handle_one_connection(THD *thd_arg) for (;;) { - NET *net= &thd->net; bool rc; - lex_start(thd); - rc= login_connection(thd); - MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + rc= thd_prepare_connection(thd); if (rc) goto end_thread; - MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0], - (char *) thd->security_ctx->host_or_ip); - - prepare_new_connection_state(thd); - - while (!net->error && net->vio != 0 && - !(thd->killed == THD::KILL_CONNECTION)) + while (thd_is_connection_alive(thd)) { mysql_audit_release(thd); if (do_command(thd)) diff --git a/sql/sql_connect.h b/sql/sql_connect.h index ff5a20dfbc2..1b71d95323d 100644 --- a/sql/sql_connect.h +++ b/sql/sql_connect.h @@ -35,6 +35,8 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void decrease_user_connections(USER_CONN *uc); bool thd_init_client_charset(THD *thd, uint cs_number); bool setup_connection_thread_globals(THD *thd); +bool thd_prepare_connection(THD *thd); +bool thd_is_connection_alive(THD *thd); int check_user(THD *thd, enum enum_server_command command, const char *passwd, uint passwd_len, const char *db, diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h index ed7bfac821a..d19d14fa167 100644 --- a/sql/sql_cursor.h +++ b/sql/sql_cursor.h @@ -46,7 +46,7 @@ protected: select_result *result; public: Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg) - :Query_arena(mem_root_arg, INITIALIZED), result(result_arg) + :Query_arena(mem_root_arg, STMT_INITIALIZED), result(result_arg) {} virtual bool is_open() const= 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 779569b10fb..74505c06a77 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2712,7 +2712,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) */ reset_stmt_params(stmt); - stmt->state= Query_arena::PREPARED; + stmt->state= Query_arena::STMT_PREPARED; general_log_print(thd, thd->command, NullS); @@ -2831,7 +2831,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->state= Query_arena::ERROR; + stmt->state= Query_arena::STMT_ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysqld_stmt_send_long_data"); @@ -2855,7 +2855,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) #endif if (thd->stmt_da->is_error()) { - stmt->state= Query_arena::ERROR; + stmt->state= Query_arena::STMT_ERROR; stmt->last_errno= thd->stmt_da->sql_errno(); strncpy(stmt->last_error, thd->stmt_da->message(), MYSQL_ERRMSG_SIZE); } @@ -3010,7 +3010,7 @@ end: Prepared_statement::Prepared_statement(THD *thd_arg) :Statement(NULL, &main_mem_root, - INITIALIZED, ++thd_arg->statement_id_counter), + STMT_INITIALIZED, ++thd_arg->statement_id_counter), thd(thd_arg), result(thd_arg), param_array(0), @@ -3283,7 +3283,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) { setup_set_params(); lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE; - state= Query_arena::PREPARED; + state= Query_arena::STMT_PREPARED; flags&= ~ (uint) IS_IN_USE; /* @@ -3401,7 +3401,7 @@ Prepared_statement::execute_loop(String *expanded_query, int reprepare_attempt= 0; /* Check if we got an error when sending long data */ - if (state == Query_arena::ERROR) + if (state == Query_arena::STMT_ERROR) { my_message(last_errno, last_error, MYF(0)); return TRUE; @@ -3464,7 +3464,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable) Item_change_list save_change_list; thd->change_list.move_elements_to(&save_change_list); - state= CONVENTIONAL_EXECUTION; + state= STMT_CONVENTIONAL_EXECUTION; if (!(lex= new (mem_root) st_lex_local)) return TRUE; @@ -3799,8 +3799,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->set_statement(&stmt_backup); thd->stmt_arena= old_stmt_arena; - if (state == Query_arena::PREPARED) - state= Query_arena::EXECUTED; + if (state == Query_arena::STMT_PREPARED) + state= Query_arena::STMT_EXECUTED; if (error == 0 && this->lex->sql_command == SQLCOM_CALL) { diff --git a/sql/table.cc b/sql/table.cc index 68e2566ffc1..f66d754de53 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1992,7 +1992,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, Query_arena *backup_stmt_arena_ptr= thd->stmt_arena; Query_arena backup_arena; - Query_arena part_func_arena(&outparam->mem_root, Query_arena::INITIALIZED); + Query_arena part_func_arena(&outparam->mem_root, + Query_arena::STMT_INITIALIZED); thd->set_n_backup_active_arena(&part_func_arena, &backup_arena); thd->stmt_arena= &part_func_arena; bool tmp; diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 23e690b1105..04503d25cd4 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1270,7 +1270,7 @@ retry: #endif /* UNIV_SYNC_DEBUG */ trx->op_info = "waiting in InnoDB queue"; - thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK); + thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK); os_event_wait(slot->event); thd_wait_end(trx->mysql_thd); @@ -1658,7 +1658,7 @@ srv_suspend_mysql_thread( /* Suspend this thread and wait for the event. */ - thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK); + thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_LOCK); os_event_wait(event); thd_wait_end(trx->mysql_thd); diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c index 61b7ae08cf5..c04ef358abe 100644 --- a/unittest/mysys/lf-t.c +++ b/unittest/mysys/lf-t.c @@ -27,6 +27,8 @@ int32 inserts= 0, N; LF_ALLOCATOR lf_allocator; LF_HASH lf_hash; +int with_my_thread_init=0; + /* pin allocator - alloc and release an element in a loop */ @@ -36,7 +38,8 @@ pthread_handler_t test_lf_pinbox(void *arg) int32 x= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_pinbox_get_pins(&lf_allocator.pinbox); @@ -49,7 +52,10 @@ pthread_handler_t test_lf_pinbox(void *arg) pthread_mutex_lock(&mutex); if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); + return 0; } @@ -68,7 +74,8 @@ pthread_handler_t test_lf_alloc(void *arg) int32 x,y= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_alloc_get_pins(&lf_allocator); @@ -101,7 +108,9 @@ pthread_handler_t test_lf_alloc(void *arg) } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); return 0; } @@ -112,7 +121,8 @@ pthread_handler_t test_lf_hash(void *arg) int32 x,y,z,sum= 0, ins= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_hash_get_pins(&lf_hash); @@ -152,14 +162,15 @@ pthread_handler_t test_lf_hash(void *arg) } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + if (with_my_thread_init) + my_thread_end(); return 0; } void do_tests() { - plan(4); + plan(7); lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used)); lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0, @@ -168,9 +179,15 @@ void do_tests() bad= my_atomic_initialize(); ok(!bad, "my_atomic_initialize() returned %d", bad); - test_concurrently("lf_pinbox", test_lf_pinbox, N= THREADS, CYCLES); - test_concurrently("lf_alloc", test_lf_alloc, N= THREADS, CYCLES); - test_concurrently("lf_hash", test_lf_hash, N= THREADS, CYCLES/10); + with_my_thread_init= 1; + test_concurrently("lf_pinbox (with my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (with my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (with my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); + + with_my_thread_init= 0; + test_concurrently("lf_pinbox (without my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (without my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (without my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); lf_hash_destroy(&lf_hash); lf_alloc_destroy(&lf_allocator);