List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:June 23 2011 12:03pm
Subject:bzr commit into mysql-5.5 branch (chuck.bell:3422) WL#5710
View as plain text  
#At file:///home/cbell/source/bzr/mysql-wl-5710/ based on revid:chuck.bell@stripped

 3422 Chuck Bell	2011-06-23 [merge]
      WL#5710 : Enable and disable plugins (mysql_plugin)
      
      Local merge with latest mysql-5.5 tree.

    added:
      mysql-test/r/archive_debug.result
      mysql-test/r/mysql_embedded.result
      mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result
      mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test
      mysql-test/t/archive_debug.test
      mysql-test/t/mysql_embedded.test
    modified:
      .bzrignore
      VERSION
      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
      extra/perror.c
      extra/yassl/src/yassl_error.cpp
      include/mysql/plugin_audit.h
      include/mysql/plugin_audit.h.pp
      libmysql/authentication_win/plugin_client.cc
      libmysqld/lib_sql.cc
      mysql-test/collections/default.experimental
      mysql-test/mysql-test-run.pl
      mysql-test/r/alter_table.result
      mysql-test/r/events_bugs.result
      mysql-test/r/flush.result
      mysql-test/r/gis-rtree.result
      mysql-test/r/multi_update.result
      mysql-test/r/multi_update_innodb.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/innodb/r/innodb-index.result
      mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result
      mysql-test/suite/innodb/t/innodb-index.test
      mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test
      mysql-test/suite/perfschema/include/cleanup_helper.inc
      mysql-test/suite/perfschema/include/upgrade_check.inc
      mysql-test/suite/perfschema/r/selects.result
      mysql-test/suite/perfschema/t/selects.test
      mysql-test/t/alter_table.test
      mysql-test/t/disabled.def
      mysql-test/t/events_bugs.test
      mysql-test/t/flush.test
      mysql-test/t/gis-rtree.test
      mysql-test/t/multi_update.test
      mysql-test/t/multi_update_innodb.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
      mysys/mf_pack.c
      plugin/audit_null/audit_null.c
      sql/event_db_repository.cc
      sql/event_parse_data.cc
      sql/event_parse_data.h
      sql/ha_partition.cc
      sql/item.h
      sql/item_timefunc.cc
      sql/item_timefunc.h
      sql/mdl.h
      sql/mysqld.cc
      sql/share/errmsg-utf8.txt
      sql/sp_head.cc
      sql/sql_audit.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_parse.cc
      sql/sql_select.cc
      sql/sql_table.cc
      sql/sql_trigger.cc
      sql/sql_trigger.h
      sql/sql_update.cc
      sql/sql_yacc.yy
      sql/table.h
      storage/archive/azio.c
      storage/archive/ha_archive.cc
      storage/innobase/btr/btr0btr.c
      storage/innobase/btr/btr0cur.c
      storage/innobase/buf/buf0buddy.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0flu.c
      storage/innobase/buf/buf0lru.c
      storage/innobase/include/btr0btr.h
      storage/innobase/include/btr0cur.h
      storage/innobase/include/btr0cur.ic
      storage/innobase/include/buf0buddy.h
      storage/innobase/include/buf0buddy.ic
      storage/innobase/include/buf0buf.h
      storage/innobase/include/buf0buf.ic
      storage/innobase/include/buf0lru.h
      storage/innobase/include/buf0types.h
      storage/innobase/include/page0cur.ic
      storage/innobase/include/page0page.h
      storage/innobase/include/page0page.ic
      storage/innobase/include/rem0rec.h
      storage/innobase/include/rem0rec.ic
      storage/innobase/include/sync0rw.ic
      storage/innobase/include/sync0sync.h
      storage/innobase/include/univ.i
      storage/innobase/page/page0cur.c
      storage/innobase/page/page0page.c
      storage/innobase/page/page0zip.c
      storage/innobase/rem/rem0rec.c
      storage/innobase/row/row0ins.c
      storage/innobase/row/row0row.c
      storage/innobase/row/row0upd.c
      storage/innobase/row/row0vers.c
      storage/innobase/sync/sync0rw.c
      storage/innobase/sync/sync0sync.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:51:14 +0000
+++ b/.bzrignore	2011-06-07 13:06:26 +0000
@@ -3133,3 +3133,4 @@ info_macros.cmake
 Docs/INFO_BIN
 Docs/INFO_SRC
 Testing
+source_downloads

=== modified file 'VERSION'
--- a/VERSION	2011-05-13 05:00:09 +0000
+++ b/VERSION	2011-06-10 08:38:27 +0000
@@ -1,4 +1,4 @@
 MYSQL_VERSION_MAJOR=5
 MYSQL_VERSION_MINOR=5
-MYSQL_VERSION_PATCH=14
+MYSQL_VERSION_PATCH=15
 MYSQL_VERSION_EXTRA=

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2011-02-09 06:50:11 +0000
+++ b/client/mysql.cc	2011-06-06 10:27:05 +0000
@@ -1564,11 +1564,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-01-16 03:59:05 +0000
+++ b/client/mysql_upgrade.c	2011-06-06 10:27:05 +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:00:09 +0000
+++ b/client/mysqladmin.cc	2011-06-06 10:27:05 +0000
@@ -206,11 +206,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-05 23:55:44 +0000
+++ b/client/mysqlbinlog.cc	2011-06-06 10:27:05 +0000
@@ -1052,7 +1052,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. "
@@ -1080,7 +1080,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 08:41:57 +0000
+++ b/client/mysqlcheck.c	2011-06-06 10:27:05 +0000
@@ -102,7 +102,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,
@@ -142,7 +142,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-03-16 14:11:20 +0000
+++ b/client/mysqldump.c	2011-06-06 10:27:05 +0000
@@ -501,11 +501,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 03:59:05 +0000
+++ b/client/mysqlimport.c	2011-06-06 10:27:05 +0000
@@ -93,7 +93,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},
@@ -145,7 +145,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 03:59:05 +0000
+++ b/client/mysqlshow.c	2011-06-06 10:27:05 +0000
@@ -191,7 +191,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},
@@ -207,7 +207,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-04-08 06:55:59 +0000
+++ b/client/mysqlslap.c	2011-06-06 10:27:05 +0000
@@ -590,7 +590,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.",
@@ -634,7 +634,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-05 23:50:31 +0000
+++ b/client/mysqltest.cc	2011-06-06 10:27:05 +0000
@@ -6423,7 +6423,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-03 21:46:12 +0000
+++ b/cmake/make_dist.cmake.in	2011-06-10 07:12:10 +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:43:15 +0000
+++ b/cmake/plugin.cmake	2011-06-10 12:57:42 +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-04-30 05:24:38 +0000
+++ b/configure.cmake	2011-06-06 10:24:28 +0000
@@ -345,6 +345,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 'extra/perror.c'
--- a/extra/perror.c	2011-03-29 12:43:49 +0000
+++ b/extra/perror.c	2011-06-07 07:53:37 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 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
@@ -11,7 +11,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
 /* Return error-text for system error messages and handler messages */
 
