List:Commits« Previous MessageNext Message »
From:Marc Alff Date:June 13 2011 1:44pm
Subject:bzr commit into mysql-trunk-wl5378 branch (marc.alff:3357)
View as plain text  
#At file:///home/malff/BZR_TREE/mysql-trunk-wl5378/ based on revid:marc.alff@stripped

 3357 Marc Alff	2011-06-13 [merge]
      Merge mysql-trunk --> mysql-trunk-wl5378

    added:
      mysql-test/r/archive_debug.result
      mysql-test/t/archive_debug.test
    modified:
      .bzrignore
      client/mysql.cc
      client/mysql_upgrade.c
      client/mysqladmin.cc
      client/mysqlbinlog.cc
      client/mysqlcheck.c
      client/mysqldump.c
      client/mysqlimport.c
      client/mysqlshow.c
      client/mysqlslap.c
      client/mysqltest.cc
      cmake/make_dist.cmake.in
      cmake/plugin.cmake
      configure.cmake
      include/mysql/plugin_audit.h
      include/mysql/plugin_audit.h.pp
      libmysql/authentication_win/plugin_client.cc
      libmysqld/emb_qcache.cc
      libmysqld/lib_sql.cc
      mysql-test/collections/default.experimental
      mysql-test/extra/rpl_tests/rpl_auto_increment.test
      mysql-test/include/icp_tests.inc
      mysql-test/r/events_bugs.result
      mysql-test/r/gis-precise.result
      mysql-test/r/gis-rtree.result
      mysql-test/r/group_by.result
      mysql-test/r/innodb_icp.result
      mysql-test/r/innodb_icp_all.result
      mysql-test/r/innodb_icp_none.result
      mysql-test/r/myisam_icp.result
      mysql-test/r/myisam_icp_all.result
      mysql-test/r/myisam_icp_none.result
      mysql-test/r/partition.result
      mysql-test/r/partition_datatype.result
      mysql-test/r/query_cache_28249.result
      mysql-test/r/sp_notembedded.result
      mysql-test/r/symlink.result
      mysql-test/r/trigger-compat.result
      mysql-test/r/trigger.result
      mysql-test/r/type_datetime.result
      mysql-test/suite/rpl/r/rpl_auto_increment.result
      mysql-test/t/disabled.def
      mysql-test/t/events_bugs.test
      mysql-test/t/gis-precise.test
      mysql-test/t/gis-rtree.test
      mysql-test/t/group_by.test
      mysql-test/t/partition.test
      mysql-test/t/partition_datatype.test
      mysql-test/t/query_cache_28249.test
      mysql-test/t/sp_notembedded.test
      mysql-test/t/symlink.test
      mysql-test/t/trigger-compat.test
      mysql-test/t/type_datetime.test
      plugin/audit_null/audit_null.c
      sql/binlog.cc
      sql/event_db_repository.cc
      sql/event_parse_data.cc
      sql/event_parse_data.h
      sql/event_scheduler.cc
      sql/field.cc
      sql/filesort.cc
      sql/gcalc_tools.cc
      sql/ha_ndbcluster_binlog.cc
      sql/ha_partition.cc
      sql/handler.cc
      sql/item.cc
      sql/item.h
      sql/item_cmpfunc.cc
      sql/item_cmpfunc.h
      sql/item_func.cc
      sql/item_row.cc
      sql/item_strfunc.cc
      sql/item_sum.cc
      sql/item_timefunc.cc
      sql/item_timefunc.h
      sql/log_event.cc
      sql/log_event_old.cc
      sql/mysqld.cc
      sql/opt_sum.cc
      sql/protocol.cc
      sql/rpl_master.cc
      sql/rpl_reporting.cc
      sql/rpl_rli.cc
      sql/rpl_slave.cc
      sql/share/errmsg-utf8.txt
      sql/sp.cc
      sql/sp_head.cc
      sql/spatial.cc
      sql/sql_acl.cc
      sql/sql_admin.cc
      sql/sql_alloc_error_handler.cc
      sql/sql_audit.cc
      sql/sql_audit.h
      sql/sql_base.cc
      sql/sql_cache.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_connect.cc
      sql/sql_derived.cc
      sql/sql_error.cc
      sql/sql_error.h
      sql/sql_insert.cc
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_load.cc
      sql/sql_parse.cc
      sql/sql_prepare.cc
      sql/sql_prepare.h
      sql/sql_select.cc
      sql/sql_servers.cc
      sql/sql_show.cc
      sql/sql_signal.cc
      sql/sql_table.cc
      sql/sql_time.cc
      sql/sql_trigger.cc
      sql/sql_trigger.h
      sql/sql_update.cc
      sql/sql_yacc.yy
      sql/structs.h
      sql/sys_vars.cc
      sql/table.cc
      sql/transaction.cc
      sql/tztime.cc
      storage/archive/azio.c
      storage/archive/ha_archive.cc
      storage/innobase/btr/btr0cur.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0lru.c
      storage/innobase/include/page0page.h
      storage/innobase/include/page0page.ic
      storage/innobase/include/rem0rec.h
      storage/innobase/include/rem0rec.ic
      storage/innobase/include/trx0trx.h
      storage/innobase/lock/lock0lock.c
      storage/innobase/row/row0row.c
      storage/innobase/row/row0vers.c
      storage/innobase/trx/trx0rec.c
      storage/myisam/mi_update.c
      storage/myisam/mi_write.c
      tests/mysql_client_test.c
=== modified file '.bzrignore'
--- a/.bzrignore	2011-05-16 08:52:10 +0000
+++ b/.bzrignore	2011-06-07 13:07:28 +0000
@@ -3160,3 +3160,4 @@ info_macros.cmake
 Docs/INFO_BIN
 Docs/INFO_SRC
 Testing
