List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:September 2 2010 8:17am
Subject:bzr push into mysql-5.5-mtr branch (bjorn.munch:3084 to 3086)
View as plain text  
 3086 Bjorn Munch	2010-09-01 [merge]
      upmerge 56383

    modified:
      mysql-test/mysql-test-run.pl
 3085 Bjorn Munch	2010-09-01 [merge]
      merge from 5.5

    added:
      include/mysql/service_thd_wait.h
      include/mysql/service_thread_scheduler.h
      libservices/my_thread_scheduler_service.c
      libservices/thd_wait_service.c
      sql/sql_callback.h
    modified:
      client/mysqltest.cc
      include/Makefile.am
      include/mysql/plugin.h
      include/mysql/plugin_audit.h.pp
      include/mysql/plugin_ftparser.h.pp
      include/mysql/services.h
      include/service_versions.h
      include/thr_lock.h
      include/violite.h
      libservices/CMakeLists.txt
      libservices/Makefile.am
      mysql-test/r/delete.result
      mysql-test/r/func_group.result
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/r/mysqld--help-win.result
      mysql-test/r/range.result
      mysql-test/suite/innodb/r/innodb_mysql.result
      mysql-test/suite/innodb/t/innodb_mysql.test
      mysql-test/suite/rpl/r/rpl_flush_logs.result
      mysql-test/suite/rpl/t/rpl_flush_logs.test
      mysql-test/t/delete.test
      mysql-test/t/func_group.test
      mysql-test/t/range.test
      mysys/my_init.c
      mysys/thr_lock.c
      sql/authors.h
      sql/item_sum.cc
      sql/item_sum.h
      sql/log.cc
      sql/mysqld.cc
      sql/mysqld.h
      sql/opt_range.cc
      sql/scheduler.cc
      sql/scheduler.h
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_connect.cc
      sql/sql_connect.h
      sql/sql_plugin_services.h
      sql/sql_select.cc
      sql/sql_show.cc
      sql/sql_yacc.yy
      sql/sys_vars.cc
      storage/innobase/buf/buf0flu.c
      storage/innobase/buf/buf0rea.c
      storage/innobase/srv/srv0srv.c
      vio/vio.c
      vio/vio_priv.h
      vio/viosocket.c
      vio/viossl.c
 3084 Bjorn Munch	2010-08-30 [merge]
      upmerge 55178,55413

    modified:
      .bzr-mysql/default.conf
      client/mysqltest.cc
      mysql-test/lib/mtr_cases.pm
      mysql-test/mysql-test-run.pl
      mysql-test/r/mysqltest.result
      mysql-test/t/mysqltest.test
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2010-08-30 13:19:46 +0000
+++ b/client/mysqltest.cc	2010-09-01 13:49:43 +0000
@@ -5255,10 +5255,8 @@ void do_connect(struct st_command *comma
   }
 #endif
 
-#ifndef EMBEDDED_LIBRARY
   if (opt_protocol)
     mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
-#endif
 
 #ifdef HAVE_SMEM
   if (con_shm)
@@ -7992,10 +7990,8 @@ int main(int argc, char **argv)
     mysql_options(&con->mysql, MYSQL_SET_CHARSET_DIR,
                   opt_charsets_dir);
 
-#ifndef EMBEDDED_LIBRARY
   if (opt_protocol)
     mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
-#endif
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
 

=== modified file 'include/Makefile.am'
--- a/include/Makefile.am	2010-07-23 20:14:35 +0000
+++ b/include/Makefile.am	2010-08-16 12:50:27 +0000
@@ -26,6 +26,8 @@ HEADERS_ABI =		mysql.h mysql_com.h mysql
 pkginclude_HEADERS =	$(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
 			my_xml.h mysql_embed.h mysql/services.h \
 			mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
+			mysql/service_thread_scheduler.h \
+			mysql/service_thd_wait.h \
 		  	my_pthread.h my_no_pthread.h \
 			decimal.h errmsg.h my_global.h my_net.h \
 			my_getopt.h sslopt-longopts.h my_dir.h \

=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h	2010-08-18 07:48:38 +0000
+++ b/include/mysql/plugin.h	2010-08-30 14:07:40 +0000
@@ -71,7 +71,7 @@ typedef struct st_mysql_xid MYSQL_XID;
   Plugin API. Common for all plugin types.
 */
 
-#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
+#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0102
 
 /*
   The allowable types of plugins

=== modified file 'include/mysql/plugin_audit.h.pp'
--- a/include/mysql/plugin_audit.h.pp	2010-08-27 06:45:35 +0000
+++ b/include/mysql/plugin_audit.h.pp	2010-08-30 14:07:40 +0000
@@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void*
 MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
                                       const char *str, unsigned int size,
                                       int allocate_lex_string);
+#include <mysql/service_thd_wait.h>
+typedef enum _thd_wait_type_e {
+  THD_WAIT_MUTEX= 1,
+  THD_WAIT_DISKIO= 2,
+  THD_WAIT_ROW_TABLE_LOCK= 3,
+  THD_WAIT_GLOBAL_LOCK= 4
+} thd_wait_type;
+extern struct thd_wait_service_st {
+  void (*thd_wait_begin_func)(void*, thd_wait_type);
+  void (*thd_wait_end_func)(void*);
+} *thd_wait_service;
+void thd_wait_begin(void* thd, thd_wait_type wait_type);
+void thd_wait_end(void* thd);
+#include <mysql/service_thread_scheduler.h>
+struct scheduler_functions;
+extern struct my_thread_scheduler_service {
+  int (*set)(struct scheduler_functions *scheduler);
+  int (*reset)();
+} *my_thread_scheduler_service;
+int my_thread_scheduler_set(struct scheduler_functions *scheduler);
+int my_thread_scheduler_reset();
 struct st_mysql_xid {
   long formatID;
   long gtrid_length;

=== modified file 'include/mysql/plugin_ftparser.h.pp'
--- a/include/mysql/plugin_ftparser.h.pp	2010-08-27 06:45:35 +0000
+++ b/include/mysql/plugin_ftparser.h.pp	2010-08-30 14:07:40 +0000
@@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void*
 MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
                                       const char *str, unsigned int size,
                                       int allocate_lex_string);
+#include <mysql/service_thd_wait.h>
+typedef enum _thd_wait_type_e {
+  THD_WAIT_MUTEX= 1,
+  THD_WAIT_DISKIO= 2,
+  THD_WAIT_ROW_TABLE_LOCK= 3,
+  THD_WAIT_GLOBAL_LOCK= 4
+} thd_wait_type;
+extern struct thd_wait_service_st {
+  void (*thd_wait_begin_func)(void*, thd_wait_type);
+  void (*thd_wait_end_func)(void*);
+} *thd_wait_service;
+void thd_wait_begin(void* thd, thd_wait_type wait_type);
+void thd_wait_end(void* thd);
+#include <mysql/service_thread_scheduler.h>
+struct scheduler_functions;
+extern struct my_thread_scheduler_service {
+  int (*set)(struct scheduler_functions *scheduler);
+  int (*reset)();
+} *my_thread_scheduler_service;
+int my_thread_scheduler_set(struct scheduler_functions *scheduler);
+int my_thread_scheduler_reset();
 struct st_mysql_xid {
   long formatID;
   long gtrid_length;

=== added file 'include/mysql/service_thd_wait.h'
--- a/include/mysql/service_thd_wait.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/service_thd_wait.h	2010-06-07 14:01:39 +0000
@@ -0,0 +1,83 @@
+/* Copyright (C) 2010, 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 MYSQL_SERVICE_THD_WAIT_INCLUDED
+#define MYSQL_SERVICE_THD_WAIT_INCLUDED
+
+/**
+  @file include/mysql/service_thd_wait.h
+  This service provides functions for plugins and storage engines to report
+  when they are going to sleep/stall.
+  
+  SYNOPSIS
+  thd_wait_begin() - call just before a wait begins
+  thd                     Thread object
+                          Use NULL if the thd is NOT known.
+  wait_type               Type of wait
+                          1 -- short wait (e.g. for mutex)
+                          2 -- medium wait (e.g. for disk io)
+                          3 -- large wait (e.g. for locked row/table)
+  NOTES
+    This is used by the threadpool to have better knowledge of which
+    threads that currently are actively running on CPUs. When a thread
+    reports that it's going to sleep/stall, the threadpool scheduler is
+    free to start another thread in the pool most likely. The expected wait
+    time is simply an indication of how long the wait is expected to
+    become, the real wait time could be very different.
+
+  thd_wait_end() called immediately after the wait is complete
+
+  thd_wait_end() MUST be called if thd_wait_begin() was called.
+
+  Using thd_wait_...() service is optional but recommended.  Using it will
+  improve performance as the thread pool will be more active at managing the
+  thread workload.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _thd_wait_type_e {
+  THD_WAIT_MUTEX= 1,
+  THD_WAIT_DISKIO= 2,
+  THD_WAIT_ROW_TABLE_LOCK= 3,
+  THD_WAIT_GLOBAL_LOCK= 4
+} thd_wait_type;
+
+extern struct thd_wait_service_st {
+  void (*thd_wait_begin_func)(MYSQL_THD, thd_wait_type);
+  void (*thd_wait_end_func)(MYSQL_THD);
+} *thd_wait_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_wait_begin(_THD, _WAIT_TYPE) \
+  thd_wait_service->thd_wait_begin_func(_THD, _WAIT_TYPE)
+#define thd_wait_end(_THD) thd_wait_service->thd_wait_end_func(_THD)
+
+#else
+
+void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type);
+void thd_wait_end(MYSQL_THD thd);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

=== added file 'include/mysql/service_thread_scheduler.h'
--- a/include/mysql/service_thread_scheduler.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/service_thread_scheduler.h	2010-06-07 14:01:39 +0000
@@ -0,0 +1,65 @@
+/*
+  Copyright (C) 2010, 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 SERVICE_THREAD_SCHEDULER_INCLUDED
+#define SERVICE_THREAD_SCHEDULER_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct scheduler_functions;
+
+extern struct my_thread_scheduler_service {
+  int (*set)(struct scheduler_functions *scheduler);
+  int (*reset)();
+} *my_thread_scheduler_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_thread_scheduler_set(F) my_thread_scheduler_service->set((F))
+#define my_thread_scheduler_reset() my_thread_scheduler_service->reset()
+
+#else
+
+/**
+  Set the thread scheduler to use for the server.
+
+  @param scheduler Pointer to scheduler callbacks to use.
+  @retval 0 Scheduler installed correctly.
+  @retval 1 Invalid value (NULL) used for scheduler.
+*/
+int my_thread_scheduler_set(struct scheduler_functions *scheduler);
+
+/**
+  Restore the previous thread scheduler.
+
+  @note If no thread scheduler was installed previously with
+  thd_set_thread_scheduler, this function will report an error.
+
+  @retval 0 Scheduler installed correctly.
+  @retval 1 No scheduler installed.
+*/
+int my_thread_scheduler_reset();
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SERVICE_THREAD_SCHEDULER_INCLUDED */

=== modified file 'include/mysql/services.h'
--- a/include/mysql/services.h	2009-11-02 20:05:42 +0000
+++ b/include/mysql/services.h	2010-06-07 14:01:39 +0000
@@ -20,6 +20,8 @@ extern "C" {
 
 #include <mysql/service_my_snprintf.h>
 #include <mysql/service_thd_alloc.h>
+#include <mysql/service_thd_wait.h>
+#include <mysql/service_thread_scheduler.h>
 
 #ifdef __cplusplus
 }

=== modified file 'include/service_versions.h'
--- a/include/service_versions.h	2009-11-02 20:05:42 +0000
+++ b/include/service_versions.h	2010-06-07 14:01:39 +0000
@@ -21,4 +21,5 @@
 
 #define VERSION_my_snprintf     0x0100
 #define VERSION_thd_alloc       0x0100
-
+#define VERSION_thd_wait        0x0100
+#define VERSION_my_thread_scheduler 0x0100

=== modified file 'include/thr_lock.h'
--- a/include/thr_lock.h	2010-07-27 12:42:36 +0000
+++ b/include/thr_lock.h	2010-08-16 12:50:27 +0000
@@ -155,6 +155,8 @@ void    thr_downgrade_write_lock(THR_LOC
                                  enum thr_lock_type new_lock_type);
 my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
                                   ulong lock_wait_timeout);