@@ -64,7 +64,8 @@ static struct my_option my_long_options[
    &ndb_code, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
 #ifdef HAVE_SYS_ERRLIST
-  {"all", 'a', "Print all the error messages and the number.",
+  {"all", 'a', "Print all the error messages and the number. Deprecated,"
+   " will be removed in a future release.",
    &print_all_codes, &print_all_codes, 0, GET_BOOL, NO_ARG,
    0, 0, 0, 0, 0, 0},
 #endif
@@ -295,6 +296,8 @@ int main(int argc,char *argv[])
   if (print_all_codes)
   {
     HA_ERRORS *ha_err_ptr;
+    printf("WARNING: option '-a/--all' is deprecated and will be removed in a"
+           " future release.\n");
     for (code=1 ; code < sys_nerr ; code++)
     {
       if (sys_errlist[code] && sys_errlist[code][0])

=== modified file 'extra/yassl/src/yassl_error.cpp'
--- a/extra/yassl/src/yassl_error.cpp	2010-02-22 13:23:47 +0000
+++ b/extra/yassl/src/yassl_error.cpp	2011-06-17 07:51:34 +0000
@@ -128,7 +128,7 @@ void SetErrorString(unsigned long error,
         break;
 
     case badVersion_error :
-        strncpy(buffer, "protocl version mismatch", max);
+        strncpy(buffer, "protocol version mismatch", max);
         break;
         
     case compress_error :

=== 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-03-04 12:12:31 +0000
+++ b/include/mysql/plugin_audit.h.pp	2011-06-03 07:27:11 +0000
@@ -43,7 +43,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);
@@ -195,13 +195,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;
@@ -217,7 +212,6 @@ struct mysql_event_general
 };
 struct mysql_event_connection
 {
-  unsigned int event_class;
   unsigned int event_subclass;
   int status;
   unsigned long thread_id;
@@ -240,6 +234,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-28 19:17:29 +0000
+++ b/libmysql/authentication_win/plugin_client.cc	2011-06-03 11:44:33 +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/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2011-05-20 09:18:36 +0000
+++ b/libmysqld/lib_sql.cc	2011-06-13 18:41:24 +0000
@@ -531,8 +531,8 @@ int init_embedded_server(int argc, char
     return 1;
   defaults_argc= *argcp;
   defaults_argv= *argvp;
-  remaining_argc= argc;
-  remaining_argv= argv;
+  remaining_argc= *argcp;
+  remaining_argv= *argvp;
 
   /* Must be initialized early for comparison of options name */
   system_charset_info= &my_charset_utf8_general_ci;

=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2011-05-26 07:05:46 +0000
+++ b/mysql-test/collections/default.experimental	2011-06-06 10:24:28 +0000
@@ -6,13 +6,10 @@ 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.outfile_loaddata @solaris           # Bug#11755168 2010-01-20 alik Test "outfile_loaddata" fails (reproducible)
 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.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_innodb_bug28430                  # Bug#11754425
@@ -29,7 +26,3 @@ sys_vars.ndb_log_update_as_write_basic
 sys_vars.have_ndbcluster_basic
 sys_vars.ndb_log_updated_only_basic
 sys_vars.rpl_init_slave_func		 # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5
-
-main.gis-rtree                           # svoj: due to BUG#11749418
-main.type_float                          # svoj: due to BUG#11749418
-main.type_newdecimal                     # svoj: due to BUG#11749418

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-06-14 20:00:51 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-06-23 12:03:03 +0000
@@ -172,6 +172,7 @@ our $exe_mysql_plugin;
 our $exe_mysqladmin;
 our $exe_mysqltest;
 our $exe_libtool;
+our $exe_mysql_embedded;
 
 our $opt_big_test= 0;
 
@@ -1952,6 +1953,8 @@ sub executable_setup () {
   $exe_mysql=          mtr_exe_exists("$path_client_bindir/mysql");
   $exe_mysql_plugin=   mtr_exe_exists("$path_client_bindir/mysql_plugin");
 
+  $exe_mysql_embedded= mtr_exe_maybe_exists("$basedir/libmysqld/examples/mysql_embedded");
+
   if ( ! $opt_skip_ndbcluster )
   {
     # Look for single threaded NDB
@@ -2357,6 +2360,7 @@ sub environment_setup {
   $ENV{'MYSQL_CLIENT_TEST'}=        mysql_client_test_arguments();
   $ENV{'EXE_MYSQL'}=                $exe_mysql;
   $ENV{'MYSQL_PLUGIN'}=             $exe_mysql_plugin;
+  $ENV{'MYSQL_EMBEDDED'}=           $exe_mysql_embedded;
 
   # ----------------------------------------------------
   # bug25714 executable may _not_ exist in

=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result	2011-04-13 06:16:40 +0000
+++ b/mysql-test/r/alter_table.result	2011-06-16 22:50:07 +0000
@@ -1345,6 +1345,35 @@ DROP TABLE t1;
 CREATE TABLE t1 (a TEXT, id INT, b INT);
 ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
 DROP TABLE t1;
+#
+# Test for bug #12652385 - "61493: REORDERING COLUMNS TO POSITION
+#                           FIRST CAN CAUSE DATA TO BE CORRUPTED".
+#
+drop table if exists t1;
+# Use MyISAM engine as the fact that InnoDB doesn't support
+# in-place ALTER TABLE in cases when columns are being renamed
+# hides some bugs.
+create table t1 (i int, j int) engine=myisam;
+insert into t1 value (1, 2);
+# First, test for original problem described in the bug report.
+select * from t1;
+i	j
+1	2
+# Change of column order by the below ALTER TABLE statement should
+# affect both column names and column contents.
+alter table t1 modify column j int first;
+select * from t1;
+j	i
+2	1
+# Now test for similar problem with the same root.
+# The below ALTER TABLE should change not only the name but
+# also the value for the last column of the table.
+alter table t1 drop column i, add column k int default 0;
+select * from t1;
+j	k
+2	0
+# Clean-up.
+drop table t1;
 End of 5.1 tests
 CREATE TABLE t1(c CHAR(10), 
 i INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY);

=== 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/flush.result'
--- a/mysql-test/r/flush.result	2011-03-07 09:08:10 +0000
+++ b/mysql-test/r/flush.result	2011-06-16 15:18:16 +0000
@@ -466,3 +466,26 @@ ALTER TABLE t1 COMMENT 'test';
 ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
 UNLOCK TABLES;
 DROP TABLE t1;
+#
+# Test for bug #12641342 - "61401: UPDATE PERFORMANCE DEGRADES
+#                           GRADUALLY IF A TRIGGER EXISTS".
+#
+# One of side-effects of this bug was that a transaction which
+# involved DML statements requiring prelocking blocked concurrent
+# FLUSH TABLES WITH READ LOCK for the whole its duration, while
+# correct behavior in this case is to block FTWRL only for duration
+# of individual DML statements.
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id INT PRIMARY KEY, value INT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW SET @var = "a";
+BEGIN;
+UPDATE t1 SET value= value + 1 WHERE id = 1;
+# Switching to connection 'con1'.
+# The below FLUSH TABLES WITH READ LOCK should succeed and
+# should not be blocked by the transaction in default connection.
+FLUSH TABLES WITH READ LOCK;
+UNLOCK TABLES;
+# Switching to connection 'default'.
+COMMIT;
+DROP TABLE t1;

=== modified file 'mysql-test/r/gis-rtree.result'
--- a/mysql-test/r/gis-rtree.result	2010-03-25 11:49:01 +0000
+++ b/mysql-test/r/gis-rtree.result	2011-06-07 15:30:43 +0000
@@ -1549,3 +1549,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/multi_update.result'
--- a/mysql-test/r/multi_update.result	2011-03-08 17:39:25 +0000
+++ b/mysql-test/r/multi_update.result	2011-06-16 06:24:00 +0000
@@ -697,4 +697,40 @@ SELECT * FROM t1;
 pk	a
 1	2
 DROP TABLE t1;
-end of tests
+#
+# BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS 
+#               UPDATED TWICE
+#
+CREATE TABLE t1 ( 
+col_int_key int, 
+pk int, 
+col_int int, 
+key(col_int_key), 
+primary key (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,2,3);
+
+CREATE TABLE t2 ( 
+col_int_key int, 
+pk_1 int, 
+pk_2 int, 
+col_int int, 
+key(col_int_key), 
+primary key (pk_1,pk_2)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2,3,4);
+
+UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
+
+SELECT * FROM t1;
+col_int_key	pk	col_int
+1	7	3
+
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
+
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
+
+SELECT * FROM t2;
+col_int_key	pk_1	pk_2	col_int
+1	7	11	4
+DROP TABLE t1,t2;

=== modified file 'mysql-test/r/multi_update_innodb.result'
--- a/mysql-test/r/multi_update_innodb.result	2011-02-21 15:49:03 +0000
+++ b/mysql-test/r/multi_update_innodb.result	2011-06-16 06:24:00 +0000
@@ -27,3 +27,43 @@ pk	a	b
 0	1	2
 DROP VIEW v1;
 DROP TABLE t1;
+#
+# BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS 
+#               UPDATED TWICE
+#
+CREATE TABLE t1 ( 
+col_int_key int, 
+pk int, 
+col_int int, 
+key(col_int_key), 
+primary key (pk)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,2,3);
+
+CREATE TABLE t2 ( 
+col_int_key int, 
+pk_1 int, 
+pk_2 int, 
+col_int int, 
+key(col_int_key), 
+primary key (pk_1,pk_2)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,2,3,4);
+
+UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
+ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
+
+SELECT * FROM t1;
+col_int_key	pk	col_int
+1	2	3
+
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
+ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
+
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
+ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
+
+SELECT * FROM t2;
+col_int_key	pk_1	pk_2	col_int
+1	2	3	4
+DROP TABLE t1,t2;

=== added file 'mysql-test/r/mysql_embedded.result'
--- a/mysql-test/r/mysql_embedded.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/mysql_embedded.result	2011-06-13 18:41:24 +0000
@@ -0,0 +1,5 @@
+#
+# Bug#12561297 : LIBMYSQLD/EXAMPLE/MYSQL_EMBEDDED IS ABORTING.
+#
+1
+1

=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2011-03-11 09:12:58 +0000
+++ b/mysql-test/r/partition.result	2011-06-13 09:57:47 +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 (
@@ -189,6 +218,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);
@@ -197,6 +235,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:29:23 +0000
+++ b/mysql-test/r/trigger.result	2011-06-10 07:20:15 +0000
@@ -2118,7 +2118,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 '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 '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:12:43 +0000
+++ b/mysql-test/r/type_datetime.result	2011-06-10 08:22:45 +0000
@@ -703,5 +703,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/innodb/r/innodb-index.result'
--- a/mysql-test/suite/innodb/r/innodb-index.result	2011-05-31 09:12:32 +0000
+++ b/mysql-test/suite/innodb/r/innodb-index.result	2011-06-23 09:40:19 +0000
@@ -1085,3 +1085,44 @@ t2	CREATE TABLE `t2` (
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t2;
 DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
+CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+BEGIN;
+SELECT * FROM t1;
+a	b
+3	a
+3	b
+1	c
+0	d
+1	e
+SET lock_wait_timeout=1;
+CREATE INDEX t1a ON t1(a);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE INDEX t2a ON t2(a);
+SELECT * FROM t2;
+a	b
+3	a
+3	b
+1	c
+0	d
+1	e
+SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
+ERROR HY000: Table definition has changed, please retry transaction
+SELECT * FROM t2;
+a	b
+3	a
+3	b
+1	c
+0	d
+1	e
+COMMIT;
+SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
+a	b
+0	d
+1	c
+1	e
+3	a
+3	b
+DROP TABLE t1,t2;

=== modified file 'mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result'
--- a/mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result	2011-06-01 09:55:08 +0000
+++ b/mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result	2011-06-02 09:42:55 +0000
@@ -1,6 +1,7 @@
 set global innodb_file_format="Barracuda";
 set global innodb_file_per_table=1;
 set global innodb_large_prefix=1;
+DROP TABLE IF EXISTS worklog5743;
 CREATE TABLE worklog5743 (
 col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
 PRIMARY KEY (col_1_varchar(3072))
@@ -874,92 +875,6 @@ COUNT(*)
 COMMIT;
 DROP TABLE worklog5743;
 CREATE TABLE worklog5743 (
-col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
-PRIMARY KEY (col_1_text(3072))
-) ROW_FORMAT=DYNAMIC, engine = innodb;
-INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
-1	1
-"In connection 1"
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-"In connection 2"
-START TRANSACTION;
-INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
-"In connection 1"
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-START TRANSACTION;
-"In connection default ....restarting the server"
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
-1	1
-"In connection 1"
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-START TRANSACTION;
-INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
-DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500);
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-"In connection default ....restarting the server"
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
-1	1
-"In connection 1"
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-START TRANSACTION;
-UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500);
-SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("b", 3500)	col_2_text = REPEAT("o", 3500)
-1	1
-"In connection default ....restarting the server"
-SELECT COUNT(*) FROM worklog5743;
-COUNT(*)
-1
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
-1	1
-DROP TABLE worklog5743;
-set global innodb_file_format="Barracuda";
-set global innodb_file_per_table=1;
-set global innodb_large_prefix=1;
-CREATE TABLE worklog5743 (
 col_1_varchar VARCHAR (4000) , col_2_varchar VARCHAR (4000) ,
 PRIMARY KEY (col_1_varchar(3072))
 ) ROW_FORMAT=DYNAMIC, engine = innodb;

=== added file 'mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result'
--- a/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result	2011-06-02 09:42:55 +0000
@@ -0,0 +1,91 @@
+set global innodb_file_format="Barracuda";
+set global innodb_file_per_table=1;
+set global innodb_large_prefix=1;
+DROP TABLE IF EXISTS worklog5743;
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
+1	1
+"In connection 1"
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+"In connection 2"
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
+"In connection 1"
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+START TRANSACTION;
+"In connection default ....restarting the server"
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
+1	1
+"In connection 1"
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500);
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+"In connection default ....restarting the server"
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
+1	1
+"In connection 1"
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+START TRANSACTION;
+UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500);
+SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("b", 3500)	col_2_text = REPEAT("o", 3500)
+1	1
+"In connection default ....restarting the server"
+SELECT COUNT(*) FROM worklog5743;
+COUNT(*)
+1
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+col_1_text = REPEAT("a", 3500)	col_2_text  = REPEAT("o", 3500)
+1	1
+DROP TABLE worklog5743;
+SET GLOBAL innodb_file_format=Antelope;
+SET GLOBAL innodb_file_per_table=0;
+SET GLOBAL innodb_file_format_max=Antelope;
+SET GLOBAL innodb_large_prefix=0;

=== modified file 'mysql-test/suite/innodb/t/innodb-index.test'
--- a/mysql-test/suite/innodb/t/innodb-index.test	2011-05-31 09:12:32 +0000
+++ b/mysql-test/suite/innodb/t/innodb-index.test	2011-06-23 09:40:19 +0000
@@ -516,34 +516,35 @@ SHOW CREATE TABLE t2;
 DROP TABLE t2;
 DROP TABLE t1;
 
-# The following tests are disabled because of the introduced timeouts for
-# metadata locks at the MySQL level as part of the fix for
-# Bug#45225 Locking: hang if drop table with no timeout
-# The following CREATE INDEX t1a ON t1(a); causes a lock wait timeout
-# start disabled45225_2
-#connect (a,localhost,root,,);
-#connect (b,localhost,root,,);
-#connection a;
-#CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
-#INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
-#connection b;
-#BEGIN;
-#SELECT * FROM t1;
-#connection a;
-#CREATE INDEX t1a ON t1(a);
-#connection b;
-#SELECT * FROM t1;
-#--error ER_TABLE_DEF_CHANGED
-#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
-#SELECT * FROM t1;
-#COMMIT;
-#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
-#connection default;
-#disconnect a;
-#disconnect b;
-#
-#DROP TABLE t1;
-# end disabled45225_2
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
+CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+connection b;
+BEGIN;
+# This acquires a MDL lock on t1 until commit.
+SELECT * FROM t1;
+connection a;
+# This times out before of the MDL lock held by connection b.
+SET lock_wait_timeout=1;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE INDEX t1a ON t1(a);
+CREATE INDEX t2a ON t2(a);
+connection b;
+SELECT * FROM t2;
+--error ER_TABLE_DEF_CHANGED
+SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
+SELECT * FROM t2;
+COMMIT;
+SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
+connection default;
+disconnect a;
+disconnect b;
+
+DROP TABLE t1,t2;
 
 #
 # restore environment to the state it was before this test execution

=== modified file 'mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test'
--- a/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test	2011-06-01 09:55:08 +0000
+++ b/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test	2011-06-02 09:42:55 +0000
@@ -26,7 +26,9 @@ set global innodb_file_format="Barracuda
 set global innodb_file_per_table=1;
 set global innodb_large_prefix=1;
 
-
+-- disable_warnings
+DROP TABLE IF EXISTS worklog5743;
+-- enable_warnings
 #------------------------------------------------------------------------------
 # Prefix index with VARCHAR data type , primary/secondary index and DML ops
 CREATE TABLE worklog5743 (
@@ -849,97 +851,6 @@ DROP TABLE worklog5743;
 
 
 #------------------------------------------------------------------------------
-# Stop the server in between when prefix index are created and see if state is
-# correct when server is restarted.
-# Server is restarted at differnt points.
-
-CREATE TABLE worklog5743 (
-col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
-PRIMARY KEY (col_1_text(3072))
-) ROW_FORMAT=DYNAMIC, engine = innodb;
-INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-
---echo "In connection 1"
---connect (con1,localhost,root,,)
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-SELECT COUNT(*) FROM worklog5743;
-
-
---echo "In connection 2"
---connect (con2,localhost,root,,)
-START TRANSACTION;
-INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
-
-
---echo "In connection 1"
---connection con1
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-SELECT COUNT(*) FROM worklog5743;
-START TRANSACTION;
-
-
---echo "In connection default ....restarting the server"
---connection default
-# Restart the server
--- source include/restart_mysqld.inc
-SELECT COUNT(*) FROM worklog5743;
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-
---disconnect con1
---disconnect con2
-
---echo "In connection 1"
---connect (con1,localhost,root,,)
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-SELECT COUNT(*) FROM worklog5743;
-START TRANSACTION;
-INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
-DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500);
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-
---echo "In connection default ....restarting the server"
---connection default
-# Restart the server
--- source include/restart_mysqld.inc
-SELECT COUNT(*) FROM worklog5743;
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-
---disconnect con1
-
---echo "In connection 1"
---connect (con2,localhost,root,,)
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-SELECT COUNT(*) FROM worklog5743;
-START TRANSACTION;
-UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500);
-SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM
-worklog5743;
-
---echo "In connection default ....restarting the server"
---connection default
-# Restart the server
--- source include/restart_mysqld.inc
-SELECT COUNT(*) FROM worklog5743;
-SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
-worklog5743;
-
-DROP TABLE worklog5743;
-
-#------------------------------------------------------------------------------
-# Reset variables at server was restarted in previous case
-set global innodb_file_format="Barracuda";
-set global innodb_file_per_table=1;
-set global innodb_large_prefix=1;
-#------------------------------------------------------------------------------
 # Select queries on prefix index column as index will be used in queries.
 # Use few select functions , join condition , subqueries.
 

=== added file 'mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test'
--- a/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test	2011-06-16 04:30:51 +0000
@@ -0,0 +1,127 @@
+######## suite/innodb/t/innodb_prefix_iindex_restart_server.test #####
+#                                                                    #
+# Testcase for worklog WL#5743: Lift the limit of index key prefixes #
+# Test scenario : Stop the server in between when prefix index are   #
+# created and see if state is preserved after restart                #
+#                                                                    #
+# Creation:                                                          #
+# 2011-06-02 Implemented this test as part of WL#5743                #
+#                                                                    #
+######################################################################
+
+# Don't test this under valgrind, memory leaks will occur due restart
+--source include/not_valgrind.inc
+# Test restart the server and "shutdown_server" looks for pid file
+# which is not there with embedded mode
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+# Save innodb variables
+let $innodb_file_format_orig=`select @@innodb_file_format`;
+let $innodb_file_per_table_orig=`select @@innodb_file_per_table`;
+let $innodb_file_format_max_orig=`select @@innodb_file_format_max`;
+let $innodb_large_prefix_orig=`select @@innodb_large_prefix`;
+
+# Set Innodb file format as feature works for Barracuda file format
+set global innodb_file_format="Barracuda";
+set global innodb_file_per_table=1;
+set global innodb_large_prefix=1;
+
+-- disable_warnings
+DROP TABLE IF EXISTS worklog5743;
+-- enable_warnings
+
+
+#------------------------------------------------------------------------------
+# Stop the server in between when prefix index are created and see if state is
+# correct when server is restarted.
+# Server is restarted at differnt points.
+
+CREATE TABLE worklog5743 (
+col_1_text TEXT(4000) , col_2_text TEXT(4000) ,
+PRIMARY KEY (col_1_text(3072))
+) ROW_FORMAT=DYNAMIC, engine = innodb;
+INSERT INTO worklog5743 VALUES(REPEAT("a", 3500) , REPEAT("o", 3500));
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+
+--echo "In connection 1"
+--connect (con1,localhost,root,,)
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+
+
+--echo "In connection 2"
+--connect (con2,localhost,root,,)
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
+
+
+--echo "In connection 1"
+--connection con1
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+START TRANSACTION;
+
+
+--echo "In connection default ....restarting the server"
+--connection default
+# Restart the server
+-- source include/restart_mysqld.inc
+SELECT COUNT(*) FROM worklog5743;
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+
+--disconnect con1
+--disconnect con2
+
+--echo "In connection 1"
+--connect (con1,localhost,root,,)
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+START TRANSACTION;
+INSERT INTO worklog5743 VALUES(REPEAT("b", 3500) , REPEAT("o", 3500));
+DELETE FROM worklog5743 WHERE col_1_text = REPEAT("b", 3500);
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+
+--echo "In connection default ....restarting the server"
+--connection default
+# Restart the server
+-- source include/restart_mysqld.inc
+SELECT COUNT(*) FROM worklog5743;
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+
+--disconnect con1
+
+--echo "In connection 1"
+--connect (con2,localhost,root,,)
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+SELECT COUNT(*) FROM worklog5743;
+START TRANSACTION;
+UPDATE worklog5743 SET col_1_text = REPEAT("b", 3500) WHERE col_1_text = REPEAT("a", 3500);
+SELECT col_1_text = REPEAT("b", 3500) , col_2_text = REPEAT("o", 3500) FROM
+worklog5743;
+
+--echo "In connection default ....restarting the server"
+--connection default
+# Restart the server
+-- source include/restart_mysqld.inc
+SELECT COUNT(*) FROM worklog5743;
+SELECT col_1_text = REPEAT("a", 3500) , col_2_text  = REPEAT("o", 3500) FROM
+worklog5743;
+
+DROP TABLE worklog5743;
+
+
+#------------------------------------------------------------------------------
+
+eval SET GLOBAL innodb_file_format=$innodb_file_format_orig;
+eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig;
+eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig;
+eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig;
+

=== modified file 'mysql-test/suite/perfschema/include/cleanup_helper.inc'
--- a/mysql-test/suite/perfschema/include/cleanup_helper.inc	2010-11-03 15:42:33 +0000
+++ b/mysql-test/suite/perfschema/include/cleanup_helper.inc	2011-06-16 20:35:01 +0000
@@ -1,25 +1,33 @@
-# Copyright (C) 2009 Sun Microsystems, Inc
+# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 #
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2 of
+# the License.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301  USA
 
 # Tests for PERFORMANCE_SCHEMA
 
 update performance_schema.setup_instruments set enabled='YES';
 
+connection con1;
 disconnect con1;
+--source include/wait_until_disconnected.inc
+connection con2;
 disconnect con2;
+--source include/wait_until_disconnected.inc
+connection con3;
 disconnect con3;
+--source include/wait_until_disconnected.inc
 
 connection default;
 

=== modified file 'mysql-test/suite/perfschema/include/upgrade_check.inc'
--- a/mysql-test/suite/perfschema/include/upgrade_check.inc	2010-09-13 23:19:39 +0000
+++ b/mysql-test/suite/perfschema/include/upgrade_check.inc	2011-06-16 20:35:01 +0000
@@ -17,8 +17,10 @@
 # $out_file and $err_file must be set within pfs_upgrade.test.
 #
 
+--source include/count_sessions.inc
 --error 1
 --exec $MYSQL_UPGRADE --skip-verbose --force > $out_file 2> $err_file
+--source include/wait_until_count_sessions.inc
 
 # Verify that mysql_upgrade complained about the performance_schema
 --cat_file $err_file

=== modified file 'mysql-test/suite/perfschema/r/selects.result'
--- a/mysql-test/suite/perfschema/r/selects.result	2010-11-03 15:42:33 +0000
+++ b/mysql-test/suite/perfschema/r/selects.result	2011-06-16 20:35:01 +0000
@@ -62,6 +62,7 @@ SELECT EVENT_ID FROM performance_schema.
 WHERE 1 = 2;
 CREATE EVENT t_ps_event
 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND
+ON COMPLETION PRESERVE
 DO INSERT INTO t_event
 SELECT DISTINCT EVENT_ID
 FROM performance_schema.events_waits_current
@@ -106,5 +107,6 @@ EVENT_ID
 [EVENT_ID]
 DROP PROCEDURE t_ps_proc;
 DROP FUNCTION t_ps_func;
+DROP EVENT t_ps_event;
 DROP TABLE t1;
 DROP TABLE t_event;

=== modified file 'mysql-test/suite/perfschema/t/selects.test'
--- a/mysql-test/suite/perfschema/t/selects.test	2010-11-03 15:42:33 +0000
+++ b/mysql-test/suite/perfschema/t/selects.test	2011-06-16 20:35:01 +0000
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 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
@@ -97,6 +97,7 @@ SELECT EVENT_ID FROM performance_schema.
 WHERE 1 = 2;
 CREATE EVENT t_ps_event
 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND
+ON COMPLETION PRESERVE
 DO INSERT INTO t_event
    SELECT DISTINCT EVENT_ID
    FROM performance_schema.events_waits_current
@@ -168,7 +169,7 @@ delimiter ;|
 SELECT t_ps_func(connection_id()) = @p_id;
 
 # We might reach this point too early which means the event scheduler has not
-# execute our "t_ps_event". Therefore we poll till the record was inserted
+# executed our "t_ps_event". Therefore we poll till the record was inserted
 # and run our test statement afterwards.
 let $wait_timeout= 20;
 let $wait_condition= SELECT COUNT(*) = 1 FROM t_event;
@@ -179,5 +180,6 @@ SELECT * FROM t_event;
 # Clean up
 DROP PROCEDURE t_ps_proc;
 DROP FUNCTION t_ps_func;
+DROP EVENT t_ps_event;
 DROP TABLE t1;
 DROP TABLE t_event;

=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test	2011-04-13 06:16:40 +0000
+++ b/mysql-test/t/alter_table.test	2011-06-16 22:50:07 +0000
@@ -1073,6 +1073,33 @@ ALTER TABLE t1 DROP COLUMN a, ADD COLUMN
 DROP TABLE t1;
 
 
+--echo #
+--echo # Test for bug #12652385 - "61493: REORDERING COLUMNS TO POSITION
+--echo #                           FIRST CAN CAUSE DATA TO BE CORRUPTED".
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+--echo # Use MyISAM engine as the fact that InnoDB doesn't support
+--echo # in-place ALTER TABLE in cases when columns are being renamed
+--echo # hides some bugs.
+create table t1 (i int, j int) engine=myisam;
+insert into t1 value (1, 2);
+--echo # First, test for original problem described in the bug report.
+select * from t1;
+--echo # Change of column order by the below ALTER TABLE statement should
+--echo # affect both column names and column contents.
+alter table t1 modify column j int first;
+select * from t1;
+--echo # Now test for similar problem with the same root.
+--echo # The below ALTER TABLE should change not only the name but
+--echo # also the value for the last column of the table.
+alter table t1 drop column i, add column k int default 0;
+select * from t1;
+--echo # Clean-up.
+drop table t1;
+
+
 --echo End of 5.1 tests
 
 #

=== 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:09:24 +0000
+++ b/mysql-test/t/disabled.def	2011-06-16 13:55:11 +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/flush.test'
--- a/mysql-test/t/flush.test	2011-03-07 09:08:10 +0000
+++ b/mysql-test/t/flush.test	2011-06-16 15:18:16 +0000
@@ -668,3 +668,36 @@ ALTER TABLE t1 COMMENT 'test';
 
 UNLOCK TABLES;
 DROP TABLE t1;
+
+
+--echo #
+--echo # Test for bug #12641342 - "61401: UPDATE PERFORMANCE DEGRADES
+--echo #                           GRADUALLY IF A TRIGGER EXISTS".
+--echo #
+--echo # One of side-effects of this bug was that a transaction which
+--echo # involved DML statements requiring prelocking blocked concurrent
+--echo # FLUSH TABLES WITH READ LOCK for the whole its duration, while
+--echo # correct behavior in this case is to block FTWRL only for duration
+--echo # of individual DML statements.
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 (id INT PRIMARY KEY, value INT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW SET @var = "a";
+BEGIN;
+UPDATE t1 SET value= value + 1 WHERE id = 1;
+
+--echo # Switching to connection 'con1'.
+connect(con1, localhost, root);
+--echo # The below FLUSH TABLES WITH READ LOCK should succeed and
+--echo # should not be blocked by the transaction in default connection.
+FLUSH TABLES WITH READ LOCK;
+UNLOCK TABLES;
+disconnect con1;
+--source include/wait_until_disconnected.inc
+
+--echo # Switching to connection 'default'.
+connection default;
+COMMIT;
+DROP TABLE t1;

=== 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/multi_update.test'
--- a/mysql-test/t/multi_update.test	2011-03-08 17:39:25 +0000
+++ b/mysql-test/t/multi_update.test	2011-06-16 06:24:00 +0000
@@ -703,4 +703,50 @@ UPDATE t1 AS A, t1 AS B SET A.pk = 1, B.
 SELECT * FROM t1;
 DROP TABLE t1;
 
---echo end of tests
+--echo #
+--echo # BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS 
+--echo #               UPDATED TWICE
+--echo #
+
+# Results differ between storage engines. This test is to verify that
+# the bugfix did NOT change behavior for MyISAM.
+# See multi_update_innodb.test for the InnoDB variant of this test
+CREATE TABLE t1 ( 
+  col_int_key int, 
+  pk int, 
+  col_int int, 
+  key(col_int_key), 
+  primary key (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,2,3);
+
+--echo
+CREATE TABLE t2 ( 
+  col_int_key int, 
+  pk_1 int, 
+  pk_2 int, 
+  col_int int, 
+  key(col_int_key), 
+  primary key (pk_1,pk_2)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2,3,4);
+
+--echo
+UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
+
+--echo
+SELECT * FROM t1;
+
+--echo
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
+--echo
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
+
+--echo
+SELECT * FROM t2;
+
+DROP TABLE t1,t2;
+
+
+
+

=== modified file 'mysql-test/t/multi_update_innodb.test'
--- a/mysql-test/t/multi_update_innodb.test	2011-02-21 15:49:03 +0000
+++ b/mysql-test/t/multi_update_innodb.test	2011-06-16 06:24:00 +0000
@@ -31,3 +31,47 @@ SELECT * FROM t1;
 DROP VIEW v1;
 DROP TABLE t1;
 
+--echo #
+--echo # BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS 
+--echo #               UPDATED TWICE
+--echo #
+
+# Results differ between storage engines.
+# See multi_update.test for the MyISAM variant of this test
+CREATE TABLE t1 ( 
+  col_int_key int, 
+  pk int, 
+  col_int int, 
+  key(col_int_key), 
+  primary key (pk)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,2,3);
+
+--echo
+CREATE TABLE t2 ( 
+  col_int_key int, 
+  pk_1 int, 
+  pk_2 int, 
+  col_int int, 
+  key(col_int_key), 
+  primary key (pk_1,pk_2)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,2,3,4);
+
+--echo
+--error ER_MULTI_UPDATE_KEY_CONFLICT
+UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
+--echo
+SELECT * FROM t1;
+
+--echo
+--error ER_MULTI_UPDATE_KEY_CONFLICT
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
+--echo
+--error ER_MULTI_UPDATE_KEY_CONFLICT
+UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
+
+--echo
+SELECT * FROM t2;
+
+DROP TABLE t1,t2;

=== added file 'mysql-test/t/mysql_embedded.test'
--- a/mysql-test/t/mysql_embedded.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysql_embedded.test	2011-06-16 13:55:11 +0000
@@ -0,0 +1,12 @@
+--echo #
+--echo # Bug#12561297 : LIBMYSQLD/EXAMPLE/MYSQL_EMBEDDED IS ABORTING.
+--echo #
+
+--source include/is_embedded.inc
+
+# Test case require mysql_embedded to be present
+if(!$MYSQL_EMBEDDED)
+{
+  --skip Test requires mysql_embedded executable
+}
+--exec $MYSQL_EMBEDDED -e 'select 1'

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2011-03-11 09:12:58 +0000
+++ b/mysql-test/t/partition.test	2011-06-13 09:57:47 +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 #
 
@@ -196,10 +227,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:12:43 +0000
+++ b/mysql-test/t/type_datetime.test	2011-06-10 08:22:45 +0000
@@ -506,5 +506,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 'mysys/mf_pack.c'
--- a/mysys/mf_pack.c	2010-12-29 00:26:31 +0000
+++ b/mysys/mf_pack.c	2011-06-15 09:18:08 +0000
@@ -193,7 +193,7 @@ size_t cleanup_dirname(register char *to
 	  while (pos >= start && *pos != FN_LIBCHAR)	/* remove prev dir */
 	    pos--;
           if (pos[1] == FN_HOMELIB ||
-              (pos > start && memcmp(pos, parent, length) == 0))
+              (pos >= start && memcmp(pos, parent, length) == 0))
 	  {					/* Don't remove ~user/ */
 	    pos=strmov(end_parentdir+1,parent);
 	    *pos=FN_LIBCHAR;

=== 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/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2011-05-27 11:42:28 +0000
+++ b/sql/event_db_repository.cc	2011-06-09 17:07:03 +0000
@@ -235,9 +235,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);
 
   /*
@@ -716,8 +723,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-03-31 14:05:33 +0000
+++ b/sql/event_parse_data.cc	2011-06-09 17:07:03 +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-03-31 14:05:33 +0000
+++ b/sql/event_parse_data.h	2011-06-09 17:07:03 +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/ha_partition.cc'
--- a/sql/ha_partition.cc	2011-06-01 08:06:55 +0000
+++ b/sql/ha_partition.cc	2011-06-13 09:21:54 +0000
@@ -3456,9 +3456,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);
@@ -4110,6 +4114,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/item.h'
--- a/sql/item.h	2011-04-08 13:15:23 +0000
+++ b/sql/item.h	2011-06-10 14:26:35 +0000
@@ -1672,6 +1672,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 field->charset_for_protocol(); }
 };
 
 

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2011-05-18 06:59:04 +0000
+++ b/sql/item_timefunc.cc	2011-06-13 09:57:47 +0000
@@ -1388,6 +1388,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:25:49 +0000
+++ b/sql/item_timefunc.h	2011-06-13 09:57:47 +0000
@@ -391,6 +391,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/mdl.h'
--- a/sql/mdl.h	2011-04-11 11:39:15 +0000
+++ b/sql/mdl.h	2011-06-16 15:18:16 +0000
@@ -152,11 +152,24 @@ enum enum_mdl_type {
 
 /** Duration of metadata lock. */
 
-enum enum_mdl_duration { MDL_STATEMENT= 0,
-                         MDL_TRANSACTION,
-                         MDL_EXPLICIT,
-                         /* This should be the last ! */
-                         MDL_DURATION_END };
+enum enum_mdl_duration {
+  /**
+    Locks with statement duration are automatically released at the end
+    of statement or transaction.
+  */
+  MDL_STATEMENT= 0,
+  /**
+    Locks with transaction duration are automatically released at the end
+    of transaction.
+  */
+  MDL_TRANSACTION,
+  /**
+    Locks with explicit duration survive the end of statement and transaction.
+    They have to be released explicitly by calling MDL_context::release_lock().
+  */
+  MDL_EXPLICIT,
+  /* This should be the last ! */
+  MDL_DURATION_END };
 
 
 /** Maximal length of key for metadata locking subsystem. */

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2011-05-26 10:56:17 +0000
+++ b/sql/mysqld.cc	2011-06-06 10:24:28 +0000
@@ -163,12 +163,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>
@@ -194,19 +194,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/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2011-05-31 09:12:32 +0000
+++ b/sql/share/errmsg-utf8.txt	2011-06-10 07:20:15 +0000
@@ -6408,3 +6408,10 @@ WARN_OPTION_BELOW_LIMIT
 
 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_head.cc'
--- a/sql/sp_head.cc	2011-05-21 08:59:32 +0000
+++ b/sql/sp_head.cc	2011-06-10 07:20:15 +0000
@@ -2543,7 +2543,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;
 

=== modified file 'sql/sql_audit.cc'
--- a/sql/sql_audit.cc	2010-12-14 14:34:23 +0000
+++ b/sql/sql_audit.cc	2011-06-03 07:27:11 +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);
 }
 
 
@@ -433,18 +438,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;
 }
@@ -457,15 +463,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
   {
@@ -476,7 +486,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_class.cc'
--- a/sql/sql_class.cc	2011-05-21 09:29:10 +0000
+++ b/sql/sql_class.cc	2011-06-16 15:18:16 +0000
@@ -3790,16 +3790,24 @@ void THD::set_mysys_var(struct st_my_thr
 
 void THD::leave_locked_tables_mode()
 {
+  if (locked_tables_mode == LTM_LOCK_TABLES)
+  {
+    /*
+      When leaving LOCK TABLES mode we have to change the duration of most
+      of the metadata locks being held, except for HANDLER and GRL locks,
+      to transactional for them to be properly released at UNLOCK TABLES.
+    */
+    mdl_context.set_transaction_duration_for_all_locks();
+    /*
+      Make sure we don't release the global read lock and commit blocker
+      when leaving LTM.
+    */
+    global_read_lock.set_explicit_lock_duration(this);
+    /* Also ensure that we don't release metadata locks for open HANDLERs. */
+    if (handler_tables_hash.records)
+      mysql_ha_set_explicit_lock_duration(this);
+  }
   locked_tables_mode= LTM_NONE;
-  mdl_context.set_transaction_duration_for_all_locks();
-  /*
-    Make sure we don't release the global read lock and commit blocker
-    when leaving LTM.
-  */
-  global_read_lock.set_explicit_lock_duration(this);
-  /* Also ensure that we don't release metadata locks for open HANDLERs. */
-  if (handler_tables_hash.records)
-    mysql_ha_set_explicit_lock_duration(this);
 }
 
 void THD::get_definer(LEX_USER *definer)

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-05-20 09:18:36 +0000
+++ b/sql/sql_class.h	2011-06-16 15:18:16 +0000
@@ -2795,7 +2795,19 @@ public:
   {
     DBUG_ASSERT(locked_tables_mode == LTM_NONE);
 
-    mdl_context.set_explicit_duration_for_all_locks();
+    if (mode_arg == LTM_LOCK_TABLES)
+    {
+      /*
+        When entering LOCK TABLES mode we should set explicit duration
+        for all metadata locks acquired so far in order to avoid releasing
+        them till UNLOCK TABLES statement.
+        We don't do this when entering prelocked mode since sub-statements
+        don't release metadata locks and restoring status-quo after leaving
+        prelocking mode gets complicated.
+      */
+      mdl_context.set_explicit_duration_for_all_locks();
+    }
+
     locked_tables_mode= mode_arg;
   }
   void leave_locked_tables_mode();

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-05-26 15:50:06 +0000
+++ b/sql/sql_parse.cc	2011-06-16 15:18:16 +0000
@@ -2027,6 +2027,11 @@ mysql_execute_command(THD *thd)
   */
   if (stmt_causes_implicit_commit(thd, CF_IMPLICT_COMMIT_BEGIN))
   {
+    /*
+      Note that this should never happen inside of stored functions
+      or triggers as all such statements prohibited there.
+    */
+    DBUG_ASSERT(! thd->in_sub_stmt);
     /* Commit or rollback the statement transaction. */
     thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
     /* Commit the normal transaction if one is active. */

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-05-06 08:27:04 +0000
+++ b/sql/sql_select.cc	2011-06-10 08:22:45 +0000
@@ -9519,24 +9519,41 @@ internal_remove_eq_conds(THD *thd, COND
       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))
       {
-	COND *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())

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-06-01 08:06:55 +0000
+++ b/sql/sql_table.cc	2011-06-16 22:50:07 +0000
@@ -4582,6 +4582,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,
@@ -5321,6 +5326,12 @@ mysql_prepare_alter_table(THD *thd, TABL
     if (drop)
     {
       drop_it.remove();
+      /*
+        ALTER TABLE DROP COLUMN always changes table data even in cases
+        when new version of the table has the same structure as the old
+        one.
+      */
+      alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
       continue;
     }
     /* Check if field is changed */
@@ -5398,7 +5409,14 @@ mysql_prepare_alter_table(THD *thd, TABL
     if (!def->after)
       new_create_list.push_back(def);
     else if (def->after == first_keyword)
+    {
       new_create_list.push_front(def);
+      /*
+        Re-ordering columns in table can't be done using in-place algorithm
+        as it always changes table data.
+      */
+      alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
+    }
     else
     {
       Create_field *find;
@@ -5414,6 +5432,10 @@ mysql_prepare_alter_table(THD *thd, TABL
         goto err;
       }
       find_it.after(def);			// Put element after this
+      /*
+        Re-ordering columns in table can't be done using in-place algorithm
+        as it always changes table data.
+      */
       alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
     }
   }

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2011-04-15 12:02:22 +0000
+++ b/sql/sql_trigger.cc	2011-06-10 07:20:15 +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	2010-09-16 09:11:13 +0000
+++ b/sql/sql_trigger.h	2011-06-10 07:20:15 +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)
   {
     bzero((char *)bodies, sizeof(bodies));
     bzero((char *)trigger_fields, 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-02-21 15:49:03 +0000
+++ b/sql/sql_update.cc	2011-06-16 06:24:00 +0000
@@ -1071,17 +1071,27 @@ bool unsafe_key_update(TABLE_LIST *leave
             return true;
           }
 
-          if (primkey_clustered &&
-              (bitmap_is_set(table1->write_set, table1->s->primary_key) ||
-               bitmap_is_set(table2->write_set, table2->s->primary_key)))
+          if (primkey_clustered)
           {
-            // Clustered primary key is updated
-            my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
-                     tl->belong_to_view ? tl->belong_to_view->alias
-                                        : tl->alias,
-                     tl2->belong_to_view ? tl2->belong_to_view->alias
-                                         : tl2->alias);
-            return true;
+            // The primary key can cover multiple columns
+            KEY key_info= table1->key_info[table1->s->primary_key];
+            KEY_PART_INFO *key_part= key_info.key_part;
+            KEY_PART_INFO *key_part_end= key_part + key_info.key_parts;
+
+            for (;key_part != key_part_end; ++key_part)
+            {
+              if (bitmap_is_set(table1->write_set, key_part->fieldnr-1) ||
+                  bitmap_is_set(table2->write_set, key_part->fieldnr-1))
+              {
+                // Clustered primary key is updated
+                my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
+                         tl->belong_to_view ? tl->belong_to_view->alias
+                         : tl->alias,
+                         tl2->belong_to_view ? tl2->belong_to_view->alias
+                         : tl2->alias);
+                return true;
+              }
+            }
           }
         }
       }

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-05-12 05:23:16 +0000
+++ b/sql/sql_yacc.yy	2011-06-09 17:07:03 +0000
@@ -2227,16 +2227,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/table.h'
--- a/sql/table.h	2011-03-25 09:06:07 +0000
+++ b/sql/table.h	2011-06-16 06:24:00 +0000
@@ -627,8 +627,8 @@ struct TABLE_SHARE
   uint db_options_in_use;		/* Options in use */
   uint db_record_offset;		/* if HA_REC_IN_SEQ */
   uint rowid_field_offset;		/* Field_nr +1 to rowid field */
-  /* Index of auto-updated TIMESTAMP field in field array */
-  uint primary_key;
+  /* Primary key index number, used in TABLE::key_info[] */
+  uint primary_key;                     
   uint next_number_index;               /* autoincrement key number */
   uint next_number_key_offset;          /* autoinc keypart offset in a key */
   uint next_number_keypart;             /* autoinc keypart number in a key */

=== 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:24:34 +0000
+++ b/storage/archive/ha_archive.cc	2011-06-03 07:49:05 +0000
@@ -1685,11 +1685,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/btr0btr.c'
--- a/storage/innobase/btr/btr0btr.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/btr/btr0btr.c	2011-06-16 13:14:16 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, 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
@@ -2275,7 +2275,7 @@ btr_attach_half_pages(
 /*==================*/
 	dict_index_t*	index,		/*!< in: the index tree */
 	buf_block_t*	block,		/*!< in/out: page to be split */
-	rec_t*		split_rec,	/*!< in: first record on upper
+	const rec_t*	split_rec,	/*!< in: first record on upper
 					half page */
 	buf_block_t*	new_block,	/*!< in/out: the new half page */
 	ulint		direction,	/*!< in: FSP_UP or FSP_DOWN */
@@ -2967,15 +2967,16 @@ btr_node_ptr_delete(
 	ut_a(err == DB_SUCCESS);
 
 	if (!compressed) {
-		btr_cur_compress_if_useful(&cursor, mtr);
+		btr_cur_compress_if_useful(&cursor, FALSE, mtr);
 	}
 }
 
 /*************************************************************//**
 If page is the only on its level, this function moves its records to the
-father page, thus reducing the tree height. */
+father page, thus reducing the tree height.
+@return father block */
 static
-void
+buf_block_t*
 btr_lift_page_up(
 /*=============*/
 	dict_index_t*	index,	/*!< in: index tree */
@@ -3092,6 +3093,8 @@ btr_lift_page_up(
 	}
 	ut_ad(page_validate(father_page, index));
 	ut_ad(btr_check_node_ptr(index, father_block, mtr));
+
+	return(father_block);
 }
 
 /*************************************************************//**
@@ -3108,11 +3111,13 @@ UNIV_INTERN
 ibool
 btr_compress(
 /*=========*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to merge or lift;
-				the page must not be empty: in record delete
-				use btr_discard_page if the page would become
-				empty */
-	mtr_t*		mtr)	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to merge
+				or lift; the page must not be empty:
+				when deleting records, use btr_discard_page()
+				if the page would become empty */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 {
 	dict_index_t*	index;
 	ulint		space;
@@ -3130,12 +3135,14 @@ btr_compress(
 	ulint*		offsets;
 	ulint		data_size;
 	ulint		n_recs;
+	ulint		nth_rec = 0; /* remove bogus warning */
 	ulint		max_ins_size;
 	ulint		max_ins_size_reorg;
 
 	block = btr_cur_get_block(cursor);
 	page = btr_cur_get_page(cursor);
 	index = btr_cur_get_index(cursor);
+
 	ut_a((ibool) !!page_is_comp(page) == dict_table_is_comp(index->table));
 
 	ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
@@ -3156,6 +3163,10 @@ btr_compress(
 	offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
 					    &father_cursor);
 
+	if (adjust) {
+		nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
+	}
+
 	/* Decide the page to which we try to merge and which will inherit
 	the locks */
 
@@ -3182,9 +3193,9 @@ btr_compress(
 	} else {
 		/* The page is the only one on the level, lift the records
 		to the father */
-		btr_lift_page_up(index, block, mtr);
-		mem_heap_free(heap);
-		return(TRUE);
+
+		merge_block = btr_lift_page_up(index, block, mtr);
+		goto func_exit;
 	}
 
 	n_recs = page_get_n_recs(page);
@@ -3266,6 +3277,10 @@ err_exit:
 
 		btr_node_ptr_delete(index, block, mtr);
 		lock_update_merge_left(merge_block, orig_pred, block);
+
+		if (adjust) {
+			nth_rec += page_rec_get_n_recs_before(orig_pred);
+		}
 	} else {
 		rec_t*		orig_succ;
 #ifdef UNIV_BTR_DEBUG
@@ -3330,7 +3345,6 @@ err_exit:
 	}
 
 	btr_blob_dbg_remove(page, index, "btr_compress");
-	mem_heap_free(heap);
 
 	if (!dict_index_is_clust(index) && page_is_leaf(merge_page)) {
 		/* Update the free bits of the B-tree page in the
@@ -3382,6 +3396,16 @@ err_exit:
 	btr_page_free(index, block, mtr);
 
 	ut_ad(btr_check_node_ptr(index, merge_block, mtr));
+func_exit:
+	mem_heap_free(heap);
+
+	if (adjust) {
+		btr_cur_position(
+			index,
+			page_rec_get_nth(merge_block->frame, nth_rec),
+			merge_block, cursor);
+	}
+
 	return(TRUE);
 }
 

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2011-05-24 08:41:31 +0000
+++ b/storage/innobase/btr/btr0cur.c	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -1972,7 +1972,6 @@ btr_cur_optimistic_update(
 	ulint		old_rec_size;
 	dtuple_t*	new_entry;
 	roll_ptr_t	roll_ptr;
-	trx_t*		trx;
 	mem_heap_t*	heap;
 	ulint		i;
 	ulint		n_ext;
@@ -1989,6 +1988,10 @@ 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)
+	     || trx_is_recv(thr_get_trx(thr)));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
 #ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
@@ -2111,13 +2114,11 @@ any_extern:
 
 	page_cur_move_to_prev(page_cursor);
 
-	trx = thr_get_trx(thr);
-
 	if (!(flags & BTR_KEEP_SYS_FLAG)) {
 		row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
 					      roll_ptr);
 		row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID,
-					      trx->id);
+					      thr_get_trx(thr)->id);
 	}
 
 	/* There are no externally stored columns in new_entry */
@@ -2203,7 +2204,9 @@ btr_cur_pessimistic_update(
 /*=======================*/
 	ulint		flags,	/*!< in: undo logging, locking, and rollback
 				flags */
-	btr_cur_t*	cursor,	/*!< in: cursor on the record to update */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the record to update;
+				cursor may become invalid if *big_rec == NULL
+				|| !(flags & BTR_KEEP_POS_FLAG) */
 	mem_heap_t**	heap,	/*!< in/out: pointer to memory heap, or NULL */
 	big_rec_t**	big_rec,/*!< out: big rec vector whose fields have to
 				be stored externally by the caller, or NULL */
@@ -2342,7 +2345,7 @@ btr_cur_pessimistic_update(
 	record to be inserted: we have to remember which fields were such */
 
 	ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
-	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
+	ut_ad(rec_offs_validate(rec, index, offsets));
 	n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
 
 	if (UNIV_LIKELY_NULL(page_zip)) {
@@ -2365,6 +2368,10 @@ make_external:
 			err = DB_TOO_BIG_RECORD;
 			goto return_after_reservations;
 		}
+
+		ut_ad(page_is_leaf(page));
+		ut_ad(dict_index_is_clust(index));
+		ut_ad(flags & BTR_KEEP_POS_FLAG);
 	}
 
 	/* Store state of explicit locks on rec on the page infimum record,
@@ -2392,6 +2399,8 @@ make_external:
 	rec = btr_cur_insert_if_possible(cursor, new_entry, n_ext, mtr);
 
 	if (rec) {
+		page_cursor->rec = rec;
+
 		lock_rec_restore_from_page_infimum(btr_cur_get_block(cursor),
 						   rec, block);
 
@@ -2405,7 +2414,10 @@ make_external:
 						     rec, index, offsets, mtr);
 		}
 
-		btr_cur_compress_if_useful(cursor, mtr);
+		btr_cur_compress_if_useful(
+			cursor,
+			big_rec_vec != NULL && (flags & BTR_KEEP_POS_FLAG),
+			mtr);
 
 		if (page_zip && !dict_index_is_clust(index)
 		    && page_is_leaf(page)) {
@@ -2425,6 +2437,21 @@ make_external:
 		}
 	}
 
+	if (big_rec_vec) {
+		ut_ad(page_is_leaf(page));
+		ut_ad(dict_index_is_clust(index));
+		ut_ad(flags & BTR_KEEP_POS_FLAG);
+
+		/* btr_page_split_and_insert() in
+		btr_cur_pessimistic_insert() invokes
+		mtr_memo_release(mtr, index->lock, MTR_MEMO_X_LOCK).
+		We must keep the index->lock when we created a
+		big_rec, so that row_upd_clust_rec() can store the
+		big_rec in the same mini-transaction. */
+
+		mtr_x_lock(dict_index_get_lock(index), mtr);
+	}
+
 	/* Was the record to be updated positioned as the first user
 	record on its page? */
 	was_first = page_cur_is_before_first(page_cursor);
@@ -2440,6 +2467,7 @@ make_external:
 	ut_a(rec);
 	ut_a(err == DB_SUCCESS);
 	ut_a(dummy_big_rec == NULL);
+	page_cursor->rec = rec;
 
 	if (dict_index_is_sec_or_ibuf(index)) {
 		/* Update PAGE_MAX_TRX_ID in the index page header.
@@ -2498,6 +2526,39 @@ return_after_reservations:
 	return(err);
 }
 
+/**************************************************************//**
+Commits and restarts a mini-transaction so that it will retain an
+x-lock on index->lock and the cursor page. */
+UNIV_INTERN
+void
+btr_cur_mtr_commit_and_start(
+/*=========================*/
+	btr_cur_t*	cursor,	/*!< in: cursor */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+{
+	buf_block_t*	block;
+
+	block = btr_cur_get_block(cursor);
+
+	ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(cursor->index),
+				MTR_MEMO_X_LOCK));
+	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+	/* Keep the locks across the mtr_commit(mtr). */
+	rw_lock_x_lock(dict_index_get_lock(cursor->index));
+	rw_lock_x_lock(&block->lock);
+	mutex_enter(&block->mutex);
+	buf_block_buf_fix_inc(block, __FILE__, __LINE__);
+	mutex_exit(&block->mutex);
+	/* Write out the redo log. */
+	mtr_commit(mtr);
+	mtr_start(mtr);
+	/* Reassociate the locks with the mini-transaction.
+	They will be released on mtr_commit(mtr). */
+	mtr_memo_push(mtr, dict_index_get_lock(cursor->index),
+		      MTR_MEMO_X_LOCK);
+	mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
+}
+
 /*==================== B-TREE DELETE MARK AND UNMARK ===============*/
 
 /****************************************************************//**
@@ -2878,10 +2939,12 @@ UNIV_INTERN
 ibool
 btr_cur_compress_if_useful(
 /*=======================*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to compress;
-				cursor does not stay valid if compression
-				occurs */
-	mtr_t*		mtr)	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to compress;
+				cursor does not stay valid if !adjust and
+				compression occurs */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 {
 	ut_ad(mtr_memo_contains(mtr,
 				dict_index_get_lock(btr_cur_get_index(cursor)),
@@ -2890,7 +2953,7 @@ btr_cur_compress_if_useful(
 				MTR_MEMO_PAGE_X_FIX));
 
 	return(btr_cur_compress_recommendation(cursor, mtr)
-	       && btr_compress(cursor, mtr));
+	       && btr_compress(cursor, adjust, mtr));
 }
 
 /*******************************************************//**
@@ -3132,7 +3195,7 @@ return_after_reservations:
 	mem_heap_free(heap);
 
 	if (ret == FALSE) {
-		ret = btr_cur_compress_if_useful(cursor, mtr);
+		ret = btr_cur_compress_if_useful(cursor, FALSE, mtr);
 	}
 
 	if (n_extents > 0) {
@@ -4092,7 +4155,7 @@ btr_blob_free(
 	    && buf_block_get_space(block) == space
 	    && buf_block_get_page_no(block) == page_no) {
 
-		if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
+		if (!buf_LRU_free_block(&block->page, all)
 		    && all && block->page.zip.data) {
 			/* Attempt to deallocate the uncompressed page
 			if the whole block cannot be deallocted. */

=== modified file 'storage/innobase/buf/buf0buddy.c'
--- a/storage/innobase/buf/buf0buddy.c	2011-01-25 08:51:13 +0000
+++ b/storage/innobase/buf/buf0buddy.c	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 2006, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 2006, 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
@@ -56,6 +56,14 @@ buf_buddy_get(
 	}
 }
 
+/** Validate a given zip_free list. */
+#define BUF_BUDDY_LIST_VALIDATE(b, i)				\
+	UT_LIST_VALIDATE(list, buf_page_t,			\
+			 b->zip_free[i],			\
+			 ut_ad(buf_page_get_state(		\
+				       ut_list_node_313)	\
+			       == BUF_BLOCK_ZIP_FREE))
+
 /**********************************************************************//**
 Add a block to the head of the appropriate buddy free list. */
 UNIV_INLINE
@@ -67,21 +75,11 @@ buf_buddy_add_to_free(
 	ulint		i)		/*!< in: index of
 					buf_pool->zip_free[] */
 {
-#ifdef UNIV_DEBUG_VALGRIND
-	buf_page_t*	b  = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
-
-	if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
-#endif /* UNIV_DEBUG_VALGRIND */
-
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
 	ut_ad(buf_pool->zip_free[i].start != bpage);
 	UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
 
-#ifdef UNIV_DEBUG_VALGRIND
-	if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
-	UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
-#endif /* UNIV_DEBUG_VALGRIND */
 }
 
 /**********************************************************************//**
@@ -95,25 +93,18 @@ buf_buddy_remove_from_free(
 	ulint		i)		/*!< in: index of
 					buf_pool->zip_free[] */
 {
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef UNIV_DEBUG
 	buf_page_t*	prev = UT_LIST_GET_PREV(list, bpage);
 	buf_page_t*	next = UT_LIST_GET_NEXT(list, bpage);
 
-	if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
-	if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
-
 	ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
 	ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* UNIV_DEBUG */
 
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
 	UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
 
-#ifdef UNIV_DEBUG_VALGRIND
-	if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
-	if (next) UNIV_MEM_FREE(next, BUF_BUDDY_LOW << i);
-#endif /* UNIV_DEBUG_VALGRIND */
 }
 
 /**********************************************************************//**
@@ -130,17 +121,13 @@ buf_buddy_alloc_zip(
 
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_a(i < BUF_BUDDY_SIZES);
+	ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
+
+	ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
 
-#ifndef UNIV_DEBUG_VALGRIND
-	/* Valgrind would complain about accessing free memory. */
-	ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-			      ut_ad(buf_page_get_state(ut_list_node_313)
-				    == BUF_BLOCK_ZIP_FREE)));
-#endif /* !UNIV_DEBUG_VALGRIND */
 	bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
 
 	if (bpage) {
-		UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
 		ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
 
 		buf_buddy_remove_from_free(buf_pool, bpage, i);
@@ -159,13 +146,10 @@ buf_buddy_alloc_zip(
 		}
 	}
 
-#ifdef UNIV_DEBUG
 	if (bpage) {
-		memset(bpage, ~i, BUF_BUDDY_LOW << i);
+		ut_d(memset(bpage, ~i, BUF_BUDDY_LOW << i));
+		UNIV_MEM_ALLOC(bpage, BUF_BUDDY_SIZES << i);
 	}
-#endif /* UNIV_DEBUG */
-
-	UNIV_MEM_ALLOC(bpage, BUF_BUDDY_SIZES << i);
 
 	return(bpage);
 }
@@ -253,6 +237,7 @@ buf_buddy_alloc_from(
 {
 	ulint	offs	= BUF_BUDDY_LOW << j;
 	ut_ad(j <= BUF_BUDDY_SIZES);
+	ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
 	ut_ad(j >= i);
 	ut_ad(!ut_align_offset(buf, offs));
 
@@ -266,13 +251,7 @@ buf_buddy_alloc_from(
 		bpage = (buf_page_t*) ((byte*) buf + offs);
 		ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
 		bpage->state = BUF_BLOCK_ZIP_FREE;
-#ifndef UNIV_DEBUG_VALGRIND
-		/* Valgrind would complain about accessing free memory. */
-		ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-				      ut_ad(buf_page_get_state(
-						    ut_list_node_313)
-					    == BUF_BLOCK_ZIP_FREE)));
-#endif /* !UNIV_DEBUG_VALGRIND */
+		ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
 		buf_buddy_add_to_free(buf_pool, bpage, j);
 	}
 
@@ -282,8 +261,8 @@ buf_buddy_alloc_from(
 /**********************************************************************//**
 Allocate a block.  The thread calling this function must hold
 buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex.
-The buf_pool->mutex may only be released and reacquired if lru != NULL.
-@return	allocated block, possibly NULL if lru==NULL */
+The buf_pool_mutex may be released and reacquired.
+@return        allocated block, never NULL */
 UNIV_INTERN
 void*
 buf_buddy_alloc_low(
@@ -295,13 +274,14 @@ buf_buddy_alloc_low(
 					will be assigned TRUE if storage was
 					allocated from the LRU list and
 					buf_pool->mutex was temporarily
-					released, or NULL if the LRU list
-					should not be used */
+					released, */
 {
 	buf_block_t*	block;
 
+	ut_ad(lru);
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(!mutex_own(&buf_pool->zip_mutex));
+	ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
 
 	if (i < BUF_BUDDY_SIZES) {
 		/* Try to allocate from the buddy system. */
@@ -320,11 +300,6 @@ buf_buddy_alloc_low(
 		goto alloc_big;
 	}
 
-	if (!lru) {
-
-		return(NULL);
-	}
-
 	/* Try replacing an uncompressed page in the buffer pool. */
 	buf_pool_mutex_exit(buf_pool);
 	block = buf_LRU_get_free_block(buf_pool);
@@ -343,63 +318,6 @@ func_exit:
 }
 
 /**********************************************************************//**
-Try to relocate the control block of a compressed page.
-@return	TRUE if relocated */
-static
-ibool
-buf_buddy_relocate_block(
-/*=====================*/
-	buf_page_t*	bpage,	/*!< in: block to relocate */
-	buf_page_t*	dpage)	/*!< in: free block to relocate to */
-{
-	buf_page_t*	b;
-	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
-
-	ut_ad(buf_pool_mutex_own(buf_pool));
-
-	switch (buf_page_get_state(bpage)) {
-	case BUF_BLOCK_ZIP_FREE:
-	case BUF_BLOCK_NOT_USED:
-	case BUF_BLOCK_READY_FOR_USE:
-	case BUF_BLOCK_FILE_PAGE:
-	case BUF_BLOCK_MEMORY:
-	case BUF_BLOCK_REMOVE_HASH:
-		ut_error;
-	case BUF_BLOCK_ZIP_DIRTY:
-		/* Cannot relocate dirty pages. */
-		return(FALSE);
-
-	case BUF_BLOCK_ZIP_PAGE:
-		break;
-	}
-
-	mutex_enter(&buf_pool->zip_mutex);
-
-	if (!buf_page_can_relocate(bpage)) {
-		mutex_exit(&buf_pool->zip_mutex);
-		return(FALSE);
-	}
-
-	buf_relocate(bpage, dpage);
-	ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
-
-	/* relocate buf_pool->zip_clean */
-	b = UT_LIST_GET_PREV(list, dpage);
-	UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
-
-	if (b) {
-		UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
-	} else {
-		UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
-	}
-
-	UNIV_MEM_INVALID(bpage, sizeof *bpage);
-
-	mutex_exit(&buf_pool->zip_mutex);
-	return(TRUE);
-}
-
-/**********************************************************************//**
 Try to relocate a block.
 @return	TRUE if relocated */
 static
@@ -415,108 +333,91 @@ buf_buddy_relocate(
 	buf_page_t*	bpage;
 	const ulint	size	= BUF_BUDDY_LOW << i;
 	ullint		usec	= ut_time_us(NULL);
+	mutex_t*	mutex;
+	ulint		space;
+	ulint		page_no;
 
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(!mutex_own(&buf_pool->zip_mutex));
 	ut_ad(!ut_align_offset(src, size));
 	ut_ad(!ut_align_offset(dst, size));
+	ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
 	UNIV_MEM_ASSERT_W(dst, size);
 
 	/* We assume that all memory from buf_buddy_alloc()
-	is used for either compressed pages or buf_page_t
-	objects covering compressed pages. */
+	is used for compressed page frames. */
 
 	/* We look inside the allocated objects returned by
-	buf_buddy_alloc() and assume that anything of
-	PAGE_ZIP_MIN_SIZE or larger is a compressed page that contains
-	a valid space_id and page_no in the page header.  Should the
-	fields be invalid, we will be unable to relocate the block.
-	We also assume that anything that fits sizeof(buf_page_t)
-	actually is a properly initialized buf_page_t object. */
-
-	if (size >= PAGE_ZIP_MIN_SIZE) {
-		/* This is a compressed page. */
-		mutex_t*	mutex;
-
-		/* The src block may be split into smaller blocks,
-		some of which may be free.  Thus, the
-		mach_read_from_4() calls below may attempt to read
-		from free memory.  The memory is "owned" by the buddy
-		allocator (and it has been allocated from the buffer
-		pool), so there is nothing wrong about this.  The
-		mach_read_from_4() calls here will only trigger bogus
-		Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
-		ulint		space	= mach_read_from_4(
-			(const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
-		ulint		page_no	= mach_read_from_4(
-			(const byte*) src + FIL_PAGE_OFFSET);
-		/* Suppress Valgrind warnings about conditional jump
-		on uninitialized value. */
-		UNIV_MEM_VALID(&space, sizeof space);
-		UNIV_MEM_VALID(&page_no, sizeof page_no);
-		bpage = buf_page_hash_get(buf_pool, space, page_no);
-
-		if (!bpage || bpage->zip.data != src) {
-			/* The block has probably been freshly
-			allocated by buf_LRU_get_free_block() but not
-			added to buf_pool->page_hash yet.  Obviously,
-			it cannot be relocated. */
+	buf_buddy_alloc() and assume that each block is a compressed
+	page that contains a valid space_id and page_no in the page
+	header. Should the fields be invalid, we will be unable to
+	relocate the block. */
+
+
+	/* The src block may be split into smaller blocks,
+	some of which may be free.  Thus, the
+	mach_read_from_4() calls below may attempt to read
+	from free memory.  The memory is "owned" by the buddy
+	allocator (and it has been allocated from the buffer
+	pool), so there is nothing wrong about this.  The
+	mach_read_from_4() calls here will only trigger bogus
+	Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
+	space	= mach_read_from_4((const byte*) src +
+			FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+	page_no	= mach_read_from_4((const byte*) src +
+			FIL_PAGE_OFFSET);
+	/* Suppress Valgrind warnings about conditional jump
+	on uninitialized value. */
+	UNIV_MEM_VALID(&space, sizeof space);
+	UNIV_MEM_VALID(&page_no, sizeof page_no);
+	bpage = buf_page_hash_get(buf_pool, space, page_no);
+
+	if (!bpage || bpage->zip.data != src) {
+		/* The block has probably been freshly
+		allocated by buf_LRU_get_free_block() but not
+		added to buf_pool->page_hash yet.  Obviously,
+		it cannot be relocated. */
 
-			return(FALSE);
-		}
-
-		ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
+		return(FALSE);
+	}
 
-		if (page_zip_get_size(&bpage->zip) != size) {
-			/* The block is of different size.  We would
-			have to relocate all blocks covered by src.
-			For the sake of simplicity, give up. */
-			ut_ad(page_zip_get_size(&bpage->zip) < size);
+	ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
 
-			return(FALSE);
-		}
+	if (page_zip_get_size(&bpage->zip) != size) {
+		/* The block is of different size.  We would
+		have to relocate all blocks covered by src.
+		For the sake of simplicity, give up. */
+		ut_ad(page_zip_get_size(&bpage->zip) < size);
 
-		/* The block must have been allocated, but it may
-		contain uninitialized data. */
-		UNIV_MEM_ASSERT_W(src, size);
-
-		mutex = buf_page_get_mutex(bpage);
-
-		mutex_enter(mutex);
-
-		if (buf_page_can_relocate(bpage)) {
-			/* Relocate the compressed page. */
-			ut_a(bpage->zip.data == src);
-			memcpy(dst, src, size);
-			bpage->zip.data = dst;
-			mutex_exit(mutex);
-success:
-			UNIV_MEM_INVALID(src, size);
-			{
-				buf_buddy_stat_t*	buddy_stat
-					= &buf_pool->buddy_stat[i];
-				buddy_stat->relocated++;
-				buddy_stat->relocated_usec
-					+= ut_time_us(NULL) - usec;
-			}
-			return(TRUE);
-		}
+		return(FALSE);
+	}
 
+	/* The block must have been allocated, but it may
+	contain uninitialized data. */
+	UNIV_MEM_ASSERT_W(src, size);
+
+	mutex = buf_page_get_mutex(bpage);
+
+	mutex_enter(mutex);
+
+	if (buf_page_can_relocate(bpage)) {
+		/* Relocate the compressed page. */
+		ut_a(bpage->zip.data == src);
+		memcpy(dst, src, size);
+		bpage->zip.data = dst;
 		mutex_exit(mutex);
-	} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
-		/* This must be a buf_page_t object. */
-#if UNIV_WORD_SIZE == 4
-		/* On 32-bit systems, there is no padding in
-		buf_page_t.  On other systems, Valgrind could complain
-		about uninitialized pad bytes. */
-		UNIV_MEM_ASSERT_RW(src, size);
-#endif
-		if (buf_buddy_relocate_block(src, dst)) {
-
-			goto success;
+		UNIV_MEM_INVALID(src, size);
+		{
+			buf_buddy_stat_t*	buddy_stat
+				= &buf_pool->buddy_stat[i];
+			buddy_stat->relocated++;
+			buddy_stat->relocated_usec
+				+= ut_time_us(NULL) - usec;
 		}
+		return(TRUE);
 	}
 
+	mutex_exit(mutex);
 	return(FALSE);
 }
 
@@ -538,12 +439,13 @@ buf_buddy_free_low(
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(!mutex_own(&buf_pool->zip_mutex));
 	ut_ad(i <= BUF_BUDDY_SIZES);
+	ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
 	ut_ad(buf_pool->buddy_stat[i].used > 0);
 
 	buf_pool->buddy_stat[i].used--;
 recombine:
 	UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i);
-	ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
+	((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
 
 	if (i == BUF_BUDDY_SIZES) {
 		buf_buddy_block_free(buf_pool, buf);
@@ -554,32 +456,36 @@ recombine:
 	ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i));
 	ut_ad(!buf_pool_contains_zip(buf_pool, buf));
 
-	/* Try to combine adjacent blocks. */
-
-	buddy = (buf_page_t*) buf_buddy_get(((byte*) buf), BUF_BUDDY_LOW << i);
-
-#ifndef UNIV_DEBUG_VALGRIND
-	/* Valgrind would complain about accessing free memory. */
-
-	if (buddy->state != BUF_BLOCK_ZIP_FREE) {
-
-		goto buddy_nonfree;
+	/* Do not recombine blocks if there are few free blocks.
+	We may waste up to 15360*max_len bytes to free blocks
+	(1024 + 2048 + 4096 + 8192 = 15360) */
+	if (UT_LIST_GET_LEN(buf_pool->zip_free[i]) < 16) {
+		goto func_exit;
 	}
-
-	/* The field buddy->state can only be trusted for free blocks.
-	If buddy->state == BUF_BLOCK_ZIP_FREE, the block is free if
-	it is in the free list. */
+ 
+	/* Try to combine adjacent blocks. */
+ 	buddy = (buf_page_t*) buf_buddy_get(((byte*) buf), BUF_BUDDY_LOW << i);
+ 
+ #ifndef UNIV_DEBUG_VALGRIND
+	/* When Valgrind instrumentation is not enabled, we can read
+	buddy->state to quickly determine that a block is not free.
+	When the block is not free, buddy->state belongs to a compressed
+	page frame that may be flagged uninitialized in our Valgrind
+	instrumentation.  */
+ 
+ 	if (buddy->state != BUF_BLOCK_ZIP_FREE) {
+ 
+ 		goto buddy_nonfree;
+ 	}
 #endif /* !UNIV_DEBUG_VALGRIND */
 
 	for (bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]); bpage; ) {
-		UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
 		ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
 
 		if (bpage == buddy) {
-buddy_free:
 			/* The buddy is free: recombine */
 			buf_buddy_remove_from_free(buf_pool, bpage, i);
-buddy_free2:
+buddy_is_free:
 			ut_ad(buf_page_get_state(buddy) == BUF_BLOCK_ZIP_FREE);
 			ut_ad(!buf_pool_contains_zip(buf_pool, buddy));
 			i++;
@@ -589,21 +495,15 @@ buddy_free2:
 		}
 
 		ut_a(bpage != buf);
-
-		{
-			buf_page_t*	next = UT_LIST_GET_NEXT(list, bpage);
-			UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
-			bpage = next;
-		}
+		UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
+		bpage = UT_LIST_GET_NEXT(list, bpage);
 	}
 
 #ifndef UNIV_DEBUG_VALGRIND
 buddy_nonfree:
-	/* Valgrind would complain about accessing free memory. */
-	ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-			      ut_ad(buf_page_get_state(ut_list_node_313)
-				    == BUF_BLOCK_ZIP_FREE)));
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* !UNIV_DEBUG_VALGRIND */
+
+	 ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
 
 	/* The buddy is not free. Is there a free block of this size? */
 	bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
@@ -611,100 +511,25 @@ buddy_nonfree:
 	if (bpage) {
 		/* Remove the block from the free list, because a successful
 		buf_buddy_relocate() will overwrite bpage->list. */
-
-		UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
 		buf_buddy_remove_from_free(buf_pool, bpage, i);
 
 		/* Try to relocate the buddy of buf to the free block. */
 		if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
 
-			ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
-			goto buddy_free2;
+			buddy->state = BUF_BLOCK_ZIP_FREE;
+			goto buddy_is_free;
 		}
 
 		buf_buddy_add_to_free(buf_pool, bpage, i);
-
-		/* Try to relocate the buddy of the free block to buf. */
-		buddy = (buf_page_t*) buf_buddy_get(((byte*) bpage),
-						    BUF_BUDDY_LOW << i);
-
-#ifndef UNIV_DEBUG_VALGRIND
-		/* Valgrind would complain about accessing free memory. */
-
-		/* The buddy must not be (completely) free, because we
-		always recombine adjacent free blocks.
-
-		(Parts of the buddy can be free in
-		buf_pool->zip_free[j] with j < i.) */
-		ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
-				      ut_ad(buf_page_get_state(
-						    ut_list_node_313)
-					    == BUF_BLOCK_ZIP_FREE
-					    && ut_list_node_313 != buddy)));
-#endif /* !UNIV_DEBUG_VALGRIND */
-
-		if (buf_buddy_relocate(buf_pool, buddy, buf, i)) {
-
-			buf = bpage;
-			UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
-			ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
-			goto buddy_free;
-		}
 	}
 
+func_exit:
 	/* Free the block to the buddy list. */
 	bpage = buf;
-#ifdef UNIV_DEBUG
-	if (i < buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE)) {
-		/* This area has most likely been allocated for at
-		least one compressed-only block descriptor.  Check
-		that there are no live objects in the area.  This is
-		not a complete check: it may yield false positives as
-		well as false negatives.  Also, due to buddy blocks
-		being recombined, it is possible (although unlikely)
-		that this branch is never reached. */
-
-		char* c;
-
-# ifndef UNIV_DEBUG_VALGRIND
-		/* Valgrind would complain about accessing
-		uninitialized memory.  Besides, Valgrind performs a
-		more exhaustive check, at every memory access. */
-		const buf_page_t* b = buf;
-		const buf_page_t* const b_end = (buf_page_t*)
-			((char*) b + (BUF_BUDDY_LOW << i));
-
-		for (; b < b_end; b++) {
-			/* Avoid false positives (and cause false
-			negatives) by checking for b->space < 1000. */
-
-			if ((b->state == BUF_BLOCK_ZIP_PAGE
-			     || b->state == BUF_BLOCK_ZIP_DIRTY)
-			    && b->space > 0 && b->space < 1000) {
-				fprintf(stderr,
-					"buddy dirty %p %u (%u,%u) %p,%lu\n",
-					(void*) b,
-					b->state, b->space, b->offset,
-					buf, i);
-			}
-		}
-# endif /* !UNIV_DEBUG_VALGRIND */
 
-		/* Scramble the block.  This should make any pointers
-		invalid and trigger a segmentation violation.  Because
-		the scrambling can be reversed, it may be possible to
-		track down the object pointing to the freed data by
-		dereferencing the unscrambled bpage->LRU or
-		bpage->list pointers. */
-		for (c = (char*) buf + (BUF_BUDDY_LOW << i);
-		     c-- > (char*) buf; ) {
-			*c = ~*c ^ i;
-		}
-	} else {
-		/* Fill large blocks with a constant pattern. */
-		memset(bpage, i, BUF_BUDDY_LOW << i);
-	}
-#endif /* UNIV_DEBUG */
+	/* Fill large blocks with a constant pattern. */
+	ut_d(memset(bpage, i, BUF_BUDDY_LOW << i));
+	UNIV_MEM_INVALID(bpage, BUF_BUDDY_LOW << i);
 	bpage->state = BUF_BLOCK_ZIP_FREE;
 	buf_buddy_add_to_free(buf_pool, bpage, i);
 }

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2011-05-24 08:41:31 +0000
+++ b/storage/innobase/buf/buf0buf.c	2011-06-20 04:37:36 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -1099,70 +1099,6 @@ buf_chunk_not_freed(
 	return(NULL);
 }
 
