List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:October 19 2010 9:26am
Subject:bzr commit into mysql-5.5-runtime branch (jon.hauglid:3167)
View as plain text  
#At file:///export/home/x/mysql-5.5-runtime-test/ based on revid:kostja@stripped

 3167 Jon Olav Hauglid	2010-10-19 [merge]
      Merge from mysql-5.5-bugteam to mysql-5.5-runtime
      No conflicts

    added:
      mysql-test/extra/rpl_tests/rpl_stop_slave.test
      mysql-test/suite/rpl/r/rpl_stop_slave.result
      mysql-test/suite/rpl/t/rpl_stop_slave.test
    modified:
      CMakeLists.txt
      Makefile.am
      cmake/abi_check.cmake
      config/ac-macros/maintainer.m4
      configure.in
      dbug/dbug.c
      include/my_dbug.h
      include/mysql/client_plugin.h
      include/mysql/client_plugin.h.pp
      mysql-test/extra/rpl_tests/rpl_start_stop_slave.test
      mysql-test/include/mtr_warnings.sql
      mysql-test/r/grant.result
      mysql-test/r/grant3.result
      mysql-test/r/ipv4_as_ipv6.result
      mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result
      mysql-test/t/grant.test
      mysql-test/t/grant3.test
      sql/handler.cc
      sql/item_func.cc
      sql/log.cc
      sql/log_event.cc
      sql/log_event.h
      sql/rpl_rli.h
      sql/slave.cc
      sql/sp_head.cc
      sql/sql_parse.cc
      sql/sql_yacc.yy
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt	2010-09-24 13:03:17 +0000
+++ b/CMakeLists.txt	2010-10-18 17:38:32 +0000
@@ -61,6 +61,8 @@ SET(BUILDTYPE_DOCSTRING
  
 IF(WITH_DEBUG)
   SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE)
+  SET(MYSQL_MAINTAINER_MODE ON CACHE BOOL
+      "MySQL maintainer-specific development environment")
   SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE)
 ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG)
   IF(CUSTOM_C_FLAGS)

=== modified file 'Makefile.am'
--- a/Makefile.am	2010-10-04 12:42:16 +0000
+++ b/Makefile.am	2010-10-13 15:11:29 +0000
@@ -263,6 +263,8 @@ test-full-qa:
 #
 # Headers which need to be checked for abi/api compatibility.
 #
+# Attention: do not forget to also add to cmake/abi_check.cmake
+#
 
 API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin_audit.h \
 			$(top_srcdir)/include/mysql/plugin_ftparser.h \

=== modified file 'cmake/abi_check.cmake'
--- a/cmake/abi_check.cmake	2010-08-27 06:45:35 +0000
+++ b/cmake/abi_check.cmake	2010-10-13 15:11:29 +0000
@@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYS
   ELSE()
     SET(COMPILER ${CMAKE_C_COMPILER})
   ENDIF()
-  SET(API_PREPROCESSOR_HEADER 
+  SET(API_PREPROCESSOR_HEADER
     ${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h
     ${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h
     ${CMAKE_SOURCE_DIR}/include/mysql.h
-    ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h 
+    ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h
     ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h
+    ${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h
+    ${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h
   )
 
   ADD_CUSTOM_TARGET(abi_check ALL

=== modified file 'config/ac-macros/maintainer.m4'
--- a/config/ac-macros/maintainer.m4	2010-09-24 12:36:31 +0000
+++ b/config/ac-macros/maintainer.m4	2010-10-18 16:27:10 +0000
@@ -8,7 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [
     [AS_HELP_STRING([--enable-mysql-maintainer-mode],
                     [Enable a MySQL maintainer-specific development environment])],
     [USE_MYSQL_MAINTAINER_MODE=$enableval],
-    [USE_MYSQL_MAINTAINER_MODE=no])
+    [AS_IF([test "$with_debug" != "no"],
+      [USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])])
   AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE])
 ])
 

=== modified file 'configure.in'
--- a/configure.in	2010-10-07 14:34:42 +0000
+++ b/configure.in	2010-10-18 17:38:32 +0000
@@ -27,7 +27,7 @@ dnl
 dnl When changing the major version number please also check the switch
 dnl statement in mysqlbinlog::check_master_version().  You may also need
 dnl to update version.c in ndb.
-AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql])
+AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql])
 
 AC_CONFIG_SRCDIR([sql/mysqld.cc])
 AC_CANONICAL_SYSTEM
@@ -118,6 +118,13 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION)
 AC_SUBST(SHARED_LIB_VERSION)
 AC_SUBST(AVAILABLE_LANGUAGES)
 
+# Check whether a debug mode should be enabled.
+AC_ARG_WITH([debug],
+    AS_HELP_STRING([--with-debug@<:@=full@:>@],
+      [Enable various amounts of debugging support (full adds a slow memory checker).]),
+    [with_debug=$withval],
+    [with_debug=no])
+
 # Whether the maintainer mode should be enabled.
 MY_MAINTAINER_MODE
 
@@ -1689,10 +1696,6 @@ then
   DEBUG_OPTIMIZE_CXX=""
 fi
 
-AC_ARG_WITH(debug,
-    [AS_HELP_STRING([--with-debug], [Add debug code @<:@default=no@:>@])],
-    [with_debug=$withval],
-    [with_debug=no])
 if test "$with_debug" = "yes"
 then
   AC_DEFINE([DBUG_ON], [1], [Use libdbug])