+source_downloads

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2011-05-26 15:20:09 +0000
+++ b/client/mysql.cc	2011-06-09 17:44:21 +0000
@@ -1640,11 +1640,11 @@ static struct my_option my_long_options[
     &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG,
     0, 0, 0, 0, 0, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+    &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
     "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+    &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };

=== modified file 'client/mysql_upgrade.c'
--- a/client/mysql_upgrade.c	2011-05-26 15:20:09 +0000
+++ b/client/mysql_upgrade.c	2011-06-06 10:29:45 +0000
@@ -92,7 +92,7 @@ static struct my_option my_long_options[
    0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade "
    "has already been executed for the current version of MySQL.",
@@ -109,7 +109,7 @@ static struct my_option my_long_options[
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
    "order of preference, my.cnf, $MYSQL_TCP_PORT, "

=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc	2011-02-11 14:38:34 +0000
+++ b/client/mysqladmin.cc	2011-06-06 10:29:45 +0000
@@ -210,11 +210,11 @@ static struct my_option my_long_options[
    &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
    SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+    &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };

=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2011-05-26 15:20:09 +0000
+++ b/client/mysqlbinlog.cc	2011-06-06 10:29:45 +0000
@@ -1037,7 +1037,7 @@ static struct my_option my_long_options[
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"disable-log-bin", 'D', "Disable binary log. This is useful, if you "
     "enabled --to-last-log and are sending the output to the same MySQL server. "
@@ -1065,7 +1065,7 @@ static struct my_option my_long_options[
   {"password", 'p', "Password to connect to remote server.",
    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+    &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
    "order of preference, my.cnf, $MYSQL_TCP_PORT, "

=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c	2011-03-08 09:21:39 +0000
+++ b/client/mysqlcheck.c	2011-06-06 10:29:45 +0000
@@ -106,7 +106,7 @@ static struct my_option my_long_options[
    &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"fast",'F', "Check only tables that haven't been closed properly.",
    &opt_fast, &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
@@ -146,7 +146,7 @@ static struct my_option my_long_options[
    NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
    "order of preference, my.cnf, $MYSQL_TCP_PORT, "

=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2011-05-26 15:20:09 +0000
+++ b/client/mysqldump.c	2011-06-06 10:29:45 +0000
@@ -508,11 +508,11 @@ static struct my_option my_long_options[
   {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
    NO_ARG, 0, 0, 0, 0, 0, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };

=== modified file 'client/mysqlimport.c'
--- a/client/mysqlimport.c	2011-01-16 04:02:29 +0000
+++ b/client/mysqlimport.c	2011-06-06 10:29:45 +0000
@@ -97,7 +97,7 @@ static struct my_option my_long_options[
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"delete", 'd', "First delete all rows from table.", &opt_delete,
    &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -149,7 +149,7 @@ static struct my_option my_long_options[
    NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
    "order of preference, my.cnf, $MYSQL_TCP_PORT, "

=== modified file 'client/mysqlshow.c'
--- a/client/mysqlshow.c	2011-01-16 04:02:29 +0000
+++ b/client/mysqlshow.c	2011-06-06 10:29:45 +0000
@@ -197,7 +197,7 @@ static struct my_option my_long_options[
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
    0, 0, 0, 0, 0, 0},
@@ -213,7 +213,7 @@ static struct my_option my_long_options[
    "solicited on the tty.",
    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
    "order of preference, my.cnf, $MYSQL_TCP_PORT, "

=== modified file 'client/mysqlslap.c'
--- a/client/mysqlslap.c	2011-05-26 15:20:09 +0000
+++ b/client/mysqlslap.c	2011-06-06 10:29:45 +0000
@@ -592,7 +592,7 @@ static struct my_option my_long_options[
    &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", OPT_DEFAULT_AUTH,
    "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"delimiter", 'F',
     "Delimiter to use in SQL statements supplied in file or command line.",
@@ -636,7 +636,7 @@ static struct my_option my_long_options[
     NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection.", &opt_mysql_port,
     &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2011-05-26 15:20:09 +0000
+++ b/client/mysqltest.cc	2011-06-06 10:29:45 +0000
@@ -6399,7 +6399,7 @@ static struct my_option my_long_options[
    &opt_connect_timeout, &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG,
    120, 0, 3600 * 12, 0, 0, 0},
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+    &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };

=== modified file 'cmake/make_dist.cmake.in'
--- a/cmake/make_dist.cmake.in	2011-03-04 15:12:05 +0000
+++ b/cmake/make_dist.cmake.in	2011-06-10 07:13:51 +0000
@@ -28,6 +28,7 @@ SET(TAR_EXECUTABLE "@TAR_EXECUTABLE@")
 SET(CMAKE_GENERATOR "@CMAKE_GENERATOR@")
 SET(CMAKE_MAKE_PROGRAM "@CMAKE_MAKE_PROGRAM@")
 SET(CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@")
+SET(PLUGIN_REPOS "@PLUGIN_REPOS@")
 
 SET(VERSION "@VERSION@")
 
@@ -53,6 +54,22 @@ IF(BZR_EXECUTABLE)
   ENDIF()
 ENDIF()
 
+IF(BZR_EXECUTABLE)
+  FOREACH(REPO ${PLUGIN_REPOS})
+    GET_FILENAME_COMPONENT(PLUGIN_NAME ${REPO} NAME)
+    SET(DEST ${PACKAGE_DIR}/plugin/${PLUGIN_NAME})
+    MESSAGE(STATUS "Running bzr export for plugin/${PLUGIN_NAME}")
+    EXECUTE_PROCESS(
+      COMMAND "${BZR_EXECUTABLE}" export ${DEST}
+      WORKING_DIRECTORY ${REPO}
+      RESULT_VARIABLE RESULT
+    )
+    IF(NOT RESULT EQUAL 0)
+      MESSAGE(STATUS "bzr export failed")
+    ENDIF()
+  ENDFOREACH()
+ENDIF()
+
 IF(NOT BZR_EXECUTABLE)
   MESSAGE(STATUS "bzr not found or source dir is not a repo, use CPack")
   

=== modified file 'cmake/plugin.cmake'
--- a/cmake/plugin.cmake	2011-05-27 12:45:38 +0000
+++ b/cmake/plugin.cmake	2011-06-10 14:12:38 +0000
@@ -32,16 +32,15 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_
 
 MACRO(PLUGIN_APPEND_COLLECTIONS plugin)
   SET(fcopied "${CMAKE_CURRENT_SOURCE_DIR}/tests/collections/FilesCopied")
-  IF(EXISTS ${fcopied})
-    RETURN()
+  IF(NOT EXISTS ${fcopied})
+    FILE(GLOB collections ${CMAKE_CURRENT_SOURCE_DIR}/tests/collections/*)
+    FOREACH(cfile ${collections})
+      FILE(READ ${cfile} contents)
+      GET_FILENAME_COMPONENT(fname ${cfile} NAME)
+      FILE(APPEND ${CMAKE_SOURCE_DIR}/mysql-test/collections/${fname} "${contents}")
+      FILE(APPEND ${fcopied} "${fname}\n")
+    ENDFOREACH()
   ENDIF()
-  FILE(GLOB collections ${CMAKE_CURRENT_SOURCE_DIR}/tests/collections/*)
-  FOREACH(cfile ${collections})
-    FILE(READ ${cfile} contents)
-    GET_FILENAME_COMPONENT(fname ${cfile} NAME)
-    FILE(APPEND ${CMAKE_SOURCE_DIR}/mysql-test/collections/${fname} "${contents}")
-    FILE(APPEND ${fcopied} "${fname}\n")
-  ENDFOREACH()
 ENDMACRO()
 
 MACRO(MYSQL_ADD_PLUGIN)
@@ -228,4 +227,11 @@ MACRO(CONFIGURE_PLUGINS)
       ADD_SUBDIRECTORY(${dir})
     ENDIF()
   ENDFOREACH()
+  FOREACH(dir ${dirs_plugin})
+    IF (EXISTS ${dir}/.bzr)
+      MESSAGE(STATUS "Found repo ${dir}/.bzr")
+      LIST(APPEND PLUGIN_BZR_REPOS "${dir}")
+    ENDIF()
+  ENDFOREACH()
+  SET(PLUGIN_REPOS "${PLUGIN_BZR_REPOS}" CACHE INTERNAL "")
 ENDMACRO()

=== modified file 'configure.cmake'
--- a/configure.cmake	2011-05-31 13:52:09 +0000
+++ b/configure.cmake	2011-06-06 10:29:45 +0000
@@ -338,6 +338,7 @@ CHECK_FUNCTION_EXISTS (fconvert HAVE_FCO
 CHECK_FUNCTION_EXISTS (fdatasync HAVE_FDATASYNC)
 CHECK_SYMBOL_EXISTS(fdatasync "unistd.h" HAVE_DECL_FDATASYNC)
 CHECK_FUNCTION_EXISTS (fesetround HAVE_FESETROUND)
+CHECK_FUNCTION_EXISTS (fedisableexcept HAVE_FEDISABLEEXCEPT)
 CHECK_FUNCTION_EXISTS (fpsetmask HAVE_FPSETMASK)
 CHECK_FUNCTION_EXISTS (fseeko HAVE_FSEEKO)
 CHECK_FUNCTION_EXISTS (fsync HAVE_FSYNC)

=== modified file 'include/mysql/plugin_audit.h'
--- a/include/mysql/plugin_audit.h	2010-12-14 14:34:23 +0000
+++ b/include/mysql/plugin_audit.h	2011-06-03 07:27:11 +0000
@@ -24,16 +24,7 @@
 
 #define MYSQL_AUDIT_CLASS_MASK_SIZE 1
 
-#define MYSQL_AUDIT_INTERFACE_VERSION 0x0200
-
-/*
-  The first word in every event class struct indicates the specific
-  class of the event.
-*/
-struct mysql_event
-{
-  unsigned int event_class;
-};
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0300
 
 
 /*************************************************************************
@@ -55,7 +46,6 @@ struct mysql_event
 
 struct mysql_event_general
 {
-  unsigned int event_class;
   unsigned int event_subclass;
   int general_error_code;
   unsigned long general_thread_id;
@@ -87,7 +77,6 @@ struct mysql_event_general
 
 struct mysql_event_connection
 {
-  unsigned int event_class;
   unsigned int event_subclass;
   int status;
   unsigned long thread_id;
@@ -118,9 +107,9 @@ struct mysql_event_connection
   waiting for the next query from the client.
   
   event_notify() is invoked whenever an event occurs which is of any
-  class for which the plugin has interest. The first word of the
-  mysql_event argument indicates the specific event class and the
-  remainder of the structure is as required for that class.
+  class for which the plugin has interest. The second argument
+  indicates the specific event class and the third argument is data
+  as required for that class.
   
   class_mask is an array of bits used to indicate what event classes
   that this plugin wants to receive.
@@ -130,7 +119,7 @@ struct st_mysql_audit
 {
   int interface_version;
   void (*release_thd)(MYSQL_THD);
-  void (*event_notify)(MYSQL_THD, const struct mysql_event *);
+  void (*event_notify)(MYSQL_THD, unsigned int, const void *);
   unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
 };
 

=== modified file 'include/mysql/plugin_audit.h.pp'
--- a/include/mysql/plugin_audit.h.pp	2011-05-04 09:54:04 +0000
+++ b/include/mysql/plugin_audit.h.pp	2011-06-03 08:00:42 +0000
@@ -44,7 +44,7 @@ typedef enum _thd_wait_type_e {
   THD_WAIT_BINLOG= 8,
   THD_WAIT_GROUP_COMMIT= 9,
   THD_WAIT_SYNC= 10,
-  THD_WAIT_LAST= 11 
+  THD_WAIT_LAST= 11
 } thd_wait_type;
 extern struct thd_wait_service_st {
   void (*thd_wait_begin_func)(void*, int);
@@ -209,13 +209,8 @@ void mysql_query_cache_invalidate4(void*
 void *thd_get_ha_data(const void* thd, const struct handlerton *hton);
 void thd_set_ha_data(void* thd, const struct handlerton *hton,
                      const void *ha_data);
-struct mysql_event
-{
-  unsigned int event_class;
-};
 struct mysql_event_general
 {
-  unsigned int event_class;
   unsigned int event_subclass;
   int general_error_code;
   unsigned long general_thread_id;
@@ -231,7 +226,6 @@ struct mysql_event_general
 };
 struct mysql_event_connection
 {
-  unsigned int event_class;
   unsigned int event_subclass;
   int status;
   unsigned long thread_id;
@@ -254,6 +248,6 @@ struct st_mysql_audit
 {
   int interface_version;
   void (*release_thd)(void*);
-  void (*event_notify)(void*, const struct mysql_event *);
+  void (*event_notify)(void*, unsigned int, const void *);
   unsigned long class_mask[1];
 };

=== modified file 'libmysql/authentication_win/plugin_client.cc'
--- a/libmysql/authentication_win/plugin_client.cc	2011-04-29 21:53:46 +0000
+++ b/libmysql/authentication_win/plugin_client.cc	2011-06-03 13:17:35 +0000
@@ -20,6 +20,16 @@
 
 #include "common.h"
 
+/*
+  The following MS C++ specific pragma embeds a comment in the resulting
+  object file. A "lib" comment tells the linker to use the specified 
+  library, thus the dependency is handled automagically.
+*/
+
+#ifdef _MSC_VER
+#pragma comment(lib, "Secur32")
+#endif
+
 static int win_auth_client_plugin_init(char*, size_t, int, va_list)
 {
   return 0;

=== modified file 'libmysqld/emb_qcache.cc'
--- a/libmysqld/emb_qcache.cc	2010-03-31 14:05:33 +0000
+++ b/libmysqld/emb_qcache.cc	2011-06-10 16:57:01 +0000
@@ -487,7 +487,7 @@ int emb_load_querycache_result(THD *thd,
   data->embedded_info->prev_ptr= prev_row;
 return_ok:
   net_send_eof(thd, thd->server_status,
-               thd->warning_info->statement_warn_count());
+               thd->get_stmt_wi()->statement_warn_count());
   DBUG_RETURN(0);
 err:
   DBUG_RETURN(1);

=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2011-05-26 15:20:09 +0000
+++ b/libmysqld/lib_sql.cc	2011-06-10 16:57:01 +0000
@@ -130,7 +130,7 @@ emb_advanced_command(MYSQL *mysql, enum
 
   /* Clear result variables */
   thd->clear_error();
-  thd->stmt_da->reset_diagnostics_area();
+  thd->get_stmt_da()->reset_diagnostics_area();
   mysql->affected_rows= ~(my_ulonglong) 0;
   mysql->field_count= 0;
   net_clear_error(net);
@@ -241,7 +241,7 @@ static my_bool emb_read_prepare_result(M
   stmt->stmt_id= thd->client_stmt_id;
   stmt->param_count= thd->client_param_count;
   stmt->field_count= 0;
-  mysql->warning_count= thd->warning_info->statement_warn_count();
+  mysql->warning_count= thd->get_stmt_wi()->statement_warn_count();
 
   if (thd->first_data)
   {
@@ -426,7 +426,7 @@ static void emb_free_embedded_thd(MYSQL
 static const char * emb_read_statistics(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  return thd->is_error() ? thd->stmt_da->message() : "";
+  return thd->is_error() ? thd->get_stmt_da()->message() : "";
 }
 
 
@@ -1047,7 +1047,7 @@ bool Protocol::send_result_set_metadata(
 
   if (flags & SEND_EOF)
     write_eof_packet(thd, thd->server_status,
-                     thd->warning_info->statement_warn_count());
+                     thd->get_stmt_wi()->statement_warn_count());
 
   DBUG_RETURN(prepare_for_send(list->elements));
  err:

=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2011-05-27 04:52:39 +0000
+++ b/mysql-test/collections/default.experimental	2011-06-13 04:17:23 +0000
@@ -6,14 +6,11 @@ binlog.binlog_multi_engine
 funcs_1.charset_collation_1              # depends on compile-time decisions
 
 main.func_math @freebsd                  # Bug#11751977 2010-05-04 alik main.func_math fails on FreeBSD in PB2
-main.gis-rtree @freebsd                  # Bug#11749418 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server
 main.lock_multi_bug38499                 # Bug#11755645 2009-09-19 alik main.lock_multi_bug38499 times out sporadically
 main.mysqlslap @windows                  # Bug#11761520 2010-08-10 alik mysqlslap fails sporadically starting from Dahlia
 main.signal_demo3 @solaris               # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 main.sp @solaris                         # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 main.subquery_sj_none @solaris          # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
-main.log_tables-big                      # Bug#11756699 2010-11-15 mattiasj report already exists
-main.type_float @freebsd                 # Bug#11749418 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server
 main.wait_timeout @solaris               # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris
 
 rpl.rpl_delayed_slave                    # BUG#11764654 rpl_delayed_slave fails sporadically in pb
@@ -22,6 +19,7 @@ rpl.rpl_heartbeat_basic
 rpl.rpl_row_sp011  @solaris              # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 rpl.rpl_seconds_behind_master            # BUG#11765124 2010-11-24 luis fails sporadically on pb2
 rpl.rpl_show_slave_running               # BUG#12346048 2011-04-11 sven fails sporadically on pb2
+rpl.rpl_change_master_dbug               # BUG#11933491 2011-06-13 Anitha  Test fails on redhat 
 
 sys_vars.max_sp_recursion_depth_func @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 sys_vars.wait_timeout_func                    # Bug#11750645 2010-04-26 alik wait_timeout_func fails
@@ -34,6 +32,3 @@ sys_vars.ndb_log_updated_only_basic
 sys_vars.rpl_init_slave_func		 # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5
 
 rpl_bhs.*                                # skozlov : WL#5139 - rpl_bhs suite generated "on-the-fly" at testing moment from rpl suite
-main.gis-rtree                           # svoj: due to BUG#11749418
-main.type_float                          # svoj: due to BUG#11749418
-main.type_newdecimal                     # svoj: due to BUG#11749418

=== modified file 'mysql-test/extra/rpl_tests/rpl_auto_increment.test'
--- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test	2010-12-21 10:39:20 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test	2011-05-02 13:52:51 +0000
@@ -256,4 +256,19 @@ connection master;
 DROP TABLE t1;
 sync_slave_with_master;
 
+#
+# WL#5872 "avoid using global heap memory to remember autoincrement
+# values for statement-based binlog".
+#
+connection master;
+eval create table t1(a int auto_increment primary key) engine=$engine_type;
+insert into t1 values (null),(null),(1025),(null);
+sync_slave_with_master;
+select * from t1;
+let $diff_tables= master:t1, slave:t1;
+--source include/diff_tables.inc
+connection master;
+drop table t1;
+sync_slave_with_master;
+
 --source include/rpl_end.inc

=== modified file 'mysql-test/include/icp_tests.inc'
--- a/mysql-test/include/icp_tests.inc	2011-03-24 13:16:36 +0000
+++ b/mysql-test/include/icp_tests.inc	2011-06-09 06:22:39 +0000
@@ -924,3 +924,43 @@ eval EXPLAIN $query;
 eval $query;
 
 DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+--echo #
+
+CREATE TABLE t1 (
+  pk INTEGER PRIMARY KEY, 
+  a INTEGER NOT NULL, 
+  b CHAR(1), 
+  KEY(b)
+);
+
+INSERT INTO t1 VALUES (23,5,'d');
+
+let query=
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+      AND (a1.a != a2.a OR a1.b IS NULL);
+
+eval EXPLAIN $query;
+eval $query;
+
+# Re-run the same query using a view. This will test the code with
+# an Item_ref object in the condition tree (note: in order for this
+# to trigger the bug the patch for Bug#59696 needs to be applied first).
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+let query=
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+      AND (a1.a != a2.a OR a1.b IS NULL);
+
+eval EXPLAIN $query;
+eval $query;
+
+DROP VIEW v1;
+DROP TABLE t1;

=== added file 'mysql-test/r/archive_debug.result'
--- a/mysql-test/r/archive_debug.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/archive_debug.result	2011-05-18 10:01:43 +0000
@@ -0,0 +1,12 @@
+#
+# BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK
+#                       WITH PARTITIONED ARCHIVE TABLES
+#
+CREATE TABLE t1(a INT) ENGINE=ARCHIVE;
+INSERT INTO t1 VALUES(1);
+SET SESSION debug='d,simulate_archive_open_failure';
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	error	Corrupt
+SET SESSION debug=DEFAULT;
+DROP TABLE t1;

=== modified file 'mysql-test/r/events_bugs.result'
--- a/mysql-test/r/events_bugs.result	2011-05-27 11:42:28 +0000
+++ b/mysql-test/r/events_bugs.result	2011-06-09 18:08:38 +0000
@@ -419,7 +419,7 @@ SET TIME_ZONE= '+04:00';
 ALTER EVENT e1 DO SELECT 2;
 SHOW EVENTS;
 Db	Name	Definer	Time zone	Type	Execute at	Interval value	Interval field	Starts	Ends	Status	Originator	character_set_client	collation_connection	Database Collation
-events_test	e1	root@localhost	-03:00	RECURRING	NULL	1	DAY	2005-12-31 20:58:59	2030-01-03 00:00:00	ENABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
+events_test	e1	root@localhost	-03:00	RECURRING	NULL	1	DAY	2005-12-31 20:58:59	2030-01-03 00:00:00	DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
 DROP EVENT e1;
 SET TIME_ZONE='+05:00';
 CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
@@ -796,6 +796,20 @@ COUNT(*)
 DROP EVENT IF EXISTS event_Bug12546938;
 DROP TABLE table_bug12546938;
 SET GLOBAL EVENT_SCHEDULER = OFF;
+DROP DATABASE IF EXISTS event_test11764334;
+CREATE DATABASE event_test11764334;
+USE event_test11764334;
+CREATE EVENT ev1 ON SCHEDULE EVERY 3 SECOND DISABLE DO SELECT 1;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+Db	Name	Definer	Time zone	Type	Execute at	Interval value	Interval field	Starts	Ends	Status	Originator	character_set_client	collation_connection	Database Collation
+event_test11764334	ev1	root@localhost	SYSTEM	RECURRING	NULL	3	SECOND	#	#	DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
+ALTER EVENT ev1 ON SCHEDULE EVERY 4 SECOND;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+Db	Name	Definer	Time zone	Type	Execute at	Interval value	Interval field	Starts	Ends	Status	Originator	character_set_client	collation_connection	Database Collation
+event_test11764334	ev1	root@localhost	SYSTEM	RECURRING	NULL	4	SECOND	#	#	DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
+DROP EVENT ev1;
+DROP DATABASE event_test11764334;
+USE test;
 DROP DATABASE events_test;
 SET GLOBAL event_scheduler= 'ON';
 SET @@global.concurrent_insert= @concurrent_insert;

=== modified file 'mysql-test/r/gis-precise.result'
--- a/mysql-test/r/gis-precise.result	2011-01-14 21:08:28 +0000
+++ b/mysql-test/r/gis-precise.result	2011-06-08 17:24:16 +0000
@@ -201,3 +201,28 @@ result
 SELECT ST_Equals(PointFromText('POINT (12 13)'),PointFromText('POINT (12 13)')) as result;
 result
 1
+#
+# BUG#11755628/47429: INTERSECTION FUNCTION CRASHED MYSQLD 
+# BUG#11759650/51979: UNION/INTERSECTION OF POLYGONS CRASHES MYSQL 
+#
+SELECT ASTEXT(ST_UNION(GEOMFROMTEXT('POLYGON((525000 183300,525400
+183300,525400 18370, 525000 183700,525000 183300))'),
+geomfromtext('POLYGON((525298.67 183511.53,525296.57
+183510.39,525296.42 183510.31,525289.11 183506.62,525283.17
+183503.47,525280.98 183502.26,525278.63 183500.97,525278.39
+183500.84,525276.79 183500,525260.7 183491.55,525263.95
+183484.75,525265.58 183481.95,525278.97 183488.73,525276.5
+183493.45,525275.5 183495.7,525280.35 183498.2,525282.3
+183499.1,525282.2 183499.3,525283.55 183500,525301.75
+183509.35,525304.45 183504.25,525307.85 183504.95,525304.5
+183510.83,525302.81 183513.8,525298.67 183511.53),(525275.06
+183489.89,525272.06 183488.37,525268.94 183494.51,525271.94
+183496.03,525275.06 183489.89),(525263.26 183491.55,525266.15
+183493.04,525269.88 183485.82,525266.99 183484.33,525263.26
+183491.55))'))) st_u;
+st_u
+MULTIPOLYGON(((525400 18370,525000.9677614468 183300,525400 183300,525400 18370)),((525000.9677614468 183300,525000 183300,525000 183700,525000.9677614468 183300)),((525265.58 183481.95,525263.95 183484.75,525260.7 183491.55,525276.79 183500,525278.39 183500.84,525278.63 183500.97,525280.98 183502.26,525283.17 183503.47,525289.11 183506.62,525296.42 183510.31,525296.57 183510.39,525298.67 183511.53,525302.81 183513.8,525304.5 183510.83,525307.85 183504.95,525304.45 183504.25,525301.75 183509.35,525283.55 183500,525282.2 183499.3,525282.3 183499.1,525280.35 183498.2,525275.5 183495.7,525276.5 183493.45,525278.97 183488.73,525265.58 183481.95),(525266.99 183484.33,525263.26 183491.55,525266.15 183493.04,525269.88 183485.82,525266.99 183484.33),(525272.06 183488.37,525268.94 183494.51,525271.94 183496.03,525275.06 183489.89,525272.06 183488.37)))
+SET @a=0x0000000001030000000200000005000000000000000000000000000000000000000000000000002440000000000000000000000000000024400000000000002440000000000000000000000000000024400000000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000400000000000000040000000000000F03F0000000000000040000000000000F03F000000000000F03F;
+SELECT ASTEXT(TOUCHES(@a, GEOMFROMTEXT('point(0 0)'))) t;
+t
+NULL

=== modified file 'mysql-test/r/gis-rtree.result'
--- a/mysql-test/r/gis-rtree.result	2010-10-28 09:54:31 +0000
+++ b/mysql-test/r/gis-rtree.result	2011-06-07 16:00:42 +0000
@@ -1535,3 +1535,30 @@ HANDLER t1 READ a NEXT;
 HANDLER t1 CLOSE;
 DROP TABLE t1;
 End of 5.0 tests.
+#
+# Bug #57323/11764487: myisam corruption with insert ignore 
+# and invalid spatial data
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=NULL;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+SELECT ASTEXT(a), ASTEXT(b) FROM t1;
+ASTEXT(a)	ASTEXT(b)
+POINT(0 0)	POINT(1 1)
+DROP TABLE t1;
+CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
+KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(0, GEOMFROMTEXT("point (1 1)"));
+INSERT IGNORE INTO t1 SET a=0, b=GEOMFROMTEXT("error");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT IGNORE INTO t1 SET a=1, b=NULL;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+SELECT a, ASTEXT(b) FROM t1;
+a	ASTEXT(b)
+0	POINT(1 1)
+DROP TABLE t1;
+End of 5.1 tests

=== modified file 'mysql-test/r/group_by.result'
--- a/mysql-test/r/group_by.result	2011-05-26 05:50:01 +0000
+++ b/mysql-test/r/group_by.result	2011-06-10 09:52:57 +0000
@@ -1967,3 +1967,23 @@ field1	field2
 DROP TABLE t1;
 DROP TABLE where_subselect;
 # End of Bug #58782
+#
+# Bug #11766429 
+# RE-EXECUTE OF PREPARED STATEMENT CRASHES IN ITEM_REF::FIX_FIELDS WITH
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2(b INT, KEY(b));
+INSERT INTO t2 VALUES (0),(0);
+PREPARE stmt FROM '
+SELECT 1 FROM t2
+LEFT JOIN t1 ON NULL
+GROUP BY t2.b, t1.a
+HAVING a <> 2';
+EXECUTE stmt;
+1
+EXECUTE stmt;
+1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1, t2;
+# End of Bug #11766429

=== modified file 'mysql-test/r/innodb_icp.result'
--- a/mysql-test/r/innodb_icp.result	2011-03-24 13:16:36 +0000
+++ b/mysql-test/r/innodb_icp.result	2011-06-09 06:22:39 +0000
@@ -871,5 +871,46 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	a1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set default_storage_engine= @save_storage_engine;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/innodb_icp_all.result'
--- a/mysql-test/r/innodb_icp_all.result	2011-03-29 08:10:26 +0000
+++ b/mysql-test/r/innodb_icp_all.result	2011-06-09 06:22:39 +0000
@@ -871,5 +871,46 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	a1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set default_storage_engine= @save_storage_engine;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/innodb_icp_none.result'
--- a/mysql-test/r/innodb_icp_none.result	2011-03-24 13:16:36 +0000
+++ b/mysql-test/r/innodb_icp_none.result	2011-06-09 06:22:39 +0000
@@ -870,5 +870,46 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	a1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t1	ref	b	b	2	const	1	Using where
+3	SUBQUERY	t1	index	NULL	b	2	NULL	1	Using index
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set default_storage_engine= @save_storage_engine;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_icp.result'
--- a/mysql-test/r/myisam_icp.result	2011-03-24 13:16:36 +0000
+++ b/mysql-test/r/myisam_icp.result	2011-06-09 06:22:39 +0000
@@ -868,4 +868,43 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_icp_all.result'
--- a/mysql-test/r/myisam_icp_all.result	2011-03-29 08:10:26 +0000
+++ b/mysql-test/r/myisam_icp_all.result	2011-06-09 06:22:39 +0000
@@ -868,4 +868,43 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_icp_none.result'
--- a/mysql-test/r/myisam_icp_none.result	2011-03-24 13:16:36 +0000
+++ b/mysql-test/r/myisam_icp_none.result	2011-06-09 06:22:39 +0000
@@ -867,4 +867,43 @@ i1
 1
 2
 DROP TABLE t1, t2, t3;
+#
+# Bug#12355958 "FAILING ASSERTION: TRX->LOCK.N_ACTIVE_THRS == 1"
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY, 
+a INTEGER NOT NULL, 
+b CHAR(1), 
+KEY(b)
+);
+INSERT INTO t1 VALUES (23,5,'d');
+EXPLAIN SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM t1 AS a1 JOIN (SELECT * FROM t1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM t1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+3	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t1	system	NULL	NULL	NULL	NULL	1	
+SELECT a1.pk 
+FROM v1 AS a1 JOIN (SELECT * FROM v1 LIMIT 1) AS a2 ON a2.b = a1.b
+WHERE a1.a = (SELECT pk FROM v1 LIMIT 1) 
+AND (a1.a != a2.a OR a1.b IS NULL);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2011-03-23 09:52:24 +0000
+++ b/mysql-test/r/partition.result	2011-06-13 10:55:58 +0000
@@ -1,5 +1,34 @@
 drop table if exists t1, t2;
 #
+# Bug#11765667: bug#58655: ASSERTION FAILED,
+#                          SERVER CRASHES WITH MYSQLD GOT SIGNAL 6
+#
+CREATE TABLE t1 (
+id MEDIUMINT NOT NULL AUTO_INCREMENT,
+dt DATE, st VARCHAR(255), uid INT,
+id2nd LONGBLOB, filler VARCHAR(255), PRIMARY KEY(id, dt)
+);
+INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
+('1991-03-14', 'Initial Insert', 200, 1234567, 'No Data'),
+('1991-02-26', 'Initial Insert', 201, 1234567, 'No Data'),
+('1992-03-16', 'Initial Insert', 234, 1234567, 'No Data'),
+('1992-07-02', 'Initial Insert', 287, 1234567, 'No Data'),
+('1991-05-26', 'Initial Insert', 256, 1234567, 'No Data'),
+('1991-04-25', 'Initial Insert', 222, 1234567, 'No Data'),
+('1993-03-12', 'Initial Insert', 267, 1234567, 'No Data'),
+('1993-03-14', 'Initial Insert', 291, 1234567, 'No Data'),
+('1991-12-20', 'Initial Insert', 298, 1234567, 'No Data'),
+('1994-10-31', 'Initial Insert', 220, 1234567, 'No Data');
+ALTER TABLE t1 PARTITION BY LIST (YEAR(dt)) (
+PARTITION d1 VALUES IN (1991, 1994),
+PARTITION d2 VALUES IN (1993),
+PARTITION d3 VALUES IN (1992, 1995, 1996)
+);
+INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
+('1991-07-14', 'After Partitioning Insert', 299, 1234567, 'Insert row');
+UPDATE t1 SET filler='Updating the row' WHERE uid=298;
+DROP TABLE t1;
+#
 # Bug#59297: Can't find record in 'tablename' on update inner join
 #
 CREATE TABLE t1 (
@@ -202,6 +231,15 @@ a	b
 2007-07-30 17:35:48	p1
 2009-07-14 17:35:55	pmax
 2009-09-21 17:31:42	pmax
+SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+a	b
+2007-07-30 17:35:48	p1
+EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	system	PRIMARY	NULL	NULL	NULL	1	
+EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	system	PRIMARY	NULL	NULL	NULL	1	
 ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
 PARTITION p3 VALUES LESS THAN (1247688000),
 PARTITION pmax VALUES LESS THAN MAXVALUE);
@@ -210,6 +248,15 @@ a	b
 2007-07-30 17:35:48	p1
 2009-07-14 17:35:55	pmax
 2009-09-21 17:31:42	pmax
+SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+a	b
+2007-07-30 17:35:48	p1
+EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	system	PRIMARY	NULL	NULL	NULL	1	
+EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	system	PRIMARY	NULL	NULL	NULL	1	
 SHOW CREATE TABLE t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (

=== modified file 'mysql-test/r/partition_datatype.result'
--- a/mysql-test/r/partition_datatype.result	2009-10-28 00:11:17 +0000
+++ b/mysql-test/r/partition_datatype.result	2011-06-13 09:57:47 +0000
@@ -338,3 +338,1003 @@ select hex(a) from t1 where a = 7;
 hex(a)
 7
 drop table t1;
+#
+# Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic
+#            by partition pruning
+SET @old_time_zone= @@session.time_zone;
+SET @@session.time_zone = 'UTC';
+# Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS
+CREATE TABLE t1
+(a TIMESTAMP NULL,
+tz varchar(16))
+ENGINE = MyISAM;
+CREATE TABLE t2 LIKE t1;
+ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
+(PARTITION `p0` VALUES LESS THAN (0),
+PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01')),
+PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP('2011-03-26 23:00:00')),
+PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 22:00:00')),
+PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 23:00:00')),
+PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-30 00:00:00')),
+PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP('2012-03-24 23:00:00')),
+PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP('2038-01-19 03:14:07')),
+PARTITION `pMax` VALUES LESS THAN MAXVALUE);
+# Test 'odd' values
+INSERT INTO t1 VALUES (NULL, 'UTC');
+INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'UTC');
+# Test invalid values
+INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'UTCI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'UTCI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+# Test start range
+INSERT INTO t1 VALUES ('1970-01-01 00:00:01', 'UTC');
+INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'UTC');
+# Test end range
+INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC');
+INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC');
+# Test Daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-26 22:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-03-26 23:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-03-26 23:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 21:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-30 00:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-30 00:00:01', 'UTC');
+SET @@session.time_zone = 'Europe/Moscow';
+# Test 'odd' values
+INSERT INTO t1 VALUES (NULL, 'Moscow');
+INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'Moscow');
+# Test invalid values
+INSERT INTO t1 VALUES ('0000-00-00 03:00:00', 'MoscowI');
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'MoscowI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'MoscowI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('1970-01-01 02:29:29', 'MoscowI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('2038-01-19 06:14:08', 'MoscowI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+INSERT INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+# values truncated to 03:00:00 due to daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-27 02:00:00', 'MoscowI');
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 1
+INSERT INTO t1 VALUES ('2011-03-27 02:00:01', 'MoscowI');
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 1
+INSERT INTO t1 VALUES ('2011-03-27 02:59:59', 'MoscowI');
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 1
+# Test start range
+INSERT INTO t1 VALUES ('1970-01-01 03:00:01', 'Moscow');
+INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'Moscow');
+# Test end range
+INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow');
+INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow');
+# Test Daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-27 01:59:59', 'Moscow');
+INSERT INTO t1 VALUES ('2011-03-27 03:00:00', 'Moscow');
+INSERT INTO t1 VALUES ('2011-03-27 03:00:01', 'Moscow');
+INSERT INTO t1 VALUES ('2011-10-30 01:59:59', 'Moscow');
+# All values between 02:00 and 02:59:59 will be interpretated as DST
+INSERT INTO t1 VALUES ('2011-10-30 02:00:00', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 02:00:01', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 02:59:59', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 03:00:00', 'Moscow');
+INSERT INTO t1 VALUES ('2011-10-30 03:00:01', 'Moscow');
+SET @@session.time_zone = 'UTC';
+INSERT INTO t2 SELECT * FROM t1;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	2
+p-2000	16
+p-2011-MSK	2
+p-2011-MSD-1	9
+p-2011-MSD-2	6
+p-2012-MSK-1	3
+p-2012-MSK-2	4
+pEnd	2
+pMax	2
+SELECT * FROM t1 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	UTC
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+1970-01-01 00:00:01	Moscow
+1970-01-01 00:00:01	UTC
+1974-02-05 18:28:16	Moscow
+1974-02-05 21:28:16	UTC
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	UTC
+2011-10-29 21:59:59	Moscow
+2011-10-29 21:59:59	UTC
+2011-10-29 22:00:00	MoscowD
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:59:59	UTC
+2011-10-30 00:00:00	Moscow
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+2038-01-19 03:14:06	Moscow
+2038-01-19 03:14:06	UTC
+2038-01-19 03:14:07	Moscow
+2038-01-19 03:14:07	UTC
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	UTC
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+1970-01-01 00:00:01	Moscow
+1970-01-01 00:00:01	UTC
+1974-02-05 18:28:16	Moscow
+1974-02-05 21:28:16	UTC
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	UTC
+2011-10-29 21:59:59	Moscow
+2011-10-29 21:59:59	UTC
+2011-10-29 22:00:00	MoscowD
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:59:59	UTC
+2011-10-30 00:00:00	Moscow
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+2038-01-19 03:14:06	Moscow
+2038-01-19 03:14:06	UTC
+2038-01-19 03:14:07	Moscow
+2038-01-19 03:14:07	UTC
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
+a	tz
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK,p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	11	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
+a	tz
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK	ALL	NULL	NULL	NULL	NULL	2	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+a	tz
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK,p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	11	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+a	tz
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	9	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
+a	tz
+2011-10-29 21:59:59	Moscow
+2011-10-29 21:59:59	UTC
+2011-10-29 22:00:00	MoscowD
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+2011-10-29 23:00:00	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2,p-2012-MSK-1	ALL	NULL	NULL	NULL	NULL	18	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
+a	tz
+2011-10-29 21:59:59	Moscow
+2011-10-29 21:59:59	UTC
+2011-10-29 22:00:00	MoscowD
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2	ALL	NULL	NULL	NULL	NULL	15	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:59:59	UTC
+2011-10-30 00:00:00	Moscow
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-2,p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	13	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:59:59	UTC
+2011-10-30 00:00:00	Moscow
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	7	Using where; Using filesort
+# Test end range changes
+DELETE FROM t2 WHERE a = 0;
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+35
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+1
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	UTC
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+a	tz
+2038-01-19 03:14:07	Moscow
+2038-01-19 03:14:07	UTC
+2038-01-19 03:14:06	Moscow
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 34
+Warning	1264	Out of range value for column 'a' at row 35
+SELECT MIN(a), MAX(a) FROM t2;
+MIN(a)	MAX(a)
+0000-00-00 00:00:00	2038-01-19 03:14:07
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+35
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+2
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	3
+p-2000	6
+p-2011-MSK	0
+p-2011-MSD-1	9
+p-2011-MSD-2	6
+p-2012-MSK-1	4
+p-2012-MSK-2	5
+pEnd	0
+pMax	2
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	UTC
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	UTC
+1970-01-01 00:00:02	Moscow
+1970-01-01 00:00:02	UTC
+1974-02-05 18:28:17	Moscow
+1974-02-05 21:28:17	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	MoscowI
+2011-03-26 23:00:01	MoscowI
+2011-03-26 23:00:01	MoscowI
+2011-03-26 23:00:01	UTC
+2011-03-26 23:00:02	Moscow
+2011-03-26 23:00:02	UTC
+2011-10-29 22:00:00	Moscow
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:00:02	MoscowD
+2011-10-29 22:00:02	UTC
+2011-10-29 23:00:00	MoscowD
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:00:02	UTC
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+2011-10-30 00:00:02	Moscow
+2011-10-30 00:00:02	UTC
+2038-01-19 03:14:07	Moscow
+2038-01-19 03:14:07	UTC
+# Test start range changes
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+36
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+3
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+a	tz
+NULL	Moscow
+NULL	UTC
+NULL	UTC
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+a	tz
+2038-01-19 03:14:07	Moscow
+2038-01-19 03:14:07	UTC
+2011-10-30 00:00:02	Moscow
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
+SELECT MIN(a), MAX(a) FROM t2;
+MIN(a)	MAX(a)
+1970-01-01 00:00:01	2038-01-19 03:14:06
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+36
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+0
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	6
+p-2000	4
+p-2011-MSK	2
+p-2011-MSD-1	9
+p-2011-MSD-2	6
+p-2012-MSK-1	3
+p-2012-MSK-2	4
+pEnd	2
+pMax	0
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	Moscow
+NULL	UTC
+NULL	UTC
+NULL	UTC
+NULL	UTC
+1970-01-01 00:00:01	Moscow
+1970-01-01 00:00:01	UTC
+1974-02-05 18:28:16	Moscow
+1974-02-05 21:28:16	UTC
+2011-03-26 22:59:59	Moscow
+2011-03-26 22:59:59	UTC
+2011-03-26 23:00:00	Moscow
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	MoscowI
+2011-03-26 23:00:00	UTC
+2011-03-26 23:00:01	Moscow
+2011-03-26 23:00:01	UTC
+2011-10-29 21:59:59	Moscow
+2011-10-29 21:59:59	UTC
+2011-10-29 22:00:00	MoscowD
+2011-10-29 22:00:00	UTC
+2011-10-29 22:00:01	MoscowD
+2011-10-29 22:00:01	UTC
+2011-10-29 22:59:59	MoscowD
+2011-10-29 22:59:59	UTC
+2011-10-29 23:00:00	UTC
+2011-10-29 23:00:01	UTC
+2011-10-29 23:59:59	UTC
+2011-10-30 00:00:00	Moscow
+2011-10-30 00:00:00	UTC
+2011-10-30 00:00:01	Moscow
+2011-10-30 00:00:01	UTC
+2038-01-19 03:14:06	Moscow
+2038-01-19 03:14:06	UTC
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` timestamp NULL DEFAULT NULL,
+  `tz` varchar(16) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
+(PARTITION p0 VALUES LESS THAN (0) ENGINE = MyISAM,
+ PARTITION `p-2000` VALUES LESS THAN (946684800) ENGINE = MyISAM,
+ PARTITION `p-2011-MSK` VALUES LESS THAN (1301180400) ENGINE = MyISAM,
+ PARTITION `p-2011-MSD-1` VALUES LESS THAN (1319925600) ENGINE = MyISAM,
+ PARTITION `p-2011-MSD-2` VALUES LESS THAN (1319929200) ENGINE = MyISAM,
+ PARTITION `p-2012-MSK-1` VALUES LESS THAN (1319932800) ENGINE = MyISAM,
+ PARTITION `p-2012-MSK-2` VALUES LESS THAN (1332630000) ENGINE = MyISAM,
+ PARTITION pEnd VALUES LESS THAN (2147483647) ENGINE = MyISAM,
+ PARTITION pMax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+TRUNCATE TABLE t2;
+SET @@session.time_zone = 'Europe/Moscow';
+INSERT INTO t2 SELECT * FROM t1;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	2
+p-2000	16
+p-2011-MSK	2
+p-2011-MSD-1	9
+p-2011-MSD-2	6
+p-2012-MSK-1	3
+p-2012-MSK-2	4
+pEnd	2
+pMax	2
+SELECT * FROM t1 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	UTC
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+1970-01-01 03:00:01	Moscow
+1970-01-01 03:00:01	UTC
+1974-02-05 21:28:16	Moscow
+1974-02-06 00:28:16	UTC
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	UTC
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+2038-01-19 06:14:06	Moscow
+2038-01-19 06:14:06	UTC
+2038-01-19 06:14:07	Moscow
+2038-01-19 06:14:07	UTC
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	MoscowI
+0000-00-00 00:00:00	UTC
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+0000-00-00 00:00:00	UTCI
+1970-01-01 03:00:01	Moscow
+1970-01-01 03:00:01	UTC
+1974-02-05 21:28:16	Moscow
+1974-02-06 00:28:16	UTC
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	UTC
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+2038-01-19 06:14:06	Moscow
+2038-01-19 06:14:06	UTC
+2038-01-19 06:14:07	Moscow
+2038-01-19 06:14:07	UTC
+# Testing the leap from 01:59:59 to 03:00:00
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
+a	tz
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK,p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	11	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
+a	tz
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK	ALL	NULL	NULL	NULL	NULL	2	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+a	tz
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK,p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	11	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+a	tz
+2011-03-27 01:59:59	Moscow
+2011-03-27 01:59:59	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSK,p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	11	Using where; Using filesort
+# Testing the leap from 02:59:59 to 02:00:00
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
+a	tz
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	9	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
+a	tz
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	9	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
+a	tz
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	9	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
+a	tz
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1	ALL	NULL	NULL	NULL	NULL	9	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2,p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	22	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2,p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	22	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2,p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	22	Using where; Using filesort
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+a	tz
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	p-2011-MSD-1,p-2011-MSD-2,p-2012-MSK-1,p-2012-MSK-2	ALL	NULL	NULL	NULL	NULL	22	Using where; Using filesort
+# Test end range changes
+DELETE FROM t2 WHERE a = 0;
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+35
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+1
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+a	tz
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+a	tz
+2038-01-19 06:14:07	Moscow
+2038-01-19 06:14:07	UTC
+2038-01-19 06:14:06	Moscow
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 8
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 9
+Warning	1264	Out of range value for column 'a' at row 34
+Warning	1264	Out of range value for column 'a' at row 35
+SELECT MIN(a), MAX(a) FROM t2;
+MIN(a)	MAX(a)
+0000-00-00 00:00:00	2038-01-19 06:14:07
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+35
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+2
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	3
+p-2000	6
+p-2011-MSK	0
+p-2011-MSD-1	9
+p-2011-MSD-2	8
+p-2012-MSK-1	0
+p-2012-MSK-2	7
+pEnd	0
+pMax	2
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	Moscow
+NULL	UTC
+0000-00-00 00:00:00	Moscow
+0000-00-00 00:00:00	UTC
+1970-01-01 03:00:02	Moscow
+1970-01-01 03:00:02	UTC
+1974-02-05 21:28:17	Moscow
+1974-02-06 00:28:17	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	MoscowI
+2011-03-27 03:00:01	MoscowI
+2011-03-27 03:00:01	MoscowI
+2011-03-27 03:00:01	UTC
+2011-03-27 03:00:02	Moscow
+2011-03-27 03:00:02	UTC
+2011-10-30 02:00:00	Moscow
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:00:02	MoscowD
+2011-10-30 02:00:02	UTC
+2011-10-30 02:00:02	UTC
+2011-10-30 03:00:00	MoscowD
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+2011-10-30 03:00:02	Moscow
+2011-10-30 03:00:02	UTC
+2038-01-19 06:14:07	Moscow
+2038-01-19 06:14:07	UTC
+# Test start range changes
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+36
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+3
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+a	tz
+NULL	Moscow
+NULL	Moscow
+NULL	UTC
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+a	tz
+2038-01-19 06:14:07	Moscow
+2038-01-19 06:14:07	UTC
+2011-10-30 03:00:02	Moscow
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 18
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 19
+SELECT MIN(a), MAX(a) FROM t2;
+MIN(a)	MAX(a)
+1970-01-01 03:00:01	2038-01-19 06:14:06
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+36
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+COUNT(*)
+0
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+PARTITION_NAME	TABLE_ROWS
+p0	6
+p-2000	4
+p-2011-MSK	0
+p-2011-MSD-1	11
+p-2011-MSD-2	9
+p-2012-MSK-1	0
+p-2012-MSK-2	4
+pEnd	2
+pMax	0
+SELECT * FROM t2 ORDER BY a, tz;
+a	tz
+NULL	Moscow
+NULL	Moscow
+NULL	Moscow
+NULL	Moscow
+NULL	UTC
+NULL	UTC
+1970-01-01 03:00:01	Moscow
+1970-01-01 03:00:01	UTC
+1974-02-05 21:28:16	Moscow
+1974-02-06 00:28:16	UTC
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	Moscow
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	MoscowI
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:00	UTC
+2011-03-27 03:00:01	Moscow
+2011-03-27 03:00:01	UTC
+2011-10-30 01:59:59	Moscow
+2011-10-30 01:59:59	UTC
+2011-10-30 02:00:00	MoscowD
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:00	UTC
+2011-10-30 02:00:01	MoscowD
+2011-10-30 02:00:01	UTC
+2011-10-30 02:00:01	UTC
+2011-10-30 02:59:59	MoscowD
+2011-10-30 02:59:59	UTC
+2011-10-30 02:59:59	UTC
+2011-10-30 03:00:00	Moscow
+2011-10-30 03:00:00	UTC
+2011-10-30 03:00:01	Moscow
+2011-10-30 03:00:01	UTC
+2038-01-19 06:14:06	Moscow
+2038-01-19 06:14:06	UTC
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` timestamp NULL DEFAULT NULL,
+  `tz` varchar(16) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
+(PARTITION p0 VALUES LESS THAN (0) ENGINE = MyISAM,
+ PARTITION `p-2000` VALUES LESS THAN (946684800) ENGINE = MyISAM,
+ PARTITION `p-2011-MSK` VALUES LESS THAN (1301180400) ENGINE = MyISAM,
+ PARTITION `p-2011-MSD-1` VALUES LESS THAN (1319925600) ENGINE = MyISAM,
+ PARTITION `p-2011-MSD-2` VALUES LESS THAN (1319929200) ENGINE = MyISAM,
+ PARTITION `p-2012-MSK-1` VALUES LESS THAN (1319932800) ENGINE = MyISAM,
+ PARTITION `p-2012-MSK-2` VALUES LESS THAN (1332630000) ENGINE = MyISAM,
+ PARTITION pEnd VALUES LESS THAN (2147483647) ENGINE = MyISAM,
+ PARTITION pMax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+TRUNCATE TABLE t2;
+DROP TABLE t1, t2;
+SET @@session.time_zone= @old_time_zone;

=== modified file 'mysql-test/r/query_cache_28249.result'
--- a/mysql-test/r/query_cache_28249.result	2008-11-28 15:45:34 +0000
+++ b/mysql-test/r/query_cache_28249.result	2011-06-10 09:40:57 +0000
@@ -8,7 +8,7 @@ SET @query_cache_size=         @@global.
 SET GLOBAL query_cache_type=1;
 SET GLOBAL query_cache_limit=10000;
 SET GLOBAL query_cache_min_res_unit=0;
-SET GLOBAL query_cache_size= 100000;
+SET GLOBAL query_cache_size= 102400;
 FLUSH TABLES;
 DROP TABLE IF EXISTS t1, t2;
 CREATE TABLE t1 (a INT);
@@ -23,10 +23,10 @@ SELECT *, (SELECT COUNT(*) FROM t2) FROM
 # Switch to connection user3
 # Poll till the select of connection user1 is blocked by the write lock on t1.
 SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = 'Waiting for table metadata lock'
   AND info = 'SELECT *, (SELECT COUNT(*) FROM t2) FROM t1';
 user	command	state	info
-root	Query	Locked	SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+root	Query	Waiting for table metadata lock	SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
 INSERT INTO t1 VALUES (4);
 # Switch to connection user2
 UNLOCK TABLES;

=== modified file 'mysql-test/r/sp_notembedded.result'
--- a/mysql-test/r/sp_notembedded.result	2011-03-18 14:16:17 +0000
+++ b/mysql-test/r/sp_notembedded.result	2011-06-08 13:44:50 +0000
@@ -254,7 +254,6 @@ CREATE PROCEDURE p1(i INT) BEGIN END;
 DROP PROCEDURE p1;
 DELETE FROM mysql.user WHERE User='mysqltest_1';
 FLUSH PRIVILEGES;
-set @@global.concurrent_insert= @old_concurrent_insert;
 #
 # Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
 #
@@ -288,3 +287,25 @@ DROP FUNCTION f1;
 # ------------------------------------------------------------------
 # -- End of 5.1 tests
 # ------------------------------------------------------------------
+#
+# Test for bug#11763757 "56510: ERROR 42000: FUNCTION DOES NOT EXIST
+# IF NOT-PRIV USER RECONNECTS ".
+#
+# The real problem was that server was unable handle properly stored
+# functions in databases which names contained dot.
+#
+DROP DATABASE IF EXISTS `my.db`;
+create database `my.db`;
+use `my.db`;
+CREATE FUNCTION f1(a int) RETURNS INT RETURN a;
+# Create new connection.
+USE `my.db`;
+SELECT f1(1);
+f1(1)
+1
+SELECT `my.db`.f1(2);
+`my.db`.f1(2)
+2
+# Switching to default connection.
+DROP DATABASE `my.db`;
+set @@global.concurrent_insert= @old_concurrent_insert;

=== modified file 'mysql-test/r/symlink.result'
--- a/mysql-test/r/symlink.result	2011-01-31 09:34:39 +0000
+++ b/mysql-test/r/symlink.result	2011-06-09 12:54:12 +0000
@@ -188,3 +188,28 @@ DROP TABLE user;
 FLUSH TABLE mysql.user;
 SELECT * FROM mysql.user;
 End of 5.1 tests
+#
+# Test for bug #11759990 - "52354: 'CREATE TABLE .. LIKE ... '
+#                           STATEMENTS FAIL".
+#
+drop table if exists t1, t2;
+create table t1 (a int primary key) engine=myisam
+data directory="MYSQLTEST_VARDIR/tmp"
+      index directory="MYSQLTEST_VARDIR/run";
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/'
+# CREATE TABLE LIKE statement on table with INDEX/DATA DIRECTORY
+# options should not fail. Per documentation newly created table
+# should not inherit value of these options from the original table.
+create table t2 like t1;
+show create table t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop tables t1, t2;

=== modified file 'mysql-test/r/trigger-compat.result'
--- a/mysql-test/r/trigger-compat.result	2010-02-03 21:48:40 +0000
+++ b/mysql-test/r/trigger-compat.result	2011-06-10 07:20:15 +0000
@@ -41,3 +41,98 @@ DROP TABLE t2;
 DROP USER mysqltest_dfn@localhost;
 DROP USER mysqltest_inv@localhost;
 DROP DATABASE mysqltest_db1;
+USE test;
+#
+# Bug#45235: 5.1 does not support 5.0-only syntax triggers in any way
+#
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (2), (3);
+INSERT INTO t3 VALUES (1), (2), (3);
+# We simulate importing a trigger from 5.0 by writing a .TRN file for
+# each trigger plus a .TRG file the way MySQL 5.0 would have done it, 
+# with syntax allowed in 5.0 only.
+#
+# Note that in 5.0 the following lines are missing from t1.TRG:
+#
+# client_cs_names='latin1'
+# connection_cl_names='latin1_swedish_ci'
+# db_cl_names='latin1_swedish_ci'
+FLUSH TABLE t1;
+FLUSH TABLE t2;
+# We will get parse errors for most DDL and DML statements when the table
+# has broken triggers. The parse error refers to the first broken 
+# trigger.
+CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
+ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a USING t1 a' at line 1'
+CREATE TRIGGER tr22 BEFORE INSERT ON t2 FOR EACH ROW DELETE FROM non_existing_table;
+ERROR 42000: Unknown trigger has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Not allowed syntax here, and trigger name cant be extracted either.' at line 1'
+SHOW TRIGGERS;
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	character_set_client	collation_connection	Database Collation
+tr11	INSERT	t1	DELETE FROM t3	BEFORE	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+tr12	INSERT	t1	DELETE FROM t3	AFTER	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+tr14	DELETE	t1	DELETE FROM non_existing_table	AFTER	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+INSERT INTO t1 VALUES (1);
+ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a USING t1 a' at line 1'
+INSERT INTO t2 VALUES (1);
+ERROR 42000: Unknown trigger has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Not allowed syntax here, and trigger name cant be extracted either.' at line 1'
+DELETE FROM t1;
+ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a USING t1 a' at line 1'
+UPDATE t1 SET a = 1 WHERE a = 1;
+ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a USING t1 a' at line 1'
+SELECT * FROM t1;
+a
+1
+2
+3
+RENAME TABLE t1 TO t1_2;
+ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a USING t1 a' at line 1'
+SHOW TRIGGERS;
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	character_set_client	collation_connection	Database Collation
+tr11	INSERT	t1	DELETE FROM t3	BEFORE	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+tr12	INSERT	t1	DELETE FROM t3	AFTER	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+tr14	DELETE	t1	DELETE FROM non_existing_table	AFTER	NULL		root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+DROP TRIGGER tr11;
+Warnings:
+Warning	1603	Triggers for table `test`.`t1` have no creation context
+DROP TRIGGER tr12;
+DROP TRIGGER tr13;
+DROP TRIGGER tr14;
+DROP TRIGGER tr15;
+SHOW TRIGGERS;
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	character_set_client	collation_connection	Database Collation
+# Make sure there is no trigger file left.
+# We write the same trigger files one more time to test DROP TABLE.
+FLUSH TABLE t1;
+FLUSH TABLE t2;
+DROP TABLE t1;
+Warnings:
+Warning	1603	Triggers for table `test`.`t1` have no creation context
+DROP TABLE t2;
+Warnings:
+Warning	1603	Triggers for table `test`.`t2` have no creation context
+DROP TABLE t3;
+# Make sure there is no trigger file left.
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (2), (3);
+# We write three trigger files. First trigger is syntaxically incorrect, next trigger is correct
+# and last trigger is broken.
+# Next we try to execute SHOW CREATE TRGGIR command for broken trigger and then try to drop one.
+FLUSH TABLE t1;
+SHOW CREATE TRIGGER tr12;
+Trigger	sql_mode	SQL Original Statement	character_set_client	collation_connection	Database Collation
+tr12		CREATE DEFINER=`root`@`localhost` TRIGGER tr12 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t2	latin1	latin1_swedish_ci	latin1_swedish_ci
+Warnings:
+Warning	1603	Triggers for table `test`.`t1` have no creation context
+SHOW CREATE TRIGGER tr11;
+Trigger	sql_mode	SQL Original Statement	character_set_client	collation_connection	Database Collation
+tr11		CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a	latin1	latin1_swedish_ci	latin1_swedish_ci
+DROP TRIGGER tr12;
+DROP TRIGGER tr11;
+DROP TABLE t1;
+DROP TABLE t2;

=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result	2011-05-09 08:48:22 +0000
+++ b/mysql-test/r/trigger.result	2011-06-10 13:31:09 +0000
@@ -2106,7 +2106,7 @@ CREATE TRIGGER trg1 BEFORE INSERT ON t2
 SHOW TRIGGERS IN db1;
 Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	character_set_client	collation_connection	Database Collation
 INSERT INTO t2 VALUES (1);
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1 VALUES (1)' at line 1
+ERROR 42000: Trigger 'trg1' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1 VALUES (1)' at line 1'
 SELECT * FROM t1;
 b
 # Work around Bug#45235

=== modified file 'mysql-test/r/type_datetime.result'
--- a/mysql-test/r/type_datetime.result	2011-01-19 14:39:13 +0000
+++ b/mysql-test/r/type_datetime.result	2011-06-10 08:34:13 +0000
@@ -704,5 +704,51 @@ b
 DROP TABLE t1;
 #
 #
+# BUG#12561818: RERUN OF STORED FUNCTION GIVES ERROR 1172: 
+#               RESULT CONSISTED OF MORE THAN ONE ROW
+#
+CREATE TABLE t1 (a DATE NOT NULL, b INT);
+INSERT INTO t1 VALUES ('0000-00-00',1), ('1999-05-10',2);
+CREATE TABLE t2 (a DATETIME NOT NULL, b INT);
+INSERT INTO t2 VALUES ('0000-00-00 00:00:00',1), ('1999-05-10 00:00:00',2);
+
+SELECT * FROM t1 WHERE a IS NULL;
+a	b
+0000-00-00	1
+SELECT * FROM t2 WHERE a IS NULL;
+a	b
+0000-00-00 00:00:00	1
+SELECT * FROM t1 LEFT JOIN t1 AS t1_2 ON 1 WHERE t1_2.a IS NULL;
+a	b	a	b
+0000-00-00	1	0000-00-00	1
+1999-05-10	2	0000-00-00	1
+SELECT * FROM t2 LEFT JOIN t2 AS t2_2 ON 1 WHERE t2_2.a IS NULL;
+a	b	a	b
+0000-00-00 00:00:00	1	0000-00-00 00:00:00	1
+1999-05-10 00:00:00	2	0000-00-00 00:00:00	1
+SELECT * FROM t1 JOIN t1 AS t1_2 ON 1 WHERE t1_2.a IS NULL;
+a	b	a	b
+0000-00-00	1	0000-00-00	1
+1999-05-10	2	0000-00-00	1
+SELECT * FROM t2 JOIN t2 AS t2_2 ON 1 WHERE t2_2.a IS NULL;
+a	b	a	b
+0000-00-00 00:00:00	1	0000-00-00 00:00:00	1
+1999-05-10 00:00:00	2	0000-00-00 00:00:00	1
+
+PREPARE stmt1 FROM 
+'SELECT *
+   FROM t1 LEFT JOIN t1 AS t1_2 ON 1
+   WHERE t1_2.a IS NULL AND t1_2.b < 2';
+EXECUTE stmt1;
+a	b	a	b
+0000-00-00	1	0000-00-00	1
+1999-05-10	2	0000-00-00	1
+EXECUTE stmt1;
+a	b	a	b
+0000-00-00	1	0000-00-00	1
+1999-05-10	2	0000-00-00	1
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1,t2;
+#
 # End of 5.5 tests
 #

=== modified file 'mysql-test/suite/rpl/r/rpl_auto_increment.result'
--- a/mysql-test/suite/rpl/r/rpl_auto_increment.result	2010-12-21 04:47:22 +0000
+++ b/mysql-test/suite/rpl/r/rpl_auto_increment.result	2011-05-02 13:52:51 +0000
@@ -320,4 +320,14 @@ SELECT * FROM t1;
 id	data
 0	2
 DROP TABLE t1;
+create table t1(a int auto_increment primary key) engine=innodb;
+insert into t1 values (null),(null),(1025),(null);
+select * from t1;
+a
+1
+2
+1025
+1026
+include/diff_tables.inc [master:t1, slave:t1]
+drop table t1;
 include/rpl_end.inc

=== added file 'mysql-test/t/archive_debug.test'
--- a/mysql-test/t/archive_debug.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/archive_debug.test	2011-05-18 10:01:43 +0000
@@ -0,0 +1,13 @@
+--source include/have_archive.inc
+--source include/have_debug.inc
+
+--echo #
+--echo # BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK
+--echo #                       WITH PARTITIONED ARCHIVE TABLES
+--echo #
+CREATE TABLE t1(a INT) ENGINE=ARCHIVE;
+INSERT INTO t1 VALUES(1);
+SET SESSION debug='d,simulate_archive_open_failure';
+CHECK TABLE t1;
+SET SESSION debug=DEFAULT;
+DROP TABLE t1;

=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def	2011-05-25 14:10:40 +0000
+++ b/mysql-test/t/disabled.def	2011-06-10 10:05:22 +0000
@@ -15,4 +15,4 @@ sum_distinct-big         : Bug#11764126
 alter_table-big          : Bug#11748731 2010-11-15 mattiasj was not tested
 create-big               : Bug#11748731 2010-11-15 mattiasj was not tested
 archive-big              : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc
-main.query_cache_28249   : Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically
+log_tables-big           : Bug#11756699 2010-11-15 mattiasj report already exists

=== modified file 'mysql-test/t/events_bugs.test'
--- a/mysql-test/t/events_bugs.test	2011-05-27 11:42:28 +0000
+++ b/mysql-test/t/events_bugs.test	2011-06-09 18:08:38 +0000
@@ -1286,6 +1286,23 @@ DROP EVENT IF EXISTS event_Bug12546938;
 DROP TABLE table_bug12546938;
 SET GLOBAL EVENT_SCHEDULER = OFF;
 
+#
+# Bug#11764334 - 57156: ALTER EVENT CHANGES THE EVENT STATUS
+#
+--disable_warnings
+DROP DATABASE IF EXISTS event_test11764334;
+--enable_warnings
+CREATE DATABASE event_test11764334;
+USE event_test11764334;
+CREATE EVENT ev1 ON SCHEDULE EVERY 3 SECOND DISABLE DO SELECT 1;
+--replace_column 9 # 10 #
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+ALTER EVENT ev1 ON SCHEDULE EVERY 4 SECOND;
+--replace_column 9 # 10 #
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+DROP EVENT ev1;
+DROP DATABASE event_test11764334;
+USE test; 
 ###########################################################################
 #
 # End of tests

=== modified file 'mysql-test/t/gis-precise.test'
--- a/mysql-test/t/gis-precise.test	2011-01-14 21:08:28 +0000
+++ b/mysql-test/t/gis-precise.test	2011-06-08 17:24:16 +0000
@@ -108,3 +108,28 @@ select st_touches(geomfromtext('polygon(
 SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 19, 59 13, 59 13, 67 13) )')) as result;
 SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 18, 59 13, 59 13, 67 13) )')) as result;
 SELECT ST_Equals(PointFromText('POINT (12 13)'),PointFromText('POINT (12 13)')) as result;
+
+
+--echo #
+--echo # BUG#11755628/47429: INTERSECTION FUNCTION CRASHED MYSQLD 
+--echo # BUG#11759650/51979: UNION/INTERSECTION OF POLYGONS CRASHES MYSQL 
+--echo #
+
+SELECT ASTEXT(ST_UNION(GEOMFROMTEXT('POLYGON((525000 183300,525400
+183300,525400 18370, 525000 183700,525000 183300))'),
+geomfromtext('POLYGON((525298.67 183511.53,525296.57
+183510.39,525296.42 183510.31,525289.11 183506.62,525283.17
+183503.47,525280.98 183502.26,525278.63 183500.97,525278.39
+183500.84,525276.79 183500,525260.7 183491.55,525263.95
+183484.75,525265.58 183481.95,525278.97 183488.73,525276.5
+183493.45,525275.5 183495.7,525280.35 183498.2,525282.3
+183499.1,525282.2 183499.3,525283.55 183500,525301.75
+183509.35,525304.45 183504.25,525307.85 183504.95,525304.5
+183510.83,525302.81 183513.8,525298.67 183511.53),(525275.06
+183489.89,525272.06 183488.37,525268.94 183494.51,525271.94
+183496.03,525275.06 183489.89),(525263.26 183491.55,525266.15
+183493.04,525269.88 183485.82,525266.99 183484.33,525263.26
+183491.55))'))) st_u;
+
+SET @a=0x0000000001030000000200000005000000000000000000000000000000000000000000000000002440000000000000000000000000000024400000000000002440000000000000000000000000000024400000000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000040000000000000F03F00000000000000400000000000000040000000000000F03F0000000000000040000000000000F03F000000000000F03F;
+SELECT ASTEXT(TOUCHES(@a, GEOMFROMTEXT('point(0 0)'))) t;

=== modified file 'mysql-test/t/gis-rtree.test'
--- a/mysql-test/t/gis-rtree.test	2010-03-25 11:49:01 +0000
+++ b/mysql-test/t/gis-rtree.test	2011-06-07 15:30:43 +0000
@@ -928,3 +928,31 @@ DROP TABLE t1;
 
 
 --echo End of 5.0 tests.
+
+
+--echo #
+--echo # Bug #57323/11764487: myisam corruption with insert ignore 
+--echo # and invalid spatial data
+--echo #
+
+CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+  SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=NULL;
+SELECT ASTEXT(a), ASTEXT(b) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1(a INT NOT NULL, b GEOMETRY NOT NULL,
+  KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(0, GEOMFROMTEXT("point (1 1)"));
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=0, b=GEOMFROMTEXT("error");
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=1, b=NULL;
+SELECT a, ASTEXT(b) FROM t1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests

=== modified file 'mysql-test/t/group_by.test'
--- a/mysql-test/t/group_by.test	2011-02-18 10:59:18 +0000
+++ b/mysql-test/t/group_by.test	2011-06-10 09:52:57 +0000
@@ -1359,3 +1359,26 @@ DROP TABLE t1;
 DROP TABLE where_subselect;
 
 --echo # End of Bug #58782
+
+--echo #
+--echo # Bug #11766429 
+--echo # RE-EXECUTE OF PREPARED STATEMENT CRASHES IN ITEM_REF::FIX_FIELDS WITH
+--echo #
+
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2(b INT, KEY(b));
+INSERT INTO t2 VALUES (0),(0);
+
+PREPARE stmt FROM '
+SELECT 1 FROM t2
+LEFT JOIN t1 ON NULL
+GROUP BY t2.b, t1.a
+HAVING a <> 2';
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1, t2;
+
+--echo # End of Bug #11766429

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2011-03-11 09:58:45 +0000
+++ b/mysql-test/t/partition.test	2011-06-13 10:55:58 +0000
@@ -15,6 +15,37 @@ drop table if exists t1, t2;
 --enable_warnings
 
 --echo #
+--echo # Bug#11765667: bug#58655: ASSERTION FAILED,
+--echo #                          SERVER CRASHES WITH MYSQLD GOT SIGNAL 6
+--echo #
+CREATE TABLE t1 (
+       id MEDIUMINT NOT NULL AUTO_INCREMENT,
+       dt DATE, st VARCHAR(255), uid INT,
+       id2nd LONGBLOB, filler VARCHAR(255), PRIMARY KEY(id, dt)
+);
+INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
+   ('1991-03-14', 'Initial Insert', 200, 1234567, 'No Data'),
+   ('1991-02-26', 'Initial Insert', 201, 1234567, 'No Data'),
+   ('1992-03-16', 'Initial Insert', 234, 1234567, 'No Data'),
+   ('1992-07-02', 'Initial Insert', 287, 1234567, 'No Data'),
+   ('1991-05-26', 'Initial Insert', 256, 1234567, 'No Data'),
+   ('1991-04-25', 'Initial Insert', 222, 1234567, 'No Data'),
+   ('1993-03-12', 'Initial Insert', 267, 1234567, 'No Data'),
+   ('1993-03-14', 'Initial Insert', 291, 1234567, 'No Data'),
+   ('1991-12-20', 'Initial Insert', 298, 1234567, 'No Data'),
+   ('1994-10-31', 'Initial Insert', 220, 1234567, 'No Data');
+ALTER TABLE t1 PARTITION BY LIST (YEAR(dt)) (
+    PARTITION d1 VALUES IN (1991, 1994),
+    PARTITION d2 VALUES IN (1993),
+    PARTITION d3 VALUES IN (1992, 1995, 1996)
+);
+INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
+   ('1991-07-14', 'After Partitioning Insert', 299, 1234567, 'Insert row');
+UPDATE t1 SET filler='Updating the row' WHERE uid=298;
+
+DROP TABLE t1;
+
+--echo #
 --echo # Bug#59297: Can't find record in 'tablename' on update inner join
 --echo #
 CREATE TABLE t1 (
@@ -205,10 +236,16 @@ INSERT INTO t1 VALUES ('2009-07-14 17:35
 INSERT INTO t1 VALUES ('2009-09-21 17:31:42', 'pmax');
 
 SELECT * FROM t1;
+SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
 ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
  PARTITION p3 VALUES LESS THAN (1247688000),
  PARTITION pmax VALUES LESS THAN MAXVALUE);
 SELECT * FROM t1;
+SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
+EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
 SHOW CREATE TABLE t1;
 DROP TABLE t1;
 

=== modified file 'mysql-test/t/partition_datatype.test'
--- a/mysql-test/t/partition_datatype.test	2009-10-28 00:11:17 +0000
+++ b/mysql-test/t/partition_datatype.test	2011-06-13 09:57:47 +0000
@@ -7,6 +7,7 @@
 # BUG#48164 limited size to 3072 bytes
 #
 -- source include/have_partition.inc
+-- source include/have_innodb.inc
 
 --disable_warnings
 drop table if exists t1;
@@ -233,3 +234,312 @@ show create table t1;
 insert into t1 values (1),(4),(7),(10),(13),(16),(19),(22),(25),(28),(31),(34);
 select hex(a) from t1 where a = 7;
 drop table t1;
+
+--echo #
+--echo # Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic
+--echo #            by partition pruning
+SET @old_time_zone= @@session.time_zone;
+SET @@session.time_zone = 'UTC';
+--echo # Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS
+CREATE TABLE t1
+(a TIMESTAMP NULL,
+ tz varchar(16))
+ENGINE = MyISAM;
+CREATE TABLE t2 LIKE t1;
+ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
+(PARTITION `p0` VALUES LESS THAN (0),
+ PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01')),
+ PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP('2011-03-26 23:00:00')),
+ PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 22:00:00')),
+ PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 23:00:00')),
+ PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-30 00:00:00')),
+ PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP('2012-03-24 23:00:00')),
+ PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP('2038-01-19 03:14:07')),
+ PARTITION `pMax` VALUES LESS THAN MAXVALUE);
+
+
+--echo # Test 'odd' values
+INSERT INTO t1 VALUES (NULL, 'UTC');
+INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'UTC');
+--echo # Test invalid values
+INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'UTCI');
+INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'UTCI');
+INSERT INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI');
+INSERT INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI');
+--echo # Test start range
+INSERT INTO t1 VALUES ('1970-01-01 00:00:01', 'UTC');
+INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'UTC');
+--echo # Test end range
+INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC');
+INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC');
+--echo # Test Daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-26 22:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-03-26 23:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-03-26 23:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 21:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 22:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:00:01', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-29 23:59:59', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-30 00:00:00', 'UTC');
+INSERT INTO t1 VALUES ('2011-10-30 00:00:01', 'UTC');
+
+SET @@session.time_zone = 'Europe/Moscow';
+
+--echo # Test 'odd' values
+INSERT INTO t1 VALUES (NULL, 'Moscow');
+INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'Moscow');
+--echo # Test invalid values
+INSERT INTO t1 VALUES ('0000-00-00 03:00:00', 'MoscowI');
+INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'MoscowI');
+INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'MoscowI');
+INSERT INTO t1 VALUES ('1970-01-01 02:29:29', 'MoscowI');
+INSERT INTO t1 VALUES ('2038-01-19 06:14:08', 'MoscowI');
+INSERT INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI');
+--echo # values truncated to 03:00:00 due to daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-27 02:00:00', 'MoscowI');
+INSERT INTO t1 VALUES ('2011-03-27 02:00:01', 'MoscowI');
+INSERT INTO t1 VALUES ('2011-03-27 02:59:59', 'MoscowI');
+--echo # Test start range
+INSERT INTO t1 VALUES ('1970-01-01 03:00:01', 'Moscow');
+INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'Moscow');
+--echo # Test end range
+INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow');
+INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow');
+--echo # Test Daylight saving shift
+INSERT INTO t1 VALUES ('2011-03-27 01:59:59', 'Moscow');
+INSERT INTO t1 VALUES ('2011-03-27 03:00:00', 'Moscow');
+INSERT INTO t1 VALUES ('2011-03-27 03:00:01', 'Moscow');
+INSERT INTO t1 VALUES ('2011-10-30 01:59:59', 'Moscow');
+--echo # All values between 02:00 and 02:59:59 will be interpretated as DST
+INSERT INTO t1 VALUES ('2011-10-30 02:00:00', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 02:00:01', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 02:59:59', 'MoscowD');
+INSERT INTO t1 VALUES ('2011-10-30 03:00:00', 'Moscow');
+INSERT INTO t1 VALUES ('2011-10-30 03:00:01', 'Moscow');
+
+
+SET @@session.time_zone = 'UTC';
+
+INSERT INTO t2 SELECT * FROM t1;
+
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+
+SELECT * FROM t1 ORDER BY a, tz;
+SELECT * FROM t2 ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+
+--echo # Test end range changes
+DELETE FROM t2 WHERE a = 0;
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
+SELECT MIN(a), MAX(a) FROM t2;
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+SELECT * FROM t2 ORDER BY a, tz;
+
+--echo # Test start range changes
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
+SELECT MIN(a), MAX(a) FROM t2;
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+SELECT * FROM t2 ORDER BY a, tz;
+
+SHOW CREATE TABLE t2;
+TRUNCATE TABLE t2;
+
+SET @@session.time_zone = 'Europe/Moscow';
+
+INSERT INTO t2 SELECT * FROM t1;
+
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+
+SELECT * FROM t1 ORDER BY a, tz;
+SELECT * FROM t2 ORDER BY a, tz;
+
+--echo # Testing the leap from 01:59:59 to 03:00:00
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
+
+
+
+--echo # Testing the leap from 02:59:59 to 02:00:00
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
+
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+EXPLAIN PARTITIONS
+SELECT * FROM t2
+WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
+
+
+
+--echo # Test end range changes
+DELETE FROM t2 WHERE a = 0;
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
+SELECT MIN(a), MAX(a) FROM t2;
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+SELECT * FROM t2 ORDER BY a, tz;
+
+--echo # Test start range changes
+INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
+SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
+UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
+SELECT MIN(a), MAX(a) FROM t2;
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t2 WHERE a = 0;
+SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
+WHERE TABLE_NAME = 't2';
+SELECT * FROM t2 ORDER BY a, tz;
+
+SHOW CREATE TABLE t2;
+TRUNCATE TABLE t2;
+
+DROP TABLE t1, t2;
+SET @@session.time_zone= @old_time_zone;

=== modified file 'mysql-test/t/query_cache_28249.test'
--- a/mysql-test/t/query_cache_28249.test	2010-08-06 11:29:37 +0000
+++ b/mysql-test/t/query_cache_28249.test	2011-06-10 09:40:57 +0000
@@ -30,7 +30,7 @@ connection user1;
 SET GLOBAL query_cache_type=1;
 SET GLOBAL query_cache_limit=10000;
 SET GLOBAL query_cache_min_res_unit=0;
-SET GLOBAL query_cache_size= 100000;
+SET GLOBAL query_cache_size= 102400;
 
 FLUSH TABLES;
 --disable_warnings
@@ -58,18 +58,18 @@ connection user3;
 # Typical information_schema.processlist content after sufficient sleep time
 #   ID  USER  COMMAND  TIME  STATE   INFO
 #   ....
-#   2   root  Query       5  Waiting for table level lock  SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+#   2   root  Query       5  Waiting for table metadata lock  SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
 #   ....
 #                            XXXXXX  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 # The values marked with 'X' must be reached.
 --echo # Poll till the select of connection user1 is blocked by the write lock on t1.
 let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist
-WHERE state = 'Waiting for table level lock'
+WHERE state = 'Waiting for table metadata lock'
   AND info = '$select_for_qc';
 --source include/wait_condition.inc
 eval
 SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Waiting for table level lock'
+WHERE state = 'Waiting for table metadata lock'
   AND info = '$select_for_qc';
 INSERT INTO t1 VALUES (4);
 

=== modified file 'mysql-test/t/sp_notembedded.test'
--- a/mysql-test/t/sp_notembedded.test	2010-08-06 11:29:37 +0000
+++ b/mysql-test/t/sp_notembedded.test	2011-06-08 13:44:50 +0000
@@ -371,16 +371,6 @@ DELETE FROM mysql.user WHERE User='mysql
 FLUSH PRIVILEGES;
 
 
-#
-# Restore global concurrent_insert value. Keep in the end of the test file.
-#
-
-set @@global.concurrent_insert= @old_concurrent_insert;
-
-# Wait till all disconnects are completed
---source include/wait_until_count_sessions.inc
-
-
 --echo #
 --echo # Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
 --echo #
@@ -449,7 +439,47 @@ DROP FUNCTION f1;
 --disconnect con1
 --disconnect con2
 
-
 --echo # ------------------------------------------------------------------
 --echo # -- End of 5.1 tests
 --echo # ------------------------------------------------------------------
+
+--echo #
+--echo # Test for bug#11763757 "56510: ERROR 42000: FUNCTION DOES NOT EXIST
+--echo # IF NOT-PRIV USER RECONNECTS ".
+--echo #
+--echo # The real problem was that server was unable handle properly stored
+--echo # functions in databases which names contained dot.
+--echo #
+
+connection default;
+
+--disable_warnings
+DROP DATABASE IF EXISTS `my.db`;
+--enable_warnings
+
+create database `my.db`;
+use `my.db`;
+
+CREATE FUNCTION f1(a int) RETURNS INT RETURN a;
+
+--echo # Create new connection.
+connect (addcon, localhost, root,,);
+connection addcon;
+USE `my.db`;
+SELECT f1(1);
+SELECT `my.db`.f1(2);
+
+--echo # Switching to default connection.
+connection default;
+disconnect addcon;
+DROP DATABASE `my.db`;
+
+#
+# Restore global concurrent_insert value. Keep in the end of the test file.
+#
+
+set @@global.concurrent_insert= @old_concurrent_insert;
+
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc
+

=== modified file 'mysql-test/t/symlink.test'
--- a/mysql-test/t/symlink.test	2011-01-31 09:34:39 +0000
+++ b/mysql-test/t/symlink.test	2011-06-09 12:54:12 +0000
@@ -277,3 +277,24 @@ SELECT * FROM mysql.user;
 --remove_file $MYSQL_TMP_DIR/mysql
 
 --echo End of 5.1 tests
+
+
+--echo #
+--echo # Test for bug #11759990 - "52354: 'CREATE TABLE .. LIKE ... '
+--echo #                           STATEMENTS FAIL".
+--echo #
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval create table t1 (a int primary key) engine=myisam
+      data directory="$MYSQLTEST_VARDIR/tmp"
+      index directory="$MYSQLTEST_VARDIR/run";
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+show create table t1;
+--echo # CREATE TABLE LIKE statement on table with INDEX/DATA DIRECTORY
+--echo # options should not fail. Per documentation newly created table
+--echo # should not inherit value of these options from the original table.
+create table t2 like t1;
+show create table t2;
+drop tables t1, t2;

=== modified file 'mysql-test/t/trigger-compat.test'
--- a/mysql-test/t/trigger-compat.test	2009-02-19 23:24:25 +0000
+++ b/mysql-test/t/trigger-compat.test	2011-06-10 07:20:15 +0000
@@ -106,4 +106,184 @@ DROP TABLE t2;
 DROP USER mysqltest_dfn@localhost;
 DROP USER mysqltest_inv@localhost;
 DROP DATABASE mysqltest_db1;
+USE test;
 
+
+--echo #
+--echo # Bug#45235: 5.1 does not support 5.0-only syntax triggers in any way
+--echo #
+let $MYSQLD_DATADIR=`SELECT @@datadir`;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (2), (3);
+INSERT INTO t3 VALUES (1), (2), (3);
+
+--echo # We simulate importing a trigger from 5.0 by writing a .TRN file for
+--echo # each trigger plus a .TRG file the way MySQL 5.0 would have done it, 
+--echo # with syntax allowed in 5.0 only.
+--echo #
+--echo # Note that in 5.0 the following lines are missing from t1.TRG:
+--echo #
+--echo # client_cs_names='latin1'
+--echo # connection_cl_names='latin1_swedish_ci'
+--echo # db_cl_names='latin1_swedish_ci'
+
+--write_file $MYSQLD_DATADIR/test/tr11.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr12.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr13.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr14.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr15.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/t1.TRG
+TYPE=TRIGGERS
+triggers='CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t3' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr12 AFTER INSERT ON t1 FOR EACH ROW DELETE FROM t3' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr13 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr14 AFTER DELETE ON t1 FOR EACH ROW DELETE FROM non_existing_table' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr15 BEFORE UPDATE ON t1 FOR EACH ROW DELETE FROM non_existing_table a USING non_existing_table a'
+sql_modes=0 0 0 0 0
+definers='root@localhost' 'root@localhost' 'root@localhost' 'root@localhost' 'root@localhost'
+EOF
+
+--write_file $MYSQLD_DATADIR/test/t2.TRG
+TYPE=TRIGGERS
+triggers='Not allowed syntax here, and trigger name cant be extracted either.'
+sql_modes=0
+definers='root@localhost'
+EOF
+
+FLUSH TABLE t1;
+FLUSH TABLE t2;
+
+--echo # We will get parse errors for most DDL and DML statements when the table
+--echo # has broken triggers. The parse error refers to the first broken 
+--echo # trigger.
+--error ER_PARSE_ERROR
+CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
+--error ER_PARSE_ERROR
+CREATE TRIGGER tr22 BEFORE INSERT ON t2 FOR EACH ROW DELETE FROM non_existing_table;
+SHOW TRIGGERS;
+--error ER_PARSE_ERROR
+INSERT INTO t1 VALUES (1);
+--error ER_PARSE_ERROR
+INSERT INTO t2 VALUES (1);
+--error ER_PARSE_ERROR
+DELETE FROM t1;
+--error ER_PARSE_ERROR
+UPDATE t1 SET a = 1 WHERE a = 1;
+SELECT * FROM t1;
+--error ER_PARSE_ERROR
+RENAME TABLE t1 TO t1_2;
+SHOW TRIGGERS;
+
+DROP TRIGGER tr11;
+DROP TRIGGER tr12;
+DROP TRIGGER tr13;
+DROP TRIGGER tr14;
+DROP TRIGGER tr15;
+
+SHOW TRIGGERS;
+
+--echo # Make sure there is no trigger file left.
+--list_files $MYSQLD_DATADIR/test/ tr*
+
+--echo # We write the same trigger files one more time to test DROP TABLE.
+--write_file $MYSQLD_DATADIR/test/tr11.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr12.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr13.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr14.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr15.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/t1.TRG
+TYPE=TRIGGERS
+triggers='CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t3' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr12 AFTER INSERT ON t1 FOR EACH ROW DELETE FROM t3' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr13 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr14 AFTER DELETE ON t1 FOR EACH ROW DELETE FROM non_existing_table' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr15 BEFORE UPDATE ON t1 FOR EACH ROW DELETE FROM non_existing_table a USING non_existing_table a'
+sql_modes=0 0 0 0 0
+definers='root@localhost' 'root@localhost' 'root@localhost' 'root@localhost' 'root@localhost'
+EOF
+
+FLUSH TABLE t1;
+FLUSH TABLE t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--echo # Make sure there is no trigger file left.
+
+--list_files $MYSQLD_DATADIR/test/ tr*
+
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (2), (3);
+
+--echo # We write three trigger files. First trigger is syntaxically incorrect, next trigger is correct
+--echo # and last trigger is broken.
+--echo # Next we try to execute SHOW CREATE TRGGIR command for broken trigger and then try to drop one.
+--write_file $MYSQLD_DATADIR/test/tr11.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/tr12.TRN
+TYPE=TRIGGERNAME
+trigger_table=t1
+EOF
+
+--write_file $MYSQLD_DATADIR/test/t1.TRG
+TYPE=TRIGGERS
+triggers='CREATE the wrongest trigger_in_the_world' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr12 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t2'
+sql_modes=0 0 0
+definers='root@localhost' 'root@localhost' 'root@localhost'
+EOF
+
+FLUSH TABLE t1;
+
+SHOW CREATE TRIGGER tr12;
+SHOW CREATE TRIGGER tr11;
+DROP TRIGGER tr12;
+DROP TRIGGER tr11;
+
+DROP TABLE t1;
+DROP TABLE t2;

=== modified file 'mysql-test/t/type_datetime.test'
--- a/mysql-test/t/type_datetime.test	2011-01-19 14:39:13 +0000
+++ b/mysql-test/t/type_datetime.test	2011-06-10 08:34:13 +0000
@@ -512,5 +512,35 @@ DROP TABLE t1;
 --echo #
 
 --echo #
+--echo # BUG#12561818: RERUN OF STORED FUNCTION GIVES ERROR 1172: 
+--echo #               RESULT CONSISTED OF MORE THAN ONE ROW
+--echo #
+
+CREATE TABLE t1 (a DATE NOT NULL, b INT);
+INSERT INTO t1 VALUES ('0000-00-00',1), ('1999-05-10',2);
+
+CREATE TABLE t2 (a DATETIME NOT NULL, b INT);
+INSERT INTO t2 VALUES ('0000-00-00 00:00:00',1), ('1999-05-10 00:00:00',2);
+
+--echo
+SELECT * FROM t1 WHERE a IS NULL;
+SELECT * FROM t2 WHERE a IS NULL;
+SELECT * FROM t1 LEFT JOIN t1 AS t1_2 ON 1 WHERE t1_2.a IS NULL;
+SELECT * FROM t2 LEFT JOIN t2 AS t2_2 ON 1 WHERE t2_2.a IS NULL;
+SELECT * FROM t1 JOIN t1 AS t1_2 ON 1 WHERE t1_2.a IS NULL;
+SELECT * FROM t2 JOIN t2 AS t2_2 ON 1 WHERE t2_2.a IS NULL;
+
+--echo
+PREPARE stmt1 FROM 
+  'SELECT *
+   FROM t1 LEFT JOIN t1 AS t1_2 ON 1
+   WHERE t1_2.a IS NULL AND t1_2.b < 2';
+EXECUTE stmt1;
+EXECUTE stmt1;
+
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1,t2;
+
+--echo #
 --echo # End of 5.5 tests
 --echo #

=== modified file 'plugin/audit_null/audit_null.c'
--- a/plugin/audit_null/audit_null.c	2010-08-12 15:19:57 +0000
+++ b/plugin/audit_null/audit_null.c	2011-06-03 07:27:11 +0000
@@ -81,11 +81,12 @@ static int audit_null_plugin_deinit(void
 */
 
 static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
-                              const struct mysql_event *event)
+                              unsigned int event_class,
+                              const void *event)
 {
   /* prone to races, oh well */
   number_of_calls++;
-  if (event->event_class == MYSQL_AUDIT_GENERAL_CLASS)
+  if (event_class == MYSQL_AUDIT_GENERAL_CLASS)
   {
     const struct mysql_event_general *event_general=
       (const struct mysql_event_general *) event;

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2011-05-30 06:25:47 +0000
+++ b/sql/binlog.cc	2011-06-09 08:58:41 +0000
@@ -1261,9 +1261,9 @@ int query_error_code(THD *thd, bool not_
   
   if (not_killed || (thd->killed == THD::KILL_BAD_DATA))
   {
-    error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
+    error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
 
-    /* thd->stmt_da->sql_errno() might be ER_SERVER_SHUTDOWN or
+    /* thd->get_stmt_da()->sql_errno() might be ER_SERVER_SHUTDOWN or
        ER_QUERY_INTERRUPTED, So here we need to make sure that error
        is not set to these errors when specified not_killed by the
        caller.
@@ -2087,7 +2087,7 @@ bool MYSQL_BIN_LOG::check_write_error(TH
   if (!thd->is_error())
     DBUG_RETURN(checked);
 
-  switch (thd->stmt_da->sql_errno())
+  switch (thd->get_stmt_da()->sql_errno())
   {
     case ER_TRANS_CACHE_FULL:
     case ER_STMT_CACHE_FULL:

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2011-05-27 11:50:52 +0000
+++ b/sql/event_db_repository.cc	2011-06-09 18:18:22 +0000
@@ -236,9 +236,16 @@ mysql_event_fill_row(THD *thd,
   if (fields[f_num= ET_FIELD_NAME]->store(et->name.str, et->name.length, scs))
     goto err_truncate;
 
-  /* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/
+  /* ON_COMPLETION field is NOT NULL thus not calling set_notnull()*/
   rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE);
-  rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
+
+  /*
+    Set STATUS value unconditionally in case of CREATE EVENT.
+    For ALTER EVENT set it only if value of this field was changed.
+    Since STATUS field is NOT NULL call to set_notnull() is not needed.
+  */
+  if (!is_update || et->status_changed)
+    rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
   rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
 
   /*
@@ -717,8 +724,6 @@ Event_db_repository::create_event(THD *t
   if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, FALSE))
     goto end;
 
-  table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE);
-
   if ((ret= table->file->ha_write_row(table->record[0])))
   {
     table->file->print_error(ret, MYF(0));

=== modified file 'sql/event_parse_data.cc'
--- a/sql/event_parse_data.cc	2010-07-02 02:58:51 +0000
+++ b/sql/event_parse_data.cc	2011-06-09 18:18:22 +0000
@@ -48,9 +48,8 @@ Event_parse_data::new_instance(THD *thd)
 
 Event_parse_data::Event_parse_data()
   :on_completion(Event_parse_data::ON_COMPLETION_DEFAULT),
-  status(Event_parse_data::ENABLED),
-  do_not_create(FALSE),
-  body_changed(FALSE),
+  status(Event_parse_data::ENABLED), status_changed(false),
+  do_not_create(FALSE), body_changed(FALSE),
   item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
   starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
   item_expression(NULL), expression(0)
@@ -142,6 +141,7 @@ Event_parse_data::check_if_in_the_past(T
   else if (status == Event_parse_data::ENABLED)
   {
     status= Event_parse_data::DISABLED;
+    status_changed= true;
     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                  ER_EVENT_EXEC_TIME_IN_THE_PAST,
                  ER(ER_EVENT_EXEC_TIME_IN_THE_PAST));
@@ -571,7 +571,10 @@ void Event_parse_data::check_originator_
     DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED."));
     if ((status == Event_parse_data::ENABLED) ||
         (status == Event_parse_data::DISABLED))
-      status = Event_parse_data::SLAVESIDE_DISABLED;
+    {
+      status= Event_parse_data::SLAVESIDE_DISABLED;
+      status_changed= true;
+    }
     originator = thd->server_id;
   }
   else

=== modified file 'sql/event_parse_data.h'
--- a/sql/event_parse_data.h	2010-07-02 02:58:51 +0000
+++ b/sql/event_parse_data.h	2011-06-09 18:18:22 +0000
@@ -55,6 +55,7 @@ public:
 
   int on_completion;
   int status;
+  bool status_changed;
   longlong originator;
   /*
     do_not_create will be set if STARTS time is in the past and

=== modified file 'sql/event_scheduler.cc'
--- a/sql/event_scheduler.cc	2010-07-23 19:03:52 +0000
+++ b/sql/event_scheduler.cc	2011-06-10 16:57:01 +0000
@@ -77,7 +77,7 @@ Event_worker_thread::print_warnings(THD
 {
   MYSQL_ERROR *err;
   DBUG_ENTER("evex_print_warnings");
-  if (thd->warning_info->is_empty())
+  if (thd->get_stmt_wi()->is_empty())
     DBUG_VOID_RETURN;
 
   char msg_buf[10 * STRING_BUFFER_USUAL_SIZE];
@@ -93,7 +93,7 @@ Event_worker_thread::print_warnings(THD
   prefix.append(et->name.str, et->name.length, system_charset_info);
   prefix.append("] ", 2);
 
-  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
   while ((err= it++))
   {
     String err_msg(msg_buf, sizeof(msg_buf), system_charset_info);

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2011-05-26 15:20:09 +0000
+++ b/sql/field.cc	2011-06-10 16:57:01 +0000
@@ -1163,7 +1163,8 @@ int Field_num::check_int(const CHARSET_I
                         ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, 
                         ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                         "integer", err.ptr(), field_name,
-                        (ulong) table->in_use->warning_info->current_row_for_warning());
+                        (ulong) table->in_use->get_stmt_wi()->
+                        current_row_for_warning());
     return 1;
   }
   /* Test if we have garbage at the end of the given string. */
@@ -2648,7 +2649,8 @@ int Field_new_decimal::store(const char
                         ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
                         ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                         "decimal", errmsg.ptr(), field_name,
-                        (ulong) table->in_use->warning_info->current_row_for_warning());
+                        (ulong) table->in_use->get_stmt_wi()->
+                        current_row_for_warning());
 
     DBUG_RETURN(err);
   }
@@ -2668,7 +2670,7 @@ int Field_new_decimal::store(const char
                           ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
                           ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                           "decimal", errmsg.ptr(), field_name,
-                          (ulong) table->in_use->warning_info->
+                          (ulong) table->in_use->get_stmt_wi()->
                           current_row_for_warning());
       my_decimal_set_zero(&decimal_value);
       break;
@@ -5231,7 +5233,7 @@ bool Field_time::get_date(MYSQL_TIME *lt
     push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                         ER_WARN_DATA_OUT_OF_RANGE,
                         ER(ER_WARN_DATA_OUT_OF_RANGE), field_name,
-                        thd->warning_info->current_row_for_warning());
+                        thd->get_stmt_wi()->current_row_for_warning());
     return 1;
   }
   return Field_time::get_time(ltime);
@@ -6230,7 +6232,7 @@ check_string_copy_error(Field_str *field
                       ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
                       ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                       "string", tmp, field->field_name,
-                      thd->warning_info->current_row_for_warning());
+                      thd->get_stmt_wi()->current_row_for_warning());
   return TRUE;
 }
 
@@ -10078,7 +10080,7 @@ Field::set_warning(MYSQL_ERROR::enum_war
   {
     thd->cuted_fields+= cuted_increment;
     push_warning_printf(thd, level, code, ER(code), field_name,
-                        thd->warning_info->current_row_for_warning());
+                        thd->get_stmt_wi()->current_row_for_warning());
     return 0;
   }
   return level >= MYSQL_ERROR::WARN_LEVEL_WARN;

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2011-05-26 15:20:09 +0000
+++ b/sql/filesort.cc	2011-06-09 08:58:41 +0000
@@ -361,8 +361,10 @@ ha_rows filesort(THD *thd, TABLE *table,
                     "%s: %s",
                     MYF(ME_ERROR + ME_WAITTANG),
                     ER_THD(thd, ER_FILSORT_ABORT),
-                    kill_errno ? ER(kill_errno) : thd->stmt_da->message());
-                    
+                    kill_errno ?
+                    ER(kill_errno) :
+                    thd->get_stmt_da()->message());
+
     if (global_system_variables.log_warnings > 1)
     {
       sql_print_warning("%s, host: %s, user: %s, thread: %lu, query: %-.4096s",

=== modified file 'sql/gcalc_tools.cc'
--- a/sql/gcalc_tools.cc	2010-10-14 05:26:25 +0000
+++ b/sql/gcalc_tools.cc	2011-06-08 17:24:16 +0000
@@ -584,8 +584,7 @@ int Gcalc_operation_reducer::start_coupl
   t1->rp= rp1;
   if (prev_range)
   {
-    rp0->outer_poly= prev_range->thread_start;
-    t1->thread_start= rp1;
+    rp0->outer_poly= t1->thread_start= prev_range->thread_start;
   }
   else
   {
@@ -617,8 +616,7 @@ int Gcalc_operation_reducer::start_i_cou
   t1->rp= rp1;
   if (prev_range)
   {
-    rp0->outer_poly= prev_range->thread_start;
-    t1->thread_start= rp1;
+    rp0->outer_poly= t1->thread_start= prev_range->thread_start;
   }
   else
   {

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2011-05-26 15:20:09 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-06-10 16:57:01 +0000
@@ -288,13 +288,13 @@ static void run_query(THD *thd, char *bu
     Thd_ndb *thd_ndb= get_thd_ndb(thd);
     for (i= 0; no_print_error[i]; i++)
       if ((thd_ndb->m_error_code == no_print_error[i]) ||
-          (thd->stmt_da->sql_errno() == (unsigned) no_print_error[i]))
+          (thd->get_stmt_da()->sql_errno() == (unsigned) no_print_error[i]))
         break;
     if (!no_print_error[i])
       sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
                       buf,
-                      thd->stmt_da->message(),
-                      thd->stmt_da->sql_errno(),
+                      thd->get_stmt_da()->message(),
+                      thd->get_stmt_da()->sql_errno(),
                       thd_ndb->m_error_code,
                       (int) thd->is_error(), thd->is_slave_error);
   }
@@ -308,7 +308,7 @@ static void run_query(THD *thd, char *bu
     is called from ndbcluster_reset_logs(), which is called from
     mysql_flush().
   */
-  thd->stmt_da->reset_diagnostics_area();
+  thd->get_stmt_da()->reset_diagnostics_area();
 
   thd->variables.option_bits= save_thd_options;
   thd->set_query(save_thd_query, save_thd_query_length);
@@ -982,7 +982,7 @@ static void print_could_not_discover_err
                   "my_errno: %d",
                    schema->db, schema->name, schema->query,
                    schema->node_id, my_errno);
-  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
   MYSQL_ERROR *err;
   while ((err= it++))
     sql_print_warning("NDB Binlog: (%d)%s", err->get_sql_errno(),
@@ -2338,8 +2338,8 @@ static int open_ndb_binlog_index(THD *th
       sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed");
     else
       sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'",
-                      thd->stmt_da->sql_errno(),
-                      thd->stmt_da->message());
+                      thd->get_stmt_da()->sql_errno(),
+                      thd->get_stmt_da()->message());
     thd->proc_info= save_proc_info;
     return -1;
   }
@@ -2395,9 +2395,9 @@ int ndb_add_ndb_binlog_index(THD *thd, v
   }
 
 add_ndb_binlog_index_err:
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
   close_thread_tables(thd);
   thd->mdl_context.release_transactional_locks();
   ndb_binlog_index= 0;
@@ -4266,9 +4266,9 @@ err:
   sql_print_information("Stopping Cluster Binlog");
   DBUG_PRINT("info",("Shutting down cluster binlog thread"));
   thd->proc_info= "Shutting down";
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
   close_thread_tables(thd);
   thd->mdl_context.release_transactional_locks();
   mysql_mutex_lock(&injector_mutex);

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2011-06-01 09:11:28 +0000
+++ b/sql/ha_partition.cc	2011-06-13 09:33:42 +0000
@@ -3611,9 +3611,13 @@ exit:
     index)
     mysql_update does not set table->next_number_field, so we use
     table->found_next_number_field instead.
+    Also checking that the field is marked in the write set.
   */
-  if (table->found_next_number_field && new_data == table->record[0] &&
-      !table->s->next_number_keypart)
+  if (table->found_next_number_field &&
+      new_data == table->record[0] &&
+      !table->s->next_number_keypart &&
+      bitmap_is_set(table->write_set,
+                    table->found_next_number_field->field_index))
   {
     if (!table_share->ha_part_data->auto_inc_initialized)
       info(HA_STATUS_AUTO);
@@ -4276,6 +4280,7 @@ void ha_partition::position(const uchar
 void ha_partition::column_bitmaps_signal()
 {
     handler::column_bitmaps_signal();
+    /* Must read all partition fields to make position() call possible */
     bitmap_union(table->read_set, &m_part_info->full_part_field_set);
 }
  

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-05-31 09:30:59 +0000
+++ b/sql/handler.cc	2011-06-09 08:58:41 +0000
@@ -1402,7 +1402,7 @@ int ha_rollback_trans(THD *thd, bool all
     trans->no_2pc=0;
     if (is_real_trans && thd->transaction_rollback_request &&
         thd->transaction.xid_state.xa_state != XA_NOTR)
-      thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno();
+      thd->transaction.xid_state.rm_error= thd->get_stmt_da()->sql_errno();
   }
   /* Always cleanup. Even if nht==0. There may be savepoints. */
   if (is_real_trans)

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2011-05-26 15:20:09 +0000
+++ b/sql/item.cc	2011-06-06 12:49:55 +0000
@@ -419,12 +419,11 @@ int Item::save_str_value_in_field(Field
 Item::Item():
   is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0),
   fixed(0), is_autogenerated_name(TRUE),
-  collation(&my_charset_bin, DERIVATION_COERCIBLE)
+  collation(&my_charset_bin, DERIVATION_COERCIBLE), with_subselect(false)
 {
   marker= 0;
   maybe_null=null_value=with_sum_func=unsigned_flag=0;
   decimals= 0; max_length= 0;
-  with_subselect= 0;
   cmp_context= (Item_result)-1;
 
   /* Put item in free list so that we can free all items at end */
@@ -470,8 +469,8 @@ Item::Item(THD *thd, Item *item):
   fixed(item->fixed),
   is_autogenerated_name(item->is_autogenerated_name),
   collation(item->collation),
-  with_subselect(item->with_subselect),
-  cmp_context(item->cmp_context)
+  cmp_context(item->cmp_context),
+  with_subselect(item->with_subselect)
 {
   next= thd->free_list;				// Put in free list
   thd->free_list= this;

=== modified file 'sql/item.h'
--- a/sql/item.h	2011-05-26 15:20:09 +0000
+++ b/sql/item.h	2011-06-10 15:29:04 +0000
@@ -567,10 +567,14 @@ public:
   my_bool is_autogenerated_name;        /* indicate was name of this Item
                                            autogenerated or set by user */
   DTCollation collation;
+  Item_result cmp_context;              /* Comparison context */
+ protected:
   my_bool with_subselect;               /* If this item is a subselect or some
                                            of its arguments is or contains a
-                                           subselect. Computed by fix_fields. */
-  Item_result cmp_context;              /* Comparison context */
+                                           subselect. Computed by fix_fields
+                                           and updated by update_used_tables. */
+
+ public:
   // alloc & destruct is done as start of select using sql_alloc
   Item();
   /*
@@ -1301,6 +1305,11 @@ public:
      @retval FALSE Otherwise.
   */
   bool is_blob_field() const;
+
+  /**
+    Checks if this item or any of its decendents contains a subquery.
+  */
+  virtual bool has_subquery() const { return with_subselect; }
 };
 
 
@@ -1730,6 +1739,8 @@ public:
   String *val_str(String *str) { return field->val_str(str); }
   my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
   void make_field(Send_field *tmp_field);
+  CHARSET_INFO *charset_for_protocol(void) const
+  { return (CHARSET_INFO *)field->charset_for_protocol(); }
 };
 
 
@@ -2693,6 +2704,14 @@ public:
     return (*ref)->is_outer_field();
   }
 
+  /**
+    Checks if the item tree that ref points to contains a subquery.
+  */
+  virtual bool has_subquery() const 
+  { 
+    DBUG_ASSERT(ref);
+    return (*ref)->has_subquery();
+  }
 };
 
 

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2011-05-26 05:50:01 +0000
+++ b/sql/item_cmpfunc.cc	2011-06-09 06:22:39 +0000
@@ -4404,7 +4404,7 @@ Item_cond::fix_fields(THD *thd, Item **r
       const_item_cache= FALSE;
     }  
     with_sum_func=	    with_sum_func || item->with_sum_func;
-    with_subselect|=        item->with_subselect;
+    with_subselect|=        item->has_subquery();
     if (item->maybe_null)
       maybe_null=1;
   }