-/*********************************************************************//**
-Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state.
-@return	TRUE if all freed */
-static
-ibool
-buf_chunk_all_free(
-/*===============*/
-	const buf_chunk_t*	chunk)	/*!< in: chunk being checked */
-{
-	const buf_block_t*	block;
-	ulint			i;
-
-	block = chunk->blocks;
-
-	for (i = chunk->size; i--; block++) {
-
-		if (buf_block_get_state(block) != BUF_BLOCK_NOT_USED) {
-
-			return(FALSE);
-		}
-	}
-
-	return(TRUE);
-}
-
-/********************************************************************//**
-Frees a chunk of buffer frames. */
-static
-void
-buf_chunk_free(
-/*===========*/
-	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
-	buf_chunk_t*	chunk)		/*!< out: chunk of buffers */
-{
-	buf_block_t*		block;
-	const buf_block_t*	block_end;
-
-	ut_ad(buf_pool_mutex_own(buf_pool));
-
-	block_end = chunk->blocks + chunk->size;
-
-	for (block = chunk->blocks; block < block_end; block++) {
-		ut_a(buf_block_get_state(block) == BUF_BLOCK_NOT_USED);
-		ut_a(!block->page.zip.data);
-
-		ut_ad(!block->page.in_LRU_list);
-		ut_ad(!block->in_unzip_LRU_list);
-		ut_ad(!block->page.in_flush_list);
-		/* Remove the block from the free list. */
-		ut_ad(block->page.in_free_list);
-		UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
-
-		/* Free the latches. */
-		mutex_free(&block->mutex);
-		rw_lock_free(&block->lock);
-#ifdef UNIV_SYNC_DEBUG
-		rw_lock_free(&block->debug_latch);
-#endif /* UNIV_SYNC_DEBUG */
-		UNIV_MEM_UNDESC(block);
-	}
-
-	os_mem_free_large(chunk->mem, chunk->mem_size);
-}
-
 /********************************************************************//**
 Set buffer pool size variables after resizing it */
 static