+void thr_set_lock_wait_callback(void (*before_wait)(void),
+                                void (*after_wait)(void));
 #ifdef	__cplusplus
 }
 #endif

=== modified file 'include/violite.h'
--- a/include/violite.h	2010-04-13 15:04:45 +0000
+++ b/include/violite.h	2010-06-07 14:01:39 +0000
@@ -217,6 +217,7 @@ struct st_vio
   void	  (*timeout)(Vio*, unsigned int which, unsigned int timeout);
   my_bool (*poll_read)(Vio *vio, uint timeout);
   my_bool (*is_connected)(Vio*);
+  my_bool (*has_data) (Vio*);
 #ifdef HAVE_OPENSSL
   void	  *ssl_arg;
 #endif

=== modified file 'libservices/CMakeLists.txt'
--- a/libservices/CMakeLists.txt	2010-08-12 15:19:57 +0000
+++ b/libservices/CMakeLists.txt	2010-08-16 12:50:27 +0000
@@ -15,7 +15,11 @@
 
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 
-SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
+SET(MYSQLSERVICES_SOURCES
+  my_snprintf_service.c
+  thd_alloc_service.c
+  thd_wait_service.c
+  my_thread_scheduler_service.c)
 
 ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
 INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR})

=== modified file 'libservices/Makefile.am'
--- a/libservices/Makefile.am	2009-11-02 20:05:42 +0000
+++ b/libservices/Makefile.am	2010-06-07 14:01:39 +0000
@@ -15,5 +15,7 @@
 
 AM_CPPFLAGS =		-I$(top_srcdir)/include
 pkglib_LIBRARIES =	libmysqlservices.a
-libmysqlservices_a_SOURCES =  my_snprintf_service.c thd_alloc_service.c
+libmysqlservices_a_SOURCES =	my_snprintf_service.c thd_alloc_service.c \
+				thd_wait_service.c \
+				my_thread_scheduler_service.c
 EXTRA_DIST = CMakeLists.txt

=== added file 'libservices/my_thread_scheduler_service.c'
--- a/libservices/my_thread_scheduler_service.c	1970-01-01 00:00:00 +0000
+++ b/libservices/my_thread_scheduler_service.c	2010-06-07 14:01:39 +0000
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2010, 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
+*/
+
+#include <service_versions.h>
+SERVICE_VERSION my_thread_scheduler_service=
+  (void*)VERSION_my_thread_scheduler;

=== added file 'libservices/thd_wait_service.c'
--- a/libservices/thd_wait_service.c	1970-01-01 00:00:00 +0000
+++ b/libservices/thd_wait_service.c	2010-06-07 14:01:39 +0000
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2010, 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
+*/
+
+#include <service_versions.h>
+SERVICE_VERSION *thd_wait_service= (void*)VERSION_thd_wait;

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2010-08-30 13:19:46 +0000
+++ b/mysql-test/mysql-test-run.pl	2010-09-01 13:52:31 +0000
@@ -244,6 +244,7 @@ my $opt_repeat= 1;
 my $opt_retry= 3;
 my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2);
 my $opt_reorder= 1;
+my $opt_force_restart= 0;
 
 my $opt_strace_client;
 
@@ -944,6 +945,7 @@ sub command_line_setup {
              'report-features'          => \$opt_report_features,
              'comment=s'                => \$opt_comment,
              'fast'                     => \$opt_fast,
+	     'force-restart'            => \$opt_force_restart,
              'reorder!'                 => \$opt_reorder,
              'enable-disabled'          => \&collect_option,
              'verbose+'                 => \$opt_verbose,
@@ -4577,6 +4579,11 @@ sub server_need_restart {
     return 1;
   }
 
+  if ( $opt_force_restart ) {
+    mtr_verbose_restart($server, "forced restart turned on");
+    return 1;
+  }
+
   if ( $tinfo->{template_path} ne $current_config_name)
   {
     mtr_verbose_restart($server, "using different config file");
@@ -5605,6 +5612,7 @@ Misc options
                         servers to exit before finishing the process
   fast                  Run as fast as possible, dont't wait for servers
                         to shutdown etc.
+  force-restart         Always restart servers between tests
   parallel=N            Run tests in N parallel threads (default=1)
                         Use parallel=auto for auto-setting of N
   repeat=N              Run each test N number of times

=== modified file 'mysql-test/r/delete.result'
--- a/mysql-test/r/delete.result	2010-05-23 20:41:18 +0000
+++ b/mysql-test/r/delete.result	2010-08-30 22:22:01 +0000
@@ -499,4 +499,13 @@ INDEX(a), INDEX(b), INDEX(c));
 INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9);
 DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
 DROP TABLE t1;
+#
+# Bug #53034: Multiple-table DELETE statements not accepting
+#             "Access compatibility" syntax
+#
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
+DROP TABLE t1, t2, t3;
 End of 5.1 tests

=== modified file 'mysql-test/r/func_group.result'
--- a/mysql-test/r/func_group.result	2010-08-25 09:21:54 +0000
+++ b/mysql-test/r/func_group.result	2010-08-30 08:36:02 +0000
@@ -1713,6 +1713,17 @@ f1	f2	f3	f4	f1 = f2
 NULL	NULL	NULL	NULL	NULL
 drop table t1;
 #
+# Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
+#             MYSQL_TYPE_LONGLONG
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1 
+ORDER BY t1.a;
+m
+1
+DROP TABLE t1;
+#
 End of 5.1 tests
 #
 # Bug#55648: Server crash on MIN/MAX on maximum time value

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2010-08-28 16:36:17 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2010-08-30 14:07:40 +0000
@@ -688,7 +688,7 @@ The following options may be given as th
  How many threads we should keep in a cache for reuse
  --thread-handling=name 
  Define threads usage for handling queries, one of
- one-thread-per-connection, no-threads
+ one-thread-per-connection, no-threads, loaded-dynamically
  --thread-stack=#    The stack size for each thread
  --time-format=name  The TIME format (ignored)
  --timed-mutexes     Specify whether to time mutexes (only InnoDB mutexes are

=== modified file 'mysql-test/r/mysqld--help-win.result'
--- a/mysql-test/r/mysqld--help-win.result	2010-08-28 16:36:17 +0000
+++ b/mysql-test/r/mysqld--help-win.result	2010-08-30 14:07:40 +0000
@@ -692,7 +692,7 @@ The following options may be given as th
  How many threads we should keep in a cache for reuse
  --thread-handling=name 
  Define threads usage for handling queries, one of
- one-thread-per-connection, no-threads
+ one-thread-per-connection, no-threads, loaded-dynamically
  --thread-stack=#    The stack size for each thread
  --time-format=name  The TIME format (ignored)
  --timed-mutexes     Specify whether to time mutexes (only InnoDB mutexes are

=== modified file 'mysql-test/r/range.result'
--- a/mysql-test/r/range.result	2010-08-11 15:55:07 +0000
+++ b/mysql-test/r/range.result	2010-08-26 12:35:38 +0000
@@ -1653,4 +1653,17 @@ a	b
 0	0
 1	1
 DROP TABLE t1;
+#
+# Bug #54802: 'NOT BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	c_key	NULL	NULL	NULL	3	Using where
+SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+c_key	c_notkey
+1	1
+3	3
+DROP TABLE t1;
 End of 5.1 tests

=== modified file 'mysql-test/suite/innodb/r/innodb_mysql.result'
--- a/mysql-test/suite/innodb/r/innodb_mysql.result	2010-08-25 10:22:34 +0000
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result	2010-08-30 08:36:02 +0000
@@ -2549,6 +2549,64 @@ LOCK TABLES t1 READ;
 ALTER TABLE t1 COMMENT 'test';
 UNLOCK TABLES;
 DROP TABLE t1;
+#
+# Bug#55656: mysqldump can be slower after bug #39653 fix
+#
+CREATE TABLE t1 (a INT , b INT, c INT, d INT,
+KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
+EXPLAIN SELECT COUNT(*) FROM t1;
+id	1
+select_type	SIMPLE
+table	t1
+type	index
+possible_keys	NULL
+key	b
+key_len	4
+ref	NULL
+rows	3
+Extra	Using index
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b);
+EXPLAIN SELECT COUNT(*) FROM t1;
+id	1
+select_type	SIMPLE
+table	t1
+type	index
+possible_keys	NULL
+key	b
+key_len	8
+ref	NULL
+rows	3
+Extra	Using index
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b,c);
+EXPLAIN SELECT COUNT(*) FROM t1;
+id	1
+select_type	SIMPLE
+table	t1
+type	index
+possible_keys	NULL
+key	b
+key_len	13
+ref	NULL
+rows	3
+Extra	Using index
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b,c,d);
+EXPLAIN SELECT COUNT(*) FROM t1;
+id	1
+select_type	SIMPLE
+table	t1
+type	index
+possible_keys	NULL
+key	PRIMARY
+key_len	8
+ref	NULL
+rows	3
+Extra	Using index
+DROP TABLE t1;
+#
 End of 5.1 tests
 #
 # Test for bug #39932 "create table fails if column for FK is in different