=== modified file 'dbug/dbug.c'
--- a/dbug/dbug.c	2010-10-01 20:12:27 +0000
+++ b/dbug/dbug.c	2010-10-19 08:30:26 +0000
@@ -905,6 +905,7 @@ void _db_set_init_(const char *control)
   CODE_STATE tmp_cs;
   bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
   tmp_cs.stack= &init_settings;
+  tmp_cs.process= db_process ? db_process : "dbug";
   DbugParse(&tmp_cs, control);
 }
 
@@ -2370,7 +2371,7 @@ static void DbugFlush(CODE_STATE *cs)
 
 void _db_flush_()
 {
-  CODE_STATE *cs;
+  CODE_STATE *cs= NULL;
   get_code_state_or_return;
   (void) fflush(cs->stack->out_file);
 }

=== modified file 'include/my_dbug.h'
--- a/include/my_dbug.h	2010-07-15 11:16:06 +0000
+++ b/include/my_dbug.h	2010-10-18 11:27:52 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -13,8 +13,18 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-#ifndef _dbug_h
-#define _dbug_h
+#ifndef MY_DBUG_INCLUDED
+#define MY_DBUG_INCLUDED
+
+#ifndef __WIN__
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <signal.h>
+#endif  /* not __WIN__ */
 
 #ifdef  __cplusplus
 extern "C" {
@@ -111,6 +121,20 @@ extern  const char* _db_get_func_(void);
 #define DBUG_CRASH_VOID_RETURN \
   DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return")
 
+/*
+  Make the program fail, without creating a core file.
+  abort() will send SIGABRT which (most likely) generates core.
+  Use SIGKILL instead, which cannot be caught.
+  We also pause the current thread, until the signal is actually delivered.
+  An alternative would be to use _exit(EXIT_FAILURE),
+  but then valgrind would report lots of memory leaks.
+ */
+#ifdef __WIN__
+#define DBUG_SUICIDE() DBUG_ABORT()
+#else
+#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause())
+#endif
+
 #else                                           /* No debugger */
 
 #define DBUG_ENTER(a1)
@@ -139,10 +163,11 @@ extern  const char* _db_get_func_(void);
 #define DBUG_EXPLAIN_INITIAL(buf,len)
 #define DEBUGGER_OFF                    do { } while(0)
 #define DEBUGGER_ON                     do { } while(0)
-#define DBUG_ABORT()                    abort()
+#define DBUG_ABORT()                    do { } while(0)
 #define DBUG_CRASH_ENTER(func)
 #define DBUG_CRASH_RETURN(val)          do { return(val); } while(0)
 #define DBUG_CRASH_VOID_RETURN          do { return; } while(0)
+#define DBUG_SUICIDE()                  do { } while(0)
 
 #endif
 
@@ -164,4 +189,5 @@ void debug_sync_point(const char* lock_n
 #ifdef	__cplusplus
 }
 #endif
-#endif
+
+#endif /* MY_DBUG_INCLUDED */

=== modified file 'include/mysql/client_plugin.h'
--- a/include/mysql/client_plugin.h	2010-10-04 12:54:41 +0000
+++ b/include/mysql/client_plugin.h	2010-10-13 15:11:29 +0000
@@ -23,8 +23,10 @@
 */
 #define MYSQL_CLIENT_PLUGIN_INCLUDED
 
+#ifndef MYSQL_ABI_CHECK
 #include <stdarg.h>
 #include <stdlib.h>
+#endif
 
 /* known plugin types */
 #define MYSQL_CLIENT_reserved1               0

=== modified file 'include/mysql/client_plugin.h.pp'
--- a/include/mysql/client_plugin.h.pp	2010-10-05 12:26:49 +0000
+++ b/include/mysql/client_plugin.h.pp	2010-10-13 15:11:29 +0000
@@ -1,5 +1,3 @@
-#include <stdarg.h>
-#include <stdlib.h>
 struct st_mysql_client_plugin
 {
   int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *);

=== modified file 'mysql-test/extra/rpl_tests/rpl_start_stop_slave.test'
--- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test	2010-04-28 12:47:49 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test	2010-10-14 01:54:07 +0000
@@ -122,4 +122,60 @@ drop table t1i, t2m;
 
 sync_slave_with_master;
 
+--echo #
+--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep
+--echo #
+
+--connection master
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT );
+
+sync_slave_with_master;
+
+--connection slave1
+--echo # Slave1: lock table for synchronization
+LOCK TABLES t1 WRITE;
+
+--connection master
+--echo # Master: insert into the table
+INSERT INTO t1 SELECT SLEEP(4);
+
+--connection slave
+--echo # Slave: wait for the insert
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+  WHERE STATE = "Waiting for table metadata lock"
+  AND INFO = "INSERT INTO t1 SELECT SLEEP(4)";
+--source include/wait_condition.inc
+
+--echo # Slave: send slave stop
+--send STOP SLAVE
+
+--connection slave1
+--echo # Slave1: wait for stop slave
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+  WHERE INFO = "STOP SLAVE";
+--source include/wait_condition.inc
+
+--echo # Slave1: unlock the table
+UNLOCK TABLES;
+
+--connection slave
+--echo # Slave: wait for the slave to stop
+--reap
+--source include/wait_for_slave_to_stop.inc
+
+--echo # Start slave again
+--source include/start_slave.inc
+
+--echo # Clean up
+--connection master
+DROP TABLE t1;
+sync_slave_with_master;
+
 # End of tests