@@ -4615,11 +4615,13 @@ void Item_cond::update_used_tables()
 
   used_tables_cache=0;
   const_item_cache=1;
+  with_subselect= false;
   while ((item=li++))
   {
     item->update_used_tables();
     used_tables_cache|= item->used_tables();
     const_item_cache&= item->const_item();
+    with_subselect|= item->has_subquery();
   }
 }
 
@@ -4803,6 +4805,8 @@ void Item_is_not_null_test::update_used_
   else
   {
     args[0]->update_used_tables();
+    with_subselect= args[0]->has_subquery();
+
     if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
     {
       /* Remember if the value is always NULL or never NULL */
@@ -5827,12 +5831,14 @@ void Item_equal::update_used_tables()
   not_null_tables_cache= used_tables_cache= 0;
   if ((const_item_cache= cond_false))
     return;
+  with_subselect= false;
   while ((item=li++))
   {
     item->update_used_tables();
     used_tables_cache|= item->used_tables();
     /* see commentary at Item_equal::update_const() */
     const_item_cache&= item->const_item() && !item->is_outer_field();
+    with_subselect|= item->has_subquery();
   }
 }
 

=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h	2011-05-26 15:20:09 +0000
+++ b/sql/item_cmpfunc.h	2011-06-09 06:22:39 +0000
@@ -1363,6 +1363,8 @@ public:
     else
     {
       args[0]->update_used_tables();
+      with_subselect= args[0]->has_subquery();
+
       if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
           !with_subselect))
       {

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2011-05-26 10:13:07 +0000
+++ b/sql/item_func.cc	2011-06-09 06:22:39 +0000
@@ -218,7 +218,7 @@ Item_func::fix_fields(THD *thd, Item **r
       used_tables_cache|=     item->used_tables();
       not_null_tables_cache|= item->not_null_tables();
       const_item_cache&=      item->const_item();
-      with_subselect|=        item->with_subselect;
+      with_subselect|=        item->has_subquery();
     }
   }
   fix_length_and_dec();