=== modified file 'mysql-test/suite/innodb/t/innodb_mysql.test'
--- a/mysql-test/suite/innodb/t/innodb_mysql.test	2010-08-20 11:22:46 +0000
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test	2010-08-27 11:33:32 +0000
@@ -746,6 +746,30 @@ UNLOCK TABLES;
 
 DROP TABLE t1;
 
+--echo #
+--echo # Bug#55656: mysqldump can be slower after bug #39653 fix
+--echo #
+
+CREATE TABLE t1 (a INT , b INT, c INT, d INT,
+  KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
+--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
+
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b);
+--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
+
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b,c);
+--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
+
+DROP INDEX b ON t1;
+CREATE INDEX b ON t1(a,b,c,d);
+--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
+
+DROP TABLE t1;
+
+--echo #
 
 
 --echo End of 5.1 tests

=== modified file 'mysql-test/suite/rpl/r/rpl_flush_logs.result'
--- a/mysql-test/suite/rpl/r/rpl_flush_logs.result	2009-12-03 08:59:58 +0000
+++ b/mysql-test/suite/rpl/r/rpl_flush_logs.result	2010-08-30 09:09:28 +0000
@@ -4,12 +4,8 @@ reset master;
 reset slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
-# Make sure the 'master_log.err-old' file does not
-# exist before execute 'flush error logs' statement.
 # Test if support 'flush error logs' statement.
 flush error logs;
-# Check the 'master_log.err-old' file is created
-# after executed 'flush error logs' statement.
 # Make sure binary logs was not be flushed
 # after execute 'flush error logs' statement.
 # Make sure relay logs was not be flushed 
@@ -42,12 +38,8 @@ flush binary logs;
 # after executed 'flush binary logs' statement.
 # Make sure the 'slave-relay-bin.000007' file does not exist
 # exist before execute 'flush error logs, relay logs' statement.
-# Make sure the 'master_log.err-old' file does not exist
-# before execute 'flush error logs, relay logs' statement.
 # Test if support to combine all kinds of logs into one statement.
 flush error logs, relay logs;
-# Check the 'master_log.err-old' file is created
-# after executed 'flush error logs, relay logs' statement.
 # Make sure binary logs was not be flushed
 # after execute 'flush error logs, relay logs' statement.
 # Check the 'slave-relay-bin.000007' file is created after
@@ -55,12 +47,8 @@ flush error logs, relay logs;
 # Make sure the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 
 # files do not exist before execute 'flush error logs, relay logs' 
 # statement.
-# Make sure the 'master_log.err-old' file does not exist
-# before execute 'flush logs' statement.
 # Test if 'flush logs' statement works fine and flush all the logs.
 flush logs;
-# Check the 'master_log.err-old' file is created
-# after executed 'flush logs' statement.
 # Check 'master-bin.000003' is created
 # after execute 'flush logs' statement.
 # Check the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 

=== modified file 'mysql-test/suite/rpl/t/rpl_flush_logs.test'
--- a/mysql-test/suite/rpl/t/rpl_flush_logs.test	2009-12-03 08:59:58 +0000
+++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test	2010-08-30 09:09:28 +0000
@@ -9,17 +9,10 @@
 connection master;
 
 # Test 'flush error logs' statement.
---echo # Make sure the 'master_log.err-old' file does not
---echo # exist before execute 'flush error logs' statement.
---error 1
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 
 --echo # Test if support 'flush error logs' statement.
 flush error logs;
 
---echo # Check the 'master_log.err-old' file is created
---echo # after executed 'flush error logs' statement.
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
 
 --echo # Make sure binary logs was not be flushed
@@ -109,19 +102,10 @@ sync_slave_with_master;
 file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
 
 connection master;
-remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
-
---echo # Make sure the 'master_log.err-old' file does not exist
---echo # before execute 'flush error logs, relay logs' statement.
---error 1
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 
 --echo # Test if support to combine all kinds of logs into one statement.
 flush error logs, relay logs;
 
---echo # Check the 'master_log.err-old' file is created
---echo # after executed 'flush error logs, relay logs' statement.
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
 
 --echo # Make sure binary logs was not be flushed
@@ -145,19 +129,10 @@ file_exists $MYSQLTEST_VARDIR/mysqld.2/d
 file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000009;
 
 connection master;
-remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
-
---echo # Make sure the 'master_log.err-old' file does not exist
---echo # before execute 'flush logs' statement.
---error 1
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 
 --echo # Test if 'flush logs' statement works fine and flush all the logs.
 flush logs;
 
---echo # Check the 'master_log.err-old' file is created
---echo # after executed 'flush logs' statement.
-file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
 file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
 
 --echo # Check 'master-bin.000003' is created

=== modified file 'mysql-test/t/delete.test'
--- a/mysql-test/t/delete.test	2010-05-23 20:41:18 +0000
+++ b/mysql-test/t/delete.test	2010-08-30 22:22:01 +0000
@@ -540,4 +540,17 @@ DELETE FROM t1 WHERE a = 10 OR b = 20 OR
 
 DROP TABLE t1;
 
+--echo #
+--echo # Bug #53034: Multiple-table DELETE statements not accepting
+--echo #             "Access compatibility" syntax
+--echo #
+
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+
+DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
+
+DROP TABLE t1, t2, t3;
+
 --echo End of 5.1 tests

=== modified file 'mysql-test/t/func_group.test'
--- a/mysql-test/t/func_group.test	2010-08-25 09:21:54 +0000
+++ b/mysql-test/t/func_group.test	2010-08-30 08:36:02 +0000
@@ -1082,6 +1082,20 @@ select a.f1 as a, b.f4 as b, a.f1 > b.f4
 from t1 a, t1 b;
 select *, f1 = f2 from t1;
 drop table t1;
+
+--echo #
+--echo # Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
+--echo #             MYSQL_TYPE_LONGLONG
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+
+SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1 
+       ORDER BY t1.a;
+
+DROP TABLE t1;
+
 --echo #
 --echo End of 5.1 tests
 

=== modified file 'mysql-test/t/range.test'
--- a/mysql-test/t/range.test	2010-08-11 12:13:59 +0000
+++ b/mysql-test/t/range.test	2010-08-24 15:51:32 +0000
@@ -1313,4 +1313,16 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY)
 
 DROP TABLE t1;
 
+--echo #
+--echo # Bug #54802: 'NOT BETWEEN' evaluation is incorrect
+--echo #
+
+CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+
+EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+
+DROP TABLE t1;
+
 --echo End of 5.1 tests