@@ -1272,8 +1208,6 @@ buf_pool_free_instance(
 	chunk = chunks + buf_pool->n_chunks;
 
 	while (--chunk >= chunks) {
-		/* Bypass the checks of buf_chunk_free(), since they
-		would fail at shutdown. */
 		os_mem_free_large(chunk->mem, chunk->mem_size);
 	}
 
@@ -1533,281 +1467,6 @@ buf_relocate(
 }
 
 /********************************************************************//**
-Shrinks a buffer pool instance. */
-static
-void
-buf_pool_shrink_instance(
-/*=====================*/
-	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
-	ulint		chunk_size)	/*!< in: number of pages to remove */
-{
-	buf_chunk_t*	chunks;
-	buf_chunk_t*	chunk;
-	ulint		max_size;
-	ulint		max_free_size;
-	buf_chunk_t*	max_chunk;
-	buf_chunk_t*	max_free_chunk;
-
-	ut_ad(!buf_pool_mutex_own(buf_pool));
-
-try_again:
-	btr_search_disable(); /* Empty the adaptive hash index again */
-	buf_pool_mutex_enter(buf_pool);
-
-shrink_again:
-	if (buf_pool->n_chunks <= 1) {
-
-		/* Cannot shrink if there is only one chunk */
-		goto func_done;
-	}
-
-	/* Search for the largest free chunk
-	not larger than the size difference */
-	chunks = buf_pool->chunks;
-	chunk = chunks + buf_pool->n_chunks;
-	max_size = max_free_size = 0;
-	max_chunk = max_free_chunk = NULL;
-
-	while (--chunk >= chunks) {
-		if (chunk->size <= chunk_size
-		    && chunk->size > max_free_size) {
-			if (chunk->size > max_size) {
-				max_size = chunk->size;
-				max_chunk = chunk;
-			}
-
-			if (buf_chunk_all_free(chunk)) {
-				max_free_size = chunk->size;
-				max_free_chunk = chunk;
-			}
-		}
-	}
-
-	if (!max_free_size) {
-
-		ulint		dirty	= 0;
-		ulint		nonfree	= 0;
-		buf_block_t*	block;
-		buf_block_t*	bend;
-
-		/* Cannot shrink: try again later
-		(do not assign srv_buf_pool_old_size) */
-		if (!max_chunk) {
-
-			goto func_exit;
-		}
-
-		block = max_chunk->blocks;
-		bend = block + max_chunk->size;
-
-		/* Move the blocks of chunk to the end of the
-		LRU list and try to flush them. */
-		for (; block < bend; block++) {
-			switch (buf_block_get_state(block)) {
-			case BUF_BLOCK_NOT_USED:
-				continue;
-			case BUF_BLOCK_FILE_PAGE:
-				break;
-			default:
-				nonfree++;
-				continue;
-			}
-
-			mutex_enter(&block->mutex);
-			/* The following calls will temporarily
-			release block->mutex and buf_pool->mutex.
-			Therefore, we have to always retry,
-			even if !dirty && !nonfree. */
-
-			if (!buf_flush_ready_for_replace(&block->page)) {
-
-				buf_LRU_make_block_old(&block->page);
-				dirty++;
-			} else if (buf_LRU_free_block(&block->page, TRUE)
-				   != BUF_LRU_FREED) {
-				nonfree++;
-			}
-
-			mutex_exit(&block->mutex);
-		}
-
-		buf_pool_mutex_exit(buf_pool);
-
-		/* Request for a flush of the chunk if it helps.
-		Do not flush if there are non-free blocks, since
-		flushing will not make the chunk freeable. */
-		if (nonfree) {
-			/* Avoid busy-waiting. */
-			os_thread_sleep(100000);
-		} else if (dirty
-			   && buf_flush_LRU(buf_pool, dirty)
-			      == ULINT_UNDEFINED) {
-
-			buf_flush_wait_batch_end(buf_pool, BUF_FLUSH_LRU);
-		}
-
-		goto try_again;
-	}
-
-	max_size = max_free_size;
-	max_chunk = max_free_chunk;
-
-	buf_pool->old_pool_size = buf_pool->curr_pool_size;
-
-	/* Rewrite buf_pool->chunks.  Copy everything but max_chunk. */
-	chunks = mem_alloc((buf_pool->n_chunks - 1) * sizeof *chunks);
-	memcpy(chunks, buf_pool->chunks,
-	       (max_chunk - buf_pool->chunks) * sizeof *chunks);
-	memcpy(chunks + (max_chunk - buf_pool->chunks),
-	       max_chunk + 1,
-	       buf_pool->chunks + buf_pool->n_chunks
-	       - (max_chunk + 1));
-	ut_a(buf_pool->curr_size > max_chunk->size);
-	buf_pool->curr_size -= max_chunk->size;
-	buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
-	chunk_size -= max_chunk->size;
-	buf_chunk_free(buf_pool, max_chunk);
-	mem_free(buf_pool->chunks);
-	buf_pool->chunks = chunks;
-	buf_pool->n_chunks--;
-
-	/* Allow a slack of one megabyte. */
-	if (chunk_size > 1048576 / UNIV_PAGE_SIZE) {
-
-		goto shrink_again;
-	}
-	goto func_exit;
-
-func_done:
-	buf_pool->old_pool_size = buf_pool->curr_pool_size;
-func_exit:
-	buf_pool_mutex_exit(buf_pool);
-	btr_search_enable();
-}
-
-/********************************************************************//**
-Shrinks the buffer pool. */
-static
-void
-buf_pool_shrink(
-/*============*/
-	ulint	chunk_size)	/*!< in: number of pages to remove */
-{
-	ulint	i;
-
-	for (i = 0; i < srv_buf_pool_instances; i++) {
-		buf_pool_t*	buf_pool;
-		ulint		instance_chunk_size;
-
-		instance_chunk_size = chunk_size / srv_buf_pool_instances;
-		buf_pool = buf_pool_from_array(i);
-		buf_pool_shrink_instance(buf_pool, instance_chunk_size);
-	}
-
-	buf_pool_set_sizes();
-}
-
-/********************************************************************//**
-Rebuild buf_pool->page_hash for a buffer pool instance. */
-static
-void
-buf_pool_page_hash_rebuild_instance(
-/*================================*/
-	buf_pool_t*	buf_pool)		/*!< in: buffer pool instance */
-{
-	ulint		i;
-	buf_page_t*	b;
-	buf_chunk_t*	chunk;
-	ulint		n_chunks;
-	hash_table_t*	zip_hash;
-	hash_table_t*	page_hash;
-
-	buf_pool_mutex_enter(buf_pool);
-
-	/* Free, create, and populate the hash table. */
-	hash_table_free(buf_pool->page_hash);
-	buf_pool->page_hash = page_hash = hash_create(2 * buf_pool->curr_size);
-	zip_hash = hash_create(2 * buf_pool->curr_size);
-
-	HASH_MIGRATE(buf_pool->zip_hash, zip_hash, buf_page_t, hash,
-		     BUF_POOL_ZIP_FOLD_BPAGE);
-
-	hash_table_free(buf_pool->zip_hash);
-	buf_pool->zip_hash = zip_hash;
-
-	/* Insert the uncompressed file pages to buf_pool->page_hash. */
-
-	chunk = buf_pool->chunks;
-	n_chunks = buf_pool->n_chunks;
-
-	for (i = 0; i < n_chunks; i++, chunk++) {
-		ulint		j;
-		buf_block_t*	block = chunk->blocks;
-
-		for (j = 0; j < chunk->size; j++, block++) {
-			if (buf_block_get_state(block)
-			    == BUF_BLOCK_FILE_PAGE) {
-				ut_ad(!block->page.in_zip_hash);
-				ut_ad(block->page.in_page_hash);
-
-				HASH_INSERT(buf_page_t, hash, page_hash,
-					    buf_page_address_fold(
-						    block->page.space,
-						    block->page.offset),
-					    &block->page);
-			}
-		}
-	}
-
-	/* Insert the compressed-only pages to buf_pool->page_hash.
-	All such blocks are either in buf_pool->zip_clean or
-	in buf_pool->flush_list. */
-
-	for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
-	     b = UT_LIST_GET_NEXT(list, b)) {
-		ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
-		ut_ad(!b->in_flush_list);
-		ut_ad(b->in_LRU_list);
-		ut_ad(b->in_page_hash);
-		ut_ad(!b->in_zip_hash);
-
-		HASH_INSERT(buf_page_t, hash, page_hash,
-			    buf_page_address_fold(b->space, b->offset), b);
-	}
-
-	buf_flush_list_mutex_enter(buf_pool);
-	for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
-	     b = UT_LIST_GET_NEXT(list, b)) {
-		ut_ad(b->in_flush_list);
-		ut_ad(b->in_LRU_list);
-		ut_ad(b->in_page_hash);
-		ut_ad(!b->in_zip_hash);
-
-		switch (buf_page_get_state(b)) {
-		case BUF_BLOCK_ZIP_DIRTY:
-			HASH_INSERT(buf_page_t, hash, page_hash,
-				    buf_page_address_fold(b->space,
-							  b->offset), b);
-			break;
-		case BUF_BLOCK_FILE_PAGE:
-			/* uncompressed page */
-			break;
-		case BUF_BLOCK_ZIP_FREE:
-		case BUF_BLOCK_ZIP_PAGE:
-		case BUF_BLOCK_NOT_USED:
-		case BUF_BLOCK_READY_FOR_USE:
-		case BUF_BLOCK_MEMORY:
-		case BUF_BLOCK_REMOVE_HASH:
-			ut_error;
-			break;
-		}
-	}
-
-	buf_flush_list_mutex_exit(buf_pool);
-	buf_pool_mutex_exit(buf_pool);
-}
-
-/********************************************************************
 Determine if a block is a sentinel for a buffer pool watch.
 @return	TRUE if a sentinel for a buffer pool watch, FALSE if not */
 UNIV_INTERN