=== added file 'mysql-test/extra/rpl_tests/rpl_stop_slave.test'
--- a/mysql-test/extra/rpl_tests/rpl_stop_slave.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test	2010-10-16 12:03:44 +0000
@@ -0,0 +1,61 @@
+#
+# Auxiliary file which is used to test BUG#56118 
+#
+# Slave should apply all statements in the transaction before stop if any
+# temporary table is created or dropped.
+#
+# USEAGE: 
+# --let $tmp_table_stm= a SQL statement 
+# --source extra/rpl_tests/rpl_stop_slave.test
+#
+
+if (`SELECT "$tmp_table_stm" = ''`)
+{
+  --echo \$tmp_table_stm is NULL
+  --die $tmp_table_stm is NULL
+}
+
+--echo
+--echo [ On Master ]
+connection master;
+BEGIN;
+DELETE FROM t1;
+eval $tmp_table_stm;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+--echo
+--echo [ On Slave ]
+connection slave;
+
+# To check if slave SQL thread is applying INSERT statement
+let $show_statement= SHOW PROCESSLIST;
+let $field= Info;
+let $condition= LIKE 'INSERT%';
+source include/wait_show_condition.inc;
+
+send STOP SLAVE SQL_THREAD;
+
+--echo
+--echo [ On Slave1 ]
+connection slave1;
+--echo # To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+--echo
+--echo [ On Slave ]
+connection slave;
+reap;
+source include/wait_for_slave_sql_to_stop.inc;
+
+--echo # Slave should stop after the transaction has committed.
+--echo # So t1 on master is same to t1 on slave.
+let diff_table_1=master:test.t1;
+let diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+connection slave;
+START SLAVE SQL_THREAD;
+source include/wait_for_slave_sql_to_start.inc;