@@ -405,11 +405,13 @@ void Item_func::update_used_tables()
 {
   used_tables_cache=0;
   const_item_cache=1;
+  with_subselect= false;
   for (uint i=0 ; i < arg_count ; i++)
   {
     args[i]->update_used_tables();
     used_tables_cache|=args[i]->used_tables();
     const_item_cache&=args[i]->const_item();
+    with_subselect|= args[i]->has_subquery();
   }
 }
 

=== modified file 'sql/item_row.cc'
--- a/sql/item_row.cc	2011-05-06 13:32:53 +0000
+++ b/sql/item_row.cc	2011-06-09 06:22:39 +0000
@@ -126,11 +126,13 @@ void Item_row::update_used_tables()
 {
   used_tables_cache= 0;
   const_item_cache= 1;
+  with_subselect= false;
   for (uint i= 0; i < arg_count; i++)
   {
     items[i]->update_used_tables();
     used_tables_cache|= items[i]->used_tables();
     const_item_cache&= items[i]->const_item();
+    with_subselect|= items[i]->has_subquery();
   }
 }
 

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2011-05-26 15:20:09 +0000
+++ b/sql/item_strfunc.cc	2011-06-09 06:22:39 +0000
@@ -2571,6 +2571,7 @@ void Item_func_make_set::update_used_tab
   item->update_used_tables();
   used_tables_cache|=item->used_tables();
   const_item_cache&=item->const_item();
+  with_subselect= item->has_subquery();
 }
 
 

=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc	2011-05-26 15:20:09 +0000
+++ b/sql/item_sum.cc	2011-06-09 06:22:39 +0000
@@ -529,10 +529,12 @@ void Item_sum::update_used_tables ()
   if (!forced_const)
   {
     used_tables_cache= 0;
+    with_subselect= false;
     for (uint i=0 ; i < arg_count ; i++)
     {
       args[i]->update_used_tables();
       used_tables_cache|= args[i]->used_tables();
+      with_subselect|= args[i]->has_subquery();
     }
 
     used_tables_cache&= PSEUDO_TABLE_BITS;

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2011-05-26 15:20:09 +0000
+++ b/sql/item_timefunc.cc	2011-06-13 10:55:58 +0000
@@ -1385,6 +1385,26 @@ longlong Item_func_unix_timestamp::val_i
   return (longlong) TIME_to_timestamp(current_thd, &ltime, &not_used);
 }
 
+enum_monotonicity_info Item_func_unix_timestamp::get_monotonicity_info() const
+{
+  if (args[0]->type() == Item::FIELD_ITEM &&
+      (args[0]->field_type() == MYSQL_TYPE_TIMESTAMP))
+    return MONOTONIC_INCREASING;
+  return NON_MONOTONIC;
+}
+
+
+longlong Item_func_unix_timestamp::val_int_endpoint(bool left_endp, bool *incl_endp)
+{
+  DBUG_ASSERT(fixed == 1);
+  DBUG_ASSERT(arg_count == 1 &&
+              args[0]->type() == Item::FIELD_ITEM &&
+              args[0]->field_type() == MYSQL_TYPE_TIMESTAMP);
+  Field *field=((Item_field*) args[0])->field;
+  /* Leave the incl_endp intact */
+  return ((Field_timestamp*) field)->get_timestamp(&null_value);
+}
+
 
 longlong Item_func_time_to_sec::val_int()
 {

=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h	2011-03-30 07:42:03 +0000
+++ b/sql/item_timefunc.h	2011-06-13 10:55:58 +0000
@@ -387,6 +387,8 @@ public:
   Item_func_unix_timestamp(Item *a) :Item_int_func(a) {}
   longlong val_int();
   const char *func_name() const { return "unix_timestamp"; }
+  enum_monotonicity_info get_monotonicity_info() const;
+  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
   /*
     UNIX_TIMESTAMP() depends on the current timezone

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-05-30 06:25:47 +0000
+++ b/sql/log_event.cc	2011-06-10 16:57:01 +0000
@@ -208,7 +208,7 @@ static void inline slave_rows_error_repo
   char buff[MAX_SLAVE_ERRMSG], *slider;
   const char *buff_end= buff + sizeof(buff);
   uint len;
-  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
   MYSQL_ERROR *err;
   buff[0]= 0;
 
@@ -221,7 +221,7 @@ static void inline slave_rows_error_repo
   }
 
   if (ha_error != 0)
-    rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
+    rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
                 "Could not execute %s event on table %s.%s;"
                 "%s handler error %s; "
                 "the event's master log %s, end_log_pos %lu",
@@ -229,7 +229,7 @@ static void inline slave_rows_error_repo
                 buff, handler_error == NULL ? "<unknown>" : handler_error,
                 log_name, pos);
   else
-    rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
+    rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
                 "Could not execute %s event on table %s.%s;"
                 "%s the event's master log %s, end_log_pos %lu",
                 type, table->s->db.str, table->s->table_name.str,
@@ -372,13 +372,13 @@ inline int ignored_error_code(int err_co
 */ 
 int convert_handler_error(int error, THD* thd, TABLE *table)
 {
-  uint actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
+  uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
                            0);
 
   if (actual_error == 0)
   {
     table->file->print_error(error, MYF(0));
-    actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
+    actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
                         ER_UNKNOWN_ERROR);
     if (actual_error == ER_UNKNOWN_ERROR)
       if (global_system_variables.log_warnings)
@@ -3760,7 +3760,7 @@ START SLAVE; . Query: '%s'", expected_er
     }
 
     /* If the query was not ignored, it is printed to the general log */
-    if (!thd->is_error() || thd->stmt_da->sql_errno() != ER_SLAVE_IGNORED_TABLE)
+    if (!thd->is_error() || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
       general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
 
 compare_errors:
@@ -3772,14 +3772,14 @@ compare_errors:
       not exist errors", we silently clear the error if TEMPORARY was used.
     */
     if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
-        thd->is_error() && thd->stmt_da->sql_errno() == ER_BAD_TABLE_ERROR &&
+        thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
         !expected_error)
-      thd->stmt_da->reset_diagnostics_area();
+      thd->get_stmt_da()->reset_diagnostics_area();
     /*
       If we expected a non-zero error code, and we don't get the same error
       code, and it should be ignored or is related to a concurrency issue.
     */
-    actual_error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
+    actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
     DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
                        expected_error, actual_error));
 
@@ -3796,7 +3796,7 @@ Error on slave: actual message='%s', err
 Default database: '%s'. Query: '%s'",
                       ER_SAFE(expected_error),
                       expected_error,
-                      actual_error ? thd->stmt_da->message() : "no error",
+                      actual_error ? thd->get_stmt_da()->message() : "no error",
                       actual_error,
                       print_slave_db_safe(db), query_arg);
       thd->is_slave_error= 1;