=== modified file 'mysys/my_init.c'
--- a/mysys/my_init.c	2010-07-23 20:16:29 +0000
+++ b/mysys/my_init.c	2010-08-16 12:50:27 +0000
@@ -477,7 +477,7 @@ static my_bool win32_init_tcp_ip()
 {
   if (win32_have_tcpip())
   {
-    WORD wVersionRequested = MAKEWORD( 2, 0 );
+    WORD wVersionRequested = MAKEWORD( 2, 2 );
     WSADATA wsaData;
  	/* Be a good citizen: maybe another lib has already initialised
  		sockets, so dont clobber them unless necessary */

=== modified file 'mysys/thr_lock.c'
--- a/mysys/thr_lock.c	2010-08-06 11:29:37 +0000
+++ b/mysys/thr_lock.c	2010-08-30 14:07:40 +0000
@@ -91,6 +91,16 @@ enum thr_lock_type thr_upgraded_concurre
 LIST *thr_lock_thread_list;			/* List of threads in use */
 ulong max_write_lock_count= ~(ulong) 0L;
 
+static void (*before_lock_wait)(void)= 0;
+static void (*after_lock_wait)(void)= 0;
+
+void thr_set_lock_wait_callback(void (*before_wait)(void),
+                                void (*after_wait)(void))
+{
+  before_lock_wait= before_wait;
+  after_lock_wait= after_wait;
+}
+
 static inline mysql_cond_t *get_cond(void)
 {
   return &my_thread_var->suspend;
@@ -431,6 +441,19 @@ wait_for_lock(struct st_lock_list *wait,
   old_proc_info= proc_info_hook(NULL, "Waiting for table level lock",
                                 __func__, __FILE__, __LINE__);
 
+  /*
+    Since before_lock_wait potentially can create more threads to
+    scheduler work for, we don't want to call the before_lock_wait
+    callback unless it will really start to wait.
+
+    For similar reasons, we do not want to call before_lock_wait and
+    after_lock_wait for each lap around the loop, so we restrict
+    ourselves to call it before_lock_wait once before starting to wait
+    and once after the thread has exited the wait loop.
+   */
+  if ((!thread_var->abort || in_wait_list) && before_lock_wait)
+    (*before_lock_wait)();
+
   set_timespec(wait_timeout, lock_wait_timeout);
   while (!thread_var->abort || in_wait_list)
   {
@@ -462,6 +485,14 @@ wait_for_lock(struct st_lock_list *wait,
       /* purecov: end */
     }
   }
+
+  /*
+    We call the after_lock_wait callback once the wait loop has
+    finished.
+   */
+  if (after_lock_wait)
+    (*after_lock_wait)();
+
   DBUG_PRINT("thr_lock", ("aborted: %d  in_wait_list: %d",
                           thread_var->abort, in_wait_list));
 

=== modified file 'sql/authors.h'
--- a/sql/authors.h	2010-05-11 16:02:50 +0000
+++ b/sql/authors.h	2010-08-16 12:50:27 +0000
@@ -93,6 +93,7 @@ struct show_table_authors_st show_table_
   { "Arjen Lentz", "Brisbane, Australia",
     "Documentation (2001-2004), Dutch error messages, LOG2()" },
   { "Marc Liyanage", "", "Created Mac OS X packages" },
+  { "Kelly Long", "Denver, CO, USA", "Pool Of Threads" },
   { "Zarko Mocnik", "", "Sorting for Slovenian language" },
   { "Per-Erik Martin", "Uppsala, Sweden", "Stored Procedures (5.0)" },
   { "Alexis Mikhailov", "", "User-defined functions" },

=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc	2010-08-20 11:22:46 +0000
+++ b/sql/item_sum.cc	2010-08-30 07:36:04 +0000
@@ -434,26 +434,6 @@ void Item_sum::mark_as_sum_func()
 }
 
 
-void Item_sum::make_field(Send_field *tmp_field)
-{
-  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
-  {
-    ((Item_field*) args[0])->field->make_field(tmp_field);
-    /* For expressions only col_name should be non-empty string. */
-    char *empty_string= (char*)"";
-    tmp_field->db_name= empty_string;
-    tmp_field->org_table_name= empty_string;
-    tmp_field->table_name= empty_string;
-    tmp_field->org_col_name= empty_string;
-    tmp_field->col_name= name;
-    if (maybe_null)
-      tmp_field->flags&= ~NOT_NULL_FLAG;
-  }
-  else
-    init_make_field(tmp_field, field_type());
-}
-
-
 void Item_sum::print(String *str, enum_query_type query_type)
 {
   /* orig_args is not filled with valid values until fix_fields() */

=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h	2010-07-19 17:11:47 +0000
+++ b/sql/item_sum.h	2010-08-30 07:36:04 +0000
@@ -427,7 +427,6 @@ public:
     forced_const= TRUE; 
   }
   virtual bool const_item() const { return forced_const; }
-  void make_field(Send_field *field);
   virtual void print(String *str, enum_query_type query_type);
   void fix_num_length_and_dec();
 

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-08-25 10:22:34 +0000
+++ b/sql/log.cc	2010-08-30 08:36:02 +0000
@@ -5447,70 +5447,93 @@ void sql_perror(const char *message)
 }
 
 
+#ifdef __WIN__
+extern "C" my_bool reopen_fstreams(const char *filename,
+                                   FILE *outstream, FILE *errstream)
+{
+  int handle_fd;
+  int stream_fd;
+  HANDLE osfh;
+
+  DBUG_ASSERT(filename && (outstream || errstream));
+
+  if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE |
+                        FILE_SHARE_DELETE, NULL,
+                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+                        NULL)) == INVALID_HANDLE_VALUE)
+    return TRUE;
+
+  if ((handle_fd= _open_osfhandle((intptr_t)osfh,
+                                  _O_APPEND | _O_TEXT)) == -1)
+  {
+    CloseHandle(osfh);
+    return TRUE;
+  }
+
+  if (outstream)
+  {
+    stream_fd= _fileno(outstream);
+    if (_dup2(handle_fd, stream_fd) < 0)
+    {
+      CloseHandle(osfh);
+      return TRUE;
+    }
+  }
+
+  if (errstream)
+  {
+    stream_fd= _fileno(errstream);
+    if (_dup2(handle_fd, stream_fd) < 0)
+    {
+      CloseHandle(osfh);
+      return TRUE;
+    }
+  }
+
+  _close(handle_fd);
+  return FALSE;
+}
+#else
+extern "C" my_bool reopen_fstreams(const char *filename,
+                                   FILE *outstream, FILE *errstream)
+{
+  if (outstream && !freopen(filename, "a+", outstream))
+    return TRUE;
+
+  if (errstream && !freopen(filename, "a+", errstream))
+    return TRUE;
+
+  return FALSE;
+}
+#endif
+
+
 /*
   Unfortunately, there seems to be no good way
   to restore the original streams upon failure.
 */
 static bool redirect_std_streams(const char *file)
 {
-  if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr))
-  {
-    setbuf(stderr, NULL);
-    return FALSE;
-  }
+  if (reopen_fstreams(file, stdout, stderr))
+    return TRUE;
 
-  return TRUE;
+  setbuf(stderr, NULL);
+  return FALSE;
 }
 
 
 bool flush_error_log()
 {
-  bool result=0;
+  bool result= 0;
   if (opt_error_log)
   {
-    char err_renamed[FN_REFLEN], *end;
-    end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
-    strmov(end, "-old");
     mysql_mutex_lock(&LOCK_error_log);
-#ifdef __WIN__
-    char err_temp[FN_REFLEN+5];
-    /*
-     On Windows is necessary a temporary file for to rename
-     the current error file.
-    */
-    strxmov(err_temp, err_renamed,"-tmp",NullS);
-    my_delete(err_temp, MYF(0));
-    if (freopen(err_temp,"a+",stdout))
-    {
-      int fd;
-      size_t bytes;
-      uchar buf[IO_SIZE];
-
-      freopen(err_temp,"a+",stderr);
-      setbuf(stderr, NULL);
-      my_delete(err_renamed, MYF(0));
-      my_rename(log_error_file, err_renamed, MYF(0));
-      redirect_std_streams(log_error_file);
-
-      if ((fd= my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
-      {
-        while ((bytes= mysql_file_read(fd, buf, IO_SIZE, MYF(0))) &&
-               bytes != MY_FILE_ERROR)
-          my_fwrite(stderr, buf, bytes, MYF(0));
-        mysql_file_close(fd, MYF(0));
-      }
-      my_delete(err_temp, MYF(0));
-    }
-    else
-     result= 1;
-#else
-   my_rename(log_error_file, err_renamed, MYF(0));
-   if (redirect_std_streams(log_error_file))
-     result= 1;
-#endif
+    if (redirect_std_streams(log_error_file))
+      result= 1;
     mysql_mutex_unlock(&LOCK_error_log);
   }
-   return result;
+  return result;
 }
 
 void MYSQL_BIN_LOG::signal_update()

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-08-25 19:00:38 +0000
+++ b/sql/mysqld.cc	2010-08-30 14:07:40 +0000
@@ -64,7 +64,9 @@
 #include "events.h"
 #include "sql_audit.h"
 #include "probes_mysql.h"
+#include "scheduler.h"
 #include "debug_sync.h"
+#include "sql_callback.h"
 
 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
 #include "../storage/perfschema/pfs_server.h"
@@ -193,6 +195,9 @@ typedef fp_except fp_except_t;
 # endif
 #endif
 
+extern "C" my_bool reopen_fstreams(const char *filename,
+                                   FILE *outstream, FILE *errstream);
+
 inline void setup_fpu()
 {
 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
@@ -456,7 +461,7 @@ ulong slave_trans_retries;
 uint  slave_net_timeout;
 ulong slave_exec_mode_options;
 ulonglong slave_type_conversions_options;
-ulong thread_cache_size=0, thread_pool_size= 0;
+ulong thread_cache_size=0;
 ulong binlog_cache_size=0;
 ulonglong  max_binlog_cache_size=0;
 ulong query_cache_size=0;
@@ -898,8 +903,6 @@ my_bool opt_enable_shared_memory;
 HANDLE smem_event_connect_request= 0;
 #endif
 
-scheduler_functions thread_scheduler;
-
 my_bool opt_use_ssl  = 0;
 char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
      *opt_ssl_cipher= NULL, *opt_ssl_key= NULL;
@@ -1087,7 +1090,8 @@ static void close_connections(void)
       continue;
 
     tmp->killed= THD::KILL_CONNECTION;
-    thread_scheduler.post_kill_notification(tmp);
+    MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
+    mysql_mutex_lock(&tmp->LOCK_thd_data);
     if (tmp->mysys_var)
     {
       tmp->mysys_var->abort=1;
@@ -1100,6 +1104,7 @@ static void close_connections(void)
       }
       mysql_mutex_unlock(&tmp->mysys_var->mutex);
     }
+    mysql_mutex_unlock(&tmp->LOCK_thd_data);
   }
   mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
 
@@ -1479,7 +1484,7 @@ void clean_up(bool print_message)
   if (print_message && my_default_lc_messages && server_start_time)
     sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
   cleanup_errmsgs();
-  thread_scheduler.end();
+  MYSQL_CALLBACK(thread_scheduler, end, ());
   finish_client_errs();
   DBUG_PRINT("quit", ("Error messages freed"));
   /* Tell main we are ready */
@@ -1752,7 +1757,7 @@ static void network_init(void)
   DBUG_ENTER("network_init");
   LINT_INIT(ret);
 
-  if (thread_scheduler.init())
+  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
     unireg_abort(1);			/* purecov: inspected */
 
   set_ports();
@@ -2000,7 +2005,7 @@ extern "C" sig_handler end_thread_signal
   if (thd && ! thd->bootstrap)
   {
     statistic_increment(killed_threads, &LOCK_status);
-    thread_scheduler.end_thread(thd,0);		/* purecov: inspected */
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd,0)); /* purecov: inspected */
   }
   DBUG_VOID_RETURN;				/* purecov: deadcode */
 }
@@ -2396,7 +2401,7 @@ and this may fail.\n\n");
           (ulong) dflt_key_cache->key_cache_mem_size);
   fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
   fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