=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql	2010-06-02 16:08:06 +0000
+++ b/mysql-test/include/mtr_warnings.sql	2010-10-14 10:05:59 +0000
@@ -16,6 +16,12 @@ CREATE TABLE test_suppressions (
 -- no invalid patterns can be inserted
 -- into test_suppressions
 --
+SET @character_set_client_saved = @@character_set_client||
+SET @character_set_results_saved = @@character_set_results||
+SET @collation_connection_saved = @@collation_connection||
+SET @@character_set_client = latin1||
+SET @@character_set_results = latin1||
+SET @@collation_connection = latin1_swedish_ci||
 /*!50002
 CREATE DEFINER=root@localhost TRIGGER ts_insert
 BEFORE INSERT ON test_suppressions
@@ -24,6 +30,9 @@ FOR EACH ROW BEGIN
   SELECT "" REGEXP NEW.pattern INTO dummy;
 END
 */||
+SET @@character_set_client = @character_set_client_saved||
+SET @@character_set_results = @character_set_results_saved||
+SET @@collation_connection = @collation_connection_saved||
 
 
 --
@@ -38,6 +47,12 @@ CREATE TABLE global_suppressions (
 -- no invalid patterns can be inserted
 -- into global_suppressions
 --
+SET @character_set_client_saved = @@character_set_client||
+SET @character_set_results_saved = @@character_set_results||
+SET @collation_connection_saved = @@collation_connection||
+SET @@character_set_client = latin1||
+SET @@character_set_results = latin1||
+SET @@collation_connection = latin1_swedish_ci||
 /*!50002
 CREATE DEFINER=root@localhost TRIGGER gs_insert
 BEFORE INSERT ON global_suppressions
@@ -46,6 +61,9 @@ FOR EACH ROW BEGIN
   SELECT "" REGEXP NEW.pattern INTO dummy;
 END
 */||
+SET @@character_set_client = @character_set_client_saved||
+SET @@character_set_results = @character_set_results_saved||
+SET @@collation_connection = @collation_connection_saved||
 
 
 

=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result	2010-10-07 16:01:17 +0000
+++ b/mysql-test/r/grant.result	2010-10-19 09:26:45 +0000
@@ -1575,6 +1575,17 @@ DROP USER 'testbug'@localhost;
 DROP TABLE db2.t1;
 DROP DATABASE db1;
 DROP DATABASE db2;
+#
+# Bug #36742
+#
+grant usage on Foo.* to myuser@Localhost identified by 'foo';
+grant select on Foo.* to myuser@localhost;
+select host,user from mysql.user where User='myuser';
+host	user
+localhost	myuser
+revoke select on Foo.* from myuser@localhost;
+delete from mysql.user where User='myuser';
+flush privileges;
 #########################################################################
 #
 # Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.

=== modified file 'mysql-test/r/grant3.result'
--- a/mysql-test/r/grant3.result	2009-10-20 06:17:57 +0000
+++ b/mysql-test/r/grant3.result	2010-10-18 14:03:53 +0000
@@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOS
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
 user	host	db	select_priv
-CUser	LOCALHOST	test	Y
 CUser	localhost	test	Y
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
 user	host	db	select_priv
-CUser	localhost	test	Y
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
 user	host	db	select_priv
 DROP USER CUser@localhost;
 DROP USER CUser@LOCALHOST;
+ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
 create table t1 (a int);
 grant select on test.t1 to CUser@localhost;
 grant select on test.t1 to CUser@LOCALHOST;
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
-CUser	LOCALHOST	test	t1	Select	
 CUser	localhost	test	t1	Select	
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
-CUser	localhost	test	t1	Select	
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
 DROP USER CUser@localhost;
 DROP USER CUser@LOCALHOST;
+ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
 grant select(a) on test.t1 to CUser@localhost;
 grant select(a) on test.t1 to CUser@LOCALHOST;
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
-CUser	LOCALHOST	test	t1		Select
 CUser	localhost	test	t1		Select
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
-CUser	localhost	test	t1		Select
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
 user	host
-CUser	LOCALHOST
 CUser	localhost
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 user	host	db	Table_name	Table_priv	Column_priv
 DROP USER CUser@localhost;
 DROP USER CUser@LOCALHOST;
+ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost'
 drop table t1;
 grant select on test.* to CUser2@localhost;
 grant select on test.* to CUser2@LOCALHOST;
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
 user	host
-CUser2	LOCALHOST
 CUser2	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
 user	host	db	select_priv
-CUser2	LOCALHOST	test	Y
 CUser2	localhost	test	Y
 REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
 user	host
-CUser2	LOCALHOST
 CUser2	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
 user	host	db	select_priv
-CUser2	localhost	test	Y
 REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
+ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost'
 flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
 user	host
-CUser2	LOCALHOST
 CUser2	localhost
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
 user	host	db	select_priv
 DROP USER CUser2@localhost;
 DROP USER CUser2@LOCALHOST;
+ERROR HY000: Operation DROP USER failed for 'CUser2'@'localhost'
 CREATE DATABASE mysqltest_1;
 CREATE TABLE mysqltest_1.t1 (a INT);
 CREATE USER 'mysqltest1'@'%';

=== modified file 'mysql-test/r/ipv4_as_ipv6.result'
--- a/mysql-test/r/ipv4_as_ipv6.result	2009-11-26 08:03:04 +0000
+++ b/mysql-test/r/ipv4_as_ipv6.result	2010-10-18 16:20:26 +0000
@@ -32,9 +32,9 @@ mysqld is alive
 CREATE USER testuser@'0:0:0:0:0:FFFF:127.0.0.1' identified by '1234';
 GRANT ALL ON test.* TO testuser@'0:0:0:0:0:FFFF:127.0.0.1';
 SHOW GRANTS FOR testuser@'0:0:0:0:0:FFFF:127.0.0.1';
-Grants for testuser@0:0:0:0:0:FFFF:127.0.0.1
-GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
-GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1'
+Grants for testuser@0:0:0:0:0:ffff:127.0.0.1
+GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
+GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1'
 SET @nip= inet_aton('0:0:0:0:0:FFFF:127.0.0.1');
 SELECT @nip;
 @nip
@@ -61,9 +61,9 @@ mysqld is alive
 CREATE USER testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' identified by '1234';
 GRANT ALL ON test.* TO testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
 SHOW GRANTS FOR testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1';
-Grants for testuser@0000:0000:0000:0000:0000:FFFF:127.0.0.1
-GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
-GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'
+Grants for testuser@0000:0000:0000:0000:0000:ffff:127.0.0.1
+GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
+GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1'
 SET @nip= inet_aton('0000:0000:0000:0000:0000:FFFF:127.0.0.1');
 SELECT @nip;
 @nip
@@ -90,9 +90,9 @@ mysqld is alive
 CREATE USER testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1' identified by '1234';
 GRANT ALL ON test.* TO testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
 SHOW GRANTS FOR testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1';
-Grants for testuser@0:0000:0000:0:0000:FFFF:127.0.0.1
-GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
-GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1'
+Grants for testuser@0:0000:0000:0:0000:ffff:127.0.0.1
+GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
+GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1'
 SET @nip= inet_aton('0:0000:0000:0:0000:FFFF:127.0.0.1');
 SELECT @nip;
 @nip
@@ -119,9 +119,9 @@ mysqld is alive
 CREATE USER testuser@'0::0000:FFFF:127.0.0.1' identified by '1234';
 GRANT ALL ON test.* TO testuser@'0::0000:FFFF:127.0.0.1';
 SHOW GRANTS FOR testuser@'0::0000:FFFF:127.0.0.1';
-Grants for testuser@0::0000:FFFF:127.0.0.1
-GRANT USAGE ON *.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
-GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:FFFF:127.0.0.1'
+Grants for testuser@0::0000:ffff:127.0.0.1
+GRANT USAGE ON *.* TO 'testuser'@'0::0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
+GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:ffff:127.0.0.1'
 SET @nip= inet_aton('0::0000:FFFF:127.0.0.1');
 SELECT @nip;
 @nip
@@ -149,9 +149,9 @@ mysqld is alive
 CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234';
 GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1';
 SHOW GRANTS FOR testuser@'::FFFF:127.0.0.1';
-Grants for testuser@::FFFF:127.0.0.1
-GRANT USAGE ON *.* TO 'testuser'@'::FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
-GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::FFFF:127.0.0.1'
+Grants for testuser@::ffff:127.0.0.1
+GRANT USAGE ON *.* TO 'testuser'@'::ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF'
+GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::ffff:127.0.0.1'
 SET @nip= inet_aton('::FFFF:127.0.0.1');
 SELECT @nip;
 @nip

=== modified file 'mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result	2010-04-28 12:47:49 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result	2010-10-14 01:54:07 +0000
@@ -43,3 +43,25 @@ one
 1
 include/start_slave.inc
 drop table t1i, t2m;
+#
+# Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT );
+# Slave1: lock table for synchronization
+LOCK TABLES t1 WRITE;
+# Master: insert into the table
+INSERT INTO t1 SELECT SLEEP(4);
+Warnings:
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave.
+# Slave: wait for the insert
+# Slave: send slave stop
+STOP SLAVE;
+# Slave1: wait for stop slave
+# Slave1: unlock the table
+UNLOCK TABLES;
+# Slave: wait for the slave to stop
+# Start slave again
+include/start_slave.inc
+# Clean up
+DROP TABLE t1;

=== added file 'mysql-test/suite/rpl/r/rpl_stop_slave.result'
--- a/mysql-test/suite/rpl/r/rpl_stop_slave.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result	2010-10-16 14:20:35 +0000
@@ -0,0 +1,77 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+
+# BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
+#
+# If a temporary table is created or dropped, the transaction should be
+# regarded similarly that a non-transactional table is modified. So 
+# STOP SLAVE should wait until the transaction has finished.
+CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
+CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
+SET DEBUG_SYNC= 'RESET';
+include/stop_slave.inc
+
+# Suspend the INSERT statement in current transaction on SQL thread.
+# It guarantees that SQL thread is applying the transaction when
+# STOP SLAVE command launchs.
+SET GLOBAL debug= 'd,after_mysql_insert';
+include/start_slave.inc
+
+# CREATE TEMPORARY TABLE with InnoDB engine
+# -----------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+
+# CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
+# ----------------------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
+SELECT c1 FROM t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+
+# Test end
+SET GLOBAL debug= '$debug_save';
+DROP TABLE t1, t2;

=== added file 'mysql-test/suite/rpl/t/rpl_stop_slave.test'
--- a/mysql-test/suite/rpl/t/rpl_stop_slave.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test	2010-10-16 14:20:35 +0000
@@ -0,0 +1,51 @@
+source include/master-slave.inc;
+source include/have_innodb.inc;
+source include/have_debug.inc;
+source include/have_debug_sync.inc;
+source include/have_binlog_format_mixed_or_statement.inc;
+
+--echo
+--echo # BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
+--echo #
+--echo # If a temporary table is created or dropped, the transaction should be
+--echo # regarded similarly that a non-transactional table is modified. So 
+--echo # STOP SLAVE should wait until the transaction has finished.
+
+CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
+CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
+
+sync_slave_with_master;
+SET DEBUG_SYNC= 'RESET';
+source include/stop_slave.inc;
+
+--echo
+--echo # Suspend the INSERT statement in current transaction on SQL thread.
+--echo # It guarantees that SQL thread is applying the transaction when
+--echo # STOP SLAVE command launchs.
+let $debug_save= `SELECT @@GLOBAL.debug`;
+SET GLOBAL debug= 'd,after_mysql_insert';
+source include/start_slave.inc;
+
+--echo
+--echo # CREATE TEMPORARY TABLE with InnoDB engine
+--echo # -----------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+--echo
+--echo # CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
+--echo # ----------------------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
+                    SELECT c1 FROM t2;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+# Don't need to verify 'CREATE TEMPORARY TABLE' with MyIASM engine, as it
+# never is binlogged into a transaction since 5.5.
+
+--echo
+--echo # Test end
+SET GLOBAL debug= '$debug_save';
+
+connection master;
+DROP TABLE t1, t2;
+source include/master-slave-end.inc;

=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test	2010-10-07 16:01:17 +0000
+++ b/mysql-test/t/grant.test	2010-10-19 09:26:45 +0000
@@ -1573,6 +1573,16 @@ DROP TABLE db2.t1;
 DROP DATABASE db1;
 DROP DATABASE db2;
 
+--echo #
+--echo # Bug #36742
+--echo #
+grant usage on Foo.* to myuser@Localhost identified by 'foo';
+grant select on Foo.* to myuser@localhost;
+select host,user from mysql.user where User='myuser';
+revoke select on Foo.* from myuser@localhost;
+delete from mysql.user where User='myuser';
+flush privileges;
+
 # Wait till we reached the initial number of concurrent sessions
 --source include/wait_until_count_sessions.inc
 

=== modified file 'mysql-test/t/grant3.test'
--- a/mysql-test/t/grant3.test	2009-10-20 06:17:57 +0000
+++ b/mysql-test/t/grant3.test	2010-10-18 14:03:53 +0000
@@ -64,6 +64,7 @@ SELECT user, host FROM mysql.user where
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
 
 DROP USER CUser@localhost;
+--error ER_CANNOT_USER
 DROP USER CUser@LOCALHOST;
 
 #### table grants
@@ -88,6 +89,7 @@ SELECT user, host FROM mysql.user where
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 
 DROP USER CUser@localhost;
+--error ER_CANNOT_USER
 DROP USER CUser@LOCALHOST;
 
 ### column grants
@@ -112,6 +114,7 @@ SELECT user, host FROM mysql.user where
 SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
 
 DROP USER CUser@localhost;
+--error ER_CANNOT_USER
 DROP USER CUser@LOCALHOST;
 
 drop table t1;
@@ -131,6 +134,7 @@ flush privileges;
 SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
 
+--error ER_NONEXISTING_GRANT
 REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
 flush privileges;
 
@@ -138,6 +142,7 @@ SELECT user, host FROM mysql.user where
 SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
 
 DROP USER CUser2@localhost;
+--error ER_CANNOT_USER
 DROP USER CUser2@LOCALHOST;
 
 

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-10-06 14:34:28 +0000
+++ b/sql/handler.cc	2010-10-18 11:27:52 +0000
@@ -1156,7 +1156,7 @@ int ha_commit_trans(THD *thd, bool all)
     uint rw_ha_count;
     bool rw_trans;
 
-    DBUG_EXECUTE_IF("crash_commit_before", DBUG_ABORT(););
+    DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE(););
 
     /* Close all cursors that can not survive COMMIT */
     if (is_real_trans)                          /* not a statement commit */
@@ -1208,7 +1208,7 @@ int ha_commit_trans(THD *thd, bool all)
         }
         status_var_increment(thd->status_var.ha_prepare_count);
       }