@@ -3820,7 +3820,7 @@ Default database: '%s'. Query: '%s'",
     {
       rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' on query. Default database: '%s'. Query: '%s'",
-                      (actual_error ? thd->stmt_da->message() :
+                      (actual_error ? thd->get_stmt_da()->message() :
                        "unexpected success or fatal error"),
                       print_slave_db_safe(thd->db), query_arg);
       thd->is_slave_error= 1;
@@ -5300,7 +5300,7 @@ int Load_log_event::do_apply_event(NET*
   {
     thd->set_time((time_t)when);
     thd->set_query_id(next_query_id());
-    thd->warning_info->opt_clear_warning_info(thd->query_id);
+    thd->get_stmt_wi()->opt_clear_warning_info(thd->query_id);
 
     TABLE_LIST tables;
     char table_buf[NAME_LEN + 1];
@@ -5450,9 +5450,9 @@ error:
   thd->catalog= 0;
   thd->set_db(NULL, 0);                   /* will free the current database */
   thd->reset_query();
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
   close_thread_tables(thd);
   /*
     - If inside a multi-statement transaction,
@@ -5479,8 +5479,8 @@ error:
     int sql_errno;
     if (thd->is_error())
     {
-      err= thd->stmt_da->message();
-      sql_errno= thd->stmt_da->sql_errno();
+      err= thd->get_stmt_da()->message();
+      sql_errno= thd->get_stmt_da()->sql_errno();
     }
     else
     {
@@ -8046,7 +8046,7 @@ int Rows_log_event::do_apply_event(Relay
 
     if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
     {
-      uint actual_error= thd->stmt_da->sql_errno();
+      uint actual_error= thd->get_stmt_da()->sql_errno();
       if (thd->is_slave_error || thd->is_fatal_error)
       {
         /*
@@ -8057,7 +8057,7 @@ int Rows_log_event::do_apply_event(Relay
         */
         rli->report(ERROR_LEVEL, actual_error,
                     "Error executing row event: '%s'",
-                    (actual_error ? thd->stmt_da->message() :
+                    (actual_error ? thd->get_stmt_da()->message() :
                      "unexpected success or fatal error"));
         thd->is_slave_error= 1;
       }

=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc	2011-05-12 21:51:20 +0000
+++ b/sql/log_event_old.cc	2011-06-09 08:58:41 +0000
@@ -99,7 +99,7 @@ Old_rows_log_event::do_apply_event(Old_r
 
     if (open_and_lock_tables(ev_thd, rli->tables_to_lock, FALSE, 0))
     {
-      uint actual_error= ev_thd->stmt_da->sql_errno();
+      uint actual_error= ev_thd->get_stmt_da()->sql_errno();
       if (ev_thd->is_slave_error || ev_thd->is_fatal_error)
       {
         /*
@@ -108,7 +108,7 @@ Old_rows_log_event::do_apply_event(Old_r
         */
         rli->report(ERROR_LEVEL, actual_error,
                     "Error '%s' on opening tables",
-                    (actual_error ? ev_thd->stmt_da->message() :
+                    (actual_error ? ev_thd->get_stmt_da()->message() :
                      "unexpected success or fatal error"));
         ev_thd->is_slave_error= 1;
       }
@@ -242,10 +242,10 @@ Old_rows_log_event::do_apply_event(Old_r
   break;
 
       default:
-  rli->report(ERROR_LEVEL, ev_thd->stmt_da->sql_errno(),
+  rli->report(ERROR_LEVEL, ev_thd->get_stmt_da()->sql_errno(),
                     "Error in %s event: row application failed. %s",
                     ev->get_type_str(),
-                    ev_thd->is_error() ? ev_thd->stmt_da->message() : "");
+                    ev_thd->is_error() ? ev_thd->get_stmt_da()->message() : "");
   thd->is_slave_error= 1;
   break;
       }
@@ -259,12 +259,12 @@ Old_rows_log_event::do_apply_event(Old_r
 
   if (error)
   {                     /* error has occured during the transaction */
-    rli->report(ERROR_LEVEL, ev_thd->stmt_da->sql_errno(),
+    rli->report(ERROR_LEVEL, ev_thd->get_stmt_da()->sql_errno(),
                 "Error in %s event: error during transaction execution "
                 "on table %s.%s. %s",
                 ev->get_type_str(), table->s->db.str,
                 table->s->table_name.str,
-                ev_thd->is_error() ? ev_thd->stmt_da->message() : "");
+                ev_thd->is_error() ? ev_thd->get_stmt_da()->message() : "");
 
     /*
       If one day we honour --skip-slave-errors in row-based replication, and

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2011-05-26 15:20:09 +0000
+++ b/sql/mysqld.cc	2011-06-06 10:29:45 +0000
@@ -159,12 +159,12 @@ extern int memcntl(caddr_t, size_t, int,
 int initgroups(const char *,unsigned int);
 #endif
 
-#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
+#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
 #include <ieeefp.h>
 #ifdef HAVE_FP_EXCEPT				// Fix type conflict
 typedef fp_except fp_except_t;
 #endif
-#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
+#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */
 #ifdef HAVE_SYS_FPU_H
 /* for IRIX to use set_fpc_csr() */
 #include <sys/fpu.h>
@@ -190,19 +190,24 @@ extern "C" my_bool reopen_fstreams(const
 
 inline void setup_fpu()
 {
-#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
+#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
   /* We can't handle floating point exceptions with threads, so disable
      this on freebsd
-     Don't fall for overflow, underflow,divide-by-zero or loss of precision
+     Don't fall for overflow, underflow,divide-by-zero or loss of precision.
+     fpsetmask() is deprecated in favor of fedisableexcept() in C99.
   */
-#if defined(__i386__)
+#if defined(FP_X_DNML)
   fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
 	      FP_X_IMP));
 #else
   fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
               FP_X_IMP));
-#endif /* __i386__ */
-#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
+#endif /* FP_X_DNML */
+#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */
+
+#ifdef HAVE_FEDISABLEEXCEPT
+  fedisableexcept(FE_ALL_EXCEPT);
+#endif
 
 #ifdef HAVE_FESETROUND
     /* Set FPU rounding mode to "round-to-nearest" */

=== modified file 'sql/opt_sum.cc'
--- a/sql/opt_sum.cc	2011-04-15 08:11:49 +0000
+++ b/sql/opt_sum.cc	2011-06-09 08:58:41 +0000
@@ -450,7 +450,7 @@ int opt_sum_query(THD *thd,
   }
 
   if (thd->is_error())
-    DBUG_RETURN(thd->stmt_da->sql_errno());
+    DBUG_RETURN(thd->get_stmt_da()->sql_errno());
 
   /*
     If we have a where clause, we can only ignore searching in the

=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc	2011-05-26 15:20:09 +0000
+++ b/sql/protocol.cc	2011-06-10 16:57:01 +0000
@@ -158,14 +158,14 @@ bool net_send_error(THD *thd, uint sql_e
     It's one case when we can push an error even though there
     is an OK or EOF already.
   */
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
 
   /* Abort multi-result sets */
   thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
   error= net_send_error_packet(thd, sql_errno, err, sqlstate);
 
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
 
   DBUG_RETURN(error);
 }
@@ -239,7 +239,7 @@ net_send_ok(THD *thd,
     int2store(pos, server_status);
     pos+=2;
   }
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
 
   if (message && message[0])
     pos= net_store_data(pos, (uchar*) message, strlen(message));
@@ -248,7 +248,7 @@ net_send_ok(THD *thd,
     error= net_flush(net);
 
 
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
   DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
 
   DBUG_RETURN(error);
@@ -288,11 +288,11 @@ net_send_eof(THD *thd, uint server_statu
   /* Set to TRUE if no active vio, to work well in case of --init-file */
   if (net->vio != 0)
   {
-    thd->stmt_da->can_overwrite_status= TRUE;
+    thd->get_stmt_da()->can_overwrite_status= TRUE;
     error= write_eof_packet(thd, net, server_status, statement_warn_count);
     if (!error)
       error= net_flush(net);
-    thd->stmt_da->can_overwrite_status= FALSE;
+    thd->get_stmt_da()->can_overwrite_status= FALSE;
     DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
   }
   DBUG_RETURN(error);
@@ -487,30 +487,30 @@ static uchar *net_store_length_fast(ucha
 void Protocol::end_statement()
 {
   DBUG_ENTER("Protocol::end_statement");
-  DBUG_ASSERT(! thd->stmt_da->is_sent);
+  DBUG_ASSERT(! thd->get_stmt_da()->is_sent);
   bool error= FALSE;
 
   /* Can not be true, but do not take chances in production. */
-  if (thd->stmt_da->is_sent)
+  if (thd->get_stmt_da()->is_sent)
     DBUG_VOID_RETURN;
 
-  switch (thd->stmt_da->status()) {
+  switch (thd->get_stmt_da()->status()) {
   case Diagnostics_area::DA_ERROR:
     /* The query failed, send error to log and abort bootstrap. */
-    error= send_error(thd->stmt_da->sql_errno(),
-                      thd->stmt_da->message(),
-                      thd->stmt_da->get_sqlstate());
+    error= send_error(thd->get_stmt_da()->sql_errno(),
+                      thd->get_stmt_da()->message(),
+                      thd->get_stmt_da()->get_sqlstate());
     break;
   case Diagnostics_area::DA_EOF:
     error= send_eof(thd->server_status,
-                    thd->stmt_da->statement_warn_count());
+                    thd->get_stmt_da()->statement_warn_count());
     break;
   case Diagnostics_area::DA_OK:
     error= send_ok(thd->server_status,
-                   thd->stmt_da->statement_warn_count(),
-                   thd->stmt_da->affected_rows(),
-                   thd->stmt_da->last_insert_id(),
-                   thd->stmt_da->message());
+                   thd->get_stmt_da()->statement_warn_count(),
+                   thd->get_stmt_da()->affected_rows(),
+                   thd->get_stmt_da()->last_insert_id(),
+                   thd->get_stmt_da()->message());
     break;
   case Diagnostics_area::DA_DISABLED:
     break;
@@ -521,7 +521,7 @@ void Protocol::end_statement()
     break;
   }
   if (!error)
-    thd->stmt_da->is_sent= TRUE;
+    thd->get_stmt_da()->is_sent= TRUE;
   DBUG_VOID_RETURN;
 }
 
@@ -639,9 +639,9 @@ bool Protocol::flush()
 {
 #ifndef EMBEDDED_LIBRARY
   bool error;
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
   error= net_flush(&thd->net);
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
   return error;
 #else
   return 0;
@@ -802,7 +802,7 @@ bool Protocol::send_result_set_metadata(
       Send no warning information, as it will be sent at statement end.
     */
     if (write_eof_packet(thd, &thd->net, thd->server_status,
-                         thd->warning_info->statement_warn_count()))
+                         thd->get_stmt_wi()->statement_warn_count()))
       DBUG_RETURN(1);
   }
   DBUG_RETURN(prepare_for_send(list->elements));

=== modified file 'sql/rpl_master.cc'
--- a/sql/rpl_master.cc	2011-05-26 15:20:09 +0000
+++ b/sql/rpl_master.cc	2011-06-09 08:58:41 +0000
@@ -649,8 +649,8 @@ void mysql_binlog_send(THD* thd, char* l
     Diagnostics_area.
   */
   Diagnostics_area temp_da;
-  Diagnostics_area *saved_da= thd->stmt_da;
-  thd->stmt_da= &temp_da;
+  Diagnostics_area *saved_da= thd->get_stmt_da();
+  thd->set_stmt_da(&temp_da);
 
   DBUG_ENTER("mysql_binlog_send");
   DBUG_PRINT("enter",("log_ident: '%s'  pos: %ld", log_ident, (long) pos));
@@ -1248,7 +1248,7 @@ impossible position";
   }
 
 end:
-  thd->stmt_da= saved_da;
+  thd->set_stmt_da(saved_da);
   end_io_cache(&log);
   mysql_file_close(file, MYF(MY_WME));
 
@@ -1279,7 +1279,7 @@ err:
     mysql_file_close(file, MYF(MY_WME));
   thd->variables.max_allowed_packet= old_max_allowed_packet;
 
-  thd->stmt_da= saved_da;
+  thd->set_stmt_da(saved_da);
   my_message(my_errno, errmsg, MYF(0));
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/rpl_reporting.cc'
--- a/sql/rpl_reporting.cc	2011-05-12 17:29:19 +0000
+++ b/sql/rpl_reporting.cc	2011-06-09 08:58:41 +0000
@@ -47,7 +47,7 @@ int Slave_reporting_capability::has_temp
   DBUG_ENTER("has_temporary_error");
 
   DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
-                  if (thd->stmt_da->is_error())
+                  if (thd->get_stmt_da()->is_error())
                   {
                     thd->clear_error();
                     my_error(ER_LOCK_DEADLOCK, MYF(0));
@@ -63,7 +63,7 @@ int Slave_reporting_capability::has_temp
   if (thd->is_fatal_error || !thd->is_error())
     DBUG_RETURN(0);
 
-  error= (error_arg == 0)? thd->stmt_da->sql_errno() : error_arg;
+  error= (error_arg == 0)? thd->get_stmt_da()->sql_errno() : error_arg;
 
   /*
     Temporary error codes:

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2011-05-26 15:20:09 +0000
+++ b/sql/rpl_rli.cc	2011-06-09 08:58:41 +0000
@@ -417,7 +417,7 @@ int Relay_log_info::wait_for_pos(THD* th
     DBUG_RETURN(-2);
 
   DBUG_PRINT("enter",("log_name: '%s'  log_pos: %lu  timeout: %lu",
-                      log_name->c_ptr(), (ulong) log_pos, (ulong) timeout));
+                      log_name->c_ptr_safe(), (ulong) log_pos, (ulong) timeout));
 
   set_timespec(abstime,timeout);
   mysql_mutex_lock(&data_lock);
@@ -1004,9 +1004,9 @@ void Relay_log_info::clear_tables_to_loc
 
 void Relay_log_info::slave_close_thread_tables(THD *thd)
 {
-  thd->stmt_da->can_overwrite_status= TRUE;
+  thd->get_stmt_da()->can_overwrite_status= TRUE;
   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-  thd->stmt_da->can_overwrite_status= FALSE;
+  thd->get_stmt_da()->can_overwrite_status= FALSE;
 
   close_thread_tables(thd);
   /*

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2011-05-21 08:25:33 +0000
+++ b/sql/rpl_slave.cc	2011-06-10 16:57:01 +0000
@@ -2927,7 +2927,7 @@ static int exec_relay_log_event(THD* thd
         else
         {
           thd->is_fatal_error= 1;
-          rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
+          rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
                       "Slave SQL thread retried transaction %lu time(s) "
                       "in vain, giving up. Consider raising the value of "
                       "the slave_transaction_retries variable.", rli->trans_retries);
@@ -3639,9 +3639,9 @@ log '%s' at position %s, relay log '%s'
 
   if (check_temp_dir(rli->slave_patternload_file))
   {
-    rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), 
+    rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), 
                 "Unable to use slave's temporary directory %s - %s", 
-                slave_load_tmpdir, thd->stmt_da->message());
+                slave_load_tmpdir, thd->get_stmt_da()->message());
     goto err;
   }
 
@@ -3651,7 +3651,7 @@ log '%s' at position %s, relay log '%s'
     execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
     if (thd->is_slave_error)
     {
-      rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
+      rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
                   "Slave SQL thread aborted. Can't execute init_slave query");
       goto err;
     }
@@ -3718,20 +3718,22 @@ log '%s' at position %s, relay log '%s'
 
         if (thd->is_error())
         {
-          char const *const errmsg= thd->stmt_da->message();
+          char const *const errmsg= thd->get_stmt_da()->message();
 
           DBUG_PRINT("info",
-                     ("thd->stmt_da->sql_errno()=%d; rli->last_error.number=%d",
-                      thd->stmt_da->sql_errno(), last_errno));
+                     ("thd->get_stmt_da()->sql_errno()=%d; "
+                      "rli->last_error.number=%d",
+                      thd->get_stmt_da()->sql_errno(), last_errno));
           if (last_errno == 0)
           {
             /*
  	      This function is reporting an error which was not reported
  	      while executing exec_relay_log_event().
  	    */ 
-            rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "%s", errmsg);
+            rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
+                        "%s", errmsg);
           }
-          else if (last_errno != thd->stmt_da->sql_errno())
+          else if (last_errno != thd->get_stmt_da()->sql_errno())
           {
             /*
              * An error was reported while executing exec_relay_log_event()
@@ -3740,12 +3742,12 @@ log '%s' at position %s, relay log '%s'
              * what caused the problem.
              */  
             sql_print_error("Slave (additional info): %s Error_code: %d",
-                            errmsg, thd->stmt_da->sql_errno());
+                            errmsg, thd->get_stmt_da()->sql_errno());
           }
         }
 
         /* Print any warnings issued */
-        List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+        List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
         MYSQL_ERROR *err;
         /*
           Added controlled slave thread cancel for replication
@@ -5485,7 +5487,7 @@ uint sql_slave_skip_counter;
 
   @param mi Pointer to Master_info object for the slave's IO thread.
 
-  @param net_report If true, saves the exit status into thd->stmt_da.
+  @param net_report If true, saves the exit status into Diagnostics_area.
 
   @retval 0 success
   @retval 1 error
@@ -5621,7 +5623,7 @@ int start_slave(THD* thd , Master_info*
 
   @param mi Pointer to Master_info object for the slave's IO thread.
 
-  @param net_report If true, saves the exit status into thd->stmt_da.
+  @param net_report If true, saves the exit status into Diagnostics_area.
 
   @retval 0 success
   @retval 1 error

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2011-05-31 09:30:59 +0000
+++ b/sql/share/errmsg-utf8.txt	2011-06-10 07:38:06 +0000
@@ -6505,3 +6505,10 @@ ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DR
 
 ER_INDEX_COLUMN_TOO_LONG
   eng "Index column size too large. The maximum column size is %lu bytes."
+
+ER_ERROR_IN_TRIGGER_BODY
+  eng "Trigger '%-.64s' has an error in its body: '%-.256s'"
+
+ER_ERROR_IN_UNKNOWN_TRIGGER_BODY
+  eng "Unknown trigger has an error in its body: '%-.256s'"
+

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sp.cc	2011-06-10 16:57:01 +0000
@@ -1727,7 +1727,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *
                                sp_find_routine(thd, TYPE_ENUM_FUNCTION,
                                                name, &thd->sp_func_cache,
                                                FALSE) != NULL;
-    thd->warning_info->clear_warning_info(thd->query_id);
+    thd->get_stmt_wi()->clear_warning_info(thd->query_id);
     if (! sp_object_found)
     {
       my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sp_head.cc	2011-06-10 16:57:01 +0000
@@ -1141,14 +1141,14 @@ find_handler_after_execution(THD *thd, s
   if (thd->is_error())
   {
     ctx->find_handler(thd,
-                      thd->stmt_da->sql_errno(),
-                      thd->stmt_da->get_sqlstate(),
+                      thd->get_stmt_da()->sql_errno(),
+                      thd->get_stmt_da()->get_sqlstate(),
                       MYSQL_ERROR::WARN_LEVEL_ERROR,
-                      thd->stmt_da->message());
+                      thd->get_stmt_da()->message());
   }
-  else if (thd->warning_info->statement_warn_count())
+  else if (thd->get_stmt_wi()->statement_warn_count())
   {
-    List_iterator<MYSQL_ERROR> it(thd->warning_info->warn_list());
+    List_iterator<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
     MYSQL_ERROR *err;
     while ((err= it++))
     {
@@ -1214,8 +1214,9 @@ sp_head::execute(THD *thd, bool merge_da
   String old_packet;
   Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
   Object_creation_ctx *saved_creation_ctx;
+  Diagnostics_area *da= thd->get_stmt_da();
   Warning_info *saved_warning_info;
-  Warning_info warning_info(thd->warning_info->warn_id(), false);
+  Warning_info warning_info(thd->get_stmt_wi()->warn_id(), false);
 
   /*
     Just reporting a stack overrun error
@@ -1286,9 +1287,9 @@ sp_head::execute(THD *thd, bool merge_da
   old_arena= thd->stmt_arena;
 
   /* Push a new warning information area. */
-  warning_info.append_warning_info(thd, thd->warning_info);
-  saved_warning_info= thd->warning_info;
-  thd->warning_info= &warning_info;
+  warning_info.append_warning_info(thd, thd->get_stmt_wi());
+  saved_warning_info= thd->get_stmt_wi();
+  da->set_warning_info(&warning_info);
 
   /*
     Switch query context. This has to be done early as this is sometimes
@@ -1388,7 +1389,7 @@ sp_head::execute(THD *thd, bool merge_da
     }
 
     /* Reset number of warnings for this query. */
-    thd->warning_info->reset_for_next_command();
+    thd->get_stmt_wi()->reset_for_next_command();
 
     DBUG_PRINT("execute", ("Instruction %u", ip));
 
@@ -1496,8 +1497,8 @@ sp_head::execute(THD *thd, bool merge_da
         propagated to the caller in any case.
   */
   if (err_status || merge_da_on_success)
-    saved_warning_info->merge_with_routine_info(thd, thd->warning_info);
-  thd->warning_info= saved_warning_info;
+    saved_warning_info->merge_with_routine_info(thd, thd->get_stmt_wi());
+  da->set_warning_info(saved_warning_info);
 
  done:
   DBUG_PRINT("info", ("err_status: %d  killed: %d  is_slave_error: %d  report_error: %d",
@@ -2129,9 +2130,9 @@ sp_head::execute_procedure(THD *thd, Lis
 
     if (!thd->in_sub_stmt)
     {
-      thd->stmt_da->can_overwrite_status= TRUE;
+      thd->get_stmt_da()->can_overwrite_status= TRUE;
       thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-      thd->stmt_da->can_overwrite_status= FALSE;
+      thd->get_stmt_da()->can_overwrite_status= FALSE;
     }
 
     thd_proc_info(thd, "closing tables");
@@ -2540,7 +2541,22 @@ void
 sp_head::restore_thd_mem_root(THD *thd)
 {
   DBUG_ENTER("sp_head::restore_thd_mem_root");
-  Item *flist= free_list;       // The old list
+
+  /*
+   In some cases our parser detects a syntax error and calls
+   LEX::cleanup_lex_after_parse_error() method only after
+   finishing parsing the whole routine. In such a situation
+   sp_head::restore_thd_mem_root() will be called twice - the
+   first time as part of normal parsing process and the second
+   time by cleanup_lex_after_parse_error().
+   To avoid ruining active arena/mem_root state in this case we
+   skip restoration of old arena/mem_root if this method has been
+   already called for this routine.
+  */
+  if (!m_thd)
+    DBUG_VOID_RETURN;
+
+  Item *flist= free_list;	// The old list
   set_query_arena(thd);         // Get new free_list and mem_root
   state= STMT_INITIALIZED_FOR_SP;
 
@@ -2968,9 +2984,9 @@ sp_lex_keeper::reset_lex_and_exec_core(T
     /* Here we also commit or rollback the current statement. */
     if (! thd->in_sub_stmt)
     {
-      thd->stmt_da->can_overwrite_status= TRUE;
+      thd->get_stmt_da()->can_overwrite_status= TRUE;
       thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
-      thd->stmt_da->can_overwrite_status= FALSE;
+      thd->get_stmt_da()->can_overwrite_status= FALSE;
     }
     thd_proc_info(thd, "closing tables");
     close_thread_tables(thd);
@@ -3004,9 +3020,9 @@ sp_lex_keeper::reset_lex_and_exec_core(T
     open_tables stage.
   */
   if (!res || !thd->is_error() ||
-      (thd->stmt_da->sql_errno() != ER_CANT_REOPEN_TABLE &&
-       thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE &&
-       thd->stmt_da->sql_errno() != ER_UPDATE_TABLE_USED))
+      (thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE &&
+       thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE &&
+       thd->get_stmt_da()->sql_errno() != ER_UPDATE_TABLE_USED))
     thd->stmt_arena->state= Query_arena::STMT_EXECUTED;
 
   /*
@@ -3092,7 +3108,7 @@ sp_instr_stmt::execute(THD *thd, uint *n
     {
       res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
 
-      if (thd->stmt_da->is_eof())
+      if (thd->get_stmt_da()->is_eof())
       {
         /* Finalize server status flags after executing a statement. */
         thd->update_server_status();
@@ -3111,7 +3127,7 @@ sp_instr_stmt::execute(THD *thd, uint *n
     thd->query_name_consts= 0;
 
     if (!thd->is_error())
-      thd->stmt_da->reset_diagnostics_area();
+      thd->get_stmt_da()->reset_diagnostics_area();
   }
   DBUG_RETURN(res || thd->is_error());
 }

=== modified file 'sql/spatial.cc'
--- a/sql/spatial.cc	2011-05-10 13:37:37 +0000
+++ b/sql/spatial.cc	2011-06-08 17:24:16 +0000
@@ -1141,7 +1141,7 @@ int Gis_polygon::store_shapes(Gcalc_shap
       return 1;
     n_points= uint4korr(data);
     data+= 4;
-    if (no_data(data, POINT_DATA_SIZE * n_points))
+    if (!n_points || no_data(data, POINT_DATA_SIZE * n_points))
       return 1;
 
     trn->start_ring();

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2011-05-31 13:52:09 +0000
+++ b/sql/sql_acl.cc	2011-06-09 08:58:41 +0000
@@ -1146,9 +1146,9 @@ my_bool acl_reload(THD *thd)
       Execution might have been interrupted; only print the error message
       if an error condition has been raised.
     */
-    if (thd->stmt_da->is_error())
+    if (thd->get_stmt_da()->is_error())
       sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
-                      thd->stmt_da->message());
+                      thd->get_stmt_da()->message());
     goto end;
   }
 
@@ -9538,7 +9538,7 @@ acl_authenticate(THD *thd, uint connect_
     sctx->external_user= my_strdup(mpvio.auth_info.external_user, MYF(0));
 
   if (res == CR_OK_HANDSHAKE_COMPLETE)
-    thd->stmt_da->disable_status();
+    thd->get_stmt_da()->disable_status();
   else
     my_ok(thd);
 

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2011-05-04 07:51:15 +0000
+++ b/sql/sql_admin.cc	2011-06-10 16:57:01 +0000
@@ -351,17 +351,18 @@ static bool mysql_admin_table(THD* thd,
           because it's already known that the table is badly damaged.
         */
 
+        Diagnostics_area *da= thd->get_stmt_da();
         Warning_info wi(thd->query_id, false);
-        Warning_info *wi_saved= thd->warning_info;
+        Warning_info *wi_saved= thd->get_stmt_wi();
 
-        thd->warning_info= &wi;
+        da->set_warning_info(&wi);
 
         open_error= open_temporary_tables(thd, table);
 
         if (!open_error)
           open_error= open_and_lock_tables(thd, table, TRUE, 0);
 
-        thd->warning_info= wi_saved;
+        da->set_warning_info(wi_saved);
       }
       else
       {
@@ -479,7 +480,7 @@ static bool mysql_admin_table(THD* thd,
     if (!table->table)
     {
       DBUG_PRINT("admin", ("open table failed"));
-      if (thd->warning_info->is_empty())
+      if (thd->get_stmt_wi()->is_empty())
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                      ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
       /* if it was a view will check md5 sum */
@@ -487,8 +488,8 @@ static bool mysql_admin_table(THD* thd,
           view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                      ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
-      if (thd->stmt_da->is_error() &&
-          table_not_corrupt_error(thd->stmt_da->sql_errno()))
+      if (thd->get_stmt_da()->is_error() &&
+          table_not_corrupt_error(thd->get_stmt_da()->sql_errno()))
         result_code= HA_ADMIN_FAILED;
       else
         /* Default failure code is corrupt table */
@@ -536,7 +537,7 @@ static bool mysql_admin_table(THD* thd,
       table->table=0;				// For query cache
       if (protocol->write())
 	goto err;
-      thd->stmt_da->reset_diagnostics_area();
+      thd->get_stmt_da()->reset_diagnostics_area();
       continue;
       /* purecov: end */
     }
@@ -621,8 +622,8 @@ static bool mysql_admin_table(THD* thd,
           we will store the error message in a result set row 
           and then clear.
         */
-        if (thd->stmt_da->is_ok())
-          thd->stmt_da->reset_diagnostics_area();
+        if (thd->get_stmt_da()->is_ok())
+          thd->get_stmt_da()->reset_diagnostics_area();
         table->table= NULL;
         result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
         goto send_result;
@@ -638,7 +639,7 @@ send_result:
     lex->cleanup_after_one_table_open();
     thd->clear_error();  // these errors shouldn't get client
     {
-      List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+      List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
       MYSQL_ERROR *err;
       while ((err= it++))
       {
@@ -652,7 +653,7 @@ send_result:
         if (protocol->write())
           goto err;
       }
-      thd->warning_info->clear_warning_info(thd->query_id);
+      thd->get_stmt_wi()->clear_warning_info(thd->query_id);
     }
     protocol->prepare_for_resend();
     protocol->store(table_name, system_charset_info);
@@ -767,8 +768,8 @@ send_result_message:
         we will store the error message in a result set row 
         and then clear.
       */
-      if (thd->stmt_da->is_ok())
-        thd->stmt_da->reset_diagnostics_area();
+      if (thd->get_stmt_da()->is_ok())
+        thd->get_stmt_da()->reset_diagnostics_area();
       trans_commit_stmt(thd);
       trans_commit(thd);
       close_thread_tables(thd);
@@ -801,7 +802,7 @@ send_result_message:
         DBUG_ASSERT(thd->is_error() || thd->killed);
         if (thd->is_error())
         {
-          const char *err_msg= thd->stmt_da->message();
+          const char *err_msg= thd->get_stmt_da()->message();
           if (!thd->vio_ok())
           {
             sql_print_error("%s", err_msg);

=== modified file 'sql/sql_alloc_error_handler.cc'
--- a/sql/sql_alloc_error_handler.cc	2010-07-02 02:58:51 +0000
+++ b/sql/sql_alloc_error_handler.cc	2011-06-09 08:58:41 +0000
@@ -38,10 +38,10 @@ extern "C" void sql_alloc_error_handler(
       returned in the error packet.
       - SHOW ERROR/SHOW WARNINGS may be empty.
     */
-    thd->stmt_da->set_error_status(thd,
-                                   ER_OUT_OF_RESOURCES,
-                                   ER(ER_OUT_OF_RESOURCES),
-                                   NULL);
+    thd->get_stmt_da()->set_error_status(thd,
+                                         ER_OUT_OF_RESOURCES,
+                                         ER(ER_OUT_OF_RESOURCES),
+                                         NULL);
   }
 
   /* Skip writing to the error log to avoid mtr complaints */

=== modified file 'sql/sql_audit.cc'
--- a/sql/sql_audit.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_audit.cc	2011-06-03 08:00:42 +0000
@@ -21,11 +21,18 @@ extern int finalize_audit_plugin(st_plug
 
 #ifndef EMBEDDED_LIBRARY
 
+struct st_mysql_event_generic
+{
+  unsigned int event_class;
+  const void *event;
+};
+
 unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
 
 static mysql_mutex_t LOCK_audit_mask;
 
-static void event_class_dispatch(THD *thd, const struct mysql_event *event);
+static void event_class_dispatch(THD *thd, unsigned int event_class,
+                                 const void *event);
 
 
 static inline
@@ -64,7 +71,6 @@ typedef void (*audit_handler_t)(THD *thd
 static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
 {
   mysql_event_general event;
-  event.event_class= MYSQL_AUDIT_GENERAL_CLASS;
   event.event_subclass= event_subtype;
   event.general_error_code= va_arg(ap, int);
   event.general_thread_id= thd ? thd->thread_id : 0;
@@ -77,14 +83,13 @@ static void general_class_handler(THD *t
   event.general_query_length= va_arg(ap, unsigned int);
   event.general_charset= va_arg(ap, struct charset_info_st *);
   event.general_rows= (unsigned long long) va_arg(ap, ha_rows);
-  event_class_dispatch(thd, (const mysql_event*) &event);
+  event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event);
 }
 
 
 static void connection_class_handler(THD *thd, uint event_subclass, va_list ap)
 {
   mysql_event_connection event;
-  event.event_class= MYSQL_AUDIT_CONNECTION_CLASS;
   event.event_subclass= event_subclass;
   event.status= va_arg(ap, int);
   event.thread_id= va_arg(ap, unsigned long);
@@ -102,7 +107,7 @@ static void connection_class_handler(THD
   event.ip_length= va_arg(ap, unsigned int);
   event.database= va_arg(ap, const char *);
   event.database_length= va_arg(ap, unsigned int);
-  event_class_dispatch(thd, (const mysql_event *) &event);
+  event_class_dispatch(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
 }
 
 
@@ -430,18 +435,19 @@ int finalize_audit_plugin(st_plugin_int
 
 static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg)
 {
-  const struct mysql_event *event= (const struct mysql_event *) arg;
+  const struct st_mysql_event_generic *event_generic=
+    (const struct st_mysql_event_generic *) arg;
   unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
   st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *);
 
-  set_audit_mask(event_class_mask, event->event_class);
+  set_audit_mask(event_class_mask, event_generic->event_class);
 
   /* Check to see if the plugin is interested in this event */
   if (check_audit_mask(data->class_mask, event_class_mask))
     return 0;
 
   /* Actually notify the plugin */
-  data->event_notify(thd, event);
+  data->event_notify(thd, event_generic->event_class, event_generic->event);
 
   return 0;
 }
@@ -454,15 +460,19 @@ static my_bool plugins_dispatch(THD *thd
   @param[in] event
 */
 
-static void event_class_dispatch(THD *thd, const struct mysql_event *event)
+static void event_class_dispatch(THD *thd, unsigned int event_class,
+                                 const void *event)
 {
+  struct st_mysql_event_generic event_generic;
+  event_generic.event_class= event_class;
+  event_generic.event= event;
   /*
     Check if we are doing a slow global dispatch. This event occurs when
     thd == NULL as it is not associated with any particular thread.
   */
   if (unlikely(!thd))
   {
-    plugin_foreach(thd, plugins_dispatch, MYSQL_AUDIT_PLUGIN, (void*) event);
+    plugin_foreach(thd, plugins_dispatch, MYSQL_AUDIT_PLUGIN, &event_generic);
   }
   else
   {
@@ -473,7 +483,7 @@ static void event_class_dispatch(THD *th
     plugins_last= plugins + thd->audit_class_plugins.elements;
 
     for (; plugins < plugins_last; plugins++)
-      plugins_dispatch(thd, *plugins, (void*) event);
+      plugins_dispatch(thd, *plugins, &event_generic);
   }
 }
 

=== modified file 'sql/sql_audit.h'
--- a/sql/sql_audit.h	2011-03-09 20:54:55 +0000
+++ b/sql/sql_audit.h	2011-06-10 16:57:01 +0000
@@ -117,7 +117,7 @@ void mysql_audit_general(THD *thd, uint
       query= thd->query_string;
       user= user_buff;
       userlen= make_user_name(thd, user_buff);
-      rows= thd->warning_info->current_row_for_warning();
+      rows= thd->get_stmt_wi()->current_row_for_warning();
     }
     else
     {
@@ -135,7 +135,7 @@ void mysql_audit_general(THD *thd, uint
 
 #define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\
   (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\
-  (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\
+  (thd)->get_stmt_da()->is_error() ? (thd)->get_stmt_da()->sql_errno() : 0,\
   (thd)->thread_id, (thd)->security_ctx->user,\
   (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
   (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\
@@ -156,7 +156,7 @@ void mysql_audit_general(THD *thd, uint
 
 #define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\
   (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\
-  (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\
+  (thd)->get_stmt_da()->is_error() ? (thd)->get_stmt_da()->sql_errno() : 0,\
   (thd)->thread_id, (thd)->security_ctx->user,\
   (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
   (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_base.cc	2011-06-10 16:57:01 +0000
@@ -676,8 +676,11 @@ get_table_share_with_discover(THD *thd,
 
     @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
   */
-  if (share || (thd->is_error() && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE))
+  if (share || (thd->is_error() &&
+      thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE))
+  {
     DBUG_RETURN(share);
+  }
 
   *error= 0;
 
@@ -1728,14 +1731,14 @@ bool close_temporary_tables(THD *thd)
       qinfo.db_len= db.length();
       thd->variables.character_set_client= cs_save;
 
-      thd->stmt_da->can_overwrite_status= TRUE;
+      thd->get_stmt_da()->can_overwrite_status= TRUE;
       if ((error= (mysql_bin_log.write(&qinfo) || error)))
       {
         /*
           If we're here following THD::cleanup, thence the connection
           has been closed already. So lets print a message to the
           error log instead of pushing yet another error into the
-          stmt_da.
+          Diagnostics_area.
 
           Also, we keep the error flag so that we propagate the error
           up in the stack. This way, if we're the SQL thread we notice
@@ -1746,7 +1749,7 @@ bool close_temporary_tables(THD *thd)
         sql_print_error("Failed to write the DROP statement for "
                         "temporary tables to binary log");
       }
-      thd->stmt_da->can_overwrite_status= FALSE;
+      thd->get_stmt_da()->can_overwrite_status= FALSE;
 
       thd->variables.pseudo_thread_id= save_pseudo_thread_id;
       thd->thread_specific_used= save_thread_specific_used;
@@ -4013,7 +4016,7 @@ recover_from_failed_open(THD *thd)
         ha_create_table_from_engine(thd, m_failed_table->db,
                                     m_failed_table->table_name);
 
-        thd->warning_info->clear_warning_info(thd->query_id);
+        thd->get_stmt_wi()->clear_warning_info(thd->query_id);
         thd->clear_error();                 // Clear error message
         thd->mdl_context.release_transactional_locks();
         break;

=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc	2011-05-31 13:52:09 +0000
+++ b/sql/sql_cache.cc	2011-06-09 08:58:41 +0000
@@ -993,7 +993,7 @@ void Query_cache::end_of_result(THD *thd
     DBUG_VOID_RETURN;
 
   /* Ensure that only complete results are cached. */
-  DBUG_ASSERT(thd->stmt_da->is_eof());
+  DBUG_ASSERT(thd->get_stmt_da()->is_eof());
 
   if (thd->killed)
   {
@@ -1756,8 +1756,8 @@ def_week_frmt: %lu, in_trans: %d, autoco
     response, we can't handle it anyway.
   */
   (void) trans_commit_stmt(thd);
-  if (!thd->stmt_da->is_set())
-    thd->stmt_da->disable_status();
+  if (!thd->get_stmt_da()->is_set())
+    thd->get_stmt_da()->disable_status();
 
   BLOCK_UNLOCK_RD(query_block);
   MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows);

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2011-05-31 13:52:09 +0000
+++ b/sql/sql_class.cc	2011-06-10 16:57:01 +0000
@@ -596,7 +596,7 @@ int thd_tx_isolation(const THD *thd)
 extern "C"
 void thd_inc_row_count(THD *thd)
 {
-  thd->warning_info->inc_current_row_for_warning();
+  thd->get_stmt_wi()->inc_current_row_for_warning();
 }
 
 
@@ -738,8 +738,6 @@ THD::THD(bool enable_plugins)
    first_successful_insert_id_in_cur_stmt(0),
    stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
    m_examined_row_count(0),
-   warning_info(&main_warning_info),
-   stmt_da(&main_da),
    m_statement_psi(NULL),
    is_fatal_error(0),
    transaction_rollback_request(0),
@@ -755,7 +753,8 @@ THD::THD(bool enable_plugins)
    debug_sync_control(0),
 #endif /* defined(ENABLED_DEBUG_SYNC) */
    m_enable_plugins(enable_plugins),
-   main_warning_info(0, false)
+   main_da(0, false),
+   m_stmt_da(&main_da)
 {
   ulong tmp;
 
@@ -1010,6 +1009,8 @@ MYSQL_ERROR* THD::raise_condition(uint s
                                   MYSQL_ERROR::enum_warning_level level,
                                   const char* msg)
 {
+  Diagnostics_area *da= get_stmt_da();
+  Warning_info *wi= da->get_warning_info();
   MYSQL_ERROR *cond= NULL;
   DBUG_ENTER("THD::raise_condition");
 
@@ -1017,7 +1018,7 @@ MYSQL_ERROR* THD::raise_condition(uint s
       (level == MYSQL_ERROR::WARN_LEVEL_NOTE))
     DBUG_RETURN(NULL);
 
-  warning_info->opt_clear_warning_info(query_id);
+  wi->opt_clear_warning_info(query_id);
 
   /*
     TODO: replace by DBUG_ASSERT(sql_errno != 0) once all bugs similar to
@@ -1077,10 +1078,10 @@ MYSQL_ERROR* THD::raise_condition(uint s
     }
     else
     {
-      if (! stmt_da->is_error())
+      if (!da->is_error())
       {
         set_row_count_func(-1);
-        stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
+        da->set_error_status(this, sql_errno, msg, sqlstate);
       }
     }
   }
@@ -1090,7 +1091,7 @@ MYSQL_ERROR* THD::raise_condition(uint s
   /* When simulating OOM, skip writing to error log to avoid mtr errors */
   DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL););
 
-  cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg);
+  cond= wi->push_warning(this, sql_errno, sqlstate, level, msg);
   DBUG_RETURN(cond);
 }
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-05-31 13:52:09 +0000
+++ b/sql/sql_class.h	2011-06-10 16:57:01 +0000
@@ -2281,8 +2281,6 @@ public:
   table_map  used_tables;
   USER_CONN *user_connect;
   const CHARSET_INFO *db_charset;
-  Warning_info *warning_info;
-  Diagnostics_area *stmt_da;
 #if defined(ENABLED_PROFILING)
   PROFILING  profiling;
 #endif
@@ -2787,8 +2785,8 @@ public:
   inline void clear_error()
   {
     DBUG_ENTER("clear_error");
-    if (stmt_da->is_error())
-      stmt_da->reset_diagnostics_area();
+    if (get_stmt_da()->is_error())
+      get_stmt_da()->reset_diagnostics_area();
     is_slave_error= 0;
     DBUG_VOID_RETURN;
   }
@@ -2815,7 +2813,7 @@ public:
   */
   inline void fatal_error()
   {
-    DBUG_ASSERT(stmt_da->is_error() || killed);
+    DBUG_ASSERT(get_stmt_da()->is_error() || killed);
     is_fatal_error= 1;
     DBUG_PRINT("error",("Fatal error set"));
   }
@@ -2832,7 +2830,25 @@ public:
 
     To raise this flag, use my_error().
   */
-  inline bool is_error() const { return stmt_da->is_error(); }
+  inline bool is_error() const { return get_stmt_da()->is_error(); }
+
+  /// Returns Warning-information-area for the current diagnostics area.
+  Warning_info *get_stmt_wi()
+  { return get_stmt_da()->get_warning_info(); }
+
+  /// Returns Diagnostics-area for the current statement.
+  Diagnostics_area *get_stmt_da()
+  { return m_stmt_da; }
+
+  /// Returns Diagnostics-area for the current statement.
+  const Diagnostics_area *get_stmt_da() const
+  { return m_stmt_da; }
+
+  /// Sets Diagnostics-area for the current statement.
+  void set_stmt_da(Diagnostics_area *da)
+  { m_stmt_da= da; }
+
+public:
   inline const CHARSET_INFO *charset()
   { return variables.character_set_client; }
   void update_charset();
@@ -3223,8 +3239,8 @@ private:
     tree itself is reused between executions and thus is stored elsewhere.
   */
   MEM_ROOT main_mem_root;
-  Warning_info main_warning_info;
   Diagnostics_area main_da;
+  Diagnostics_area *m_stmt_da;
 
   /**
     It will be set TURE if CURRENT_USER() is called in account management
@@ -3247,24 +3263,24 @@ private:
 };
 
 
-/** A short cut for thd->stmt_da->set_ok_status(). */
+/** A short cut for thd->get_stmt_da()->set_ok_status(). */
 
 inline void
 my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0,
         const char *message= NULL)
 {
   thd->set_row_count_func(affected_rows);
-  thd->stmt_da->set_ok_status(thd, affected_rows, id, message);
+  thd->get_stmt_da()->set_ok_status(thd, affected_rows, id, message);
 }
 
 
-/** A short cut for thd->stmt_da->set_eof_status(). */
+/** A short cut for thd->get_stmt_da()->set_eof_status(). */
 
 inline void
 my_eof(THD *thd)
 {
   thd->set_row_count_func(-1);
-  thd->stmt_da->set_eof_status(thd);
+  thd->get_stmt_da()->set_eof_status(thd);
 }
 
 #define tmp_disable_binlog(A)       \

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2011-05-30 11:42:03 +0000
+++ b/sql/sql_connect.cc	2011-06-09 08:58:41 +0000
@@ -631,7 +631,8 @@ void end_connection(THD *thd)
                         thd->thread_id,(thd->db ? thd->db : "unconnected"),
                         sctx->user ? sctx->user : "unauthenticated",
                         sctx->host_or_ip,
-                        (thd->stmt_da->is_error() ? thd->stmt_da->message() :
+                        (thd->get_stmt_da()->is_error() ?
+                         thd->get_stmt_da()->message() :
                          ER(ER_UNKNOWN_ERROR)));
     }
   }
@@ -669,7 +670,7 @@ void prepare_new_connection_state(THD* t
                         thd->thread_id,(thd->db ? thd->db : "unconnected"),
                         sctx->user ? sctx->user : "unauthenticated",
                         sctx->host_or_ip, "init_connect command failed");
-      sql_print_warning("%s", thd->stmt_da->message());
+      sql_print_warning("%s", thd->get_stmt_da()->message());
     }
     thd->proc_info=0;
     thd->set_time();

=== modified file 'sql/sql_derived.cc'
--- a/sql/sql_derived.cc	2011-03-08 19:14:42 +0000
+++ b/sql/sql_derived.cc	2011-06-09 08:58:41 +0000
@@ -184,9 +184,9 @@ exit:
     if (orig_table_list->view)
     {
       if (thd->is_error() &&
-          (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR ||
-          thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
-          thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST))
+          (thd->get_stmt_da()->sql_errno() == ER_BAD_FIELD_ERROR ||
+          thd->get_stmt_da()->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
+          thd->get_stmt_da()->sql_errno() == ER_SP_DOES_NOT_EXIST))
       {
         thd->clear_error();
         my_error(ER_VIEW_INVALID, MYF(0), orig_table_list->db,

=== modified file 'sql/sql_error.cc'
--- a/sql/sql_error.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_error.cc	2011-06-10 16:57:01 +0000
@@ -318,6 +318,21 @@ MYSQL_ERROR::set_sqlstate(const char* sq
   m_returned_sqlstate[SQLSTATE_LENGTH]= '\0';
 }
 
+Diagnostics_area::Diagnostics_area()
+ : m_main_wi(0, false),
+   m_current_wi(&m_main_wi)
+{
+  reset_diagnostics_area();
+}
+
+Diagnostics_area::Diagnostics_area(ulonglong warn_id,
+                                   bool allow_unlimited_warnings)
+ : m_main_wi(warn_id, allow_unlimited_warnings),
+   m_current_wi(&m_main_wi)
+{
+  reset_diagnostics_area();
+}
+
 /**
   Clear this diagnostics area.
 
@@ -363,7 +378,7 @@ Diagnostics_area::set_ok_status(THD *thd
   if (is_error() || is_disabled())
     return;
 
-  m_statement_warn_count= thd->warning_info->statement_warn_count();
+  m_statement_warn_count= thd->get_stmt_wi()->statement_warn_count();
   m_affected_rows= affected_rows_arg;
   m_last_insert_id= last_insert_id_arg;
   if (message_arg)
@@ -398,7 +413,7 @@ Diagnostics_area::set_eof_status(THD *th
     anyway.
   */
   m_statement_warn_count= (thd->spcont ?
-                           0 : thd->warning_info->statement_warn_count());
+                           0 : thd->get_stmt_wi()->statement_warn_count());
 
   m_status= DA_EOF;
   DBUG_VOID_RETURN;
@@ -667,7 +682,7 @@ bool mysqld_show_warnings(THD *thd, ulon
   List<Item> field_list;
   DBUG_ENTER("mysqld_show_warnings");
 
-  DBUG_ASSERT(thd->warning_info->is_read_only());
+  DBUG_ASSERT(thd->get_stmt_wi()->is_read_only());
 
   field_list.push_back(new Item_empty_string("Level", 7));
   field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG));
@@ -685,7 +700,7 @@ bool mysqld_show_warnings(THD *thd, ulon
 
   unit->set_limit(sel);
 
-  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
   while ((err= it++))
   {
     /* Skip levels that the user is not interested in */
@@ -708,7 +723,7 @@ bool mysqld_show_warnings(THD *thd, ulon
   }
   my_eof(thd);
 
-  thd->warning_info->set_read_only(FALSE);
+  thd->get_stmt_wi()->set_read_only(FALSE);
 
   DBUG_RETURN(FALSE);
 }

=== modified file 'sql/sql_error.h'
--- a/sql/sql_error.h	2011-04-15 12:14:35 +0000
+++ b/sql/sql_error.h	2011-06-10 07:49:17 +0000
@@ -23,114 +23,6 @@
 
 class THD;
 
-/**
-  Stores status of the currently executed statement.
-  Cleared at the beginning of the statement, and then
-  can hold either OK, ERROR, or EOF status.
-  Can not be assigned twice per statement.
-*/
-
-class Diagnostics_area
-{
-public:
-  enum enum_diagnostics_status
-  {
-    /** The area is cleared at start of a statement. */
-    DA_EMPTY= 0,
-    /** Set whenever one calls my_ok(). */
-    DA_OK,
-    /** Set whenever one calls my_eof(). */
-    DA_EOF,
-    /** Set whenever one calls my_error() or my_message(). */
-    DA_ERROR,
-    /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
-    DA_DISABLED
-  };
-  /** True if status information is sent to the client. */
-  bool is_sent;
-  /** Set to make set_error_status after set_{ok,eof}_status possible. */
-  bool can_overwrite_status;
-
-  void set_ok_status(THD *thd, ulonglong affected_rows_arg,
-                     ulonglong last_insert_id_arg,
-                     const char *message);
-  void set_eof_status(THD *thd);
-  void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg,
-                        const char *sqlstate);
-
-  void disable_status();
-
-  void reset_diagnostics_area();
-
-  bool is_set() const { return m_status != DA_EMPTY; }
-  bool is_error() const { return m_status == DA_ERROR; }
-  bool is_eof() const { return m_status == DA_EOF; }
-  bool is_ok() const { return m_status == DA_OK; }
-  bool is_disabled() const { return m_status == DA_DISABLED; }
-  enum_diagnostics_status status() const { return m_status; }
-
-  const char *message() const
-  { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
-
-  uint sql_errno() const
-  { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
-
-  const char* get_sqlstate() const
-  { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
-
-  ulonglong affected_rows() const
-  { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
-
-  ulonglong last_insert_id() const
-  { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
-
-  uint statement_warn_count() const
-  {
-    DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
-    return m_statement_warn_count;
-  }
-
-  Diagnostics_area() { reset_diagnostics_area(); }
-
-private:
-  /** Message buffer. Can be used by OK or ERROR status. */
-  char m_message[MYSQL_ERRMSG_SIZE];
-  /**
-    SQL error number. One of ER_ codes from share/errmsg.txt.
-    Set by set_error_status.
-  */
-  uint m_sql_errno;
-
-  char m_sqlstate[SQLSTATE_LENGTH+1];
-
-  /**
-    The number of rows affected by the last statement. This is
-    semantically close to thd->row_count_func, but has a different
-    life cycle. thd->row_count_func stores the value returned by
-    function ROW_COUNT() and is cleared only by statements that
-    update its value, such as INSERT, UPDATE, DELETE and few others.
-    This member is cleared at the beginning of the next statement.
-
-    We could possibly merge the two, but life cycle of thd->row_count_func
-    can not be changed.
-  */
-  ulonglong    m_affected_rows;
-  /**
-    Similarly to the previous member, this is a replacement of
-    thd->first_successful_insert_id_in_prev_stmt, which is used
-    to implement LAST_INSERT_ID().
-  */
-  ulonglong   m_last_insert_id;
-  /**
-    Number of warnings of this last statement. May differ from
-    the number of warnings returned by SHOW WARNINGS e.g. in case
-    the statement doesn't clear the warnings, and doesn't generate
-    them.
-  */
-  uint	     m_statement_warn_count;
-  enum_diagnostics_status m_status;
-};
-
 ///////////////////////////////////////////////////////////////////////////
 
 /**
@@ -524,6 +416,133 @@ public:
   char *ptr() { return err_buffer; }
 };
 
+///////////////////////////////////////////////////////////////////////////
+
+/**
+  Stores status of the currently executed statement.
+  Cleared at the beginning of the statement, and then
+  can hold either OK, ERROR, or EOF status.
+  Can not be assigned twice per statement.
+*/
+
+class Diagnostics_area
+{
+public:
+  enum enum_diagnostics_status
+  {
+    /** The area is cleared at start of a statement. */
+    DA_EMPTY= 0,
+    /** Set whenever one calls my_ok(). */
+    DA_OK,
+    /** Set whenever one calls my_eof(). */
+    DA_EOF,
+    /** Set whenever one calls my_error() or my_message(). */
+    DA_ERROR,
+    /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
+    DA_DISABLED
+  };
+  /** True if status information is sent to the client. */
+  bool is_sent;
+  /** Set to make set_error_status after set_{ok,eof}_status possible. */
+  bool can_overwrite_status;
+
+  void set_ok_status(THD *thd, ulonglong affected_rows_arg,
+                     ulonglong last_insert_id_arg,
+                     const char *message);
+  void set_eof_status(THD *thd);
+  void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg,
+                        const char *sqlstate);
+
+  void disable_status();
+
+  void reset_diagnostics_area();
+
+  bool is_set() const { return m_status != DA_EMPTY; }
+  bool is_error() const { return m_status == DA_ERROR; }
+  bool is_eof() const { return m_status == DA_EOF; }
+  bool is_ok() const { return m_status == DA_OK; }
+  bool is_disabled() const { return m_status == DA_DISABLED; }
+  enum_diagnostics_status status() const { return m_status; }
+
+  const char *message() const
+  { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
+
+  uint sql_errno() const
+  { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
+
+  const char* get_sqlstate() const
+  { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
+
+  ulonglong affected_rows() const
+  { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
+
+  ulonglong last_insert_id() const
+  { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
+
+  uint statement_warn_count() const
+  {
+    DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
+    return m_statement_warn_count;
+  }
+
+public:
+  Diagnostics_area();
+  Diagnostics_area(ulonglong warn_id, bool allow_unlimited_warnings);
+
+public:
+  inline Warning_info *get_warning_info()
+  { return m_current_wi; }
+
+  inline const Warning_info *get_warning_info() const
+  { return m_current_wi; }
+
+  inline void set_warning_info(Warning_info *wi)
+  { m_current_wi= wi; }
+
+private:
+  /** Message buffer. Can be used by OK or ERROR status. */
+  char m_message[MYSQL_ERRMSG_SIZE];
+  /**
+    SQL error number. One of ER_ codes from share/errmsg.txt.
+    Set by set_error_status.
+  */
+  uint m_sql_errno;
+
+  char m_sqlstate[SQLSTATE_LENGTH+1];
+
+  /**
+    The number of rows affected by the last statement. This is
+    semantically close to thd->row_count_func, but has a different
+    life cycle. thd->row_count_func stores the value returned by
+    function ROW_COUNT() and is cleared only by statements that
+    update its value, such as INSERT, UPDATE, DELETE and few others.
+    This member is cleared at the beginning of the next statement.
+
+    We could possibly merge the two, but life cycle of thd->row_count_func
+    can not be changed.
+  */
+  ulonglong    m_affected_rows;
+  /**
+    Similarly to the previous member, this is a replacement of
+    thd->first_successful_insert_id_in_prev_stmt, which is used
+    to implement LAST_INSERT_ID().
+  */
+  ulonglong   m_last_insert_id;
+  /**
+    Number of warnings of this last statement. May differ from
+    the number of warnings returned by SHOW WARNINGS e.g. in case
+    the statement doesn't clear the warnings, and doesn't generate
+    them.
+  */
+  uint	     m_statement_warn_count;
+  enum_diagnostics_status m_status;
+
+  Warning_info m_main_wi;
+  Warning_info *m_current_wi;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
 
 void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
                   uint code, const char *msg);

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2011-05-30 06:25:47 +0000
+++ b/sql/sql_insert.cc	2011-06-10 16:57:01 +0000
@@ -931,7 +931,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
       error=write_record(thd, table ,&info);
     if (error)
       break;
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
   }
 
   free_underlaid_joins(thd, &thd->lex->select_lex);
@@ -1086,11 +1086,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
       sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	      (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
 	      (ulong) (info.records - info.copied),
-              (ulong) thd->warning_info->statement_warn_count());
+              (ulong) thd->get_stmt_wi()->statement_warn_count());
     else
       sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	      (ulong) (info.deleted + updated),
-              (ulong) thd->warning_info->statement_warn_count());
+              (ulong) thd->get_stmt_wi()->statement_warn_count());
     ::my_ok(thd, info.copied + info.deleted + updated, id, buff);
   }
   thd->abort_on_warning= 0;
@@ -2153,10 +2153,11 @@ bool delayed_get_table(THD *thd, MDL_req
             want to send "Server shutdown in progress" in the
             INSERT THREAD.
           */
-          if (di->thd.stmt_da->sql_errno() == ER_SERVER_SHUTDOWN)
+          if (di->thd.get_stmt_da()->sql_errno() == ER_SERVER_SHUTDOWN)
             my_message(ER_QUERY_INTERRUPTED, ER(ER_QUERY_INTERRUPTED), MYF(0));
           else
-            my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(),
+            my_message(di->thd.get_stmt_da()->sql_errno(),
+                       di->thd.get_stmt_da()->message(),
                        MYF(0));
         }
         di->unlock();
@@ -2241,10 +2242,12 @@ TABLE *Delayed_insert::get_local_table(T
         killed using THD::notify_shared_lock() or
         kill_delayed_threads_for_table().
       */
-      if (!thd.is_error() || thd.stmt_da->sql_errno() == ER_SERVER_SHUTDOWN)
+      if (!thd.is_error() ||
+          thd.get_stmt_da()->sql_errno() == ER_SERVER_SHUTDOWN)
         my_message(ER_QUERY_INTERRUPTED, ER(ER_QUERY_INTERRUPTED), MYF(0));
       else
-        my_message(thd.stmt_da->sql_errno(), thd.stmt_da->message(), MYF(0));
+        my_message(thd.get_stmt_da()->sql_errno(),
+                   thd.get_stmt_da()->message(), MYF(0));
       goto error;
     }
   }
@@ -2627,8 +2630,8 @@ pthread_handler_t handle_delayed_insert(
   if (my_thread_init())
   {
     /* Can't use my_error since store_globals has not yet been called */
-    thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
-                                   ER(ER_OUT_OF_RESOURCES), NULL);
+    thd->get_stmt_da()->set_error_status(thd, ER_OUT_OF_RESOURCES,
+                                         ER(ER_OUT_OF_RESOURCES), NULL);
     di->handler_thread_initialized= TRUE;
   }
   else
@@ -2638,8 +2641,8 @@ pthread_handler_t handle_delayed_insert(
     if (init_thr_lock() || thd->store_globals())
     {
       /* Can't use my_error since store_globals has perhaps failed */
-      thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
-                                     ER(ER_OUT_OF_RESOURCES), NULL);
+      thd->get_stmt_da()->set_error_status(thd, ER_OUT_OF_RESOURCES,
+                                           ER(ER_OUT_OF_RESOURCES), NULL);
       di->handler_thread_initialized= TRUE;
       thd->fatal_error();
       goto err;
@@ -3048,7 +3051,7 @@ bool Delayed_insert::handle_inserts(void
 	{
 	  /* This should never happen */
 	  table->file->print_error(error,MYF(0));
-	  sql_print_error("%s", thd.stmt_da->message());
+	  sql_print_error("%s", thd.get_stmt_da()->message());
           DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
 	  goto err;
 	}
@@ -3093,7 +3096,7 @@ bool Delayed_insert::handle_inserts(void
   if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
   {						// This shouldn't happen
     table->file->print_error(error,MYF(0));
-    sql_print_error("%s", thd.stmt_da->message());
+    sql_print_error("%s", thd.get_stmt_da()->message());
     DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
     goto err;
   }
@@ -3519,7 +3522,7 @@ bool select_insert::send_eof()
   error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
           table->file->ha_end_bulk_insert() : 0);
   if (!error && thd->is_error())
-    error= thd->stmt_da->sql_errno();
+    error= thd->get_stmt_da()->sql_errno();
 
   table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
   table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -3570,11 +3573,11 @@ bool select_insert::send_eof()
   if (info.ignore)
     sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	    (ulong) (info.records - info.copied),
-            (ulong) thd->warning_info->statement_warn_count());
+            (ulong) thd->get_stmt_wi()->statement_warn_count());
   else
     sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	    (ulong) (info.deleted+info.updated),
-            (ulong) thd->warning_info->statement_warn_count());
+            (ulong) thd->get_stmt_wi()->statement_warn_count());
   row_count= info.copied + info.deleted +
              ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
               info.touched : info.updated);

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_lex.cc	2011-06-10 09:52:57 +0000
@@ -380,6 +380,8 @@ void lex_start(THD *thd)
   lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
   lex->select_lex.init_order();
   lex->select_lex.group_list.empty();
+  if (lex->select_lex.group_list_ptrs)
+    lex->select_lex.group_list_ptrs->clear();
   lex->describe= DESCRIBE_NONE;
   lex->subqueries= FALSE;
   lex->context_analysis_only= 0;
@@ -1776,6 +1778,8 @@ void st_select_lex::init_select()
   st_select_lex_node::init_select();
   sj_nests.empty();
   group_list.empty();
+  if (group_list_ptrs)
+    group_list_ptrs->clear();
   type= db= 0;
   having= 0;
   table_join_options= 0;
@@ -3059,6 +3063,8 @@ static void fix_prepare_info_in_table_li
     The passed WHERE and HAVING are to be saved for the future executions.
     This function saves it, and returns a copy which can be thrashed during
     this execution of the statement. By saving/thrashing here we mean only
+    We also save the chain of ORDER::next in group_list, in case
+    the list is modified by remove_const().
     AND/OR trees.
     The function also calls fix_prepare_info_in_table_list that saves all
     ON expressions.    
@@ -3070,6 +3076,19 @@ void st_select_lex::fix_prepare_informat
   if (!thd->stmt_arena->is_conventional() && first_execution)
   {
     first_execution= 0;
+    if (group_list.first)
+    {
+      if (!group_list_ptrs)
+      {
+        void *mem= thd->stmt_arena->alloc(sizeof(Group_list_ptrs));
+        group_list_ptrs= new (mem) Group_list_ptrs(thd->stmt_arena->mem_root);
+      }
+      group_list_ptrs->reserve(group_list.elements);
+      for (ORDER *order= group_list.first; order; order= order->next)
+      {
+        group_list_ptrs->push_back(order);
+      }
+    }
     if (*conds)
     {
       prep_where= *conds;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-05-12 17:29:19 +0000
+++ b/sql/sql_lex.h	2011-06-10 09:52:57 +0000
@@ -24,6 +24,7 @@
 #include "sql_trigger.h"
 #include "item.h"               /* From item_subselect.h: subselect_union_engine */
 #include "thr_lock.h"                  /* thr_lock_type, TL_UNLOCK */
+#include "mem_root_array.h"
 
 /* YACC and LEX Definitions */
 
@@ -185,6 +186,7 @@ enum enum_drop_mode
 #define TL_OPTION_ALIAS         8
 
 typedef List<Item> List_item;
+typedef Mem_root_array<ORDER*, true> Group_list_ptrs;
 
 /* SERVERS CACHE CHANGES */
 typedef struct st_lex_server_options
@@ -628,7 +630,16 @@ public:
   enum olap_type olap;
   /* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */
   SQL_I_List<TABLE_LIST>  table_list;
-  SQL_I_List<ORDER>       group_list; /* GROUP BY clause. */
+
+  /*
+    GROUP BY clause.
+    This list may be mutated during optimization (by remove_const()),
+    so for prepared statements, we keep a copy of the ORDER.next pointers in
+    group_list_ptrs, and re-establish the original list before each execution.
+  */
+  SQL_I_List<ORDER>       group_list;
+  Group_list_ptrs        *group_list_ptrs;
+
   List<Item>          item_list;  /* list of fields & expressions */
   List<String>        interval_list;
   bool	              is_item_list_lookup;
@@ -819,7 +830,8 @@ public:
   bool test_limit();
 
   friend void lex_start(THD *thd);
-  st_select_lex() : n_sum_items(0), n_child_sum_items(0) {}
+  st_select_lex() : group_list_ptrs(NULL), n_sum_items(0), n_child_sum_items(0)
+  {}
   void make_empty_select()
   {
     init_query();

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_load.cc	2011-06-10 16:57:01 +0000
@@ -590,7 +590,7 @@ int mysql_load(THD *thd,sql_exchange *ex
   }
   sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
 	  (ulong) (info.records - info.copied),
-          (ulong) thd->warning_info->statement_warn_count());
+          (ulong) thd->get_stmt_wi()->statement_warn_count());
 
 #ifndef EMBEDDED_LIBRARY
   if (mysql_bin_log.is_open())
@@ -833,7 +833,7 @@ read_fixed_length(THD *thd, COPY_INFO &i
         push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                             ER_WARN_TOO_FEW_RECORDS,
                             ER(ER_WARN_TOO_FEW_RECORDS),
-                            thd->warning_info->current_row_for_warning());
+                            thd->get_stmt_wi()->current_row_for_warning());
         if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
             ((Field_timestamp*) field)->set_time();
       }
@@ -857,7 +857,7 @@ read_fixed_length(THD *thd, COPY_INFO &i
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                           ER_WARN_TOO_MANY_RECORDS,
                           ER(ER_WARN_TOO_MANY_RECORDS),
-                          thd->warning_info->current_row_for_warning());
+                          thd->get_stmt_wi()->current_row_for_warning());
     }
 
     if (thd->killed ||
@@ -893,9 +893,9 @@ read_fixed_length(THD *thd, COPY_INFO &i
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                           ER_WARN_TOO_MANY_RECORDS,
                           ER(ER_WARN_TOO_MANY_RECORDS),
-                          thd->warning_info->current_row_for_warning());
+                          thd->get_stmt_wi()->current_row_for_warning());
     }
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
 continue_loop:;
   }
   DBUG_RETURN(test(read_info.error));
@@ -959,7 +959,7 @@ read_sep_field(THD *thd, COPY_INFO &info
           if (field->reset())
           {
             my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
-                     thd->warning_info->current_row_for_warning());
+                     thd->get_stmt_wi()->current_row_for_warning());
             DBUG_RETURN(1);
           }
           field->set_null();
@@ -1031,7 +1031,7 @@ read_sep_field(THD *thd, COPY_INFO &info
           if (field->reset())
           {
             my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
-                     thd->warning_info->current_row_for_warning());
+                     thd->get_stmt_wi()->current_row_for_warning());
             DBUG_RETURN(1);
           }
           if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
@@ -1046,7 +1046,7 @@ read_sep_field(THD *thd, COPY_INFO &info
           push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                               ER_WARN_TOO_FEW_RECORDS,
                               ER(ER_WARN_TOO_FEW_RECORDS),
-                              thd->warning_info->current_row_for_warning());
+                              thd->get_stmt_wi()->current_row_for_warning());
         }
         else if (item->type() == Item::STRING_ITEM)
         {
@@ -1092,11 +1092,11 @@ read_sep_field(THD *thd, COPY_INFO &info
       thd->cuted_fields++;			/* To long row */
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                           ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
-                          thd->warning_info->current_row_for_warning());
+                          thd->get_stmt_wi()->current_row_for_warning());
       if (thd->killed)
         DBUG_RETURN(1);
     }
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
 continue_loop:;
   }
   DBUG_RETURN(test(read_info.error));
@@ -1230,7 +1230,7 @@ read_xml_field(THD *thd, COPY_INFO &info
           push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                               ER_WARN_TOO_FEW_RECORDS,
                               ER(ER_WARN_TOO_FEW_RECORDS),
-                              thd->warning_info->current_row_for_warning());
+                              thd->get_stmt_wi()->current_row_for_warning());
         }
         else
           ((Item_user_var_as_out_param *)item)->set_null_value(cs);
@@ -1260,7 +1260,7 @@ read_xml_field(THD *thd, COPY_INFO &info
       We don't need to reset auto-increment field since we are restoring
       its default value at the beginning of each loop iteration.
     */
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
     continue_loop:;
   }
   DBUG_RETURN(test(read_info.error) || thd->is_error());

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-05-30 06:25:47 +0000
+++ b/sql/sql_parse.cc	2011-06-10 16:57:01 +0000
@@ -794,7 +794,7 @@ bool do_command(THD *thd)
     Consider moving to init_connect() instead.
   */
   thd->clear_error();				// Clear error message
-  thd->stmt_da->reset_diagnostics_area();
+  thd->get_stmt_da()->reset_diagnostics_area();
 
   net_new_transaction(net);
 
@@ -1173,7 +1173,7 @@ bool dispatch_command(enum enum_server_c
       }
 
 /* PSI end */
-      MYSQL_END_STATEMENT(thd->m_statement_psi, thd->stmt_da);
+      MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
 
 /* DTRACE end */
       if (MYSQL_QUERY_DONE_ENABLED())
@@ -1319,7 +1319,7 @@ bool dispatch_command(enum enum_server_c
     /* We don't calculate statistics for this command */
     general_log_print(thd, command, NullS);
     net->error=0;				// Don't give 'abort' message
-    thd->stmt_da->disable_status();              // Don't send anything back
+    thd->get_stmt_da()->disable_status();              // Don't send anything back
     error=TRUE;					// End server
     break;
 #ifndef EMBEDDED_LIBRARY
@@ -1459,7 +1459,7 @@ bool dispatch_command(enum enum_server_c
 #else
     (void) my_net_write(net, (uchar*) buff, length);
     (void) net_flush(net);
-    thd->stmt_da->disable_status();
+    thd->get_stmt_da()->disable_status();
 #endif
     break;
   }
@@ -1534,7 +1534,8 @@ bool dispatch_command(enum enum_server_c
     mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
 
   mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
-                      thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0,
+                      thd->get_stmt_da()->is_error() ?
+                      thd->get_stmt_da()->sql_errno() : 0,
                       command_name[command].str);
 
   log_slow_statement(thd);
@@ -1547,7 +1548,7 @@ bool dispatch_command(enum enum_server_c
   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
   /* Performance Schema Interface instrumentation, end */
-  MYSQL_END_STATEMENT(thd->m_statement_psi, thd->stmt_da);
+  MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
   thd->m_statement_psi= NULL;
 
   /* DTRACE instrumentation, end */
@@ -2024,12 +2025,12 @@ mysql_execute_command(THD *thd)
     variables, but for now this is probably good enough.
   */
   if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
-    thd->warning_info->set_read_only(TRUE);
+    thd->get_stmt_wi()->set_read_only(TRUE);
   else
   {
-    thd->warning_info->set_read_only(FALSE);
+    thd->get_stmt_wi()->set_read_only(FALSE);
     if (all_tables)
-      thd->warning_info->opt_clear_warning_info(thd->query_id);
+      thd->get_stmt_wi()->opt_clear_warning_info(thd->query_id);
   }
 
 #ifdef HAVE_REPLICATION
@@ -4526,7 +4527,7 @@ finish:
     /* report error issued during command execution */
     if (thd->killed_errno())
     {
-      if (! thd->stmt_da->is_set())
+      if (! thd->get_stmt_da()->is_set())
         thd->send_kill_message();
     }
     if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
@@ -4539,9 +4540,9 @@ finish:
     else
     {
       /* If commit fails, we should be able to reset the OK status. */
-      thd->stmt_da->can_overwrite_status= TRUE;
+      thd->get_stmt_da()->can_overwrite_status= TRUE;
       trans_commit_stmt(thd);
-      thd->stmt_da->can_overwrite_status= FALSE;
+      thd->get_stmt_da()->can_overwrite_status= FALSE;
     }
   }
 
@@ -4560,10 +4561,10 @@ finish:
     /* No transaction control allowed in sub-statements. */
     DBUG_ASSERT(! thd->in_sub_stmt);
     /* If commit fails, we should be able to reset the OK status. */
-    thd->stmt_da->can_overwrite_status= TRUE;
+    thd->get_stmt_da()->can_overwrite_status= TRUE;
     /* Commit the normal transaction if one is active. */
     trans_commit_implicit(thd);
-    thd->stmt_da->can_overwrite_status= FALSE;
+    thd->get_stmt_da()->can_overwrite_status= FALSE;
     thd->mdl_context.release_transactional_locks();
   }
   else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
@@ -5442,8 +5443,8 @@ void THD::reset_for_next_command()
     thd->user_var_events_alloc= thd->mem_root;
   }
   thd->clear_error();
-  thd->stmt_da->reset_diagnostics_area();
-  thd->warning_info->reset_for_next_command();
+  thd->get_stmt_da()->reset_diagnostics_area();
+  thd->get_stmt_wi()->reset_for_next_command();
   thd->rand_used= 0;
   thd->m_sent_row_count= thd->m_examined_row_count= 0;
   thd->thd_marker.emb_on_expr_nest= NULL;

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_prepare.cc	2011-06-10 16:57:01 +0000
@@ -340,7 +340,7 @@ static bool send_prep_stmt(Prepared_stat
   int2store(buff+5, columns);
   int2store(buff+7, stmt->param_count);
   buff[9]= 0;                                   // Guard against a 4.1 client
-  tmp= min(stmt->thd->warning_info->statement_warn_count(), 65535);
+  tmp= min(stmt->thd->get_stmt_wi()->statement_warn_count(), 65535);
   int2store(buff+10, tmp);
 
   /*
@@ -357,7 +357,7 @@ static bool send_prep_stmt(Prepared_stat
 
   if (!error)
     /* Flag that a response has already been sent */
-    thd->stmt_da->disable_status();
+    thd->get_stmt_da()->disable_status();
 
   DBUG_RETURN(error);
 }
@@ -370,7 +370,7 @@ static bool send_prep_stmt(Prepared_stat
   thd->client_stmt_id= stmt->id;
   thd->client_param_count= stmt->param_count;
   thd->clear_error();
-  thd->stmt_da->disable_status();
+  thd->get_stmt_da()->disable_status();
 
   return 0;
 }
@@ -1957,7 +1957,7 @@ static bool check_prepared_statement(Pre
 
   /* Reset warning count for each query that uses tables */
   if (tables)
-    thd->warning_info->opt_clear_warning_info(thd->query_id);
+    thd->get_stmt_wi()->opt_clear_warning_info(thd->query_id);
 
   if (sql_command_flags[sql_command] & CF_HA_CLOSE)
     mysql_ha_rm_tables(thd, tables);
@@ -2428,6 +2428,14 @@ void reinit_stmt_before_use(THD *thd, LE
       DBUG_ASSERT(sl->join == 0);
       ORDER *order;
       /* Fix GROUP list */
+      if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0)
+      {
+        for (uint ix= 0; ix < sl->group_list_ptrs->size() - 1; ++ix)
+        {
+          order= sl->group_list_ptrs->at(ix);
+          order->next= sl->group_list_ptrs->at(ix+1);
+        }
+      }
       for (order= sl->group_list.first; order; order= order->next)
         order->item= &order->item_ptr;
       /* Fix ORDER list */
@@ -2745,7 +2753,7 @@ void mysqld_stmt_close(THD *thd, char *p
   Prepared_statement *stmt;
   DBUG_ENTER("mysqld_stmt_close");
 
-  thd->stmt_da->disable_status();
+  thd->get_stmt_da()->disable_status();
 
   if (!(stmt= find_prepared_statement(thd, stmt_id)))
     DBUG_VOID_RETURN;
@@ -2821,7 +2829,7 @@ void mysql_stmt_get_longdata(THD *thd, c
 
   status_var_increment(thd->status_var.com_stmt_send_long_data);
 
-  thd->stmt_da->disable_status();
+  thd->get_stmt_da()->disable_status();
 #ifndef EMBEDDED_LIBRARY
   /* Minimal size of long data packet is 6 bytes */
   if (packet_length < MYSQL_LONG_DATA_HEADER)
@@ -2850,26 +2858,23 @@ void mysql_stmt_get_longdata(THD *thd, c
 
   param= stmt->param_array[param_number];
 
-  Diagnostics_area new_stmt_da, *save_stmt_da= thd->stmt_da;
-  Warning_info new_warnning_info(thd->query_id, false);
-  Warning_info *save_warinig_info= thd->warning_info;
+  Diagnostics_area new_stmt_da(thd->query_id, false);
+  Diagnostics_area *save_stmt_da= thd->get_stmt_da();
 
-  thd->stmt_da= &new_stmt_da;
-  thd->warning_info= &new_warnning_info;
+  thd->set_stmt_da(&new_stmt_da);
 
 #ifndef EMBEDDED_LIBRARY
   param->set_longdata(packet, (ulong) (packet_end - packet));
 #else
   param->set_longdata(thd->extra_data, thd->extra_length);
 #endif
-  if (thd->stmt_da->is_error())
+  if (thd->get_stmt_da()->is_error())
   {
     stmt->state= Query_arena::STMT_ERROR;
-    stmt->last_errno= thd->stmt_da->sql_errno();
-    strncpy(stmt->last_error, thd->stmt_da->message(), MYSQL_ERRMSG_SIZE);
+    stmt->last_errno= thd->get_stmt_da()->sql_errno();
+    strncpy(stmt->last_error, thd->get_stmt_da()->message(), MYSQL_ERRMSG_SIZE);
   }
-  thd->stmt_da= save_stmt_da;
-  thd->warning_info= save_warinig_info;
+  thd->set_stmt_da(save_stmt_da);
 
   general_log_print(thd, thd->get_command(), NullS);
 
@@ -2945,8 +2950,8 @@ Reprepare_observer::report_error(THD *th
     that this thread execution stops and returns to the caller,
     backtracking all the way to Prepared_statement::execute_loop().
   */
-  thd->stmt_da->set_error_status(thd, ER_NEED_REPREPARE,
-                                 ER(ER_NEED_REPREPARE), "HY000");
+  thd->get_stmt_da()->set_error_status(thd, ER_NEED_REPREPARE,
+                                       ER(ER_NEED_REPREPARE), "HY000");
   m_invalidated= TRUE;
 
   return TRUE;
@@ -3454,7 +3459,7 @@ reexecute:
       reprepare_observer.is_invalidated() &&
       reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
   {
-    DBUG_ASSERT(thd->stmt_da->sql_errno() == ER_NEED_REPREPARE);
+    DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE);
     thd->clear_error();
 
     error= reprepare();
@@ -3556,7 +3561,7 @@ Prepared_statement::reprepare()
       Sic: we can't simply silence warnings during reprepare, because if
       it's failed, we need to return all the warnings to the user.
     */
-    thd->warning_info->clear_warning_info(thd->query_id);
+    thd->get_stmt_wi()->clear_warning_info(thd->query_id);
   }
   return error;
 }
@@ -3918,7 +3923,7 @@ Ed_result_set::Ed_result_set(List<Ed_row
 */
 
 Ed_connection::Ed_connection(THD *thd)
-  :m_warning_info(thd->query_id, false),
+  :m_diagnostics_area(thd->query_id, false),
   m_thd(thd),
   m_rsets(0),
   m_current_rset(0)
@@ -3944,7 +3949,7 @@ Ed_connection::free_old_result()
   }
   m_current_rset= m_rsets;
   m_diagnostics_area.reset_diagnostics_area();
-  m_warning_info.clear_warning_info(m_thd->query_id);
+  m_diagnostics_area.get_warning_info()->clear_warning_info(m_thd->query_id);
 }
 
 
@@ -3981,23 +3986,20 @@ bool Ed_connection::execute_direct(Serve
   Protocol_local protocol_local(m_thd, this);
   Prepared_statement stmt(m_thd);
   Protocol *save_protocol= m_thd->protocol;
-  Diagnostics_area *save_diagnostics_area= m_thd->stmt_da;
-  Warning_info *save_warning_info= m_thd->warning_info;
+  Diagnostics_area *save_diagnostics_area= m_thd->get_stmt_da();
 
   DBUG_ENTER("Ed_connection::execute_direct");
 
   free_old_result(); /* Delete all data from previous execution, if any */
 
   m_thd->protocol= &protocol_local;
-  m_thd->stmt_da= &m_diagnostics_area;
-  m_thd->warning_info= &m_warning_info;
+  m_thd->set_stmt_da(&m_diagnostics_area);
 
   rc= stmt.execute_server_runnable(server_runnable);
   m_thd->protocol->end_statement();
 
   m_thd->protocol= save_protocol;
-  m_thd->stmt_da= save_diagnostics_area;
-  m_thd->warning_info= save_warning_info;
+  m_thd->set_stmt_da(save_diagnostics_area);
   /*
     Protocol_local makes use of m_current_rset to keep
     track of the last result set, while adding result sets to the end.

=== modified file 'sql/sql_prepare.h'
--- a/sql/sql_prepare.h	2010-07-02 18:15:21 +0000
+++ b/sql/sql_prepare.h	2011-06-10 07:49:17 +0000
@@ -252,7 +252,7 @@ public:
   */
   ulong get_warn_count() const
   {
-    return m_warning_info.warn_count();
+    return m_diagnostics_area.get_warning_info()->warn_count();
   }
   /**
     Get the server warnings as a result set.
@@ -261,7 +261,9 @@ public:
     The second is a numeric code.
     The third is warning text.
   */
-  List<MYSQL_ERROR> *get_warn_list() { return &m_warning_info.warn_list(); }
+  List<MYSQL_ERROR> *get_warn_list()
+  { return &m_diagnostics_area.get_warning_info()->warn_list(); }
+
   /**
     The following members are only valid if execute_direct()
     or move_to_next_result() returned an error.
@@ -310,7 +312,6 @@ public:
   ~Ed_connection() { free_old_result(); }
 private:
   Diagnostics_area m_diagnostics_area;
-  Warning_info m_warning_info;
   /**
     Execute direct interface does not support multi-statements, only
     multi-results. So we never have a situation when we have

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_select.cc	2011-06-10 16:57:01 +0000
@@ -1270,14 +1270,8 @@ static void save_index_subquery_explain_
     join_tab->packed_info |= TAB_INFO_USING_INDEX;
   if (where)
     join_tab->packed_info |= TAB_INFO_USING_WHERE;
-  for (uint i = 0; i < join_tab->ref.key_parts; i++)
-  {
-    if (join_tab->ref.cond_guards[i])
-    {
-      join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
-      break;
-    }
-  }
+  if (join_tab->has_guarded_conds())
+    join_tab->packed_info|= TAB_INFO_FULL_SCAN_ON_NULL;
 }
 
 
@@ -10118,7 +10112,7 @@ static bool uses_index_fields_only(Item
       contains a subquery. If this is the case we do not include this
       part of the condition.
     */
-    return !item->with_subselect;
+    return !item->has_subquery();
   }
 
   const Item::Type item_type= item->type();
@@ -11971,7 +11965,7 @@ remove_const(JOIN *join,ORDER *first_ord
       *simple_order=0;				// Must do a temp table to sort
     else if (!(order_tables & not_const_tables))
     {
-      if (order->item[0]->with_subselect && 
+      if (order->item[0]->has_subquery() && 
           !(join->select_lex->options & SELECT_DESCRIBE))
         order->item[0]->val_str(&order->item[0]->str_value);
       DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
@@ -14821,24 +14815,41 @@ internal_remove_eq_conds(THD *thd, Item
       Field *field=((Item_field*) args[0])->field;
       /* fix to replace 'NULL' dates with '0' (shreeve@stripped) */
       /*
-        datetime_field IS NULL has to be modified to
-        datetime_field == 0
+        See BUG#12594011
+        Documentation says that
+        SELECT datetime_notnull d FROM t1 WHERE d IS NULL
+        shall return rows where d=='0000-00-00'
+
+        Thus, for DATE and DATETIME columns defined as NOT NULL,
+        "date_notnull IS NULL" has to be modified to
+        "date_notnull IS NULL OR date_notnull == 0" (if outer join)
+        "date_notnull == 0"                         (otherwise)
+
       */
       if (((field->type() == MYSQL_TYPE_DATE) ||
            (field->type() == MYSQL_TYPE_DATETIME)) &&
-          (field->flags & NOT_NULL_FLAG) && !field->table->maybe_null)
+          (field->flags & NOT_NULL_FLAG))
       {
-	Item *new_cond;
-	if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
-	{
-	  cond=new_cond;
-          /*
-            Item_func_eq can't be fixed after creation so we do not check
-            cond->fixed, also it do not need tables so we use 0 as second
-            argument.
-          */
-	  cond->fix_fields(thd, &cond);
-	}
+        Item *item0= new(thd->mem_root) Item_int((longlong)0, 1);
+        Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
+        if (!eq_cond)
+          return cond;
+
+        if (field->table->pos_in_table_list->outer_join)
+        {
+          // outer join: transform "col IS NULL" to "col IS NULL or col=0"
+          Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
+          if (!or_cond)
+            return cond;
+          cond= or_cond;
+        }
+        else
+        {
+          // not outer join: transform "col IS NULL" to "col=0"
+          cond= eq_cond;
+        }
+
+        cond->fix_fields(thd, &cond);
       }
     }
     if (cond->const_item())
@@ -17661,7 +17672,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
     /* Set first_unmatched for the last inner table of this group */
     join_tab->last_inner->first_unmatched= join_tab;
   }
-  join->thd->warning_info->reset_current_row_for_warning();
+  join->thd->get_stmt_wi()->reset_current_row_for_warning();
 
   error= (*join_tab->read_first_record)(join_tab);
 
@@ -17988,7 +17999,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
       enum enum_nested_loop_state rc;
       /* A match from join_tab is found for the current partial join. */
       rc= (*join_tab->next_select)(join, join_tab+1, 0);
-      join->thd->warning_info->inc_current_row_for_warning();
+      join->thd->get_stmt_wi()->inc_current_row_for_warning();
       if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
         DBUG_RETURN(rc);
 
@@ -18020,7 +18031,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
     }
     else
     {
-      join->thd->warning_info->inc_current_row_for_warning();
+      join->thd->get_stmt_wi()->inc_current_row_for_warning();
       if (join_tab->not_null_compl)
       {
         /* a NULL-complemented row is not in a table so cannot be locked */
@@ -18035,7 +18046,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
       with the beginning coinciding with the current partial join.
     */
     join->examined_rows++;
-    join->thd->warning_info->inc_current_row_for_warning();
+    join->thd->get_stmt_wi()->inc_current_row_for_warning();
     if (join_tab->not_null_compl)
       join_tab->read_record.unlock_row(join_tab);
   }
@@ -19722,27 +19733,23 @@ static Item *
 part_of_refkey(TABLE *table,Field *field)
 {
   if (!table->reginfo.join_tab)
-    return (Item*) 0;             // field from outer non-select (UPDATE,...)
+    return NULL;                  // field from outer non-select (UPDATE,...)
 
   uint ref_parts=table->reginfo.join_tab->ref.key_parts;
   if (ref_parts)
   {
-    KEY_PART_INFO *key_part=
-      table->key_info[table->reginfo.join_tab->ref.key].key_part;
-    uint part;
+    if (table->reginfo.join_tab->has_guarded_conds())
+      return NULL;
 
-    for (part=0 ; part < ref_parts ; part++)
-    {
-      if (table->reginfo.join_tab->ref.cond_guards[part])
-        return 0;
-    }
+    const KEY_PART_INFO *key_part=
+      table->key_info[table->reginfo.join_tab->ref.key].key_part;
 
-    for (part=0 ; part < ref_parts ; part++,key_part++)
+    for (uint part=0 ; part < ref_parts ; part++,key_part++)
       if (field->eq(key_part->field) &&
 	  !(key_part->key_part_flag & HA_PART_KEY_SEG))
 	return table->reginfo.join_tab->ref.items[part];
   }
-  return (Item*) 0;
+  return NULL;
 }
 
 
@@ -23479,14 +23486,8 @@ void select_describe(JOIN *join, bool ne
           extra.append(STRING_WITH_LEN("; End materialize"));
         }
 
-        for (uint part= 0; part < tab->ref.key_parts; part++)
-        {
-          if (tab->ref.cond_guards[part])
-          {
-            extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
-            break;
-          }
-        }
+        if (tab->has_guarded_conds())
+          extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
         if (i > 0 && tab[-1].next_select == sub_select_cache)
         {

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2011-04-19 03:29:06 +0000
+++ b/sql/sql_servers.cc	2011-06-09 08:58:41 +0000
@@ -261,9 +261,9 @@ bool servers_reload(THD *thd)
       Execution might have been interrupted; only print the error message
       if an error condition has been raised.
     */
-    if (thd->stmt_da->is_error())
+    if (thd->get_stmt_da()->is_error())
       sql_print_error("Can't open and lock privilege tables: %s",
-                      thd->stmt_da->message());
+                      thd->get_stmt_da()->message());
     return_val= FALSE;
     goto end;
   }

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_show.cc	2011-06-10 08:33:15 +0000
@@ -3130,7 +3130,7 @@ fill_schema_table_by_open(THD *thd, bool
     of backward compatibility.
   */
   if (!is_show_fields_or_keys && result && thd->is_error() &&
-      thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
+      thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE)
   {
     /*
       Hide error for a non-existing table.
@@ -3220,7 +3220,7 @@ static int fill_schema_table_names(THD *
     default:
       DBUG_ASSERT(0);
     }
-    if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
+    if (thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE)
     {
       thd->clear_error();
       return 0;
@@ -4118,13 +4118,13 @@ err:
       column with the error text, and clear the error so that the operation
       can continue.
     */
-    const char *error= thd->is_error() ? thd->stmt_da->message() : "";
+    const char *error= thd->is_error() ? thd->get_stmt_da()->message() : "";
     table->field[20]->store(error, strlen(error), cs);
 
     if (thd->is_error())
     {
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
       thd->clear_error();
     }
   }
@@ -4281,7 +4281,7 @@ static int get_schema_column_record(THD
       */
       if (thd->is_error())
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                     thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                     thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
       thd->clear_error();
       res= 0;
     }
@@ -4942,7 +4942,7 @@ static int get_schema_stat_record(THD *t
       */
       if (thd->is_error())
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                     thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                     thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
       thd->clear_error();
       res= 0;
     }
@@ -5161,7 +5161,7 @@ static int get_schema_views_record(THD *
       DBUG_RETURN(1);
     if (res && thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
   }
   if (res)
     thd->clear_error();
@@ -5195,7 +5195,7 @@ static int get_schema_constraints_record
   {
     if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -5298,7 +5298,7 @@ static int get_schema_triggers_record(TH
   {
     if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -5379,7 +5379,7 @@ static int get_schema_key_column_usage_r
   {
     if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -5666,7 +5666,7 @@ static int get_schema_partitions_record(
   {
     if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -6195,7 +6195,7 @@ get_referential_constraints_record(THD *
   {
     if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->stmt_da->sql_errno(), thd->stmt_da->message());
+                   thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -6803,25 +6803,26 @@ static bool do_fill_table(THD *thd,
   // Warning_info, so "useful warnings" get rejected. In order to avoid
   // that problem we create a Warning_info instance, which is capable of
   // storing "unlimited" number of warnings.
-  Warning_info wi(thd->query_id, true);
-  Warning_info *wi_saved= thd->warning_info;
+  Diagnostics_area *da= thd->get_stmt_da();
+  Warning_info *wi= da->get_warning_info();
+  Warning_info wi_tmp(thd->query_id, true);
 
-  thd->warning_info= &wi;
+  da->set_warning_info(&wi_tmp);
 
   bool res= table_list->schema_table->fill_table(
     thd, table_list, join_table->condition());
 
-  thd->warning_info= wi_saved;
+  da->set_warning_info(wi);
 
   // Pass an error if any.
 
-  if (thd->stmt_da->is_error())
+  if (da->is_error())
   {
-    thd->warning_info->push_warning(thd,
-                                    thd->stmt_da->sql_errno(),
-                                    thd->stmt_da->get_sqlstate(),
-                                    MYSQL_ERROR::WARN_LEVEL_ERROR,
-                                    thd->stmt_da->message());
+    wi->push_warning(thd,
+                     da->sql_errno(),
+                     da->get_sqlstate(),
+                     MYSQL_ERROR::WARN_LEVEL_ERROR,
+                     da->message());
   }
 
   // Pass warnings (if any).
@@ -6830,13 +6831,13 @@ static bool do_fill_table(THD *thd,
   // correspond to the errors which were filtered out in fill_table().
 
 
-  List_iterator_fast<MYSQL_ERROR> it(wi.warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(wi_tmp.warn_list());
   MYSQL_ERROR *err;
 
   while ((err= it++))
   {
     if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_ERROR)
-      thd->warning_info->push_warning(thd, err);
+      wi->push_warning(thd, err);
   }
 
   return res;

=== modified file 'sql/sql_signal.cc'
--- a/sql/sql_signal.cc	2011-03-09 20:54:55 +0000
+++ b/sql/sql_signal.cc	2011-06-10 16:57:01 +0000
@@ -467,9 +467,9 @@ bool Sql_cmd_signal::execute(THD *thd)
     This has roots in the SQL standard specification for SIGNAL.
   */
 
-  thd->stmt_da->reset_diagnostics_area();
+  thd->get_stmt_da()->reset_diagnostics_area();
   thd->set_row_count_func(0);
-  thd->warning_info->clear_warning_info(thd->query_id);
+  thd->get_stmt_wi()->clear_warning_info(thd->query_id);
 
   result= raise_condition(thd, &cond);
 
@@ -484,7 +484,7 @@ bool Sql_cmd_resignal::execute(THD *thd)
 
   DBUG_ENTER("Sql_cmd_resignal::execute");
 
-  thd->warning_info->m_warn_id= thd->query_id;
+  thd->get_stmt_wi()->m_warn_id= thd->query_id;
 
   if (! thd->spcont || ! (signaled= thd->spcont->raised_condition()))
   {

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-06-01 09:11:28 +0000
+++ b/sql/sql_table.cc	2011-06-10 16:57:01 +0000
@@ -2942,7 +2942,7 @@ const CHARSET_INFO* get_sql_field_charse
 
 bool check_duplicate_warning(THD *thd, char *msg, ulong length)
 {
-  List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
+  List_iterator_fast<MYSQL_ERROR> it(thd->get_stmt_wi()->warn_list());
   MYSQL_ERROR *err;
   while ((err= it++))
   {
@@ -4786,6 +4786,11 @@ bool mysql_create_like_table(THD* thd, T
   local_create_info.options|= create_info->options & HA_LEX_CREATE_TMP_TABLE;
   /* Reset auto-increment counter for the new table. */
   local_create_info.auto_increment_value= 0;
+  /*
+    Do not inherit values of DATA and INDEX DIRECTORY options from
+    the original table. This is documented behavior.
+  */
+  local_create_info.data_file_name= local_create_info.index_file_name= NULL;
 
   if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name,
                                        &local_create_info, &local_alter_info,
@@ -7053,7 +7058,7 @@ bool mysql_alter_table(THD *thd,char *ne
 end_temporary:
   my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 	      (ulong) (copied + deleted), (ulong) deleted,
-	      (ulong) thd->warning_info->statement_warn_count());
+	      (ulong) thd->get_stmt_wi()->statement_warn_count());
   my_ok(thd, copied + deleted, 0L, tmp_name);
   DBUG_RETURN(FALSE);
 
@@ -7080,7 +7085,7 @@ err:
     Report error here.
   */
   if (alter_info->error_if_not_empty &&
-      thd->warning_info->current_row_for_warning())
+      thd->get_stmt_wi()->current_row_for_warning())
   {
     const char *f_val= 0;
     enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
@@ -7285,7 +7290,7 @@ copy_data_between_tables(TABLE *from,TAB
   init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
   if (ignore)
     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
-  thd->warning_info->reset_current_row_for_warning();
+  thd->get_stmt_wi()->reset_current_row_for_warning();
   restore_record(to, s->default_values);        // Create empty record
   while (!(error=info.read_record(&info)))
   {
@@ -7344,7 +7349,7 @@ copy_data_between_tables(TABLE *from,TAB
     }
     else
       found_count++;
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
   }
   end_read_record(&info);
   free_io_cache(from);

=== modified file 'sql/sql_time.cc'
--- a/sql/sql_time.cc	2011-03-09 20:54:55 +0000
+++ b/sql/sql_time.cc	2011-06-10 16:57:01 +0000
@@ -817,7 +817,7 @@ void make_truncated_value_warning(THD *t
     cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                        type_str, str.c_ptr(), field_name,
-                       (ulong) thd->warning_info->current_row_for_warning());
+                       (ulong) thd->get_stmt_wi()->current_row_for_warning());
   else
   {
     if (time_type > MYSQL_TIMESTAMP_ERROR)

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_trigger.cc	2011-06-10 07:38:06 +0000
@@ -31,6 +31,7 @@
 #include "sql_acl.h"                       // *_ACL, is_acl_user
 #include "sql_handler.h"                        // mysql_ha_rm_tables
 #include "sp_cache.h"                     // sp_invalidate_cache
+#include <mysys_err.h>
 
 /*************************************************************************/
 
@@ -305,6 +306,55 @@ private:
 
 
 /**
+  An error handler that catches all non-OOM errors which can occur during
+  parsing of trigger body. Such errors are ignored and corresponding error
+  message is used to construct a more verbose error message which contains
+  name of problematic trigger. This error message is later emitted when
+  one tries to perform DML or some of DDL on this table.
+  Also, if possible, grabs name of the trigger being parsed so it can be
+  used to correctly drop problematic trigger.
+*/
+class Deprecated_trigger_syntax_handler : public Internal_error_handler 
+{
+private:
+
+  char m_message[MYSQL_ERRMSG_SIZE];
+  LEX_STRING *m_trigger_name;
+
+public:
+
+  Deprecated_trigger_syntax_handler() : m_trigger_name(NULL) {}
+
+  virtual bool handle_condition(THD *thd,
+                                uint sql_errno,
+                                const char* sqlstate,
+                                MYSQL_ERROR::enum_warning_level level,
+                                const char* message,
+                                MYSQL_ERROR ** cond_hdl)
+  {
+    if (sql_errno != EE_OUTOFMEMORY &&
+        sql_errno != ER_OUT_OF_RESOURCES)
+    {
+      if(thd->lex->spname)
+        m_trigger_name= &thd->lex->spname->m_name;
+      if (m_trigger_name)
+        my_snprintf(m_message, sizeof(m_message),
+                    ER(ER_ERROR_IN_TRIGGER_BODY),
+                    m_trigger_name->str, message);
+      else
+        my_snprintf(m_message, sizeof(m_message),
+                    ER(ER_ERROR_IN_UNKNOWN_TRIGGER_BODY), message);
+      return true;
+    }
+    return false;
+  }
+
+  LEX_STRING *get_trigger_name() { return m_trigger_name; }
+  char *get_error_message() { return m_message; }
+};
+
+
+/**
   Create or drop trigger for table.
 
   @param thd     current thread context (including trigger definition in LEX)
@@ -591,6 +641,8 @@ bool Table_triggers_list::create_trigger
   LEX_STRING *trg_connection_cl_name;
   LEX_STRING *trg_db_cl_name;
 
+  if (check_for_broken_triggers())
+    return true;
 
   /* Trigger must be in the same schema as target table. */
   if (my_strcasecmp(table_alias_charset, table->s->db.str,
@@ -864,7 +916,7 @@ static bool rm_trigger_file(char *path,
   @param path         char buffer of size FN_REFLEN to be used
                       for constructing path to .TRN file.
   @param db           trigger's database name
-  @param table_name   trigger's name
+  @param trigger_name trigger's name
 
   @retval
     False   success
@@ -1329,12 +1381,11 @@ bool Table_triggers_list::check_n_load(T
         lex_start(thd);
         thd->spcont= NULL;
 
-        if (parse_sql(thd, & parser_state, creation_ctx))
-        {
-          /* Currently sphead is always deleted in case of a parse error */
-          DBUG_ASSERT(lex.sphead == 0);
-          goto err_with_lex_cleanup;
-        }
+        Deprecated_trigger_syntax_handler error_handler;
+        thd->push_internal_handler(&error_handler);
+        bool parse_error= parse_sql(thd, & parser_state, creation_ctx);
+        thd->pop_internal_handler();
+
         /*
           Not strictly necessary to invoke this method here, since we know
           that we've parsed CREATE TRIGGER and not an
@@ -1345,6 +1396,54 @@ bool Table_triggers_list::check_n_load(T
         */
         lex.set_trg_event_type_for_tables();
 
+        if (parse_error)
+        {
+          if (!triggers->m_has_unparseable_trigger)
+            triggers->set_parse_error_message(error_handler.get_error_message());
+          /* Currently sphead is always set to NULL in case of a parse error */
+          DBUG_ASSERT(lex.sphead == 0);
+          if (error_handler.get_trigger_name())
+          {
+            LEX_STRING *trigger_name;
+            const LEX_STRING *orig_trigger_name= error_handler.get_trigger_name();
+
+            if (!(trigger_name= alloc_lex_string(&table->mem_root)) ||
+                !(trigger_name->str= strmake_root(&table->mem_root,
+                                                  orig_trigger_name->str,
+                                                  orig_trigger_name->length)))
+              goto err_with_lex_cleanup;
+
+            trigger_name->length= orig_trigger_name->length;
+
+            if (triggers->names_list.push_back(trigger_name,
+                                               &table->mem_root))
+              goto err_with_lex_cleanup;
+          }
+          else
+          {
+            /* 
+               The Table_triggers_list is not constructed as a list of
+               trigger objects as one would expect, but rather of lists of
+               properties of equal length. Thus, even if we don't get the
+               trigger name, we still fill all in all the lists with
+               placeholders as we might otherwise create a skew in the
+               lists. Obviously, this has to be refactored.
+            */
+            LEX_STRING *empty= alloc_lex_string(&table->mem_root);
+            if (!empty)
+              goto err_with_lex_cleanup;
+
+            empty->str= const_cast<char*>("");
+            empty->length= 0;
+            if (triggers->names_list.push_back(empty, &table->mem_root))
+              goto err_with_lex_cleanup;
+          }
+          lex_end(&lex);
+          continue;
+        }
+
+        lex.sphead->set_info(0, 0, &lex.sp_chistics, (ulong) *trg_sql_mode);
+
         int event= lex.trg_chistics.event;
         int action_time= lex.trg_chistics.action_time;
 
@@ -1411,9 +1510,8 @@ bool Table_triggers_list::check_n_load(T
         char fname[NAME_LEN + 1];
         DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) ||
                      (check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) &&
-                      !my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))) &&
-                    (!my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
-                                    table_name) ||
+                      !my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))));
+        DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name, table_name) ||
                      (check_n_cut_mysql50_prefix(table_name, fname, sizeof(fname)) &&
                       !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, fname))));
 #endif
@@ -1695,6 +1793,13 @@ bool Table_triggers_list::drop_all_trigg
 
     while ((trigger= it_name++))
     {
+      /*
+        Trigger, which body we failed to parse during call
+        Table_triggers_list::check_n_load(), might be missing name.
+        Such triggers have zero-length name and are skipped here.
+      */
+      if (trigger->length == 0)
+        continue;
       if (rm_trigname_file(path, db, trigger->str))
       {
         /*
@@ -1913,6 +2018,11 @@ bool Table_triggers_list::change_table_n
   }
   if (table.triggers)
   {
+    if (table.triggers->check_for_broken_triggers())
+    {
+      result= 1;
+      goto end;
+    }
     LEX_STRING old_table_name= { (char *) old_alias, strlen(old_alias) };
     LEX_STRING new_table_name= { (char *) new_table, strlen(new_table) };
     /*
@@ -2001,6 +2111,9 @@ bool Table_triggers_list::process_trigge
   sp_head *sp_trigger= bodies[event][time_type];
   SELECT_LEX *save_current_select;
 
+  if (check_for_broken_triggers())
+    return true;
+
   if (sp_trigger == NULL)
     return FALSE;
 
@@ -2134,6 +2247,22 @@ void Table_triggers_list::mark_fields_us
 }
 
 
+/**
+   Signals to the Table_triggers_list that a parse error has occured when
+   reading a trigger from file. This makes the Table_triggers_list enter an
+   error state flagged by m_has_unparseable_trigger == true. The error message
+   will be used whenever a statement invoking or manipulating triggers is
+   issued against the Table_triggers_list's table.
+
+   @param error_message The error message thrown by the parser.
+ */
+void Table_triggers_list::set_parse_error_message(char *error_message)
+{
+  m_has_unparseable_trigger= true;
+  strcpy(m_parse_error_message, error_message);
+}
+
+
 /**
   Trigger BUG#14090 compatibility hook.
 

=== modified file 'sql/sql_trigger.h'
--- a/sql/sql_trigger.h	2011-05-26 15:20:09 +0000
+++ b/sql/sql_trigger.h	2011-06-10 07:38:06 +0000
@@ -97,6 +97,27 @@ class Table_triggers_list: public Sql_al
   */
   GRANT_INFO        subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
 
+  /**
+     This flag indicates that one of the triggers was not parsed successfully,
+     and as a precaution the object has entered a state where all trigger
+     access results in errors until all such triggers are dropped. It is not
+     safe to add triggers since we don't know if the broken trigger has the
+     same name or event type. Nor is it safe to invoke any trigger for the
+     aforementioned reasons. The only safe operations are drop_trigger and
+     drop_all_triggers.
+
+     @see Table_triggers_list::set_parse_error
+   */
+  bool m_has_unparseable_trigger;
+
+  /**
+    This error will be displayed when the user tries to manipulate or invoke
+    triggers on a table that has broken triggers. It will get set only once
+    per statement and thus will contain the first parse error encountered in
+    the trigger file.
+   */
+  char m_parse_error_message[MYSQL_ERRMSG_SIZE];
+
 public:
   /**
     Field responsible for storing triggers definitions in file.
@@ -118,8 +139,9 @@ public:
 
   /* End of character ser context. */
 
-  Table_triggers_list(TABLE *table_arg):
-    record1_field(0), trigger_table(table_arg)
+  Table_triggers_list(TABLE *table_arg)
+    :record1_field(0), trigger_table(table_arg),
+    m_has_unparseable_trigger(false)
   {
     memset(bodies, 0, sizeof(bodies));
     memset(trigger_fields, 0, sizeof(trigger_fields));
@@ -176,6 +198,8 @@ public:
 
   void mark_fields_used(trg_event_type event);
 
+  void set_parse_error_message(char *error_message);
+
   friend class Item_trigger_field;
 
   bool add_tables_and_routines_for_triggers(THD *thd,
@@ -193,6 +217,16 @@ private:
                                      const char *new_db_name,
                                      LEX_STRING *old_table_name,
                                      LEX_STRING *new_table_name);
+
+  bool check_for_broken_triggers() 
+  {
+    if (m_has_unparseable_trigger)
+    {
+      my_message(ER_PARSE_ERROR, m_parse_error_message, MYF(0));
+      return true;
+    }
+    return false;
+  }
 };
 
 extern const LEX_STRING trg_action_time_type_names[];

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2011-05-26 15:20:09 +0000
+++ b/sql/sql_update.cc	2011-06-10 16:57:01 +0000
@@ -791,7 +791,7 @@ int mysql_update(THD *thd,
     }
     else
       table->file->unlock_row();
-    thd->warning_info->inc_current_row_for_warning();
+    thd->get_stmt_wi()->inc_current_row_for_warning();
     if (thd->is_error())
     {
       error= 1;
@@ -897,7 +897,7 @@ int mysql_update(THD *thd,
     char buff[MYSQL_ERRMSG_SIZE];
     my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
                 (ulong) updated,
-                (ulong) thd->warning_info->statement_warn_count());
+                (ulong) thd->get_stmt_wi()->statement_warn_count());
     my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
           id, buff);
     DBUG_PRINT("info",("%ld records updated", (long) updated));

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-05-26 15:20:09 +0000
+++ b/sql/sql_yacc.yy	2011-06-09 18:18:22 +0000
@@ -2262,16 +2262,19 @@ opt_ev_status:
         | ENABLE_SYM
           {
             Lex->event_parse_data->status= Event_parse_data::ENABLED;
+            Lex->event_parse_data->status_changed= true;
             $$= 1;
           }
         | DISABLE_SYM ON SLAVE
           {
             Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
+            Lex->event_parse_data->status_changed= true; 
             $$= 1;
           }
         | DISABLE_SYM
           {
             Lex->event_parse_data->status= Event_parse_data::DISABLED;
+            Lex->event_parse_data->status_changed= true;
             $$= 1;
           }
         ;

=== modified file 'sql/structs.h'
--- a/sql/structs.h	2011-04-26 08:49:10 +0000
+++ b/sql/structs.h	2011-06-06 19:16:54 +0000
@@ -299,105 +299,139 @@ public:
   };
 };
 
-/* List of Discrete_interval objects */
+/// List of Discrete_interval objects
 class Discrete_intervals_list {
+
+/**
+   Discrete_intervals_list objects are used to remember the
+   intervals of autoincrement values that have been used by the
+   current INSERT statement, so that the values can be written to the
+   binary log.  However, the binary log can currently only store the
+   beginning of the first interval (because WL#3404 is not yet
+   implemented).  Hence, it is currently not necessary to store
+   anything else than the first interval, in the list.  When WL#3404 is
+   implemented, we should change the '# define' below.
+*/
+#define DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT 1
+
 private:
+  /**
+    To avoid heap allocation in the common case when there is only one
+    interval in the list, we store the first interval here.
+  */
+  Discrete_interval        first_interval;
   Discrete_interval        *head;
   Discrete_interval        *tail;
-  /*
+  /**
     When many intervals are provided at the beginning of the execution of a
     statement (in a replication slave or SET INSERT_ID), "current" points to
     the interval being consumed by the thread now (so "current" goes from
     "head" to "tail" then to NULL).
   */
   Discrete_interval        *current;
-  uint                  elements; // number of elements
-  void set_members(Discrete_interval *h, Discrete_interval *t,
-                   Discrete_interval *c, uint el)
-  {  
-    head= h;
-    tail= t;
-    current= c;
-    elements= el;
+  uint                  elements;               ///< number of elements
+  void operator=(Discrete_intervals_list &);    // prevent use of this
+  bool append(Discrete_interval *new_interval)
+  {
+    if (unlikely(new_interval == NULL))
+      return true;
+    DBUG_PRINT("info",("adding new auto_increment interval"));
+    if (head == NULL)
+      head= current= new_interval;
+    else
+      tail->next= new_interval;
+    tail= new_interval;
+    elements++;
+    return false;
   }
-  void operator=(Discrete_intervals_list &);  /* prevent use of these */
-  Discrete_intervals_list(const Discrete_intervals_list &);
-
-public:
-  Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
-  void empty_no_free()
+  void copy_shallow(const Discrete_intervals_list *other)
   {
-    set_members(NULL, NULL, NULL, 0);
+    const Discrete_interval *o_first_interval= &other->first_interval;
+    first_interval= other->first_interval;
+    head= other->head == o_first_interval ? &first_interval : other->head;
+    tail= other->tail == o_first_interval ? &first_interval : other->tail;
+    current=
+      other->current == o_first_interval ? &first_interval : other->current;
+    elements= other->elements;
   }
+  Discrete_intervals_list(const Discrete_intervals_list &other)
+  { copy_shallow(&other); }
+
+public:
+  Discrete_intervals_list()
+    : head(NULL), tail(NULL), current(NULL), elements(0) {}
   void empty()
   {
-    for (Discrete_interval *i= head; i;)
+    if (head)
     {
-      Discrete_interval *next= i->next;
-      delete i;
-      i= next;
+      // first element, not on heap, should not be delete-d; start with next:
+      for (Discrete_interval *i= head->next; i;)
+      {
+#ifdef DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT
+        DBUG_ASSERT(0);
+#endif
+        Discrete_interval *next= i->next;
+        delete i;
+        i= next;
+      }
     }
-    empty_no_free();
+    head= tail= current= NULL;
+    elements= 0;
   }
-  void copy_shallow(const Discrete_intervals_list * dli)
+  void swap(Discrete_intervals_list *other)
   {
-    head= dli->get_head();
-    tail= dli->get_tail();
-    current= dli->get_current();
-    elements= dli->nb_elements();
+    const Discrete_intervals_list tmp(*other);
+    other->copy_shallow(this);
+    copy_shallow(&tmp);
   }
-  void swap (Discrete_intervals_list * dli)
+  const Discrete_interval *get_next()
   {
-    Discrete_interval *h, *t, *c;
-    uint el;
-    h= dli->get_head();
-    t= dli->get_tail();
-    c= dli->get_current();
-    el= dli->nb_elements();
-    dli->copy_shallow(this);
-    set_members(h, t, c, el);
-  }
-  const Discrete_interval* get_next()
-  {
-    Discrete_interval *tmp= current;
+    const Discrete_interval *tmp= current;
     if (current != NULL)
       current= current->next;
     return tmp;
   }
   ~Discrete_intervals_list() { empty(); };
+  /**
+    Appends an interval to the list.
+
+    @param start  start of interval
+    @val   how    many values it contains
+    @param incr   what increment between each value
+    @retval true  error
+    @retval false success
+  */
   bool append(ulonglong start, ulonglong val, ulonglong incr)
   {
-    DBUG_ENTER("Discrete_intervals_list::append");
-    /* first, see if this can be merged with previous */
-    if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
+    // If there are no intervals, add one.
+    if (head == NULL)
     {
-      /* it cannot, so need to add a new interval */
-      Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
-      DBUG_RETURN(append(new_interval));
+      first_interval.replace(start, val, incr);
+      return append(&first_interval);
     }
-    DBUG_RETURN(0);
-  }
-  
-  bool append(Discrete_interval *new_interval)
-  {
-    DBUG_ENTER("Discrete_intervals_list::append");
-    if (unlikely(new_interval == NULL))
-      DBUG_RETURN(1);
-    DBUG_PRINT("info",("adding new auto_increment interval"));
-    if (head == NULL)
-      head= current= new_interval;
-    else
-      tail->next= new_interval;
-    tail= new_interval;
-    elements++;
-    DBUG_RETURN(0);
+    // If this interval can be merged with previous, do that.
+    if (tail->merge_if_contiguous(start, val, incr) == 0)
+      return false;
+    // If this interval cannot be merged, append it.
+#ifdef DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT
+    /*
+      We cannot create yet another interval as we already contain one. This
+      situation can happen. Assume innodb_autoinc_lock_mode>=1 and
+       CREATE TABLE T(A INT AUTO_INCREMENT PRIMARY KEY) ENGINE=INNODB;
+       INSERT INTO T VALUES (NULL),(NULL),(1025),(NULL);
+      Then InnoDB will reserve [1,4] (because of 4 rows) then
+      [1026,1026]. Only the first interval is important for
+      statement-based binary logging as it tells the starting point. So we
+      ignore the second interval:
+    */
+    return false;
+#else
+    return append(new Discrete_interval(start, val, incr));
+#endif
   }
   ulonglong minimum()     const { return (head ? head->minimum() : 0); };
   ulonglong maximum()     const { return (head ? tail->maximum() : 0); };
   uint      nb_elements() const { return elements; }
-  Discrete_interval* get_head() const { return head; };
-  Discrete_interval* get_tail() const { return tail; };
-  Discrete_interval* get_current() const { return current; };
 };
 
 #endif /* STRUCTS_INCLUDED */

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2011-05-26 12:34:14 +0000
+++ b/sql/sys_vars.cc	2011-06-13 13:44:21 +0000
@@ -2862,7 +2862,7 @@ static Sys_var_session_special Sys_rand_
 
 static ulonglong read_error_count(THD *thd)
 {
-  return thd->warning_info->error_count();
+  return thd->get_stmt_wi()->error_count();
 }
 // this really belongs to the SHOW STATUS
 static Sys_var_session_special Sys_error_count(
@@ -2874,7 +2874,7 @@ static Sys_var_session_special Sys_error
 
 static ulonglong read_warning_count(THD *thd)
 {
-  return thd->warning_info->warn_count();
+  return thd->get_stmt_wi()->warn_count();
 }
 // this really belongs to the SHOW STATUS
 static Sys_var_session_special Sys_warning_count(

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-05-26 15:20:09 +0000
+++ b/sql/table.cc	2011-06-09 08:58:41 +0000
@@ -3841,26 +3841,32 @@ void TABLE_LIST::hide_view_error(THD *th
   /* Hide "Unknown column" or "Unknown function" error */
   DBUG_ASSERT(thd->is_error());
 
-  if (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR ||
-      thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST ||
-      thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
-      thd->stmt_da->sql_errno() == ER_PROCACCESS_DENIED_ERROR ||
-      thd->stmt_da->sql_errno() == ER_COLUMNACCESS_DENIED_ERROR ||
-      thd->stmt_da->sql_errno() == ER_TABLEACCESS_DENIED_ERROR ||
-      thd->stmt_da->sql_errno() == ER_TABLE_NOT_LOCKED ||
-      thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
-  {
-    TABLE_LIST *top= top_table();
-    thd->clear_error();
-    my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str);
-  }
-  else if (thd->stmt_da->sql_errno() == ER_NO_DEFAULT_FOR_FIELD)
-  {
-    TABLE_LIST *top= top_table();
-    thd->clear_error();
-    // TODO: make correct error message
-    my_error(ER_NO_DEFAULT_FOR_VIEW_FIELD, MYF(0),
-             top->view_db.str, top->view_name.str);
+  switch (thd->get_stmt_da()->sql_errno()) {
+    case ER_BAD_FIELD_ERROR:
+    case ER_SP_DOES_NOT_EXIST:
+    case ER_FUNC_INEXISTENT_NAME_COLLISION:
+    case ER_PROCACCESS_DENIED_ERROR:
+    case ER_COLUMNACCESS_DENIED_ERROR:
+    case ER_TABLEACCESS_DENIED_ERROR:
+    case ER_TABLE_NOT_LOCKED:
+    case ER_NO_SUCH_TABLE:
+    {
+      TABLE_LIST *top= top_table();
+      thd->clear_error();
+      my_error(ER_VIEW_INVALID, MYF(0),
+               top->view_db.str, top->view_name.str);
+      break;
+    }
+
+    case ER_NO_DEFAULT_FOR_FIELD:
+    {
+      TABLE_LIST *top= top_table();
+      thd->clear_error();
+      // TODO: make correct error message
+      my_error(ER_NO_DEFAULT_FOR_VIEW_FIELD, MYF(0),
+               top->view_db.str, top->view_name.str);
+      break;
+    }
   }
 }
 

=== modified file 'sql/transaction.cc'
--- a/sql/transaction.cc	2011-05-16 14:30:54 +0000
+++ b/sql/transaction.cc	2011-06-09 08:58:41 +0000
@@ -752,7 +752,7 @@ bool trans_xa_rollback(THD *thd)
       ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
       xid_cache_delete(xs);
     }
-    DBUG_RETURN(thd->stmt_da->is_error());
+    DBUG_RETURN(thd->get_stmt_da()->is_error());
   }
 
   if (xa_state != XA_IDLE && xa_state != XA_PREPARED && xa_state != XA_ROLLBACK_ONLY)

=== modified file 'sql/tztime.cc'
--- a/sql/tztime.cc	2011-05-26 15:20:09 +0000
+++ b/sql/tztime.cc	2011-06-09 08:58:41 +0000
@@ -1671,7 +1671,7 @@ my_tz_init(THD *org_thd, const char *def
                            MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT))
   {
     sql_print_warning("Can't open and lock time zone table: %s "
-                      "trying to live without them", thd->stmt_da->message());
+                      "trying to live without them", thd->get_stmt_da()->message());
     /* We will try emulate that everything is ok */
     return_val= time_zone_tables_exist= 0;
     goto end_with_setting_default_tz;

=== modified file 'storage/archive/azio.c'
--- a/storage/archive/azio.c	2010-07-26 15:54:20 +0000
+++ b/storage/archive/azio.c	2011-06-03 07:49:05 +0000
@@ -114,6 +114,15 @@ int az_open (azio_stream *s, const char
 
   errno = 0;
   s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd;
+  DBUG_EXECUTE_IF("simulate_archive_open_failure",
+  {
+    if (s->file >= 0)
+    {
+      my_close(s->file, MYF(0));
+      s->file= -1;
+      my_errno= EMFILE;
+    }
+  });
 
   if (s->file < 0 ) 
   {

=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc	2011-05-10 13:41:34 +0000
+++ b/storage/archive/ha_archive.cc	2011-06-03 08:00:42 +0000
@@ -1680,11 +1680,12 @@ int ha_archive::check(THD* thd, HA_CHECK
   azflush(&(share->archive_write), Z_SYNC_FLUSH);
   mysql_mutex_unlock(&share->mutex);
 
+  if (init_archive_reader())
+    DBUG_RETURN(HA_ADMIN_CORRUPT);
   /*
     Now we will rewind the archive file so that we are positioned at the 
     start of the file.
   */
-  init_archive_reader();
   read_data_header(&archive);
   while (!(rc= get_row(&archive, table->record[0])))
     count--;

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2011-05-24 08:42:51 +0000
+++ b/storage/innobase/btr/btr0cur.c	2011-06-09 11:00:38 +0000
@@ -1987,6 +1987,9 @@ btr_cur_optimistic_update(
 
 	heap = mem_heap_create(1024);
 	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+	ut_a(!rec_offs_any_null_extern(rec, offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
 #ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2011-05-24 08:42:51 +0000
+++ b/storage/innobase/buf/buf0buf.c	2011-06-06 17:03:14 +0000
@@ -2950,7 +2950,6 @@ loop:
 			buf_pool, space, offset, fold);
 	}
 
-loop2:
 	if (!block || buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
 		rw_lock_s_unlock(hash_lock);
 		block = NULL;
@@ -3096,15 +3095,10 @@ wait_until_unfixed:
 			buf_LRU_block_free_non_file_page(block);
 			buf_pool_mutex_exit(buf_pool);
 			mutex_exit(&block->mutex);
-
-			block = (buf_block_t*) hash_bpage;
-
 			rw_lock_x_unlock(hash_lock);
-			rw_lock_s_lock(hash_lock);
-			/* Note that we are still holding the
-			hash_lock which is fine as this is what
-			we expect when we move to loop2 above. */
-			goto loop2;
+
+			block = NULL;
+			goto loop;
 		}
 
 		if (UNIV_UNLIKELY

=== modified file 'storage/innobase/buf/buf0lru.c'
--- a/storage/innobase/buf/buf0lru.c	2011-04-13 08:34:16 +0000
+++ b/storage/innobase/buf/buf0lru.c	2011-06-06 17:26:31 +0000
@@ -1473,7 +1473,8 @@ buf_LRU_free_block(
 	if (!buf_page_can_relocate(bpage)) {
 
 		/* Do not free buffer-fixed or I/O-fixed blocks. */
-		goto no_free_exit;
+		ret = BUF_LRU_NOT_FREED;
+		goto func_exit;
 	}
 
 #ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1485,7 +1486,8 @@ buf_LRU_free_block(
 		/* Do not completely free dirty blocks. */
 
 		if (bpage->oldest_modification) {
-			goto no_free_exit;
+			ret = BUF_LRU_NOT_FREED;
+			goto func_exit;
 		}
 	} else if ((bpage->oldest_modification)
 		   && (buf_page_get_state(bpage)
@@ -1494,7 +1496,8 @@ buf_LRU_free_block(
 		ut_ad(buf_page_get_state(bpage)
 		      == BUF_BLOCK_ZIP_DIRTY);
 
-		goto no_free_exit;
+		ret = BUF_LRU_NOT_FREED;
+		goto func_exit;
 
 	} else if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
 
@@ -1512,24 +1515,29 @@ buf_LRU_free_block(
 		the block mutex. In that case we free the newly
 		allocated descriptor and return */
 		if (!buf_page_can_relocate(bpage)) {
+
+			rw_lock_x_unlock(hash_lock);
+			mutex_exit(block_mutex);
+
 			if (b) {
 				buf_buddy_free(buf_pool, b, sizeof(*b));
 			}
-no_free_exit:
-			ret = BUF_LRU_NOT_FREED;
+
+			return(BUF_LRU_NOT_FREED);
+		}
+
+		if (UNIV_UNLIKELY(!b)) {
+			ret = BUF_LRU_CANNOT_RELOCATE;
 func_exit:
 			rw_lock_x_unlock(hash_lock);
 			mutex_exit(block_mutex);
 			return(ret);
-		}
 
-		if (UNIV_UNLIKELY(!b)) {
-			ret = BUF_LRU_CANNOT_RELOCATE;
-			goto func_exit;
 		}
 
 		memcpy(b, bpage, sizeof *b);
 	}
+
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(buf_page_in_file(bpage));
 	ut_ad(bpage->in_LRU_list);

=== modified file 'storage/innobase/include/page0page.h'
--- a/storage/innobase/include/page0page.h	2011-05-09 08:48:47 +0000
+++ b/storage/innobase/include/page0page.h	2011-06-06 13:28:31 +0000
@@ -618,6 +618,7 @@ rec_t*
 page_rec_find_owner_rec(
 /*====================*/
 	rec_t*	rec);	/*!< in: the physical record */
+#ifndef UNIV_HOTBACKUP
 /***********************************************************************//**
 Write a 32-bit field in a data dictionary record. */
 UNIV_INLINE
@@ -626,9 +627,10 @@ page_rec_write_field(
 /*=================*/
 	rec_t*	rec,	/*!< in/out: record to update */
 	ulint	i,	/*!< in: index of the field to update */
-	ulint	page_no,/*!< in: value to write */
+	ulint	val,	/*!< in: value to write */
 	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 	__attribute__((nonnull));
+#endif /* !UNIV_HOTBACKUP */
 /************************************************************//**
 Returns the maximum combined size of records which can be inserted on top
 of record heap.

=== modified file 'storage/innobase/include/page0page.ic'
--- a/storage/innobase/include/page0page.ic	2011-05-09 08:48:47 +0000
+++ b/storage/innobase/include/page0page.ic	2011-06-06 13:28:31 +0000
@@ -959,6 +959,7 @@ page_get_free_space_of_empty(
 		       - 2 * PAGE_DIR_SLOT_SIZE));
 }
 
+#ifndef UNIV_HOTBACKUP
 /***********************************************************************//**
 Write a 32-bit field in a data dictionary record. */
 UNIV_INLINE
@@ -979,6 +980,7 @@ page_rec_write_field(
 
 	mlog_write_ulint(data, val, MLOG_4BYTES, mtr);
 }
+#endif /* !UNIV_HOTBACKUP */
 
 /************************************************************//**
 Each user record on a page, and also the deleted user records in the heap

=== modified file 'storage/innobase/include/rem0rec.h'
--- a/storage/innobase/include/rem0rec.h	2011-03-22 12:34:16 +0000
+++ b/storage/innobase/include/rem0rec.h	2011-06-09 11:00:38 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -480,6 +480,18 @@ ulint
 rec_offs_any_extern(
 /*================*/
 	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+/******************************************************//**
+Determine if the offsets are for a record containing null BLOB pointers.
+@return	first field containing a null BLOB pointer, or NULL if none found */
+UNIV_INLINE
+const byte*
+rec_offs_any_null_extern(
+/*=====================*/
+	const rec_t*	rec,		/*!< in: record */
+	const ulint*	offsets)	/*!< in: rec_get_offsets(rec) */
+	__attribute__((nonnull, warn_unused_result));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 /******************************************************//**
 Returns nonzero if the extern bit is set in nth field of rec.
 @return	nonzero if externally stored */

=== modified file 'storage/innobase/include/rem0rec.ic'
--- a/storage/innobase/include/rem0rec.ic	2011-03-22 12:34:16 +0000
+++ b/storage/innobase/include/rem0rec.ic	2011-06-09 11:00:38 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -26,6 +26,7 @@ Created 5/30/1994 Heikki Tuuri
 #include "mach0data.h"
 #include "ut0byte.h"
 #include "dict0dict.h"
+#include "btr0types.h"
 
 /* Compact flag ORed to the extra size returned by rec_get_offsets() */
 #define REC_OFFS_COMPACT	((ulint) 1 << 31)
@@ -1087,6 +1088,44 @@ rec_offs_any_extern(
 	return(UNIV_UNLIKELY(*rec_offs_base(offsets) & REC_OFFS_EXTERNAL));
 }
 
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+/******************************************************//**
+Determine if the offsets are for a record containing null BLOB pointers.
+@return	first field containing a null BLOB pointer, or NULL if none found */
+UNIV_INLINE
+const byte*
+rec_offs_any_null_extern(
+/*=====================*/
+	const rec_t*	rec,		/*!< in: record */
+	const ulint*	offsets)	/*!< in: rec_get_offsets(rec) */
+{
+	ulint	i;
+	ut_ad(rec_offs_validate(rec, NULL, offsets));
+
+	if (!rec_offs_any_extern(offsets)) {
+		return(NULL);
+	}
+
+	for (i = 0; i < rec_offs_n_fields(offsets); i++) {
+		if (rec_offs_nth_extern(offsets, i)) {
+			ulint		len;
+			const byte*	field
+				= rec_get_nth_field(rec, offsets, i, &len);
+
+			ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
+			if (!memcmp(field + len
+				    - BTR_EXTERN_FIELD_REF_SIZE,
+				    field_ref_zero,
+				    BTR_EXTERN_FIELD_REF_SIZE)) {
+				return(field);
+			}
+		}
+	}
+
+	return(NULL);
+}
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 /******************************************************//**
 Returns nonzero if the extern bit is set in nth field of rec.
 @return	nonzero if externally stored */

=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	2011-05-11 00:39:50 +0000
+++ b/storage/innobase/include/trx0trx.h	2011-06-06 09:35:20 +0000
@@ -486,6 +486,18 @@ struct trx_lock_struct {
 
 	ib_vector_t*	table_locks;	/*!< All table locks requested by this
 					transaction, including AUTOINC locks */
+
+	ibool		cancel;		/*!< TRUE if the transaction is being
+					rolled back either via deadlock
+					detection or due to lock timeout. The
+					caller has to acquire the trx_t::mutex
+					in order to cancel the locks. In
+					lock_trx_table_locks_remove() we
+					check for this cancel of a transaction's
+					locks and avoid reacquiring the trx
+					mutex to prevent recursive deadlocks.
+					Protected by both the lock sys mutex
+					and the trx_t::mutex. */
 };
 
 #define TRX_MAGIC_N	91118598
@@ -540,7 +552,6 @@ struct trx_struct{
 					state and lock
 					(except some fields of lock, which
 					are protected by lock_sys->mutex) */
-
 	trx_state_t	state;		/*!< State of the trx from the point
 					of view of concurrency control:
 					TRX_STATE_NOT_STARTED (!in_trx_list),

=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c	2011-05-27 03:36:33 +0000
+++ b/storage/innobase/lock/lock0lock.c	2011-06-06 09:35:20 +0000
@@ -4393,7 +4393,8 @@ lock_trx_table_locks_remove(
 
 	ut_ad(lock_mutex_own());
 
-	if (!trx->lock.was_chosen_as_deadlock_victim) {
+	/* It is safe to read this because we are holding the lock mutex */
+	if (!trx->lock.cancel) {
 		trx_mutex_enter(trx);
 	} else {
 		ut_ad(trx_mutex_own(trx));
@@ -4415,7 +4416,7 @@ lock_trx_table_locks_remove(
 		if (lock == lock_to_remove) {
 			ib_vector_set(trx->lock.table_locks, i, NULL);
 
-			if (!trx->lock.was_chosen_as_deadlock_victim) {
+			if (!trx->lock.cancel) {
 				trx_mutex_exit(trx);
 			}
 
@@ -4423,7 +4424,7 @@ lock_trx_table_locks_remove(
 		}
 	}
 
-	if (!trx->lock.was_chosen_as_deadlock_victim) {
+	if (!trx->lock.cancel) {
 		trx_mutex_exit(trx);
 	}
 
@@ -6246,6 +6247,8 @@ lock_cancel_waiting_and_release(
 	ut_ad(lock_mutex_own());
 	ut_ad(trx_mutex_own(lock->trx));
 
+	lock->trx->lock.cancel = TRUE;
+
 	if (lock_get_type_low(lock) == LOCK_REC) {
 
 		lock_rec_dequeue_from_page(lock);
@@ -6271,6 +6274,8 @@ lock_cancel_waiting_and_release(
 	if (thr != NULL) {
 		lock_wait_release_thread_if_suspended(thr);
 	}
+
+	lock->trx->lock.cancel = FALSE;
 }
 
 /*********************************************************************//**

=== modified file 'storage/innobase/row/row0row.c'
--- a/storage/innobase/row/row0row.c	2011-05-31 09:30:59 +0000
+++ b/storage/innobase/row/row0row.c	2011-06-09 19:13:37 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -200,6 +200,14 @@ row_build(
 		ut_ad(rec_offs_validate(rec, index, offsets));
 	}
 
+#if 0 /* defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG */
+	/* This one can fail in trx_rollback_active() if
+	the server crashed during an insert before the
+	btr_store_big_rec_extern_fields() did mtr_commit()
+	all BLOB pointers to the clustered index record. */
+	ut_a(!rec_offs_any_null_extern(rec, offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 	if (type != ROW_COPY_POINTERS) {
 		/* Take a copy of rec to heap */
 		buf = mem_heap_alloc(heap, rec_offs_size(offsets));
@@ -383,6 +391,10 @@ row_rec_to_index_entry(
 		rec = rec_copy(buf, rec, offsets);
 		/* Avoid a debug assertion in rec_offs_validate(). */
 		rec_offs_make_valid(rec, index, offsets);
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+	} else {
+		ut_a(!rec_offs_any_null_extern(rec, offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 	}
 
 	entry = row_rec_to_index_entry_low(rec, index, offsets, n_ext, heap);

=== modified file 'storage/innobase/row/row0vers.c'
--- a/storage/innobase/row/row0vers.c	2011-05-04 11:29:29 +0000
+++ b/storage/innobase/row/row0vers.c	2011-06-09 11:00:38 +0000
@@ -557,6 +557,11 @@ row_vers_build_for_consistent_read(
 				/* The view already sees this version: we can
 				copy it to in_heap and return */
 
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+				ut_a(!rec_offs_any_null_extern(
+					     version, *offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 				buf = mem_heap_alloc(in_heap,
 						     rec_offs_size(*offsets));
 				*old_vers = rec_copy(buf, version, *offsets);
@@ -590,6 +595,10 @@ row_vers_build_for_consistent_read(
 		*offsets = rec_get_offsets(prev_version, index, *offsets,
 					   ULINT_UNDEFINED, offset_heap);
 
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+		ut_a(!rec_offs_any_null_extern(prev_version, *offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 		trx_id = row_get_rec_trx_id(prev_version, index, *offsets);
 
 		if (read_view_sees_trx_id(view, trx_id)) {
@@ -684,6 +693,10 @@ row_vers_build_for_semi_consistent_read(
 			/* We found a version that belongs to a
 			committed transaction: return it. */
 
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+			ut_a(!rec_offs_any_null_extern(version, *offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 			if (rec == version) {
 				*old_vers = rec;
 				err = DB_SUCCESS;
@@ -741,6 +754,9 @@ row_vers_build_for_semi_consistent_read(
 		version = prev_version;
 		*offsets = rec_get_offsets(version, index, *offsets,
 					   ULINT_UNDEFINED, offset_heap);
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+		ut_a(!rec_offs_any_null_extern(version, *offsets));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 	}/* for (;;) */
 
 	if (heap) {

=== modified file 'storage/innobase/trx/trx0rec.c'
--- a/storage/innobase/trx/trx0rec.c	2011-05-31 09:30:59 +0000
+++ b/storage/innobase/trx/trx0rec.c	2011-06-09 11:00:38 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -1546,6 +1546,10 @@ trx_undo_prev_version_build(
 	ut_a(table_id == index->table->id);
 	ut_a(ptr);
 
+# if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+	ut_a(!rec_offs_any_null_extern(rec, offsets));
+# endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+
 	if (row_upd_changes_field_size_or_external(index, offsets, update)) {
 		ulint	n_ext;
 

=== modified file 'storage/myisam/mi_update.c'
--- a/storage/myisam/mi_update.c	2011-01-11 09:09:21 +0000
+++ b/storage/myisam/mi_update.c	2011-06-07 16:00:42 +0000
@@ -192,8 +192,8 @@ err:
   save_errno=my_errno;
   if (changed)
     key_changed|= HA_STATE_CHANGED;
-  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_OUT_OF_MEM ||
-      my_errno == HA_ERR_RECORD_FILE_FULL)
+  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
+      my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
   {
     info->errkey= (int) i;
     flag=0;
@@ -211,8 +211,9 @@ err:
 	{
 	  uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
 	  uint old_length= _mi_make_key(info,i,old_key,oldrec,pos);
-	  if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) ||
-	      _mi_ck_write(info,i,old_key,old_length))
+	  if ((flag++ && 
+	       share->keyinfo[i].ck_delete(info, i, new_key, new_length)) ||
+	      share->keyinfo[i].ck_insert(info, i, old_key, old_length))
 	    break;
 	}
       }

=== modified file 'storage/myisam/mi_write.c'
--- a/storage/myisam/mi_write.c	2011-03-28 08:51:35 +0000
+++ b/storage/myisam/mi_write.c	2011-06-07 16:00:42 +0000
@@ -204,7 +204,7 @@ err:
         else
 	{
 	  uint key_length=_mi_make_key(info,i,buff,record,filepos);
-	  if (_mi_ck_delete(info,i,buff,key_length))
+	  if (share->keyinfo[i].ck_delete(info, i, buff, key_length))
 	  {
 	    if (local_lock_tree)
               mysql_rwlock_unlock(&share->key_root_lock[i]);

=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c	2011-05-31 13:52:09 +0000
+++ b/tests/mysql_client_test.c	2011-06-10 15:29:04 +0000
@@ -19593,6 +19593,81 @@ static void test_bug11766854()
   DBUG_VOID_RETURN;
 }
 
+/**
+  Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR 
+                       CHAR/VARCHAR/TEXT COLUMNS IN VIEWS 
+*/
+static void test_bug12337762()
+{
+  int rc,i=0;
+  MYSQL_RES *result;
+  MYSQL_FIELD *field;
+  unsigned int tab_charsetnr[3]= {0};
+
+  DBUG_ENTER("test_bug12337762");
+  myheader("test_bug12337762");
+
+  /*
+    Creating table with specific charset.
+  */
+  rc= mysql_query(mysql, "drop table if exists charset_tab");
+  rc= mysql_query(mysql, "create table charset_tab("\
+                         "txt1 varchar(32) character set Latin1,"\
+                         "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
+                         "txt3 varchar(32) character set utf8 collate utf8_bin"\
+						 ")");
+  
+  DIE_UNLESS(rc == 0);
+  DIE_IF(mysql_errno(mysql));
+
+  /*
+    Creating view from table created earlier.
+  */
+  rc= mysql_query(mysql, "drop view if exists charset_view");
+  rc= mysql_query(mysql, "create view charset_view as "\
+                         "select * from charset_tab;");
+  DIE_UNLESS(rc == 0);
+  DIE_IF(mysql_errno(mysql));
+
+  /*
+    Checking field information for table.
+  */
+  result= mysql_list_fields(mysql, "charset_tab", NULL);
+  DIE_IF(mysql_errno(mysql));
+  i=0;
+  while((field= mysql_fetch_field(result)))
+  {
+    printf("field name %s\n", field->name);
+    printf("field table %s\n", field->table);
+    printf("field type %d\n", field->type);
+    printf("field charset %d\n", field->charsetnr);
+    tab_charsetnr[i++]= field->charsetnr;
+    printf("\n");
+  }
+  mysql_free_result(result);
+
+  /*
+    Checking field information for view.
+  */
+  result= mysql_list_fields(mysql, "charset_view", NULL);
+  DIE_IF(mysql_errno(mysql));
+  i=0;
+  while((field= mysql_fetch_field(result)))
+  {
+    printf("field name %s\n", field->name);
+    printf("field table %s\n", field->table);
+    printf("field type %d\n", field->type);
+    printf("field charset %d\n", field->charsetnr);
+    printf("\n");
+    /* 
+      charset value for field must be same for both, view and table.
+    */
+    DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
+  }
+  mysql_free_result(result);
+
+  DBUG_VOID_RETURN;
+}
 
 /**
   Bug#54790: Use of non-blocking mode for sockets limits performance
@@ -19692,10 +19767,10 @@ static struct my_option client_test_long
    &opt_getopt_ll_test, &opt_getopt_ll_test, 0,
    GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0},
   {"plugin_dir", 0, "Directory for client-side plugins.",
-   (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+   &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"default_auth", 0, "Default authentication client-side plugin to use.",
-   (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+   &opt_default_auth, &opt_default_auth, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
@@ -19979,6 +20054,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug56976", test_bug56976 },
   { "test_bug11766854", test_bug11766854 },
   { "test_bug54790", test_bug54790 },
+  { "test_bug12337762", test_bug12337762 },
   { 0, 0 }
 };
 
@@ -20117,29 +20193,29 @@ int main(int argc, char **argv)
     if (!argc)
     {
       for (fptr= my_tests; fptr->name; fptr++)
-	(*fptr->function)();	
+        (*fptr->function)();	
     }
     else
     {
       for ( ; *argv ; argv++)
       {
-	for (fptr= my_tests; fptr->name; fptr++)
-	{
-	  if (!strcmp(fptr->name, *argv))
-	  {
-	    (*fptr->function)();
-	    break;
-	  }
-	}
-	if (!fptr->name)
-	{
-	  fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv);
-	  fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n",
-		  my_progname);
-	  client_disconnect(mysql, 1);
-	  free_defaults(defaults_argv);
-	  exit(1);
-	}
+        for (fptr= my_tests; fptr->name; fptr++)
+        {
+          if (!strcmp(fptr->name, *argv))
+          {
+            (*fptr->function)();
+            break;
+          }
+        }
+        if (!fptr->name)
+        {
+          fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv);
+          fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n",
+                  my_progname);
+          client_disconnect(mysql, 1);
+          free_defaults(defaults_argv);
+          exit(1);
+        }
       }
     }
 

No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
Thread
bzr commit into mysql-trunk-wl5378 branch (marc.alff:3357) Marc Alff13 Jun