-  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
+  fprintf(stderr, "max_threads=%u\n", thread_scheduler->max_threads);
   fprintf(stderr, "thread_count=%u\n", thread_count);
   fprintf(stderr, "connection_count=%u\n", connection_count);
   fprintf(stderr, "It is possible that mysqld could use up to \n\
@@ -2404,7 +2409,7 @@ key_buffer_size + (read_buffer_size + so
 bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
 		     (global_system_variables.read_buff_size +
 		      global_system_variables.sortbuff_size) *
-		     thread_scheduler.max_threads +
+		     thread_scheduler->max_threads +
                      max_connections * sizeof(THD)) / 1024);
   fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
 
@@ -2651,7 +2656,7 @@ pthread_handler_t signal_hand(void *arg
     This should actually be '+ max_number_of_slaves' instead of +10,
     but the +10 should be quite safe.
   */
-  init_thr_alarm(thread_scheduler.max_threads +
+  init_thr_alarm(thread_scheduler->max_threads +
 		 global_system_variables.max_insert_delayed_threads + 10);
   if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
   {
@@ -3738,13 +3743,15 @@ static int init_server_components()
       opt_error_log= 0;                         // Too long file name
     else
     {
+      my_bool res;
 #ifndef EMBEDDED_LIBRARY
-      if (freopen(log_error_file, "a+", stdout))
+      res= reopen_fstreams(log_error_file, stdout, stderr);
+#else
+      res= reopen_fstreams(log_error_file, NULL, stderr);
 #endif
-      {
-        if (freopen(log_error_file, "a+", stderr))
-          setbuf(stderr, NULL);
-      }
+
+      if (!res)
+        setbuf(stderr, NULL);
     }
   }
 
@@ -4353,23 +4360,6 @@ int mysqld_main(int argc, char **argv)
   }
 #endif
 
-#ifdef	__WIN__
-  /*
-    Before performing any socket operation (like retrieving hostname
-    in init_common_variables we have to call WSAStartup
-  */
-  {
-    WSADATA WsaData;
-    if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
-    {
-      /* errors are not read yet, so we use english text here */
-      my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
-      /* Not enough initializations for unireg_abort() */
-      return 1;
-    }
-  }
-#endif /* __WIN__ */
-
   if (init_common_variables())
     unireg_abort(1);				// Will do exit
 
@@ -4457,8 +4447,8 @@ int mysqld_main(int argc, char **argv)
 #ifdef __WIN__
   if (!opt_console)
   {
-    freopen(log_error_file,"a+",stdout);
-    freopen(log_error_file,"a+",stderr);
+    if (reopen_fstreams(log_error_file, stdout, stderr))
+      unireg_abort(1);
     setbuf(stderr, NULL);
     FreeConsole();				// Remove window
   }
@@ -5028,7 +5018,7 @@ static void create_new_thread(THD *thd)
 
   thread_count++;
 
-  thread_scheduler.add_connection(thd);
+  MYSQL_CALLBACK(thread_scheduler, add_connection, (thd));
 
   DBUG_VOID_RETURN;
 }
@@ -7344,14 +7334,12 @@ static int get_options(int *argc_ptr, ch
     return 1;
 
 #ifdef EMBEDDED_LIBRARY
-  one_thread_scheduler(&thread_scheduler);
+  one_thread_scheduler();
 #else
   if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
-    one_thread_per_connection_scheduler(&thread_scheduler);
-  else if (thread_handling == SCHEDULER_NO_THREADS)
-    one_thread_scheduler(&thread_scheduler);
-  else
-    pool_of_threads_scheduler(&thread_scheduler);  /* purecov: tested */
+    one_thread_per_connection_scheduler();
+  else                  /* thread_handling == SCHEDULER_NO_THREADS) */
+    one_thread_scheduler();
 #endif
 
   global_system_variables.engine_condition_pushdown=

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2010-08-18 11:29:04 +0000
+++ b/sql/mysqld.h	2010-08-30 14:07:40 +0000
@@ -28,7 +28,7 @@ class THD;
 struct handlerton;
 class Time_zone;
 
-class scheduler_functions;
+struct scheduler_functions;
 
 typedef struct st_mysql_const_lex_string LEX_CSTRING;
 typedef struct st_mysql_show_var SHOW_VAR;
@@ -175,7 +175,7 @@ extern ulong binlog_cache_size, open_fil
 extern ulonglong max_binlog_cache_size;
 extern ulong max_binlog_size, max_relay_log_size;
 extern ulong opt_binlog_rows_event_max_size;
-extern ulong rpl_recovery_rank, thread_cache_size, thread_pool_size;
+extern ulong rpl_recovery_rank, thread_cache_size;
 extern ulong back_log;
 extern char language[FN_REFLEN];
 extern ulong server_id, concurrency;
@@ -207,7 +207,7 @@ extern my_bool old_mode;
 extern LEX_STRING opt_init_connect, opt_init_slave;
 extern int bootstrap_error;
 extern I_List<THD> threads;
-extern scheduler_functions thread_scheduler;
+extern char err_shared_dir[];
 extern TYPELIB thread_handling_typelib;
 extern my_decimal decimal_zero;
 

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2010-07-15 13:47:50 +0000
+++ b/sql/opt_range.cc	2010-08-26 12:35:38 +0000
@@ -5620,7 +5620,11 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_P
         SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
                                     field_item, (Item*)(intptr)i, inv);
         if (inv)
+        {
           tree= !tree ? tmp : tree_or(param, tree, tmp);
+          if (tree == NULL)
+            break;
+        }
         else 
           tree= tree_and(param, tree, tmp);
       }

=== modified file 'sql/scheduler.cc'
--- a/sql/scheduler.cc	2010-03-31 14:05:33 +0000
+++ b/sql/scheduler.cc	2010-06-15 07:44:26 +0000
@@ -25,55 +25,103 @@
 #include "unireg.h"                    // REQUIRED: for other includes
 #include "scheduler.h"
 #include "sql_connect.h"         // init_new_connection_handler_thread
+#include "scheduler.h"
+#include "sql_callback.h"
 
 /*
-  'Dummy' functions to be used when we don't need any handling for a scheduler
-  event
- */
+  End connection, in case when we are using 'no-threads'
+*/
 
-static bool init_dummy(void) {return 0;}
-static void post_kill_dummy(THD* thd) {}  
-static void end_dummy(void) {}
-static bool end_thread_dummy(THD *thd, bool cache_thread) { return 0; }
+static bool no_threads_end(THD *thd, bool put_in_cache)
+{
+  unlink_thd(thd);
+  mysql_mutex_unlock(&LOCK_thread_count);
+  return 1;                                     // Abort handle_one_connection
+}
 
-/*
-  Initialize default scheduler with dummy functions so that setup functions
-  only need to declare those that are relvant for their usage
+static scheduler_functions one_thread_scheduler_functions=
+{
+  1,                                     // max_threads
+  NULL,                                  // init
+  init_new_connection_handler_thread,    // init_new_connection_thread
+#ifndef EMBEDDED_LIBRARY
+  handle_connection_in_main_thread,      // add_connection
+#else
+  NULL,                                  // add_connection
+#endif // EMBEDDED_LIBRARY
+  NULL,                                  // thd_wait_begin
+  NULL,                                  // thd_wait_end
+  NULL,                                  // post_kill_notification
+  no_threads_end,                        // end_thread
+  NULL,                                  // end
+};
+
+#ifndef EMBEDDED_LIBRARY
+static scheduler_functions one_thread_per_connection_scheduler_functions=
+{
+  0,                                     // max_threads
+  NULL,                                  // init
+  init_new_connection_handler_thread,    // init_new_connection_thread
+  create_thread_to_handle_connection,    // add_connection
+  NULL,                                  // thd_wait_begin
+  NULL,                                  // thd_wait_end
+  NULL,                                  // post_kill_notification
+  one_thread_per_connection_end,         // end_thread
+  NULL,                                  // end
+};
+#endif  // EMBEDDED_LIBRARY
+
+
+scheduler_functions *thread_scheduler= NULL;
+
+/** @internal
+  Helper functions to allow mysys to call the thread scheduler when
+  waiting for locks.
 */
 
-scheduler_functions::scheduler_functions()
-  :init(init_dummy),
-   init_new_connection_thread(init_new_connection_handler_thread),
-   add_connection(0),                           // Must be defined
-   post_kill_notification(post_kill_dummy),
-   end_thread(end_thread_dummy), end(end_dummy)
-{}
+/**@{*/
+static void scheduler_wait_begin(void) {
+  MYSQL_CALLBACK(thread_scheduler,
+                 thd_wait_begin, (current_thd, THD_WAIT_ROW_TABLE_LOCK));
+}
+
+static void scheduler_wait_end(void) {
+  MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd));
+}
+/**@}*/
 
+/**
+  Common scheduler init function.
+
+  The scheduler is either initialized by calling
+  one_thread_scheduler() or one_thread_per_connection_scheduler() in
+  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);
+}
 
 /*
-  End connection, in case when we are using 'no-threads'
+  Initialize scheduler for --thread-handling=one-thread-per-connection
 */
 
-static bool no_threads_end(THD *thd, bool put_in_cache)
+#ifndef EMBEDDED_LIBRARY
+void one_thread_per_connection_scheduler()
 {
-  unlink_thd(thd);
-  mysql_mutex_unlock(&LOCK_thread_count);
-  return 1;                                     // Abort handle_one_connection
+  scheduler_init();
+  one_thread_per_connection_scheduler_functions.max_threads= max_connections;
+  thread_scheduler= &one_thread_per_connection_scheduler_functions;
 }
-
+#endif
 
 /*
   Initailize scheduler for --thread-handling=no-threads
 */
 
-void one_thread_scheduler(scheduler_functions* func)
+void one_thread_scheduler()
 {
-  func->max_threads= 1;
-#ifndef EMBEDDED_LIBRARY
-  func->add_connection= handle_connection_in_main_thread;
-#endif
-  func->init_new_connection_thread= init_dummy;
-  func->end_thread= no_threads_end;
+  scheduler_init();
+  thread_scheduler= &one_thread_scheduler_functions;
 }
 
 