@@ -1913,123 +1572,6 @@ buf_pool_watch_set(
 	return(NULL);
 }
 
-/********************************************************************//**
-Rebuild buf_pool->page_hash. */
-static
-void
-buf_pool_page_hash_rebuild(void)
-/*============================*/
-{
-	ulint   i;
-
-	for (i = 0; i < srv_buf_pool_instances; i++) {
-		buf_pool_page_hash_rebuild_instance(buf_pool_from_array(i));
-	}
-}
-
-/********************************************************************//**
-Increase the buffer pool size of one buffer pool instance. */
-static
-void
-buf_pool_increase_instance(
-/*=======================*/
-	buf_pool_t*	buf_pool,	/*!< in: buffer pool instane */
-	ulint		change_size)	/*!< in: new size of the pool */
-{
-	buf_chunk_t*	chunks;
-	buf_chunk_t*	chunk;
-
-	buf_pool_mutex_enter(buf_pool);
-	chunks = mem_alloc((buf_pool->n_chunks + 1) * sizeof *chunks);
-
-	memcpy(chunks, buf_pool->chunks, buf_pool->n_chunks * sizeof *chunks);
-
-	chunk = &chunks[buf_pool->n_chunks];
-
-	if (!buf_chunk_init(buf_pool, chunk, change_size)) {
-		mem_free(chunks);
-	} else {
-		buf_pool->old_pool_size = buf_pool->curr_pool_size;
-		buf_pool->curr_size += chunk->size;
-		buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
-		mem_free(buf_pool->chunks);
-		buf_pool->chunks = chunks;
-		buf_pool->n_chunks++;
-	}
-
-	buf_pool_mutex_exit(buf_pool);
-}
-
-/********************************************************************//**
-Increase the buffer pool size. */
-static
-void
-buf_pool_increase(
-/*==============*/
-	ulint   change_size)
-{
-	ulint   i;
-
-	for (i = 0; i < srv_buf_pool_instances; i++) {
-		buf_pool_increase_instance(
-			buf_pool_from_array(i),
-			change_size / srv_buf_pool_instances);
-	}
-
-	buf_pool_set_sizes();
-}
-
-/********************************************************************//**
-Resizes the buffer pool. */
-UNIV_INTERN
-void
-buf_pool_resize(void)
-/*=================*/
-{
-	ulint	change_size;
-	ulint	min_change_size = 1048576 * srv_buf_pool_instances;
-
-	buf_pool_mutex_enter_all();
-
-  	if (srv_buf_pool_old_size == srv_buf_pool_size) {
-
-		buf_pool_mutex_exit_all();
-
-  		return;
-
-  	} else if (srv_buf_pool_curr_size + min_change_size
-		   > srv_buf_pool_size) {
-
-		change_size = (srv_buf_pool_curr_size - srv_buf_pool_size)
-			    / UNIV_PAGE_SIZE;
-
-		buf_pool_mutex_exit_all();
-
-  		/* Disable adaptive hash indexes and empty the index
-  		in order to free up memory in the buffer pool chunks. */
-		buf_pool_shrink(change_size);
-
-	} else if (srv_buf_pool_curr_size + min_change_size
-		   < srv_buf_pool_size) {
-
-  		/* Enlarge the buffer pool by at least one megabyte */
-
-		change_size = srv_buf_pool_size - srv_buf_pool_curr_size;
-
-		buf_pool_mutex_exit_all();
-
-		buf_pool_increase(change_size);
-	} else {
-		srv_buf_pool_size = srv_buf_pool_old_size;
-
-		buf_pool_mutex_exit_all();
-
-		return;
-	}
-
-  	buf_pool_page_hash_rebuild();
-}
-
 /****************************************************************//**
 Remove the sentinel block for the watch before replacing it with a real block.
 buf_page_watch_clear() or buf_page_watch_occurred() will notice that
@@ -2365,7 +1907,7 @@ err_exit:
 		mutex_enter(block_mutex);
 
 		/* Discard the uncompressed page frame if possible. */