-      DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT(););
+      DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
       if (error || (is_real_trans && xid &&
                     (error= !(cookie= tc_log->log_xid(thd, xid)))))
       {
@@ -1216,13 +1216,13 @@ int ha_commit_trans(THD *thd, bool all)
         error= 1;
         goto end;
       }
-      DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_ABORT(););
+      DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
     }
     error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
-    DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_ABORT(););
+    DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
     if (cookie)
       tc_log->unlog(cookie, xid);
-    DBUG_EXECUTE_IF("crash_commit_after", DBUG_ABORT(););
+    DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
     RUN_HOOK(transaction, after_commit, (thd, FALSE));
 end:
     if (rw_trans)

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2010-10-05 11:33:54 +0000
+++ b/sql/item_func.cc	2010-10-14 01:54:07 +0000
@@ -3691,48 +3691,92 @@ longlong Item_master_pos_wait::val_int()
 }
 
 
+/**
+  Enables a session to wait on a condition until a timeout or a network
+  disconnect occurs.
+
+  @remark The connection is polled every m_interrupt_interval nanoseconds.
+*/
+
+class Interruptible_wait
+{
+  THD *m_thd;
+  struct timespec m_abs_timeout;
+  static const ulonglong m_interrupt_interval;
+
+  public:
+    Interruptible_wait(THD *thd)
+    : m_thd(thd) {}
+
+    ~Interruptible_wait() {}
+
+  public:
+    /**
+      Set the absolute timeout.
+
+      @param timeout The amount of time in nanoseconds to wait
+    */
+    void set_timeout(ulonglong timeout)
+    {
+      /*
+        Calculate the absolute system time at the start so it can
+        be controlled in slices. It relies on the fact that once
+        the absolute time passes, the timed wait call will fail
+        automatically with a timeout error.
+      */
+      set_timespec_nsec(m_abs_timeout, timeout);
+    }
+
+    /** The timed wait. */
+    int wait(mysql_cond_t *, mysql_mutex_t *);
+};
+
+
+/** Time to wait before polling the connection status. */
+const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000);
+
 
 /**
-  Wait for a given condition to be signaled within the specified timeout.
+  Wait for a given condition to be signaled.
+
+  @param cond   The condition variable to wait on.
+  @param mutex  The associated mutex.
 
-  @param cond the condition variable to wait on
-  @param lock the associated mutex
-  @param abstime the amount of time in seconds to wait
+  @remark The absolute timeout is preserved across calls.
 
   @retval return value from mysql_cond_timedwait
 */
 