@@ -81,11 +129,58 @@ void one_thread_scheduler(scheduler_func
   Initialize scheduler for --thread-handling=one-thread-per-connection
 */
 
-#ifndef EMBEDDED_LIBRARY
-void one_thread_per_connection_scheduler(scheduler_functions* func)
+/*
+  thd_scheduler keeps the link between THD and events.
+  It's embedded in the THD class.
+*/
+
+thd_scheduler::thd_scheduler()
+  : m_psi(NULL), data(NULL)
+{
+#ifndef DBUG_OFF
+  dbug_explain[0]= '\0';
+  set_explain= FALSE;
+#endif
+}
+
+
+thd_scheduler::~thd_scheduler()
+{
+}
+
+static scheduler_functions *saved_thread_scheduler;
+static uint saved_thread_handling;
+
+extern "C"
+int my_thread_scheduler_set(scheduler_functions *scheduler)
+{
+  DBUG_ASSERT(scheduler != 0);
+
+  if (scheduler == NULL)
+    return 1;
+
+  saved_thread_scheduler= thread_scheduler;
+  saved_thread_handling= thread_handling;
+  thread_scheduler= scheduler;
+  // Scheduler loaded dynamically
+  thread_handling= SCHEDULER_TYPES_COUNT;
+  return 0;
+}
+
+
+extern "C"
+int my_thread_scheduler_reset()
 {
-  func->max_threads= max_connections;
-  func->add_connection= create_thread_to_handle_connection;
-  func->end_thread= one_thread_per_connection_end;
+  DBUG_ASSERT(saved_thread_scheduler != NULL);
+
+  if (saved_thread_scheduler == NULL)
+    return 1;
+
+  thread_scheduler= saved_thread_scheduler;
+  thread_handling= saved_thread_handling;
+  saved_thread_scheduler= 0;
+  return 0;
 }
-#endif /* EMBEDDED_LIBRARY */
+
+
+

=== modified file 'sql/scheduler.h'
--- a/sql/scheduler.h	2009-09-23 21:32:31 +0000
+++ b/sql/scheduler.h	2010-06-07 14:01:39 +0000
@@ -28,38 +28,77 @@ class THD;
 
 /* Functions used when manipulating threads */
 
-class scheduler_functions
+struct scheduler_functions
 {
-public:
   uint max_threads;
   bool (*init)(void);
   bool (*init_new_connection_thread)(void);
   void (*add_connection)(THD *thd);
+  void (*thd_wait_begin)(THD *thd, int wait_type);
+  void (*thd_wait_end)(THD *thd);
   void (*post_kill_notification)(THD *thd);
   bool (*end_thread)(THD *thd, bool cache_thread);
   void (*end)(void);
-  scheduler_functions();
 };
 
+
+/**
+  Scheduler types enumeration.
+
+  The default of --thread-handling is the first one in the
+  thread_handling_names array, this array has to be consistent with
+  the order in this array, so to change default one has to change the
+  first entry in this enum and the first entry in the
+  thread_handling_names array.
+
+  @note The last entry of the enumeration is also used to mark the
+  thread handling as dynamic. In this case the name of the thread
+  handling is fetched from the name of the plugin that implements it.
+*/
 enum scheduler_types
 {
   SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
   SCHEDULER_NO_THREADS,
-  SCHEDULER_POOL_OF_THREADS
+  SCHEDULER_TYPES_COUNT
 };
 
-void one_thread_per_connection_scheduler(scheduler_functions* func);
-void one_thread_scheduler(scheduler_functions* func);
+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
 };
 
-#define HAVE_POOL_OF_THREADS 0                  /* For easyer tests */
-#define pool_of_threads_scheduler(A) one_thread_per_connection_scheduler(A)
-
+/*
+ To be used for pool-of-threads (implemeneted differently on various OSs)
+*/
 class thd_scheduler
-{};
+{
+public:
+  /*
+    Thread instrumentation for the user job.
+    This member holds the instrumentation while the user job is not run
+    by a thread.
+
+    Note that this member is not conditionally declared
+    (ifdef HAVE_PSI_INTERFACE), because doing so will change the binary
+    layout of THD, which is exposed to plugin code that may be compiled
+    differently.
+  */
+  PSI_thread *m_psi;
+
+  void *data;                  /* scheduler-specific data structure */
+
+#  ifndef DBUG_OFF
+  char dbug_explain[512];
+  bool set_explain;
+#  endif
+
+  thd_scheduler();
+  ~thd_scheduler();
+};
+
+extern scheduler_functions *thread_scheduler;
 
-#endif /* SCHEDULER_INCLUDED */
+#endif

=== added file 'sql/sql_callback.h'
--- a/sql/sql_callback.h	1970-01-01 00:00:00 +0000
+++ b/sql/sql_callback.h	2010-06-07 14:01:39 +0000
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2010, 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 SQL_CALLBACK_INCLUDED
+#define SQL_CALLBACK_INCLUDED
+
+/**
+   Macro used for an internal callback.
+
+   The macro will check that the object exists and that the function
+   is defined. If that is the case, it will call the function with the
+   given parameters.
+
+   If the object or the function is not defined, the callback will be
+   considered successful (nothing needed to be done) and will
+   therefore return no error.
+ */
+
+#define MYSQL_CALLBACK(OBJ, FUNC, PARAMS)         \
+  do {                                            \
+    if ((OBJ) && ((OBJ)->FUNC))                   \
+      (OBJ)->FUNC PARAMS;                         \
+  } while (0)
+
+#define MYSQL_CALLBACK_ELSE(OBJ, FUNC, PARAMS, ELSE)    \
+  (((OBJ) && ((OBJ)->FUNC)) ? (OBJ)->FUNC PARAMS : (ELSE))
+
+
+#endif /* SQL_CALLBACK_INCLUDED */

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-08-20 02:59:58 +0000
+++ b/sql/sql_class.cc	2010-08-30 14:07:40 +0000
@@ -57,6 +57,7 @@
 #include "transaction.h"
 #include "debug_sync.h"
 #include "sql_parse.h"                          // is_update_query
+#include "sql_callback.h"
 
 /*
   The following is used to initialise Table_ident with a internal
@@ -1075,6 +1076,7 @@ THD::~THD()
   DBUG_ENTER("~THD()");
   /* Ensure that no one is using THD */
   mysql_mutex_lock(&LOCK_thd_data);
+  mysys_var=0;					// Safety (shouldn't be needed)
   mysql_mutex_unlock(&LOCK_thd_data);
   add_to_status(&global_status_var, &status_var);
 
@@ -1100,7 +1102,6 @@ THD::~THD()
   my_free(db);
   db= NULL;
   free_root(&transaction.mem_root,MYF(0));
-  mysys_var=0;					// Safety (shouldn't be needed)
   mysql_mutex_destroy(&LOCK_thd_data);
 #ifndef DBUG_OFF
   dbug_sentry= THD_SENTRY_GONE;