-		if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
+		if (buf_LRU_free_block(bpage, FALSE)) {
 
 			mutex_exit(block_mutex);
 			goto lookup;
@@ -2768,12 +2310,8 @@ loop:
 
 	if (block) {
 		/* If the guess is a compressed page descriptor that
-		has been allocated by buf_buddy_alloc(), it may have
-		been invalidated by buf_buddy_relocate().  In that
-		case, block could point to something that happens to
-		contain the expected bits in block->page.  Similarly,
-		the guess may be pointing to a buffer pool chunk that
-		has been released when resizing the buffer pool. */
+		has been allocated by buf_page_alloc_descriptor(),
+		it may have been freed by buf_relocate(). */
 
 		if (!buf_block_is_uncompressed(buf_pool, block)
 		    || offset != block->page.offset
@@ -2951,8 +2489,10 @@ wait_until_unfixed:
 
 		if (buf_page_get_state(&block->page)
 		    == BUF_BLOCK_ZIP_PAGE) {
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 			UT_LIST_REMOVE(list, buf_pool->zip_clean,
 				       &block->page);
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 			ut_ad(!block->page.in_flush_list);
 		} else {
 			/* Relocate buf_pool->flush_list. */
@@ -2978,11 +2518,10 @@ wait_until_unfixed:
 		mutex_exit(&buf_pool->zip_mutex);
 		buf_pool->n_pend_unzip++;
 
-		bpage->state = BUF_BLOCK_ZIP_FREE;
-		buf_buddy_free(buf_pool, bpage, sizeof *bpage);
-
 		buf_pool_mutex_exit(buf_pool);
 
+		buf_page_free_descriptor(bpage);
+
 		/* Decompress the page and apply buffered operations
 		while not holding buf_pool->mutex or block->mutex. */
 		success = buf_zip_decompress(block, srv_use_checksums);
@@ -3028,7 +2567,7 @@ wait_until_unfixed:
 		/* Try to evict the block from the buffer pool, to use the
 		insert buffer (change buffer) as much as possible. */
 
-		if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
+		if (buf_LRU_free_block(&block->page, TRUE)) {
 			mutex_exit(&block->mutex);
 			if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
 				/* Set the watch, as it would have
@@ -3687,20 +3226,11 @@ err_exit:
 
 		mutex_exit(&block->mutex);
 	} else {
-		/* Defer buf_buddy_alloc() until after the block has
-		been found not to exist.  The buf_buddy_alloc() and
-		buf_buddy_free() calls may be expensive because of
-		buf_buddy_relocate(). */
-
 		/* The compressed page must be allocated before the
 		control block (bpage), in order to avoid the
 		invocation of buf_buddy_relocate_block() on
 		uninitialized data. */
 		data = buf_buddy_alloc(buf_pool, zip_size, &lru);
-		bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru);
-
-		/* Initialize the buf_pool pointer. */
-		bpage->buf_pool_index = buf_pool_index(buf_pool);
 
 		/* If buf_buddy_alloc() allocated storage from the LRU list,
 		it released and reacquired buf_pool->mutex.  Thus, we must
@@ -3716,8 +3246,6 @@ err_exit:
 
 				/* The block was added by some other thread. */
 				watch_page = NULL;
-				bpage->state = BUF_BLOCK_ZIP_FREE;
-				buf_buddy_free(buf_pool, bpage, sizeof *bpage);
 				buf_buddy_free(buf_pool, data, zip_size);
 
 				bpage = NULL;
@@ -3725,6 +3253,11 @@ err_exit:
 			}
 		}
 
+		bpage = buf_page_alloc_descriptor();
+
+		/* Initialize the buf_pool pointer. */
+		bpage->buf_pool_index = buf_pool_index(buf_pool);
+
 		page_zip_des_init(&bpage->zip);
 		page_zip_set_size(&bpage->zip, zip_size);
 		bpage->zip.data = data;
@@ -3764,7 +3297,9 @@ err_exit:
 
 		/* The block must be put to the LRU list, to the old blocks */
 		buf_LRU_add_block(bpage, TRUE/* to old blocks */);
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 		buf_LRU_insert_zip_clean(bpage);
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 
 		buf_page_set_io_fix(bpage, BUF_IO_READ);
 

=== modified file 'storage/innobase/buf/buf0flu.c'
--- a/storage/innobase/buf/buf0flu.c	2011-04-05 07:18:43 +0000
+++ b/storage/innobase/buf/buf0flu.c	2011-06-16 12:13:24 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 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
@@ -524,7 +524,9 @@ buf_flush_remove(
 	case BUF_BLOCK_ZIP_DIRTY:
 		buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
 		UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 		buf_LRU_insert_zip_clean(bpage);
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 		break;
 	case BUF_BLOCK_FILE_PAGE:
 		UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);

=== modified file 'storage/innobase/buf/buf0lru.c'
--- a/storage/innobase/buf/buf0lru.c	2011-02-28 13:39:07 +0000
+++ b/storage/innobase/buf/buf0lru.c	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 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
@@ -353,31 +353,34 @@ scan_again:
 
 	while (bpage != NULL) {
 		buf_page_t*	prev_bpage;
-		ibool		prev_bpage_buf_fix = FALSE;
+		mutex_t*	block_mutex = NULL;
 
 		ut_a(buf_page_in_file(bpage));
 
 		prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
 
 		/* bpage->space and bpage->io_fix are protected by
-		buf_pool->mutex and block_mutex.  It is safe to check
-		them while holding buf_pool->mutex only. */
+		buf_pool_mutex and block_mutex.  It is safe to check
+		them while holding buf_pool_mutex only. */
 
 		if (buf_page_get_space(bpage) != id) {
 			/* Skip this block, as it does not belong to
 			the space that is being invalidated. */
+			goto next_page;
 		} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
 			/* We cannot remove this page during this scan
 			yet; maybe the system is currently reading it
 			in, or flushing the modifications to the file */
 
 			all_freed = FALSE;
+			goto next_page;
 		} else {
-			mutex_t* block_mutex = buf_page_get_mutex(bpage);
+			block_mutex = buf_page_get_mutex(bpage);
 			mutex_enter(block_mutex);
 
 			if (bpage->buf_fix_count > 0) {
 
+				mutex_exit(block_mutex);
 				/* We cannot remove this page during
 				this scan yet; maybe the system is
 				currently reading it in, or flushing
@@ -387,106 +390,59 @@ scan_again:
 
 				goto next_page;
 			}
+		}
+
+		ut_ad(mutex_own(block_mutex));
 
 #ifdef UNIV_DEBUG
-			if (buf_debug_prints) {
-				fprintf(stderr,
-					"Dropping space %lu page %lu\n",
-					(ulong) buf_page_get_space(bpage),
-					(ulong) buf_page_get_page_no(bpage));
-			}
+		if (buf_debug_prints) {
+			fprintf(stderr,
+				"Dropping space %lu page %lu\n",
+				(ulong) buf_page_get_space(bpage),
+				(ulong) buf_page_get_page_no(bpage));
+		}
 #endif
-			if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
-				/* This is a compressed-only block
-				descriptor.  Ensure that prev_bpage
-				cannot be relocated when bpage is freed. */
-				if (UNIV_LIKELY(prev_bpage != NULL)) {
-					switch (buf_page_get_state(
-							prev_bpage)) {
-					case BUF_BLOCK_FILE_PAGE:
-						/* Descriptors of uncompressed
-						blocks will not be relocated,
-						because we are holding the
-						buf_pool->mutex. */
-						break;
-					case BUF_BLOCK_ZIP_PAGE:
-					case BUF_BLOCK_ZIP_DIRTY:
-						/* Descriptors of compressed-
-						only blocks can be relocated,
-						unless they are buffer-fixed.
-						Because both bpage and
-						prev_bpage are protected by
-						buf_pool_zip_mutex, it is
-						not necessary to acquire
-						further mutexes. */
-						ut_ad(&buf_pool->zip_mutex
-						      == block_mutex);
-						ut_ad(mutex_own(block_mutex));
-						prev_bpage_buf_fix = TRUE;
-						prev_bpage->buf_fix_count++;
-						break;
-					default:
-						ut_error;
-					}
-				}
-			} else if (((buf_block_t*) bpage)->is_hashed) {
-				ulint	page_no;
-				ulint	zip_size;
-
-				buf_pool_mutex_exit(buf_pool);
+		if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
+			/* This is a compressed-only block
+			descriptor. Do nothing. */
+		} else if (((buf_block_t*) bpage)->is_hashed) {
+			ulint	page_no;
+			ulint	zip_size;
 
-				zip_size = buf_page_get_zip_size(bpage);
-				page_no = buf_page_get_page_no(bpage);
+			buf_pool_mutex_exit(buf_pool);
 
-				mutex_exit(block_mutex);
+			zip_size = buf_page_get_zip_size(bpage);
+			page_no = buf_page_get_page_no(bpage);
 
-				/* Note that the following call will acquire
-				an S-latch on the page */
+			mutex_exit(block_mutex);
 
-				btr_search_drop_page_hash_when_freed(
-					id, zip_size, page_no);
-				goto scan_again;
-			}
+			/* Note that the following call will acquire
+			an S-latch on the page */
 
-			if (bpage->oldest_modification != 0) {
+			btr_search_drop_page_hash_when_freed(
+				id, zip_size, page_no);
+			goto scan_again;
+		}
 
-				buf_flush_remove(bpage);
-			}
+		if (bpage->oldest_modification != 0) {
 
-			/* Remove from the LRU list. */
+			buf_flush_remove(bpage);
+		}
 
-			if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
-			    != BUF_BLOCK_ZIP_FREE) {
-				buf_LRU_block_free_hashed_page((buf_block_t*)
-							       bpage);
-			} else {
-				/* The block_mutex should have been
-				released by buf_LRU_block_remove_hashed_page()
-				when it returns BUF_BLOCK_ZIP_FREE. */
-				ut_ad(block_mutex == &buf_pool->zip_mutex);
-				ut_ad(!mutex_own(block_mutex));
-
-				if (prev_bpage_buf_fix) {
-					/* We temporarily buffer-fixed
-					prev_bpage, so that
-					buf_buddy_free() could not
-					relocate it, in case it was a
-					compressed-only block
-					descriptor. */
-
-					mutex_enter(block_mutex);
-					ut_ad(prev_bpage->buf_fix_count > 0);
-					prev_bpage->buf_fix_count--;
-					mutex_exit(block_mutex);
-				}
+		/* Remove from the LRU list. */
 
-				goto next_page_no_mutex;
-			}
-next_page:
+		if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
+		    != BUF_BLOCK_ZIP_FREE) {
+			buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
 			mutex_exit(block_mutex);
+		} else {
+			/* The block_mutex should have been released
+			by buf_LRU_block_remove_hashed_page() when it
+			returns BUF_BLOCK_ZIP_FREE. */
+			ut_ad(block_mutex == &buf_pool->zip_mutex);
+			ut_ad(!mutex_own(block_mutex));
 		}
-
-next_page_no_mutex:
+next_page:
 		bpage = prev_bpage;
 	}
 
@@ -525,6 +481,7 @@ buf_LRU_invalidate_tablespace(
 	}
 }
 
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 /********************************************************************//**
 Insert a compressed block into buf_pool->zip_clean in the LRU order. */
 UNIV_INTERN
@@ -557,6 +514,7 @@ buf_LRU_insert_zip_clean(
 		UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
 	}
 }
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 
 /******************************************************************//**
 Try to free an uncompressed page of a compressed block from the unzip
@@ -600,7 +558,7 @@ buf_LRU_free_from_unzip_LRU_list(
 	     UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
 	     block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
 
-		enum buf_lru_free_block_status	freed;
+		ibool freed;
 
 		ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
 		ut_ad(block->in_unzip_LRU_list);
@@ -610,24 +568,9 @@ buf_LRU_free_from_unzip_LRU_list(
 		freed = buf_LRU_free_block(&block->page, FALSE);
 		mutex_exit(&block->mutex);
 
-		switch (freed) {
-		case BUF_LRU_FREED:
+		if (freed) {
 			return(TRUE);
-
-		case BUF_LRU_CANNOT_RELOCATE:
-			/* If we failed to relocate, try
-			regular LRU eviction. */
-			return(FALSE);
-
-		case BUF_LRU_NOT_FREED:
-			/* The block was buffer-fixed or I/O-fixed.
-			Keep looking. */
-			continue;
 		}
-
-		/* inappropriate return value from
-		buf_LRU_free_block() */
-		ut_error;
 	}
 
 	return(FALSE);
@@ -660,10 +603,9 @@ buf_LRU_free_from_common_LRU_list(
 	     UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
 	     bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
 
-		enum buf_lru_free_block_status	freed;
-		unsigned			accessed;
-		mutex_t*			block_mutex
-			= buf_page_get_mutex(bpage);
+		ibool		freed;
+		unsigned	accessed;
+		mutex_t*	block_mutex = buf_page_get_mutex(bpage);
 
 		ut_ad(buf_page_in_file(bpage));
 		ut_ad(bpage->in_LRU_list);
@@ -673,8 +615,7 @@ buf_LRU_free_from_common_LRU_list(
 		freed = buf_LRU_free_block(bpage, TRUE);
 		mutex_exit(block_mutex);
 
-		switch (freed) {
-		case BUF_LRU_FREED:
+		if (freed) {
 			/* Keep track of pages that are evicted without
 			ever being accessed. This gives us a measure of
 			the effectiveness of readahead */
@@ -682,21 +623,7 @@ buf_LRU_free_from_common_LRU_list(
 				++buf_pool->stat.n_ra_pages_evicted;
 			}
 			return(TRUE);
-
-		case BUF_LRU_NOT_FREED:
-			/* The block was dirty, buffer-fixed, or I/O-fixed.
-			Keep looking. */
-			continue;
-
-		case BUF_LRU_CANNOT_RELOCATE:
-			/* This should never occur, because we
-			want to discard the compressed page too. */
-			break;
 		}
-
-		/* inappropriate return value from
-		buf_LRU_free_block() */
-		ut_error;
 	}
 
 	return(FALSE);
@@ -1422,17 +1349,16 @@ buf_LRU_make_block_old(
 Try to free a block.  If bpage is a descriptor of a compressed-only
 page, the descriptor object will be freed as well.
 
-NOTE: If this function returns BUF_LRU_FREED, it will temporarily
+NOTE: If this function returns TRUE, it will temporarily
 release buf_pool->mutex.  Furthermore, the page frame will no longer be
 accessible via bpage.
 
 The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
 release these two mutexes after the call.  No other
 buf_page_get_mutex() may be held when calling this function.
-@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
-BUF_LRU_NOT_FREED otherwise. */
+@return TRUE if freed, FALSE otherwise. */
 UNIV_INTERN
-enum buf_lru_free_block_status
+ibool
 buf_LRU_free_block(
 /*===============*/
 	buf_page_t*	bpage,	/*!< in: block to be freed */
@@ -1458,7 +1384,7 @@ buf_LRU_free_block(
 	if (!buf_page_can_relocate(bpage)) {
 
 		/* Do not free buffer-fixed or I/O-fixed blocks. */
-		return(BUF_LRU_NOT_FREED);
+		return(FALSE);
 	}
 
 #ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1470,7 +1396,7 @@ buf_LRU_free_block(
 		/* Do not completely free dirty blocks. */
 
 		if (bpage->oldest_modification) {
-			return(BUF_LRU_NOT_FREED);
+			return(FALSE);
 		}
 	} else if (bpage->oldest_modification) {
 		/* Do not completely free dirty blocks. */
@@ -1478,7 +1404,7 @@ buf_LRU_free_block(
 		if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
 			ut_ad(buf_page_get_state(bpage)
 			      == BUF_BLOCK_ZIP_DIRTY);
-			return(BUF_LRU_NOT_FREED);
+			return(FALSE);
 		}
 
 		goto alloc;
@@ -1487,14 +1413,8 @@ buf_LRU_free_block(
 		If it cannot be allocated (without freeing a block
 		from the LRU list), refuse to free bpage. */
 alloc:
-		buf_pool_mutex_exit_forbid(buf_pool);
-		b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
-		buf_pool_mutex_exit_allow(buf_pool);
-
-		if (UNIV_UNLIKELY(!b)) {
-			return(BUF_LRU_CANNOT_RELOCATE);
-		}
-
+		b = buf_page_alloc_descriptor();
+		ut_a(b);
 		memcpy(b, bpage, sizeof *b);
 	}
 
@@ -1598,7 +1518,9 @@ alloc:
 			}
 
 			if (b->state == BUF_BLOCK_ZIP_PAGE) {
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 				buf_LRU_insert_zip_clean(b);
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 			} else {
 				/* Relocate on buf_pool->flush_list. */
 				buf_flush_relocate_on_flush_list(bpage, b);
@@ -1665,7 +1587,7 @@ alloc:
 		mutex_enter(block_mutex);
 	}
 
-	return(BUF_LRU_FREED);
+	return(TRUE);
 }
 
 /******************************************************************//**
@@ -1884,7 +1806,9 @@ buf_LRU_block_remove_hashed_page(
 		ut_a(bpage->zip.data);
 		ut_a(buf_page_get_zip_size(bpage));
 
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 		UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 
 		mutex_exit(&buf_pool->zip_mutex);
 		buf_pool_mutex_exit_forbid(buf_pool);
@@ -1893,11 +1817,9 @@ buf_LRU_block_remove_hashed_page(
 			buf_pool, bpage->zip.data,
 			page_zip_get_size(&bpage->zip));
 
-		bpage->state = BUF_BLOCK_ZIP_FREE;
-		buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
 		buf_pool_mutex_exit_allow(buf_pool);
+		buf_page_free_descriptor(bpage);
 
-		UNIV_MEM_UNDESC(bpage);
 		return(BUF_BLOCK_ZIP_FREE);
 
 	case BUF_BLOCK_FILE_PAGE:

=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/include/btr0btr.h	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, 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
@@ -481,11 +481,14 @@ UNIV_INTERN
 ibool
 btr_compress(
 /*=========*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to merge or lift;
-				the page must not be empty: in record delete
-				use btr_discard_page if the page would become
-				empty */
-	mtr_t*		mtr);	/*!< in: mtr */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to merge
+				or lift; the page must not be empty:
+				when deleting records, use btr_discard_page()
+				if the page would become empty */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /*************************************************************//**
 Discards a page from a B-tree. This is used to remove the last record from
 a B-tree page: the whole page must be removed at the same time. This cannot

=== modified file 'storage/innobase/include/btr0cur.h'
--- a/storage/innobase/include/btr0cur.h	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/include/btr0cur.h	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, 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
@@ -36,6 +36,9 @@ Created 10/16/1994 Heikki Tuuri
 #define BTR_NO_LOCKING_FLAG	2	/* do no record lock checking */
 #define BTR_KEEP_SYS_FLAG	4	/* sys fields will be found from the
 					update vector or inserted entry */
+#define BTR_KEEP_POS_FLAG	8	/* btr_cur_pessimistic_update()
+					must keep cursor position when
+					moving columns to big_rec */
 
 #ifndef UNIV_HOTBACKUP
 #include "que0types.h"
@@ -310,7 +313,9 @@ btr_cur_pessimistic_update(
 /*=======================*/
 	ulint		flags,	/*!< in: undo logging, locking, and rollback
 				flags */
-	btr_cur_t*	cursor,	/*!< in: cursor on the record to update */
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the record to update;
+				cursor may become invalid if *big_rec == NULL
+				|| !(flags & BTR_KEEP_POS_FLAG) */
 	mem_heap_t**	heap,	/*!< in/out: pointer to memory heap, or NULL */
 	big_rec_t**	big_rec,/*!< out: big rec vector whose fields have to
 				be stored externally by the caller, or NULL */
@@ -322,6 +327,16 @@ btr_cur_pessimistic_update(
 	que_thr_t*	thr,	/*!< in: query thread */
 	mtr_t*		mtr);	/*!< in: mtr; must be committed before
 				latching any further pages */
+/*****************************************************************
+Commits and restarts a mini-transaction so that it will retain an
+x-lock on index->lock and the cursor page. */
+UNIV_INTERN
+void
+btr_cur_mtr_commit_and_start(
+/*=========================*/
+	btr_cur_t*	cursor,	/*!< in: cursor */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	UNIV_COLD __attribute__((nonnull));
 /***********************************************************//**
 Marks a clustered index record deleted. Writes an undo log record to
 undo log on this delete marking. Writes in the trx id field the id
@@ -364,10 +379,13 @@ UNIV_INTERN
 ibool
 btr_cur_compress_if_useful(
 /*=======================*/
-	btr_cur_t*	cursor,	/*!< in: cursor on the page to compress;
+	btr_cur_t*	cursor,	/*!< in/out: cursor on the page to compress;
 				cursor does not stay valid if compression
 				occurs */
-	mtr_t*		mtr);	/*!< in: mtr */
+	ibool		adjust,	/*!< in: TRUE if should adjust the
+				cursor position even if compression occurs */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /*******************************************************//**
 Removes the record on which the tree cursor is positioned. It is assumed
 that the mtr has an x-latch on the page where the cursor is positioned,

=== modified file 'storage/innobase/include/btr0cur.ic'
--- a/storage/innobase/include/btr0cur.ic	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/btr0cur.ic	2011-06-16 09:07:49 +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
@@ -139,7 +139,7 @@ btr_cur_compress_recommendation(
 	btr_cur_t*	cursor,	/*!< in: btr cursor */
 	mtr_t*		mtr)	/*!< in: mtr */
 {
-	page_t*		page;
+	const page_t*		page;
 
 	ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
 				MTR_MEMO_PAGE_X_FIX));

=== modified file 'storage/innobase/include/buf0buddy.h'
--- a/storage/innobase/include/buf0buddy.h	2010-10-20 11:46:28 +0000
+++ b/storage/innobase/include/buf0buddy.h	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2006, 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
@@ -37,25 +37,24 @@ Created December 2006 by Marko Makela
 /**********************************************************************//**
 Allocate a block.  The thread calling this function must hold
 buf_pool->mutex and must not hold buf_pool->zip_mutex or any
-block->mutex.  The buf_pool->mutex may only be released and reacquired
-if lru != NULL.  This function should only be used for allocating
-compressed page frames or control blocks (buf_page_t).  Allocated
-control blocks must be properly initialized immediately after
-buf_buddy_alloc() has returned the memory, before releasing
-buf_pool->mutex.
-@return	allocated block, possibly NULL if lru == NULL */
+block->mutex.  The buf_pool_mutex may be released and reacquired.
+This function should only be used for allocating compressed page frames.
+@return	allocated block, never NULL */
 UNIV_INLINE
 void*
 buf_buddy_alloc(
 /*============*/
-	buf_pool_t*	buf_pool,
-			/*!< buffer pool in which the block resides */
-	ulint	size,	/*!< in: block size, up to UNIV_PAGE_SIZE */
-	ibool*	lru)	/*!< in: pointer to a variable that will be assigned
-			TRUE if storage was allocated from the LRU list
-			and buf_pool->mutex was temporarily released,
-			or NULL if the LRU list should not be used */
-	__attribute__((malloc));
+	buf_pool_t*	buf_pool,	/*!< in: buffer pool in which
+					the page resides */
+	ulint		size,		/*!< in: compressed page size
+					(between PAGE_ZIP_MIN_SIZE and
+					UNIV_PAGE_SIZE) */
+	ibool*		lru)		/*!< in: pointer to a variable
+					that will be assigned TRUE if
+				       	storage was allocated from the
+				       	LRU list and buf_pool->mutex was
+				       	temporarily released */
+	__attribute__((malloc, nonnull));
 
 /**********************************************************************//**
 Release a block. */