-#define INTERRUPT_INTERVAL (5 * ULL(1000000000))
-
-static int interruptible_wait(THD *thd, mysql_cond_t *cond,
-                              mysql_mutex_t *lock, double time)
+int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
 {
   int error;
-  struct timespec abstime;
-  ulonglong slice, timeout= (ulonglong) (time * 1000000000.0);
+  struct timespec timeout;
 
-  do
+  while (1)
   {
     /* Wait for a fixed interval. */
-    if (timeout > INTERRUPT_INTERVAL)
-      slice= INTERRUPT_INTERVAL;
-    else
-      slice= timeout;
+    set_timespec_nsec(timeout, m_interrupt_interval);
+
+    /* But only if not past the absolute timeout. */
+    if (cmp_timespec(timeout, m_abs_timeout) > 0)
+      timeout= m_abs_timeout;
 
-    timeout-= slice;
-    set_timespec_nsec(abstime, slice);
-    error= mysql_cond_timedwait(cond, lock, &abstime);
+    error= mysql_cond_timedwait(cond, mutex, &timeout);
     if (error == ETIMEDOUT || error == ETIME)
     {
       /* Return error if timed out or connection is broken. */
-      if (!timeout || !thd->is_connected())
+      if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected())
         break;
     }
-  } while (error && timeout);
+    /* Otherwise, propagate status to the caller. */
+    else
+      break;
+  }
 
   return error;
 }
 
+
 /**
   Get a user level lock.  If the thread has an old lock this is first released.
 
@@ -3748,10 +3792,11 @@ longlong Item_func_get_lock::val_int()
 {
   DBUG_ASSERT(fixed == 1);
   String *res=args[0]->val_str(&value);
-  double timeout= args[1]->val_real();
+  ulonglong timeout= args[1]->val_int();
   THD *thd=current_thd;
   User_level_lock *ull;
   int error;
+  Interruptible_wait timed_cond(thd);
   DBUG_ENTER("Item_func_get_lock::val_int");
 
   /*
@@ -3812,11 +3857,13 @@ longlong Item_func_get_lock::val_int()
   thd->mysys_var->current_mutex= &LOCK_user_locks;
   thd->mysys_var->current_cond=  &ull->cond;
 
+  timed_cond.set_timeout(timeout * ULL(1000000000));
+
   error= 0;
   while (ull->locked && !thd->killed)
   {
     DBUG_PRINT("info", ("waiting on lock"));
-    error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout);
+    error= timed_cond.wait(&ull->cond, &LOCK_user_locks);
     if (error == ETIMEDOUT || error == ETIME)
     {
       DBUG_PRINT("info", ("lock wait timeout"));
@@ -4011,6 +4058,7 @@ void Item_func_benchmark::print(String *
 longlong Item_func_sleep::val_int()
 {
   THD *thd= current_thd;
+  Interruptible_wait timed_cond(thd);
   mysql_cond_t cond;
   double timeout;
   int error;
@@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int()
   if (timeout < 0.00001)
     return 0;
 
+  timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0));
+
   mysql_cond_init(key_item_func_sleep_cond, &cond, NULL);
   mysql_mutex_lock(&LOCK_user_locks);
 
@@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int()
   error= 0;
   while (!thd->killed)
   {
-    error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout);
+    error= timed_cond.wait(&cond, &LOCK_user_locks);
     if (error == ETIMEDOUT || error == ETIME)
       break;
     error= 0;

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-09-29 14:26:32 +0000
+++ b/sql/log.cc	2010-10-18 11:27:52 +0000
@@ -2849,7 +2849,7 @@ bool MYSQL_BIN_LOG::open(const char *log
     sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
     DBUG_RETURN(1);
   }
-  DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_ABORT(););
+  DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE(););
 #endif
 
   write_error= 0;
@@ -2946,7 +2946,7 @@ bool MYSQL_BIN_LOG::open(const char *log
     if (write_file_name_to_index_file)
     {
 #ifdef HAVE_REPLICATION
-      DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_ABORT(););
+      DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE(););
 #endif
 
       DBUG_ASSERT(my_b_inited(&index_file) != 0);
@@ -2965,7 +2965,7 @@ bool MYSQL_BIN_LOG::open(const char *log
         goto err;
 
 #ifdef HAVE_REPLICATION
-      DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_ABORT(););
+      DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE(););
 #endif
     }
   }
@@ -3428,7 +3428,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
   /* Store where we are in the new file for the execution thread */
   flush_relay_log_info(rli);
 