@@ -1189,7 +1190,7 @@ void THD::awake(THD::killed_state state_
   {
     thr_alarm_kill(thread_id);
     if (!slave_thread)
-      thread_scheduler.post_kill_notification(this);
+      MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
 #ifdef SIGNAL_WITH_VIO_CLOSE
     if (this != current_thd)
     {
@@ -1258,6 +1259,15 @@ bool THD::store_globals()
   if (my_pthread_setspecific_ptr(THR_THD,  this) ||
       my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
     return 1;
+  /*
+    mysys_var is concurrently readable by a killer thread.
+    It is protected by LOCK_thd_data, it is not needed to lock while the
+    pointer is changing from NULL not non-NULL. If the kill thread reads
+    NULL it doesn't refer to anything, but if it is non-NULL we need to
+    ensure that the thread doesn't proceed to assign another thread to
+    have the mysys_var reference (which in fact refers to the worker
+    threads local storage with key THR_KEY_mysys. 
+  */
   mysys_var=my_thread_var;
   /*
     Let mysqld define the thread id (not mysys)
@@ -3187,6 +3197,60 @@ extern "C" bool thd_sqlcom_can_generate_
 {
   return sqlcom_can_generate_row_events(thd);
 }
+
+#ifndef EMBEDDED_LIBRARY
+extern "C" void thd_pool_wait_begin(MYSQL_THD thd, int wait_type);
+extern "C" void thd_pool_wait_end(MYSQL_THD thd);
+
+/*
+  Interface for MySQL Server, plugins and storage engines to report
+  when they are going to sleep/stall.
+  
+  SYNOPSIS
+  thd_wait_begin()
+  thd                     Thread object
+  wait_type               Type of wait
+                          1 -- short wait (e.g. for mutex)
+                          2 -- medium wait (e.g. for disk io)
+                          3 -- large wait (e.g. for locked row/table)
+  NOTES
+    This is used by the threadpool to have better knowledge of which
+    threads that currently are actively running on CPUs. When a thread
+    reports that it's going to sleep/stall, the threadpool scheduler is
+    free to start another thread in the pool most likely. The expected wait
+    time is simply an indication of how long the wait is expected to
+    become, the real wait time could be very different.
+
+  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)
+{
+  MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type));
+}
+
+/**
+  Interface for MySQL Server, plugins and storage engines to report
+  when they waking up from a sleep/stall.
+
+  @param  thd   Thread handle
+*/
+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)
+{
+  /* do NOTHING for the embedded library */
+  return;
+}
+
+extern "C" void thd_wait_end(MYSQL_THD thd)
+{
+  /* do NOTHING for the embedded library */
+  return;
+}
+#endif
 #endif // INNODB_COMPATIBILITY_HOOKS */
 
 /****************************************************************************
@@ -3370,6 +3434,13 @@ void THD::set_query_id(query_id_t new_qu
   mysql_mutex_unlock(&LOCK_thd_data);
 }
 
+/** Assign a new value to thd->mysys_var.  */
+void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
+{
+  mysql_mutex_lock(&LOCK_thd_data);
+  mysys_var= new_mysys_var;
+  mysql_mutex_unlock(&LOCK_thd_data);
+}
 
 /**
   Leave explicit LOCK TABLES or prelocked mode and restore value of

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-08-25 10:22:34 +0000
+++ b/sql/sql_class.h	2010-08-30 14:07:40 +0000
@@ -1634,6 +1634,10 @@ public:
         xid_state.xid.null();
       free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
     }
+    my_bool is_active()
+    {
+      return (all.ha_list != NULL);
+    }
     st_transactions()
     {
       bzero((char*)this, sizeof(*this));
@@ -2664,7 +2668,7 @@ public:
   virtual void set_statement(Statement *stmt);
 
   /**
-    Assign a new value to thd->query and thd->query_id.
+    Assign a new value to thd->query and thd->query_id and mysys_var.
     Protected with LOCK_thd_data mutex.
   */
   void set_query(char *query_arg, uint32 query_length_arg);
@@ -2677,6 +2681,7 @@ public:
     open_tables= open_tables_arg;
     mysql_mutex_unlock(&LOCK_thd_data);
   }
+  void set_mysys_var(struct st_my_thread_var *new_mysys_var);
   void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
   {
     DBUG_ASSERT(locked_tables_mode == LTM_NONE);

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2010-08-05 12:53:09 +0000
+++ b/sql/sql_connect.cc	2010-08-16 12:50:27 +0000
@@ -35,6 +35,7 @@
 #include "hostname.h" // inc_host_errors, ip_to_hostname,
                       // reset_host_errors
 #include "sql_acl.h"  // acl_getroot, NO_ACCESS, SUPER_ACL
+#include "sql_callback.h"
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
 /*
@@ -966,7 +967,7 @@ bool setup_connection_thread_globals(THD
   {
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
     statistic_increment(aborted_connects,&LOCK_status);
-    thread_scheduler.end_thread(thd, 0);
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
     return 1;                                   // Error
   }
   return 0;
@@ -989,7 +990,7 @@ bool setup_connection_thread_globals(THD
 */
 
 
-static bool login_connection(THD *thd)
+bool login_connection(THD *thd)
 {
   NET *net= &thd->net;
   int error;
@@ -1027,7 +1028,7 @@ static bool login_connection(THD *thd)
     This mainly updates status variables
 */
 
-static void end_connection(THD *thd)
+void end_connection(THD *thd)
 {
   NET *net= &thd->net;
   plugin_thdvar_cleanup(thd);
@@ -1068,7 +1069,7 @@ static void end_connection(THD *thd)
   Initialize THD to handle queries
 */
 
-static void prepare_new_connection_state(THD* thd)
+void prepare_new_connection_state(THD* thd)
 {
   Security_context *sctx= thd->security_ctx;
 
@@ -1137,11 +1138,11 @@ void do_handle_one_connection(THD *thd_a
 
   thd->thr_create_utime= my_micro_time();
 
-  if (thread_scheduler.init_new_connection_thread())
+  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
   {
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
     statistic_increment(aborted_connects,&LOCK_status);
-    thread_scheduler.end_thread(thd,0);
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
     return;
   }
 
@@ -1195,7 +1196,7 @@ void do_handle_one_connection(THD *thd_a
    
 end_thread:
     close_connection(thd, 0, 1);
-    if (thread_scheduler.end_thread(thd,1))
+    if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0))
       return;                                 // Probably no-threads
 
     /*

=== modified file 'sql/sql_connect.h'
--- a/sql/sql_connect.h	2010-03-31 14:05:33 +0000
+++ b/sql/sql_connect.h	2010-06-07 14:01:39 +0000
@@ -40,4 +40,8 @@ int check_user(THD *thd, enum enum_serve
 	       const char *passwd, uint passwd_len, const char *db,
 	       bool check_count);
 
+bool login_connection(THD *thd);
+void prepare_new_connection_state(THD* thd);
+void end_connection(THD *thd);
+
 #endif /* SQL_CONNECT_INCLUDED */

=== modified file 'sql/sql_plugin_services.h'
--- a/sql/sql_plugin_services.h	2009-11-02 20:05:42 +0000
+++ b/sql/sql_plugin_services.h	2010-06-07 14:01:39 +0000
@@ -36,9 +36,23 @@ static struct thd_alloc_service_st thd_a
   thd_make_lex_string
 };
 
+static struct thd_wait_service_st thd_wait_handler= {
+  thd_wait_begin,
+  thd_wait_end
+};
+
+static struct my_thread_scheduler_service my_thread_scheduler_handler= {
+  my_thread_scheduler_set,
+  my_thread_scheduler_reset,
+};
+
+
 static struct st_service_ref list_of_services[]=
 {
   { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
-  { "thd_alloc_service",   VERSION_thd_alloc,   &thd_alloc_handler }
+  { "thd_alloc_service",   VERSION_thd_alloc,   &thd_alloc_handler },
+  { "thd_wait_service",    VERSION_thd_wait,    &thd_wait_handler },
+  { "my_thread_scheduler_service",
+    VERSION_my_thread_scheduler, &my_thread_scheduler_handler },
 };
 

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-08-17 12:12:52 +0000
+++ b/sql/sql_select.cc	2010-08-27 11:33:32 +0000
@@ -13243,6 +13243,34 @@ ok:
 }
 
 
+/**
+  Find shortest key suitable for full table scan.
+
+  @param table                 Table to scan
+  @param usable_keys           Allowed keys
+
+  @note
+     As far as 
+     1) clustered primary key entry data set is a set of all record
+        fields (key fields and not key fields) and
+     2) secondary index entry data is a union of its key fields and
+        primary key fields (at least InnoDB and its derivatives don't
+        duplicate primary key fields there, even if the primary and
+        the secondary keys have a common subset of key fields),
+     then secondary index entry data is always a subset of primary key entry.
+     Unfortunately, key_info[nr].key_length doesn't show the length
+     of key/pointer pair but a sum of key field lengths only, thus
+     we can't estimate index IO volume comparing only this key_length
+     value of secondary keys and clustered PK.
+     So, try secondary keys first, and choose PK only if there are no
+     usable secondary covering keys or found best secondary key include
+     all table fields (i.e. same as PK):
+
+  @return
+    MAX_KEY     no suitable key found
+    key index   otherwise
+*/
+
 uint find_shortest_key(TABLE *table, const key_map *usable_keys)
 {
   uint best= MAX_KEY;
@@ -13255,23 +13283,6 @@ uint find_shortest_key(TABLE *table, con
     uint min_length= (uint) ~0;
     for (uint nr=0; nr < table->s->keys ; nr++)
     {
-      /*
-       As far as 
-       1) clustered primary key entry data set is a set of all record
-          fields (key fields and not key fields) and
-       2) secondary index entry data is a union of its key fields and
-          primary key fields (at least InnoDB and its derivatives don't
-          duplicate primary key fields there, even if the primary and
-          the secondary keys have a common subset of key fields),
-       then secondary index entry data is always a subset of primary key
-       entry, and the PK is always longer.
-       Unfortunately, key_info[nr].key_length doesn't show the length
-       of key/pointer pair but a sum of key field lengths only, thus
-       we can't estimate index IO volume comparing only this key_length
-       value of seconday keys and clustered PK.
-       So, try secondary keys first, and choose PK only if there are no
-       usable secondary covering keys:
-      */
       if (nr == usable_clustered_pk)
         continue;
       if (usable_keys->is_set(nr))
@@ -13284,7 +13295,20 @@ uint find_shortest_key(TABLE *table, con
       }
     }
   }
-  return best != MAX_KEY ? best : usable_clustered_pk;
+  if (usable_clustered_pk != MAX_KEY)
+  {
+    /*
+     If the primary key is clustered and found shorter key covers all table
+     fields then primary key scan normally would be faster because amount of
+     data to scan is the same but PK is clustered.
+     It's safe to compare key parts with table fields since duplicate key
+     parts aren't allowed.
+     */
+    if (best == MAX_KEY ||
+        table->key_info[best].key_parts >= table->s->fields)
+      best= usable_clustered_pk;
+  }
+  return best;
 }
 
 /**

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2010-08-18 11:29:04 +0000
+++ b/sql/sql_show.cc	2010-08-30 14:07:40 +0000
@@ -1815,6 +1815,7 @@ void mysqld_list_processes(THD *thd,cons
         if ((thd_info->db=tmp->db))             // Safe test
           thd_info->db=thd->strdup(thd_info->db);
         thd_info->command=(int) tmp->command;
+        mysql_mutex_lock(&tmp->LOCK_thd_data);
         if ((mysys_var= tmp->mysys_var))
           mysql_mutex_lock(&mysys_var->mutex);
         thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
@@ -1822,16 +1823,15 @@ void mysqld_list_processes(THD *thd,cons
         if (mysys_var)
           mysql_mutex_unlock(&mysys_var->mutex);
 
-        thd_info->start_time= tmp->start_time;
         thd_info->query=0;
         /* Lock THD mutex that protects its data when looking at it. */
-        mysql_mutex_lock(&tmp->LOCK_thd_data);
         if (tmp->query())
         {
           uint length= min(max_query_length, tmp->query_length());
           thd_info->query= (char*) thd->strmake(tmp->query(),length);
         }
         mysql_mutex_unlock(&tmp->LOCK_thd_data);
+        thd_info->start_time= tmp->start_time;
         thread_infos.append(thd_info);
       }
     }
@@ -1918,6 +1918,7 @@ int fill_schema_processlist(THD* thd, TA
         table->field[3]->set_notnull();
       }
 
+      mysql_mutex_lock(&tmp->LOCK_thd_data);
       if ((mysys_var= tmp->mysys_var))
         mysql_mutex_lock(&mysys_var->mutex);
       /* COMMAND */
@@ -1938,6 +1939,7 @@ int fill_schema_processlist(THD* thd, TA
 
       if (mysys_var)
         mysql_mutex_unlock(&mysys_var->mutex);
+      mysql_mutex_unlock(&tmp->LOCK_thd_data);
 
       /* INFO */
       /* Lock THD mutex that protects its data when looking at it. */
@@ -7490,13 +7492,16 @@ int finalize_schema_table(st_plugin_int
   ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
   DBUG_ENTER("finalize_schema_table");
 
-  if (schema_table && plugin->plugin->deinit)
+  if (schema_table)
   {
-    DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
-    if (plugin->plugin->deinit(NULL))
+    if (plugin->plugin->deinit)
     {
-      DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
-                             plugin->name.str));
+      DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
+      if (plugin->plugin->deinit(NULL))
+      {
+        DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
+                               plugin->name.str));
+      }
     }
     my_free(schema_table);
   }

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-08-25 10:22:34 +0000
+++ b/sql/sql_yacc.yy	2010-08-30 22:22:01 +0000
@@ -1425,6 +1425,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %type <table>
         table_ident table_ident_nodb references xid
+        table_ident_opt_wild
 
 %type <simple_string>
         remember_name remember_end opt_db text_or_password
@@ -10371,7 +10372,7 @@ table_alias_ref_list:
         ;
 
 table_alias_ref:
-          table_ident
+          table_ident_opt_wild
           {
             if (!Select->add_table_to_list(YYTHD, $1, NULL,
                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
@@ -12159,6 +12160,21 @@ table_ident:
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
+        ;
+
+table_ident_opt_wild:
+          ident opt_wild
+          {
+            $$= new Table_ident($1);
+            if ($$ == NULL)
+              MYSQL_YYABORT;
+          }
+        | ident '.' ident opt_wild
+          {
+            $$= new Table_ident(YYTHD, $1,$3,0);
+            if ($$ == NULL)
+              MYSQL_YYABORT;
+          }
         ;
 
 table_ident_nodb:

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-08-25 00:21:43 +0000
+++ b/sql/sys_vars.cc	2010-08-30 14:07:40 +0000
@@ -1673,19 +1673,13 @@ static Sys_var_ulong Sys_trans_prealloc_
 
 static const char *thread_handling_names[]=
 {
-  "one-thread-per-connection", "no-threads",
-#if HAVE_POOL_OF_THREADS == 1
-  "pool-of-threads",
-#endif
+  "one-thread-per-connection", "no-threads", "loaded-dynamically",
   0
 };
 static Sys_var_enum Sys_thread_handling(
        "thread_handling",
        "Define threads usage for handling queries, one of "
-       "one-thread-per-connection, no-threads"
-#if HAVE_POOL_OF_THREADS == 1
-       ", pool-of-threads"
-#endif
+       "one-thread-per-connection, no-threads, loaded-dynamically"
        , READ_ONLY GLOBAL_VAR(thread_handling), CMD_LINE(REQUIRED_ARG),
        thread_handling_names, DEFAULT(0));
 

=== modified file 'storage/innobase/buf/buf0flu.c'
--- a/storage/innobase/buf/buf0flu.c	2010-07-30 14:39:16 +0000
+++ b/storage/innobase/buf/buf0flu.c	2010-08-30 14:07:40 +0000
@@ -43,6 +43,8 @@ Created 11/11/1995 Heikki Tuuri
 #include "log0log.h"
 #include "os0file.h"
 #include "trx0sys.h"
+#include "mysql/plugin.h"
+#include "mysql/service_thd_wait.h"
 
 /**********************************************************************
 These statistics are generated for heuristics used in estimating the
@@ -1744,10 +1746,14 @@ buf_flush_wait_batch_end(
 
 			buf_pool = buf_pool_from_array(i);
 
+			thd_wait_begin(NULL, THD_WAIT_DISKIO);
 			os_event_wait(buf_pool->no_flush[type]);
+			thd_wait_end(NULL);
 		}
 	} else {
+		thd_wait_begin(NULL, THD_WAIT_DISKIO);
 		os_event_wait(buf_pool->no_flush[type]);
+		thd_wait_end(NULL);
 	}
 }
 

=== modified file 'storage/innobase/buf/buf0rea.c'
--- a/storage/innobase/buf/buf0rea.c	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/buf/buf0rea.c	2010-08-16 12:50:27 +0000
@@ -37,6 +37,8 @@ Created 11/5/1995 Heikki Tuuri
 #include "os0file.h"
 #include "srv0start.h"
 #include "srv0srv.h"
+#include "mysql/plugin.h"
+#include "mysql/service_thd_wait.h"
 
 /** The linear read-ahead area size */
 #define	BUF_READ_AHEAD_LINEAR_AREA	BUF_READ_AHEAD_AREA
@@ -135,6 +137,7 @@ buf_read_page_low(
 
 	ut_ad(buf_page_in_file(bpage));
 
+	thd_wait_begin(NULL, THD_WAIT_DISKIO);
 	if (zip_size) {
 		*err = fil_io(OS_FILE_READ | wake_later,
 			      sync, space, zip_size, offset, 0, zip_size,
@@ -146,6 +149,7 @@ buf_read_page_low(
 			      sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
 			      ((buf_block_t*) bpage)->frame, bpage);
 	}
+	thd_wait_end(NULL);
 	ut_a(*err == DB_SUCCESS);
 
 	if (sync) {

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	2010-08-17 08:19:24 +0000
+++ b/storage/innobase/srv/srv0srv.c	2010-08-30 14:07:40 +0000
@@ -84,6 +84,8 @@ Created 10/8/1995 Heikki Tuuri
 #include "ha_prototypes.h"
 #include "trx0i_s.h"
 #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#include "mysql/plugin.h"
+#include "mysql/service_thd_wait.h"
 
 /* This is set to TRUE if the MySQL user has set it in MySQL; currently
 affects only FOREIGN KEY definition parsing */
@@ -1232,7 +1234,9 @@ retry:
 
 	trx->op_info = "waiting in InnoDB queue";
 
+	thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
 	os_event_wait(slot->event);
+	thd_wait_end(trx->mysql_thd);
 
 	trx->op_info = "";
 
@@ -1597,7 +1601,9 @@ srv_suspend_mysql_thread(
 
 	/* Suspend this thread and wait for the event. */
 
+	thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
 	os_event_wait(event);
+	thd_wait_end(trx->mysql_thd);
 
 	/* After resuming, reacquire the data dictionary latch if
 	necessary. */

=== modified file 'vio/vio.c'
--- a/vio/vio.c	2010-07-08 21:20:08 +0000
+++ b/vio/vio.c	2010-08-16 12:50:27 +0000
@@ -44,6 +44,11 @@ static my_bool no_poll_read(Vio *vio __a
 
 #endif
 
+static my_bool has_no_data(Vio *vio __attribute__((unused)))
+{
+  return FALSE;
+}
+
 /*
  * Helper to fill most of the Vio* with defaults.
  */
@@ -83,6 +88,7 @@ static void vio_init(Vio* vio, enum enum
 
     vio->poll_read      =no_poll_read;
     vio->is_connected   =vio_is_connected_pipe;
+    vio->has_data       =has_no_data;
 
     vio->timeout=vio_win32_timeout;
     /* Set default timeout */
@@ -110,6 +116,7 @@ static void vio_init(Vio* vio, enum enum
 
     vio->poll_read      =no_poll_read;
     vio->is_connected   =vio_is_connected_shared_memory;
+    vio->has_data       =has_no_data;
 
     /* Currently, shared memory is on Windows only, hence the below is ok*/
     vio->timeout= vio_win32_timeout; 
@@ -137,6 +144,7 @@ static void vio_init(Vio* vio, enum enum
     vio->timeout	=vio_timeout;
     vio->poll_read      =vio_poll_read;
     vio->is_connected   =vio_is_connected;
+    vio->has_data       =vio_ssl_has_data;
     DBUG_VOID_RETURN;
   }
 #endif /* HAVE_OPENSSL */
@@ -155,6 +163,8 @@ static void vio_init(Vio* vio, enum enum
   vio->timeout          =vio_timeout;
   vio->poll_read        =vio_poll_read;
   vio->is_connected     =vio_is_connected;
+  vio->has_data=        (flags & VIO_BUFFERED_READ) ?
+                            vio_buff_has_data : has_no_data;
   DBUG_VOID_RETURN;
 }
 

=== modified file 'vio/vio_priv.h'
--- a/vio/vio_priv.h	2009-12-16 08:33:54 +0000
+++ b/vio/vio_priv.h	2010-06-07 14:01:39 +0000
@@ -49,6 +49,7 @@ int vio_close_shared_memory(Vio * vio);
 #endif
 
 void	vio_timeout(Vio *vio,uint which, uint timeout);
+my_bool vio_buff_has_data(Vio *vio);
 
 #ifdef HAVE_OPENSSL
 #include "my_net.h"			/* needed because of struct in_addr */
@@ -62,5 +63,7 @@ void vio_ssl_delete(Vio *vio);
 
 int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
 
+my_bool vio_ssl_has_data(Vio *vio);
+
 #endif /* HAVE_OPENSSL */
 #endif /* VIO_PRIV_INCLUDED */

=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c	2010-05-21 13:17:01 +0000
+++ b/vio/viosocket.c	2010-08-16 12:50:27 +0000
@@ -98,6 +98,10 @@ size_t vio_read_buff(Vio *vio, uchar* bu
 #undef VIO_UNBUFFERED_READ_MIN_SIZE
 }
 
+my_bool vio_buff_has_data(Vio *vio)
+{
+  return (vio->read_pos != vio->read_end);
+}
 
 size_t vio_write(Vio * vio, const uchar* buf, size_t size)
 {

=== modified file 'vio/viossl.c'
--- a/vio/viossl.c	2010-07-15 11:13:30 +0000
+++ b/vio/viossl.c	2010-08-16 12:50:27 +0000
@@ -244,6 +244,9 @@ int vio_ssl_blocking(Vio *vio __attribut
   return (set_blocking_mode ? 0 : 1);
 }
 
-
+my_bool vio_ssl_has_data(Vio *vio)
+{
+  return SSL_pending(vio->ssl_arg) > 0 ? TRUE : FALSE;
+}
 
 #endif /* HAVE_OPENSSL */


Attachment: [text/bzr-bundle] bzr/bjorn.munch@oracle.com-20100901135231-927op2nd3bxmmydu.bundle
Thread
bzr push into mysql-5.5-mtr branch (bjorn.munch:3084 to 3086) Bjorn Munch2 Sep