=== modified file 'storage/innobase/include/buf0buddy.ic'
--- a/storage/innobase/include/buf0buddy.ic	2010-10-20 11:46:28 +0000
+++ b/storage/innobase/include/buf0buddy.ic	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2006, 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
@@ -36,8 +36,8 @@ Created December 2006 by Marko Makela
 /**********************************************************************//**
 Allocate a block.  The thread calling this function must hold
 buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex.
-The buf_pool->mutex may only be released and reacquired if lru != NULL.
-@return	allocated block, possibly NULL if lru==NULL */
+The buf_pool_mutex may be released and reacquired.
+@return	allocated block, never NULL */
 UNIV_INTERN
 void*
 buf_buddy_alloc_low(
@@ -48,9 +48,8 @@ buf_buddy_alloc_low(
 			or BUF_BUDDY_SIZES */
 	ibool*	lru)	/*!< in: pointer to a variable that will be assigned
 			TRUE if storage was allocated from the LRU list
-			and buf_pool->mutex was temporarily released,
-			or NULL if the LRU list should not be used */
-	__attribute__((malloc));
+			and buf_pool_mutex was temporarily released */
+	__attribute__((malloc, nonnull));
 
 /**********************************************************************//**
 Deallocate a block. */
@@ -77,6 +76,8 @@ buf_buddy_get_slot(
 	ulint	i;
 	ulint	s;
 
+	ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+
 	for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1) {
 	}
 
@@ -87,29 +88,28 @@ buf_buddy_get_slot(
 /**********************************************************************//**
 Allocate a block.  The thread calling this function must hold
 buf_pool->mutex and must not hold buf_pool->zip_mutex or any
-block->mutex.  The buf_pool->mutex may only be released and reacquired
-if lru != NULL.  This function should only be used for allocating
-compressed page frames or control blocks (buf_page_t).  Allocated
-control blocks must be properly initialized immediately after
-buf_buddy_alloc() has returned the memory, before releasing
-buf_pool->mutex.
-@return	allocated block, possibly NULL if lru == NULL */
+block->mutex.  The buf_pool_mutex may be released and reacquired.
+This function should only be used for allocating compressed page frames.
+@return	allocated block, never NULL */
 UNIV_INLINE
 void*
 buf_buddy_alloc(
 /*============*/
 	buf_pool_t*	buf_pool,	/*!< in: buffer pool in which
 					the page resides */
-	ulint		size,		/*!< in: block size, up to
-					UNIV_PAGE_SIZE */
+	ulint		size,		/*!< in: compressed page size
+					(between PAGE_ZIP_MIN_SIZE and
+					UNIV_PAGE_SIZE) */
 	ibool*		lru)		/*!< in: pointer to a variable
 					that will be assigned TRUE if
 				       	storage was allocated from the
 				       	LRU list and buf_pool->mutex was
-				       	temporarily released, or NULL if
-				       	the LRU list should not be used */
+				       	temporarily released */
 {
 	ut_ad(buf_pool_mutex_own(buf_pool));
+	ut_ad(ut_is_2pow(size));
+	ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+	ut_ad(size <= UNIV_PAGE_SIZE);
 
 	return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru));
 }
@@ -127,6 +127,9 @@ buf_buddy_free(
 					UNIV_PAGE_SIZE */
 {
 	ut_ad(buf_pool_mutex_own(buf_pool));
+	ut_ad(ut_is_2pow(size));
+	ut_ad(size >= PAGE_ZIP_MIN_SIZE);
+	ut_ad(size <= UNIV_PAGE_SIZE);
 
 	buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
 }

=== modified file 'storage/innobase/include/buf0buf.h'
--- a/storage/innobase/include/buf0buf.h	2011-05-24 08:41:31 +0000
+++ b/storage/innobase/include/buf0buf.h	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 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
@@ -246,12 +246,6 @@ buf_relocate(
 				BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
 	buf_page_t*	dpage)	/*!< in/out: destination control block */
 	__attribute__((nonnull));
-/********************************************************************//**
-Resizes the buffer pool. */
-UNIV_INTERN
-void
-buf_pool_resize(void);
-/*=================*/
 /*********************************************************************//**
 Gets the current size of buffer buf_pool in bytes.
 @return	size in bytes */
@@ -275,6 +269,22 @@ ib_uint64_t
 buf_pool_get_oldest_modification(void);
 /*==================================*/
 /********************************************************************//**
+Allocates a buf_page_t descriptor. This function must succeed. In case
+of failure we assert in this function. */
+UNIV_INLINE
+buf_page_t*
+buf_page_alloc_descriptor(void)
+/*===========================*/
+	__attribute__((malloc));
+/********************************************************************//**
+Free a buf_page_t descriptor. */
+UNIV_INLINE
+void
+buf_page_free_descriptor(
+/*=====================*/
+	buf_page_t*	bpage)	/*!< in: bpage descriptor to free. */
+	__attribute__((nonnull));
+/********************************************************************//**
 Allocates a buffer block.
 @return	own: the allocated block, in state BUF_BLOCK_MEMORY */
 UNIV_INTERN
@@ -582,6 +592,31 @@ buf_block_get_modify_clock(
 #else /* !UNIV_HOTBACKUP */
 # define buf_block_modify_clock_inc(block) ((void) 0)
 #endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Increments the bufferfix count. */
+UNIV_INLINE
+void
+buf_block_buf_fix_inc_func(
+/*=======================*/
+#ifdef UNIV_SYNC_DEBUG
+	const char*	file,	/*!< in: file name */
+	ulint		line,	/*!< in: line */
+#endif /* UNIV_SYNC_DEBUG */
+	buf_block_t*	block)	/*!< in/out: block to bufferfix */
+	__attribute__((nonnull));
+#ifdef UNIV_SYNC_DEBUG
+/** Increments the bufferfix count.
+@param b	in/out: block to bufferfix
+@param f	in: file name where requested
+@param l	in: line number where requested */
+# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
+#else /* UNIV_SYNC_DEBUG */
+/** Increments the bufferfix count.
+@param b	in/out: block to bufferfix
+@param f	in: file name where requested
+@param l	in: line number where requested */
+# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
+#endif /* UNIV_SYNC_DEBUG */
 /********************************************************************//**
 Calculates a page checksum which is stored to the page when it is written
 to a file. Note that we must be careful to calculate the same value
@@ -1196,7 +1231,7 @@ ulint
 buf_get_free_list_len(void);
 /*=======================*/
 
-/********************************************************************
+/********************************************************************//**
 Determine if a block is a sentinel for a buffer pool watch.
 @return	TRUE if a sentinel for a buffer pool watch, FALSE if not */
 UNIV_INTERN
@@ -1732,8 +1767,10 @@ struct buf_pool_struct{
 	frames and buf_page_t descriptors of blocks that exist
 	in the buffer pool only in compressed form. */
 	/* @{ */
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 	UT_LIST_BASE_NODE_T(buf_page_t)	zip_clean;
 					/*!< unmodified compressed pages */
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
 					/*!< buddy free lists */
 

=== modified file 'storage/innobase/include/buf0buf.ic'
--- a/storage/innobase/include/buf0buf.ic	2011-01-25 08:51:13 +0000
+++ b/storage/innobase/include/buf0buf.ic	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -754,6 +754,35 @@ buf_block_get_lock_hash_val(
 }
 
 /********************************************************************//**
+Allocates a buf_page_t descriptor. This function must succeed. In case
+of failure we assert in this function.
+@return: the allocated descriptor. */
+UNIV_INLINE
+buf_page_t*
+buf_page_alloc_descriptor(void)
+/*===========================*/
+{
+	buf_page_t*	bpage;
+
+	bpage = (buf_page_t*) ut_malloc(sizeof *bpage);
+	ut_d(memset(bpage, 0, sizeof *bpage));
+	UNIV_MEM_ALLOC(bpage, sizeof *bpage);
+
+	return(bpage);
+}
+
+/********************************************************************//**
+Free a buf_page_t descriptor. */
+UNIV_INLINE
+void
+buf_page_free_descriptor(
+/*=====================*/
+	buf_page_t*	bpage)	/*!< in: bpage descriptor to free. */
+{
+	ut_free(bpage);
+}
+
+/********************************************************************//**
 Frees a buffer block which does not contain a file page. */
 UNIV_INLINE
 void
@@ -897,19 +926,6 @@ buf_block_buf_fix_inc_func(
 
 	block->page.buf_fix_count++;
 }
-#ifdef UNIV_SYNC_DEBUG
-/** Increments the bufferfix count.
-@param b	in/out: block to bufferfix
-@param f	in: file name where requested
-@param l	in: line number where requested */
-# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
-#else /* UNIV_SYNC_DEBUG */
-/** Increments the bufferfix count.
-@param b	in/out: block to bufferfix
-@param f	in: file name where requested
-@param l	in: line number where requested */
-# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
-#endif /* UNIV_SYNC_DEBUG */
 
 /*******************************************************************//**
 Decrements the bufferfix count. */
@@ -1160,7 +1176,7 @@ buf_block_dbg_add_level(
 				where we have acquired latch */
 	ulint		level)	/*!< in: latching order level */
 {
-	sync_thread_add_level(&block->lock, level);
+	sync_thread_add_level(&block->lock, level, FALSE);
 }
 #endif /* UNIV_SYNC_DEBUG */
 /********************************************************************//**

=== modified file 'storage/innobase/include/buf0lru.h'
--- a/storage/innobase/include/buf0lru.h	2011-01-25 08:51:13 +0000
+++ b/storage/innobase/include/buf0lru.h	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 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
@@ -30,18 +30,6 @@ Created 11/5/1995 Heikki Tuuri
 #include "ut0byte.h"
 #include "buf0types.h"
 
-/** The return type of buf_LRU_free_block() */
-enum buf_lru_free_block_status {
-	/** freed */
-	BUF_LRU_FREED = 0,
-	/** not freed because the caller asked to remove the
-	uncompressed frame but the control block cannot be
-	relocated */
-	BUF_LRU_CANNOT_RELOCATE,
-	/** not freed because of some other reason */
-	BUF_LRU_NOT_FREED
-};
-
 /******************************************************************//**
 Tries to remove LRU flushed blocks from the end of the LRU list and put them
 to the free list. This is beneficial for the efficiency of the insert buffer
@@ -85,6 +73,7 @@ void
 buf_LRU_invalidate_tablespace(
 /*==========================*/
 	ulint	id);	/*!< in: space id */
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 /********************************************************************//**
 Insert a compressed block into buf_pool->zip_clean in the LRU order. */
 UNIV_INTERN
@@ -92,22 +81,22 @@ void
 buf_LRU_insert_zip_clean(
 /*=====================*/
 	buf_page_t*	bpage);	/*!< in: pointer to the block in question */
+#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 
 /******************************************************************//**
 Try to free a block.  If bpage is a descriptor of a compressed-only
 page, the descriptor object will be freed as well.
 
-NOTE: If this function returns BUF_LRU_FREED, it will temporarily
+NOTE: If this function returns TRUE, it will temporarily
 release buf_pool->mutex.  Furthermore, the page frame will no longer be
 accessible via bpage.
 
 The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
 release these two mutexes after the call.  No other
 buf_page_get_mutex() may be held when calling this function.
-@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
-BUF_LRU_NOT_FREED otherwise. */
+@return TRUE if freed, FALSE otherwise. */
 UNIV_INTERN
-enum buf_lru_free_block_status
+ibool
 buf_LRU_free_block(
 /*===============*/
 	buf_page_t*	bpage,	/*!< in: block to be freed */

=== modified file 'storage/innobase/include/buf0types.h'
--- a/storage/innobase/include/buf0types.h	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/buf0types.h	2011-06-17 20:29:19 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 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,8 @@ Created 11/17/1995 Heikki Tuuri
 #ifndef buf0types_h
 #define buf0types_h
 
+#include "page0types.h"
+
 /** Buffer page (uncompressed or compressed) */
 typedef	struct buf_page_struct		buf_page_t;
 /** Buffer block for which an uncompressed page exists */
@@ -60,17 +62,10 @@ enum buf_io_fix {
 
 /** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
 /* @{ */
-#if UNIV_WORD_SIZE <= 4 /* 32-bit system */
-/** Base-2 logarithm of the smallest buddy block size */
-# define BUF_BUDDY_LOW_SHIFT	6
-#else /* 64-bit system */
-/** Base-2 logarithm of the smallest buddy block size */
-# define BUF_BUDDY_LOW_SHIFT	7
-#endif
+#define BUF_BUDDY_LOW_SHIFT	PAGE_ZIP_MIN_SIZE_SHIFT
+
 #define BUF_BUDDY_LOW		(1 << BUF_BUDDY_LOW_SHIFT)
-					/*!< minimum block size in the binary
-					buddy system; must be at least
-					sizeof(buf_page_t) */
+
 #define BUF_BUDDY_SIZES		(UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
 					/*!< number of buddy sizes */
 

=== modified file 'storage/innobase/include/page0cur.ic'
--- a/storage/innobase/include/page0cur.ic	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/page0cur.ic	2011-06-16 09:07:49 +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
@@ -27,6 +27,8 @@ Created 10/4/1994 Heikki Tuuri
 #include "buf0types.h"
 
 #ifdef UNIV_DEBUG
+# include "rem0cmp.h"
+
 /*********************************************************//**
 Gets pointer to the page frame where the cursor is positioned.
 @return	page */
@@ -268,6 +270,7 @@ page_cur_tuple_insert(
 					      index, rec, offsets, mtr);
 	}
 
+	ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, offsets));
 	mem_heap_free(heap);
 	return(rec);
 }

=== modified file 'storage/innobase/include/page0page.h'
--- a/storage/innobase/include/page0page.h	2011-05-09 08:12:26 +0000
+++ b/storage/innobase/include/page0page.h	2011-06-16 09:07:49 +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
@@ -284,16 +284,42 @@ page_get_supremum_offset(
 	const page_t*	page);	/*!< in: page which must have record(s) */
 #define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
 #define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
+
 /************************************************************//**
-Returns the middle record of record list. If there are an even number
-of records in the list, returns the first record of upper half-list.
-@return	middle record */
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
 UNIV_INTERN
+const rec_t*
+page_rec_get_nth_const(
+/*===================*/
+	const page_t*	page,	/*!< in: page */
+	ulint		nth)	/*!< in: nth record */
+	__attribute__((nonnull, warn_unused_result));
+/************************************************************//**
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
+UNIV_INLINE
+rec_t*
+page_rec_get_nth(
+/*=============*/
+	page_t*	page,	/*< in: page */
+	ulint	nth)	/*!< in: nth record */
+	__attribute__((nonnull, warn_unused_result));
+
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Returns the middle record of the records on the page. If there is an
+even number of records in the list, returns the first record of the
+upper half-list.
+@return	middle record */
+UNIV_INLINE
 rec_t*
 page_get_middle_rec(
 /*================*/
-	page_t*	page);	/*!< in: page */
-#ifndef UNIV_HOTBACKUP
+	page_t*	page)	/*!< in: page */
+	__attribute__((nonnull, warn_unused_result));
 /*************************************************************//**
 Compares a data tuple to a physical record. Differs from the function
 cmp_dtuple_rec_with_match in the way that the record must reside on an
@@ -348,6 +374,7 @@ page_get_n_recs(
 /***************************************************************//**
 Returns the number of records before the given record in chain.
 The number includes infimum and supremum records.
+This is the inverse function of page_rec_get_nth().
 @return	number of records */
 UNIV_INTERN
 ulint
@@ -618,6 +645,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 +654,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:12:26 +0000
+++ b/storage/innobase/include/page0page.ic	2011-06-16 09:07:49 +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
@@ -419,7 +419,37 @@ page_rec_is_infimum(
 	return(page_rec_is_infimum_low(page_offset(rec)));
 }
 
+/************************************************************//**
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
+UNIV_INLINE
+rec_t*
+page_rec_get_nth(
+/*=============*/
+	page_t*	page,	/*!< in: page */
+	ulint	nth)	/*!< in: nth record */
+{
+	return((rec_t*) page_rec_get_nth_const(page, nth));
+}
+
 #ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Returns the middle record of the records on the page. If there is an
+even number of records in the list, returns the first record of the
+upper half-list.
+@return	middle record */
+UNIV_INLINE
+rec_t*
+page_get_middle_rec(
+/*================*/
+	page_t*	page)	/*!< in: page */
+{
+	ulint	middle = (page_get_n_recs(page) + PAGE_HEAP_NO_USER_LOW) / 2;
+
+	return(page_rec_get_nth(page, middle));
+}
+
 /*************************************************************//**
 Compares a data tuple to a physical record. Differs from the function
 cmp_dtuple_rec_with_match in the way that the record must reside on an
@@ -959,6 +989,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 +1010,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-21 07:56:38 +0000
+++ b/storage/innobase/include/rem0rec.h	2011-06-16 09:07:49 +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-21 07:56:38 +0000
+++ b/storage/innobase/include/rem0rec.ic	2011-06-16 09:07:49 +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/sync0rw.ic'
--- a/storage/innobase/include/sync0rw.ic	2011-02-15 09:29:56 +0000
+++ b/storage/innobase/include/sync0rw.ic	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -603,16 +603,16 @@ rw_lock_x_unlock_direct(
 
 	ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
 
-#ifdef UNIV_SYNC_DEBUG
-	rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
-#endif
-
 	if (lock->lock_word == 0) {
 		lock->recursive = FALSE;
 		UNIV_MEM_INVALID(&lock->writer_thread,
 				 sizeof lock->writer_thread);
 	}
 
+#ifdef UNIV_SYNC_DEBUG
+	rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
+#endif
+
 	lock->lock_word += X_LOCK_DECR;
 
 	ut_ad(!lock->waiters);

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	2011-04-05 07:18:43 +0000
+++ b/storage/innobase/include/sync0sync.h	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -400,8 +400,10 @@ void
 sync_thread_add_level(
 /*==================*/
 	void*	latch,	/*!< in: pointer to a mutex or an rw-lock */
-	ulint	level);	/*!< in: level in the latching order; if
+	ulint	level,	/*!< in: level in the latching order; if
 			SYNC_LEVEL_VARYING, nothing is done */
+	ibool	relock)	/*!< in: TRUE if re-entering an x-lock */
+	__attribute__((nonnull));
 /******************************************************************//**
 Removes a latch from the thread level array if it is found there.
 @return TRUE if found in the array; it is no error if the latch is

=== modified file 'storage/innobase/include/univ.i'
--- a/storage/innobase/include/univ.i	2011-05-10 12:50:53 +0000
+++ b/storage/innobase/include/univ.i	2011-06-16 09:07:49 +0000
@@ -1,8 +1,7 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
-Copyright (c) 2009, Sun Microsystems, Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
 Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -51,7 +50,7 @@ Created 1/20/1994 Heikki Tuuri
 
 #define INNODB_VERSION_MAJOR	1
 #define INNODB_VERSION_MINOR	1
-#define INNODB_VERSION_BUGFIX	7
+#define INNODB_VERSION_BUGFIX	8
 
 /* The following is the InnoDB version as shown in
 SELECT plugin_version FROM information_schema.plugins;

=== modified file 'storage/innobase/page/page0cur.c'
--- a/storage/innobase/page/page0cur.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/page/page0cur.c	2011-06-16 09:07:49 +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
@@ -1180,14 +1180,15 @@ page_cur_insert_rec_zip_reorg(
 	/* Before trying to reorganize the page,
 	store the number of preceding records on the page. */
 	pos = page_rec_get_n_recs_before(rec);