-  DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT(););
+  DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
 
   mysql_mutex_lock(&rli->log_space_lock);
   rli->relay_log.purge_logs(to_purge_if_included, included,
@@ -3556,7 +3556,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
       break;
   }
 
-  DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_ABORT(););
+  DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE(););
 
   if ((error= sync_purge_index_file()))
   {
@@ -3571,7 +3571,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
     goto err;
   }
 
-  DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_ABORT(););
+  DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE(););
 
 err:
   /* Read each entry from purge_index_file and delete the file. */
@@ -3581,7 +3581,7 @@ err:
                     " that would be purged.");
   close_purge_index_file();
 
-  DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_ABORT(););
+  DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE(););
 
   if (need_mutex)
     mysql_mutex_unlock(&LOCK_index);
@@ -5177,7 +5177,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
                           DBUG_PRINT("info", ("error writing binlog cache: %d",
                                                write_error));
                         DBUG_PRINT("info", ("crashing before writing xid"));
-                        DBUG_ABORT();
+                        DBUG_SUICIDE();
                       });
 
       if ((write_error= write_cache(cache, false, false)))
@@ -5192,7 +5192,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
       bool synced= 0;
       if (flush_and_sync(&synced))
         goto err;
-      DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_ABORT(););
+      DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
       if (cache->error)				// Error on read
       {
         sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-10-09 10:18:16 +0000
+++ b/sql/log_event.cc	2010-10-13 10:08:39 +0000
@@ -1244,7 +1244,7 @@ Log_event* Log_event::read_log_event(con
       break;
 #ifdef HAVE_REPLICATION
     case SLAVE_EVENT: /* can never happen (unused event) */
-      ev = new Slave_log_event(buf, event_len);
+      ev = new Slave_log_event(buf, event_len, description_event);
       break;
 #endif /* HAVE_REPLICATION */
     case CREATE_FILE_EVENT:
@@ -1332,8 +1332,10 @@ Log_event* Log_event::read_log_event(con
     (because constructor is "void") ; so instead we leave the pointer we
     wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
     Same for Format_description_log_event, member 'post_header_len'.
+
+    SLAVE_EVENT is never used, so it should not be read ever.
   */
-  if (!ev || !ev->is_valid())
+  if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
   {
     DBUG_PRINT("error",("Found invalid event in binary log"));
 
@@ -6117,8 +6119,12 @@ void Slave_log_event::init_from_mem_pool
 
 
 /** This code is not used, so has not been updated to be format-tolerant. */
-Slave_log_event::Slave_log_event(const char* buf, uint event_len)
-  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
+/* We are using description_event so that slave does not crash on Log_event
+  constructor */
+Slave_log_event::Slave_log_event(const char* buf, 
+                                 uint event_len,
+                                 const Format_description_log_event* description_event)
+  :Log_event(buf,description_event),mem_pool(0),master_host(0)
 {
   if (event_len < LOG_EVENT_HEADER_LEN)
     return;

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2010-07-15 13:47:50 +0000
+++ b/sql/log_event.h	2010-10-13 10:08:39 +0000
@@ -1846,7 +1846,9 @@ public:
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
 #endif
 
-  Slave_log_event(const char* buf, uint event_len);
+  Slave_log_event(const char* buf,
+                  uint event_len,
+                  const Format_description_log_event *description_event);
   ~Slave_log_event();
   int get_data_size();
   bool is_valid() const { return master_host != 0; }

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2010-03-31 14:05:33 +0000
+++ b/sql/rpl_rli.h	2010-10-13 10:08:39 +0000
@@ -97,6 +97,16 @@ public:
   */
   MYSQL_BIN_LOG relay_log;
   LOG_INFO linfo;
+
+  /*
+   cur_log
+     Pointer that either points at relay_log.get_log_file() or
+     &rli->cache_buf, depending on whether the log is hot or there was
+     the need to open a cold relay_log.
+
+   cache_buf 
+     IO_CACHE used when opening cold relay logs.
+   */
   IO_CACHE cache_buf,*cur_log;
 
   /*

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2010-10-09 10:18:16 +0000
+++ b/sql/slave.cc	2010-10-16 14:20:35 +0000
@@ -881,7 +881,17 @@ static bool sql_slave_killed(THD* thd, R
   DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
   if (abort_loop || thd->killed || rli->abort_slave)
   {
-    if (thd->transaction.all.modified_non_trans_table && rli->is_in_group())
+    /*
+      The transaction should always be binlogged if OPTION_KEEP_LOG is set
+      (it implies that something can not be rolled back). And such case
+      should be regarded similarly as modifing a non-transactional table
+      because retrying of the transaction will lead to an error or inconsistency
+      as well.
+      Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped.
+    */
+    if ((thd->transaction.all.modified_non_trans_table ||
+         (thd->variables.option_bits & OPTION_KEEP_LOG))
+        && rli->is_in_group())
     {
       char msg_stopped[]=
         "... The slave SQL is stopped, leaving the current group "
@@ -4726,12 +4736,66 @@ static Log_event* next_event(Relay_log_i
         DBUG_ASSERT(rli->cur_log_fd == -1);
 
         /*
-          Read pointer has to be at the start since we are the only
-          reader.
-          We must keep the LOCK_log to read the 4 first bytes, as this is a hot
-          log (same as when we call read_log_event() above: for a hot log we
-          take the mutex).
+           When the SQL thread is [stopped and] (re)started the
+           following may happen:
+
+           1. Log was hot at stop time and remains hot at restart
+
+              SQL thread reads again from hot_log (SQL thread was
+              reading from the active log when it was stopped and the
+              very same log is still active on SQL thread restart).
+
+              In this case, my_b_seek is performed on cur_log, while
+              cur_log points to relay_log.get_log_file();
+
+           2. Log was hot at stop time but got cold before restart
+
+              The log was hot when SQL thread stopped, but it is not
+              anymore when the SQL thread restarts.
+
+              In this case, the SQL thread reopens the log, using
+              cache_buf, ie, cur_log points to &cache_buf, and thence
+              its coordinates are reset.
+
+           3. Log was already cold at stop time
+
+              The log was not hot when the SQL thread stopped, and, of
+              course, it will not be hot when it restarts.
+
+              In this case, the SQL thread opens the cold log again,
+              using cache_buf, ie, cur_log points to &cache_buf, and
+              thence its coordinates are reset.
+
+           4. Log was hot at stop time, DBA changes to previous cold
+              log and restarts SQL thread
+
+              The log was hot when the SQL thread was stopped, but the
+              user changed the coordinates of the SQL thread to
+              restart from a previous cold log.
+
+              In this case, at start time, cur_log points to a cold
+              log, opened using &cache_buf as cache, and coordinates
+              are reset. However, as it moves on to the next logs, it
+              will eventually reach the hot log. If the hot log is the
+              same at the time the SQL thread was stopped, then
+              coordinates were not reset - the cur_log will point to
+              relay_log.get_log_file(), and not a freshly opened
+              IO_CACHE through cache_buf. For this reason we need to
+              deploy a my_b_seek before calling check_binlog_magic at
+              this point of the code (see: BUG#55263 for more
+              details).
+          
+          NOTES: 
+            - We must keep the LOCK_log to read the 4 first bytes, as
+              this is a hot log (same as when we call read_log_event()
+              above: for a hot log we take the mutex).
+
+            - Because of scenario #4 above, we need to have a
+              my_b_seek here. Otherwise, we might hit the assertion
+              inside check_binlog_magic.
         */
+
+        my_b_seek(cur_log, (my_off_t) 0);
         if (check_binlog_magic(cur_log,&errmsg))
         {
           if (!hot_log)

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2010-10-12 12:19:33 +0000
+++ b/sql/sp_head.cc	2010-10-13 09:34:02 +0000
@@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd)
     The same with db_load_routine() required circa 7k bytes and
     14k bytes accordingly. Hence, here we book the stack with some
     reasonable margin.
+
+    Reverting back to 8 * STACK_MIN_SIZE until further fix.
+    8 * STACK_MIN_SIZE is required on some exotic platforms.
   */
-  if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet))
+  if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
     DBUG_RETURN(TRUE);
 
   /* init per-instruction memroot */

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-10-07 16:01:17 +0000
+++ b/sql/sql_parse.cc	2010-10-19 09:26:45 +0000
@@ -2832,6 +2832,15 @@ end_with_restore_list:
       thd->first_successful_insert_id_in_cur_stmt=
         thd->first_successful_insert_id_in_prev_stmt;
 
+    DBUG_EXECUTE_IF("after_mysql_insert",
+                    {
+                      const char act[]=
+                        "now "
+                        "wait_for signal.continue";
+                      DBUG_ASSERT(opt_debug_sync_timeout > 0);
+                      DBUG_ASSERT(!debug_sync_set_action(current_thd,
+                                                         STRING_WITH_LEN(act)));
+                    };);
     break;
   }
   case SQLCOM_REPLACE_SELECT:

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-10-07 23:34:59 +0000
+++ b/sql/sql_yacc.yy	2010-10-13 06:27:03 +0000
@@ -12334,6 +12334,12 @@ user:
                                          system_charset_info, 0) ||
                 check_host_name(&$$->host))
               MYSQL_YYABORT;
+            /*
+              Convert hostname part of username to lowercase.
+              It's OK to use in-place lowercase as long as
+              the character set is utf8.
+            */
+            my_casedn_str(system_charset_info, $$->host.str);
           }
         | CURRENT_USER optional_braces
           {

No bundle (reason: revision is a merge).
Thread
bzr commit into mysql-5.5-runtime branch (jon.hauglid:3167) Jon Olav Hauglid19 Oct