+	ut_ad(pos > 0);
 
 	if (page_zip_reorganize(block, index, mtr)) {
 		/* The page was reorganized: Find rec by seeking to pos,
 		and update *current_rec. */
-		rec = page + PAGE_NEW_INFIMUM;
-
-		while (--pos) {
-			rec = page + rec_get_next_offs(rec, TRUE);
+		if (pos > 1) {
+			rec = page_rec_get_nth(page, pos - 1);
+		} else {
+			rec = page + PAGE_NEW_INFIMUM;
 		}
 
 		*current_rec = rec;
@@ -1283,6 +1284,12 @@ page_cur_insert_rec_zip(
 			insert_rec = page_cur_insert_rec_zip_reorg(
 				current_rec, block, index, insert_rec,
 				page, page_zip, mtr);
+#ifdef UNIV_DEBUG
+			if (insert_rec) {
+				rec_offs_make_valid(
+					insert_rec, index, offsets);
+			}
+#endif /* UNIV_DEBUG */
 		}
 
 		return(insert_rec);

=== modified file 'storage/innobase/page/page0page.c'
--- a/storage/innobase/page/page0page.c	2011-05-09 08:12:26 +0000
+++ b/storage/innobase/page/page0page.c	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, 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
@@ -1465,55 +1465,54 @@ page_dir_balance_slot(
 	}
 }
 
-#ifndef UNIV_HOTBACKUP
 /************************************************************//**
-Returns the middle record of the record list. If there are an even number
-of records in the list, returns the first record of the upper half-list.
-@return	middle record */
+Returns the nth record of the record list.
+This is the inverse function of page_rec_get_n_recs_before().
+@return	nth record */
 UNIV_INTERN
-rec_t*
-page_get_middle_rec(
-/*================*/
-	page_t*	page)	/*!< in: page */
+const rec_t*
+page_rec_get_nth_const(
+/*===================*/
+	const page_t*	page,	/*!< in: page */
+	ulint		nth)	/*!< in: nth record */
 {
-	page_dir_slot_t*	slot;
-	ulint			middle;
+	const page_dir_slot_t*	slot;
 	ulint			i;
 	ulint			n_owned;
-	ulint			count;
-	rec_t*			rec;
-
-	/* This many records we must leave behind */
-	middle = (page_get_n_recs(page) + PAGE_HEAP_NO_USER_LOW) / 2;
+	const rec_t*		rec;
 
-	count = 0;
+	ut_ad(nth < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
 
 	for (i = 0;; i++) {
 
 		slot = page_dir_get_nth_slot(page, i);
 		n_owned = page_dir_slot_get_n_owned(slot);
 
-		if (count + n_owned > middle) {
+		if (n_owned > nth) {
 			break;
 		} else {
-			count += n_owned;
+			nth -= n_owned;
 		}
 	}
 
 	ut_ad(i > 0);
 	slot = page_dir_get_nth_slot(page, i - 1);
-	rec = (rec_t*) page_dir_slot_get_rec(slot);
-	rec = page_rec_get_next(rec);
+	rec = page_dir_slot_get_rec(slot);
 
-	/* There are now count records behind rec */
-
-	for (i = 0; i < middle - count; i++) {
-		rec = page_rec_get_next(rec);
+	if (page_is_comp(page)) {
+		do {
+			rec = page_rec_get_next_low(rec, TRUE);
+			ut_ad(rec);
+		} while (nth--);
+	} else {
+		do {
+			rec = page_rec_get_next_low(rec, FALSE);
+			ut_ad(rec);
+		} while (nth--);
 	}
 
 	return(rec);
 }
-#endif /* !UNIV_HOTBACKUP */
 
 /***************************************************************//**
 Returns the number of records before the given record in chain.
@@ -1575,6 +1574,7 @@ page_rec_get_n_recs_before(
 	n--;
 
 	ut_ad(n >= 0);
+	ut_ad(n < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
 
 	return((ulint) n);
 }

=== modified file 'storage/innobase/page/page0zip.c'
--- a/storage/innobase/page/page0zip.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/page/page0zip.c	2011-06-16 12:13:24 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2005, 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
@@ -3912,17 +3912,9 @@ page_zip_write_trx_id_and_roll_ptr(
 	UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
 }
 
-#ifdef UNIV_ZIP_DEBUG
-/** Set this variable in a debugger to disable page_zip_clear_rec().
-The only observable effect should be the compression ratio due to
-deleted records not being zeroed out.  In rare cases, there can be
-page_zip_validate() failures on the node_ptr, trx_id and roll_ptr
-columns if the space is reallocated for a smaller record. */
-UNIV_INTERN ibool	page_zip_clear_rec_disable;
-#endif /* UNIV_ZIP_DEBUG */
-
 /**********************************************************************//**
-Clear an area on the uncompressed and compressed page, if possible. */
+Clear an area on the uncompressed and compressed page.
+Do not clear the data payload, as that would grow the modification log. */
 static
 void
 page_zip_clear_rec(
@@ -3934,6 +3926,9 @@ page_zip_clear_rec(
 {
 	ulint	heap_no;
 	page_t*	page	= page_align(rec);
+	byte*	storage;
+	byte*	field;
+	ulint	len;
 	/* page_zip_validate() would fail here if a record
 	containing externally stored columns is being deleted. */
 	ut_ad(rec_offs_validate(rec, index, offsets));
@@ -3949,60 +3944,46 @@ page_zip_clear_rec(
 	UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
 			   rec_offs_extra_size(offsets));
 
-	if (
-#ifdef UNIV_ZIP_DEBUG
-	    !page_zip_clear_rec_disable &&
-#endif /* UNIV_ZIP_DEBUG */
-	    page_zip->m_end
-	    + 1 + ((heap_no - 1) >= 64)/* size of the log entry */
-	    + page_zip_get_trailer_len(page_zip,
-				       dict_index_is_clust(index), NULL)
-	    < page_zip_get_size(page_zip)) {
-		byte*	data;
-
-		/* Clear only the data bytes, because the allocator and
-		the decompressor depend on the extra bytes. */
-		memset(rec, 0, rec_offs_data_size(offsets));
-
-		if (!page_is_leaf(page)) {
-			/* Clear node_ptr on the compressed page. */
-			byte*	storage	= page_zip->data
-				+ page_zip_get_size(page_zip)
-				- (page_dir_get_n_heap(page)
-				   - PAGE_HEAP_NO_USER_LOW)
-				* PAGE_ZIP_DIR_SLOT_SIZE;
-
-			memset(storage - (heap_no - 1) * REC_NODE_PTR_SIZE,
-			       0, REC_NODE_PTR_SIZE);
-		} else if (dict_index_is_clust(index)) {
-			/* Clear trx_id and roll_ptr on the compressed page. */
-			byte*	storage	= page_zip->data
-				+ page_zip_get_size(page_zip)
-				- (page_dir_get_n_heap(page)
-				   - PAGE_HEAP_NO_USER_LOW)
-				* PAGE_ZIP_DIR_SLOT_SIZE;
-
-			memset(storage - (heap_no - 1)
-			       * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
-			       0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
-		}
+	if (!page_is_leaf(page)) {
+		/* Clear node_ptr. On the compressed page,
+		there is an array of node_ptr immediately before the
+		dense page directory, at the very end of the page. */
+		storage	= page_zip->data
+			+ page_zip_get_size(page_zip)
+			- (page_dir_get_n_heap(page)
+			   - PAGE_HEAP_NO_USER_LOW)
+			* PAGE_ZIP_DIR_SLOT_SIZE;
+		ut_ad(dict_index_get_n_unique_in_tree(index) ==
+		      rec_offs_n_fields(offsets) - 1);
+		field	= rec_get_nth_field(rec, offsets,
+					    rec_offs_n_fields(offsets) - 1,
+					    &len);
+		ut_ad(len == REC_NODE_PTR_SIZE);
 
-		/* Log that the data was zeroed out. */
-		data = page_zip->data + page_zip->m_end;
-		ut_ad(!*data);
-		if (UNIV_UNLIKELY(heap_no - 1 >= 64)) {
-			*data++ = (byte) (0x80 | (heap_no - 1) >> 7);
-			ut_ad(!*data);
-		}
-		*data++ = (byte) ((heap_no - 1) << 1 | 1);
-		ut_ad(!*data);
-		ut_ad((ulint) (data - page_zip->data)
-		      < page_zip_get_size(page_zip));
-		page_zip->m_end = data - page_zip->data;
-		page_zip->m_nonempty = TRUE;
-	} else if (page_is_leaf(page) && dict_index_is_clust(index)) {
-		/* Do not clear the record, because there is not enough space
-		to log the operation. */
+		ut_ad(!rec_offs_any_extern(offsets));
+		memset(field, 0, REC_NODE_PTR_SIZE);
+		memset(storage - (heap_no - 1) * REC_NODE_PTR_SIZE,
+		       0, REC_NODE_PTR_SIZE);
+	} else if (dict_index_is_clust(index)) {
+		/* Clear trx_id and roll_ptr. On the compressed page,
+		there is an array of these fields immediately before the
+		dense page directory, at the very end of the page. */
+		const ulint	trx_id_pos
+			= dict_col_get_clust_pos(
+			dict_table_get_sys_col(
+				index->table, DATA_TRX_ID), index);
+		storage	= page_zip->data
+			+ page_zip_get_size(page_zip)
+			- (page_dir_get_n_heap(page)
+			   - PAGE_HEAP_NO_USER_LOW)
+			* PAGE_ZIP_DIR_SLOT_SIZE;
+		field	= rec_get_nth_field(rec, offsets, trx_id_pos, &len);
+		ut_ad(len == DATA_TRX_ID_LEN);
+
+		memset(field, 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
+		memset(storage - (heap_no - 1)
+		       * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
+		       0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
 
 		if (rec_offs_any_extern(offsets)) {
 			ulint	i;
@@ -4011,15 +3992,18 @@ page_zip_clear_rec(
 				/* Clear all BLOB pointers in order to make
 				page_zip_validate() pass. */
 				if (rec_offs_nth_extern(offsets, i)) {
-					ulint	len;
-					byte*	field = rec_get_nth_field(
+					field = rec_get_nth_field(
 						rec, offsets, i, &len);
+					ut_ad(len
+					      == BTR_EXTERN_FIELD_REF_SIZE);
 					memset(field + len
 					       - BTR_EXTERN_FIELD_REF_SIZE,
 					       0, BTR_EXTERN_FIELD_REF_SIZE);
 				}
 			}
 		}
+	} else {
+		ut_ad(!rec_offs_any_extern(offsets));
 	}
 
 #ifdef UNIV_ZIP_DEBUG

=== modified file 'storage/innobase/rem/rem0rec.c'
--- a/storage/innobase/rem/rem0rec.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/rem/rem0rec.c	2011-06-16 12:13:24 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, 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
@@ -408,7 +408,7 @@ rec_init_offsets(
 		do {
 			ulint	len;
 			if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
-				len = offs += 4;
+				len = offs += REC_NODE_PTR_SIZE;
 				goto resolved;
 			}
 
@@ -640,7 +640,7 @@ rec_get_offsets_reverse(
 	do {
 		ulint	len;
 		if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
-			len = offs += 4;
+			len = offs += REC_NODE_PTR_SIZE;
 			goto resolved;
 		}
 
@@ -1131,9 +1131,9 @@ rec_convert_dtuple_to_rec_comp(
 
 		if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
 			ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
-			ut_ad(len == 4);
+			ut_ad(len == REC_NODE_PTR_SIZE);
 			memcpy(end, dfield_get_data(field), len);
-			end += 4;
+			end += REC_NODE_PTR_SIZE;
 			break;
 		}
 

=== modified file 'storage/innobase/row/row0ins.c'
--- a/storage/innobase/row/row0ins.c	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/row/row0ins.c	2011-06-16 09:07:49 +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
@@ -345,9 +345,9 @@ row_ins_clust_index_entry_by_modify(
 			return(DB_LOCK_TABLE_FULL);
 
 		}
-		err = btr_cur_pessimistic_update(0, cursor,
-						 heap, big_rec, update,
-						 0, thr, mtr);
+		err = btr_cur_pessimistic_update(
+			BTR_KEEP_POS_FLAG, cursor, heap, big_rec, update,
+			0, thr, mtr);
 	}
 
 	return(err);
@@ -1973,6 +1973,7 @@ row_ins_index_entry_low(
 	ulint		modify = 0; /* remove warning */
 	rec_t*		insert_rec;
 	rec_t*		rec;
+	ulint*		offsets;
 	ulint		err;
 	ulint		n_unique;
 	big_rec_t*	big_rec			= NULL;
@@ -2081,6 +2082,42 @@ row_ins_index_entry_low(
 			err = row_ins_clust_index_entry_by_modify(
 				mode, &cursor, &heap, &big_rec, entry,
 				thr, &mtr);
+
+			if (big_rec) {
+				ut_a(err == DB_SUCCESS);
+				/* Write out the externally stored
+				columns while still x-latching
+				index->lock and block->lock. We have
+				to mtr_commit(mtr) first, so that the
+				redo log will be written in the
+				correct order. Otherwise, we would run
+				into trouble on crash recovery if mtr
+				freed B-tree pages on which some of
+				the big_rec fields will be written. */
+				btr_cur_mtr_commit_and_start(&cursor, &mtr);
+
+				rec = btr_cur_get_rec(&cursor);
+				offsets = rec_get_offsets(
+					rec, index, NULL,
+					ULINT_UNDEFINED, &heap);
+
+				err = btr_store_big_rec_extern_fields(
+					index, btr_cur_get_block(&cursor),
+					rec, offsets, &mtr, FALSE, big_rec);
+				/* If writing big_rec fails (for
+				example, because of DB_OUT_OF_FILE_SPACE),
+				the record will be corrupted. Even if
+				we did not update any externally
+				stored columns, our update could cause
+				the record to grow so that a
+				non-updated column was selected for
+				external storage. This non-update
+				would not have been written to the
+				undo log, and thus the record cannot
+				be rolled back. */
+				ut_a(err == DB_SUCCESS);
+				goto stored_big_rec;
+			}
 		} else {
 			ut_ad(!n_ext);
 			err = row_ins_sec_index_entry_by_modify(
@@ -2109,8 +2146,6 @@ function_exit:
 	mtr_commit(&mtr);
 
 	if (UNIV_LIKELY_NULL(big_rec)) {
-		rec_t*	rec;
-		ulint*	offsets;
 		mtr_start(&mtr);
 
 		btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
@@ -2124,6 +2159,7 @@ function_exit:
 			index, btr_cur_get_block(&cursor),
 			rec, offsets, &mtr, FALSE, big_rec);
 
+stored_big_rec:
 		if (modify) {
 			dtuple_big_rec_free(big_rec);
 		} else {

=== modified file 'storage/innobase/row/row0row.c'
--- a/storage/innobase/row/row0row.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/row/row0row.c	2011-06-16 09:07:49 +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
@@ -192,6 +192,7 @@ row_build(
 
 	ut_ad(index && rec && heap);
 	ut_ad(dict_index_is_clust(index));
+	ut_ad(!mutex_own(&kernel_mutex));
 
 	if (!offsets) {
 		offsets = rec_get_offsets(rec, index, offsets_,
@@ -200,6 +201,36 @@ row_build(
 		ut_ad(rec_offs_validate(rec, index, offsets));
 	}
 
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+	if (UNIV_LIKELY_NULL(rec_offs_any_null_extern(rec, offsets))) {
+		/* This condition can occur during crash recovery before
+		trx_rollback_active() has completed execution.
+
+		This condition is possible if the server crashed
+		during an insert or update before
+		btr_store_big_rec_extern_fields() did mtr_commit() all
+		BLOB pointers to the clustered index record.
+
+		Look up the transaction that holds the implicit lock
+		on this record, and assert that it was recovered (and
+		will soon be rolled back). */
+
+		ulint		trx_id_pos	= dict_index_get_sys_col_pos(
+				index, DATA_TRX_ID);
+		ulint		len;
+		trx_id_t	trx_id		= trx_read_trx_id(
+			rec_get_nth_field(rec, offsets, trx_id_pos, &len));
+		trx_t*		trx;
+		ut_a(len == 6);
+
+		mutex_enter(&kernel_mutex);
+		trx = trx_get_on_id(trx_id);
+		ut_a(trx);
+		ut_a(trx->is_recovered);
+		mutex_exit(&kernel_mutex);
+	}
+#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 +414,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/row0upd.c'
--- a/storage/innobase/row/row0upd.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/row/row0upd.c	2011-06-16 09:07:49 +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
@@ -1999,28 +1999,43 @@ row_upd_clust_rec(
 	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
 				    dict_table_is_comp(index->table)));
 
-	err = btr_cur_pessimistic_update(BTR_NO_LOCKING_FLAG, btr_cur,
-					 &heap, &big_rec, node->update,
-					 node->cmpl_info, thr, mtr);
-	mtr_commit(mtr);
-
-	if (err == DB_SUCCESS && big_rec) {
+	err = btr_cur_pessimistic_update(
+		BTR_NO_LOCKING_FLAG | BTR_KEEP_POS_FLAG, btr_cur,
+		&heap, &big_rec, node->update, node->cmpl_info, thr, mtr);
+	if (big_rec) {
 		ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 		rec_t*		rec;
 		rec_offs_init(offsets_);
 
-		mtr_start(mtr);
+		ut_a(err == DB_SUCCESS);
+		/* Write out the externally stored columns while still
+		x-latching index->lock and block->lock. We have to
+		mtr_commit(mtr) first, so that the redo log will be
+		written in the correct order. Otherwise, we would run
+		into trouble on crash recovery if mtr freed B-tree
+		pages on which some of the big_rec fields will be
+		written. */
+		btr_cur_mtr_commit_and_start(btr_cur, mtr);
 
-		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
 		rec = btr_cur_get_rec(btr_cur);
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(btr_cur), rec,
 			rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
 			mtr, TRUE, big_rec);
-		mtr_commit(mtr);
+		/* If writing big_rec fails (for example, because of
+		DB_OUT_OF_FILE_SPACE), the record will be corrupted.
+		Even if we did not update any externally stored
+		columns, our update could cause the record to grow so
+		that a non-updated column was selected for external
+		storage. This non-update would not have been written
+		to the undo log, and thus the record cannot be rolled
+		back. */
+		ut_a(err == DB_SUCCESS);
 	}
 
+	mtr_commit(mtr);
+
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}

=== modified file 'storage/innobase/row/row0vers.c'
--- a/storage/innobase/row/row0vers.c	2011-01-25 10:35:35 +0000
+++ b/storage/innobase/row/row0vers.c	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1997, 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
@@ -550,6 +550,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);
@@ -583,6 +588,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)) {
@@ -682,6 +691,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;
@@ -739,6 +752,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/sync/sync0rw.c'
--- a/storage/innobase/sync/sync0rw.c	2011-02-25 11:21:02 +0000
+++ b/storage/innobase/sync/sync0rw.c	2011-06-16 09:07:49 +0000
@@ -782,7 +782,9 @@ rw_lock_add_debug_info(
 	rw_lock_debug_mutex_exit();
 
 	if ((pass == 0) && (lock_type != RW_LOCK_WAIT_EX)) {
-		sync_thread_add_level(lock, lock->level);
+		sync_thread_add_level(lock, lock->level,
+				      lock_type == RW_LOCK_EX
+				      && lock->lock_word < 0);
 	}
 }
 

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	2011-04-05 07:18:43 +0000
+++ b/storage/innobase/sync/sync0sync.c	2011-06-16 09:07:49 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2011, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -690,7 +690,7 @@ mutex_set_debug_info(
 	ut_ad(mutex);
 	ut_ad(file_name);
 
-	sync_thread_add_level(mutex, mutex->level);
+	sync_thread_add_level(mutex, mutex->level, FALSE);
 
 	mutex->file_name = file_name;
 	mutex->line	 = line;
@@ -1133,8 +1133,9 @@ void
 sync_thread_add_level(
 /*==================*/
 	void*	latch,	/*!< in: pointer to a mutex or an rw-lock */
-	ulint	level)	/*!< in: level in the latching order; if
+	ulint	level,	/*!< in: level in the latching order; if
 			SYNC_LEVEL_VARYING, nothing is done */
+	ibool	relock)	/*!< in: TRUE if re-entering an x-lock */
 {
 	ulint		i;
 	sync_level_t*	slot;
@@ -1185,6 +1186,10 @@ sync_thread_add_level(
 
 	array = thread_slot->levels;
 
+	if (relock) {
+		goto levels_ok;
+	}
+
 	/* NOTE that there is a problem with _NODE and _LEAF levels: if the
 	B-tree height changes, then a leaf can change to an internal node
 	or the other way around. We do not know at present if this can cause
@@ -1350,6 +1355,7 @@ sync_thread_add_level(
 		ut_error;
 	}
 
+levels_ok:
 	if (array->next_free == ULINT_UNDEFINED) {
 		ut_a(array->n_elems < array->max_elems);
 

=== modified file 'storage/innobase/trx/trx0rec.c'
--- a/storage/innobase/trx/trx0rec.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/trx/trx0rec.c	2011-06-16 09:07:49 +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
@@ -1593,6 +1593,10 @@ trx_undo_prev_version_build(
 		return(DB_ERROR);
 	}
 
+# 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:07:37 +0000
+++ b/storage/myisam/mi_update.c	2011-06-07 15:44:15 +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:49:43 +0000
+++ b/storage/myisam/mi_write.c	2011-06-07 15:44:15 +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-03-22 11:48:56 +0000
+++ b/tests/mysql_client_test.c	2011-06-10 14:26:35 +0000
@@ -19588,6 +19588,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;
+}
 
 /*
   Read and parse arguments and MySQL options from my.cnf
@@ -19647,10 +19722,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}
 };
@@ -19933,6 +20008,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug57058", test_bug57058 },
   { "test_bug56976", test_bug56976 },
   { "test_bug11766854", test_bug11766854 },
+  { "test_bug12337762", test_bug12337762 },
   { 0, 0 }
 };
 
@@ -20071,29 +20147,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-5.5 branch (chuck.bell:3422) WL#5710Chuck Bell23 Jun