List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:November 9 2011 9:45am
Subject:bzr push into mysql-trunk-mtr branch (bjorn.munch:3134 to 3137)
View as plain text  
 3137 Bjorn Munch	2011-11-09 [merge]
      null upmerge

 3136 Bjorn Munch	2011-11-09 [merge]
      merge trunk => trunk-mtr

    removed:
      mysql-test/suite/binlog/r/binlog_truncate_innodb.result
      mysql-test/suite/binlog/t/binlog_truncate_innodb.test
    added:
      unittest/gunit/filesort_buffer-t.cc
    modified:
      configure.cmake
      include/mysql/psi/mysql_socket.h
      include/mysql/psi/psi.h
      mysql-test/include/join_cache.inc
      mysql-test/r/filesort_debug.result
      mysql-test/r/join_cache_bka.result
      mysql-test/r/join_cache_bka_nixbnl.result
      mysql-test/r/join_cache_bkaunique.result
      mysql-test/r/join_cache_bnl.result
      mysql-test/r/join_cache_nojb.result
      mysql-test/suite/binlog/t/disabled.def
      mysql-test/suite/opt_trace/include/general.inc
      mysql-test/suite/opt_trace/include/general2.inc
      mysql-test/suite/opt_trace/include/subquery.inc
      mysql-test/suite/opt_trace/r/filesort_pq.result
      mysql-test/suite/opt_trace/r/general2_no_prot.result
      mysql-test/suite/opt_trace/r/general2_ps_prot.result
      mysql-test/suite/opt_trace/r/general_no_prot_none.result
      mysql-test/suite/opt_trace/r/general_ps_prot_none.result
      mysql-test/suite/opt_trace/r/subquery_no_prot.result
      mysql-test/suite/opt_trace/r/subquery_ps_prot.result
      mysql-test/t/disabled.def
      mysql-test/t/filesort_debug.test
      mysql-test/valgrind.supp
      scripts/mysql_config.pl.in
      scripts/mysql_config.sh
      sql/field.h
      sql/field_conv.cc
      sql/filesort.cc
      sql/filesort_utils.cc
      sql/filesort_utils.h
      sql/mdl.cc
      sql/mysqld.cc
      sql/opt_trace.h
      sql/opt_trace2server.cc
      sql/sql_class.h
      sql/sql_parse.cc
      sql/sql_select.cc
      sql/sql_show.cc
      sql/table.h
      storage/innobase/btr/btr0pcur.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/ibuf/ibuf0ibuf.c
      storage/innobase/include/btr0pcur.h
      storage/innobase/include/btr0pcur.ic
      unittest/gunit/CMakeLists.txt
 3135 Bjorn Munch	2011-11-09 [merge]
      upmerge small test fix from 5.5-mtr

    modified:
      mysql-test/extra/binlog_tests/ctype_ucs_binlog.test
 3134 Bjorn Munch	2011-11-08 [merge]
      upmerge 13055685,13096353

    modified:
      client/mysqltest.cc
      mysql-test/include/wait_for_slave_io_error.inc
      mysql-test/r/mysqltest.result
      mysql-test/suite/rpl/r/rpl_packet.result
      mysql-test/suite/rpl/t/rpl_packet.test
      mysql-test/t/mysqltest.test
=== modified file 'configure.cmake'
--- a/configure.cmake	2011-11-04 12:59:47 +0000
+++ b/configure.cmake	2011-11-08 14:33:41 +0000
@@ -82,9 +82,12 @@ ENDMACRO()
 IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_C_COMPILER_ID MATCHES "SunPro")
   DIRNAME(${CMAKE_CXX_COMPILER} CXX_PATH)
   SET(STLPORT_SUFFIX "lib/stlport4")
-  IF(CMAKE_CXX_FLAGS MATCHES "-m64")
+  IF(CMAKE_CXX_FLAGS MATCHES "-m64" AND CMAKE_SYSTEM_PROCESSOR MATCHES "sparc")
     SET(STLPORT_SUFFIX "lib/stlport4/v9")
   ENDIF()
+  IF(CMAKE_CXX_FLAGS MATCHES "-m64" AND CMAKE_SYSTEM_PROCESSOR MATCHES "i386")
+    SET(STLPORT_SUFFIX "lib/stlport4/amd64")
+  ENDIF()
 
   FIND_LIBRARY(STL_LIBRARY_NAME
     NAMES "stlport"
@@ -94,7 +97,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND
   IF(STL_LIBRARY_NAME)
     DIRNAME(${STL_LIBRARY_NAME} STLPORT_PATH)
     # We re-distribute libstlport.so which is a symlink to libstlport.so.1
-    # There is no 'readlink' on solaris, sigh ..., so we use perl to find it:
+    # There is no 'readlink' on solaris, so we use perl to follow links:
     SET(PERLSCRIPT
       "my $link= $ARGV[0]; use Cwd qw(abs_path); my $file = abs_path($link); print $file;")
     EXECUTE_PROCESS(
@@ -107,6 +110,9 @@ IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND
             DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
     # Using the $ORIGIN token with the -R option to locate the libraries
     # on a path relative to the executable:
+    # We need an extra backslash to pass $ORIGIN to the mysql_config script...
+    SET(QUOTED_CMAKE_CXX_LINK_FLAGS
+      "${CMAKE_CXX_LINK_FLAGS} -R'\\$ORIGIN/../lib' -R${STLPORT_PATH}")
     SET(CMAKE_CXX_LINK_FLAGS
       "${CMAKE_CXX_LINK_FLAGS} -R'\$ORIGIN/../lib' -R${STLPORT_PATH}")
     MESSAGE(STATUS "CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS}")

=== modified file 'include/mysql/psi/mysql_socket.h'
--- a/include/mysql/psi/mysql_socket.h	2011-09-20 15:42:23 +0000
+++ b/include/mysql/psi/mysql_socket.h	2011-11-08 04:28:05 +0000
@@ -97,7 +97,7 @@ mysql_socket_invalid()
   MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
   return mysql_socket;
 }
-
+
 /**
   Set socket descriptor and address.
   @param socket nstrumented socket
@@ -105,10 +105,19 @@ mysql_socket_invalid()
   @param addr unformatted socket address
   @param adr_len length of socket addres
 */
+
 static inline void
-mysql_socket_set_address(MYSQL_SOCKET socket,
-                         const struct sockaddr *addr,
-                         socklen_t addr_len)
+mysql_socket_set_address(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+  MYSQL_SOCKET socket,
+  const struct sockaddr *addr,
+  socklen_t addr_len
+#else
+  MYSQL_SOCKET socket __attribute__ ((unused)),
+  const struct sockaddr *addr __attribute__ ((unused)),
+  socklen_t addr_len __attribute__ ((unused))
+#endif
+)
 {
 #ifdef HAVE_PSI_SOCKET_INTERFACE
   PSI_CALL(set_socket_info)(socket.m_psi, NULL, addr, addr_len);
@@ -121,7 +130,13 @@ mysql_socket_set_address(MYSQL_SOCKET so
   @param thread instrumented owning thread
 */
 static inline void
-mysql_socket_set_thread_owner(MYSQL_SOCKET socket)
+mysql_socket_set_thread_owner(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+MYSQL_SOCKET socket
+#else
+MYSQL_SOCKET socket __attribute__ ((unused))
+#endif
+)
 {
 #ifdef HAVE_PSI_SOCKET_INTERFACE
   PSI_CALL(set_socket_thread_owner)(socket.m_psi);

=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2011-11-03 16:03:34 +0000
+++ b/include/mysql/psi/psi.h	2011-11-08 04:28:05 +0000
@@ -16,6 +16,18 @@
 #ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
 #define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
 
+#ifdef EMBEDDED_LIBRARY
+#define DISABLE_PSI_MUTEX
+#define DISABLE_PSI_RWLOCK
+#define DISABLE_PSI_COND
+#define DISABLE_PSI_FILE
+#define DISABLE_PSI_TABLE
+#define DISABLE_PSI_SOCKET
+#define DISABLE_PSI_STAGE
+#define DISABLE_PSI_STATEMENT
+#define DISABLE_PSI_IDLE
+#endif /* EMBEDDED_LIBRARY */
+
 #ifndef MY_GLOBAL_INCLUDED
 /*
   Make sure a .c or .cc file contains an include to my_global.h first.

=== modified file 'mysql-test/extra/binlog_tests/ctype_ucs_binlog.test'
--- a/mysql-test/extra/binlog_tests/ctype_ucs_binlog.test	2007-12-12 17:19:24 +0000
+++ b/mysql-test/extra/binlog_tests/ctype_ucs_binlog.test	2011-11-09 08:58:18 +0000
@@ -15,7 +15,6 @@ source include/show_binlog_events.inc;
 # absolutely need variables names to be quoted and strings to be
 # escaped).
 flush logs;
---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
 let $MYSQLD_DATADIR= `select @@datadir`;
 --exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000001 
 drop table t2;

=== modified file 'mysql-test/include/join_cache.inc'
--- a/mysql-test/include/join_cache.inc	2011-08-08 14:16:20 +0000
+++ b/mysql-test/include/join_cache.inc	2011-11-04 15:20:13 +0000
@@ -1961,3 +1961,26 @@ eval EXPLAIN $query;
 eval $query;
 
 DROP TABLE t1, t2, t3, t4;
+
+--echo #
+--echo # Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+--echo #               POINTS TO UNINITIALISED BYTE(S)
+--echo #
+
+CREATE TABLE t1 (
+  col1 varchar(10),
+  col2 varchar(1024)
+) ENGINE=innodb;
+
+INSERT INTO t1 VALUES ('a','a');
+
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+
+DROP TABLE t1,t2;
+
+--echo # End of Bug#12997905

=== modified file 'mysql-test/r/filesort_debug.result'
--- a/mysql-test/r/filesort_debug.result	2011-02-24 07:18:03 +0000
+++ b/mysql-test/r/filesort_debug.result	2011-11-07 15:32:36 +0000
@@ -16,7 +16,7 @@ DROP TABLE t1;
 #
 CREATE TABLE t1(f0 int auto_increment primary key, f1 int);
 INSERT INTO t1(f1) VALUES (0),(1),(2),(3),(4),(5);
-SET session debug= '+d,make_char_array_fail';
+SET session debug= '+d,alloc_sort_buffer_fail';
 CALL mtr.add_suppression("Out of sort memory");
 SELECT * FROM t1 ORDER BY f1 ASC, f0;
 ERROR HY001: Out of sort memory, consider increasing server sort buffer size

=== modified file 'mysql-test/r/join_cache_bka.result'
--- a/mysql-test/r/join_cache_bka.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/r/join_cache_bka.result	2011-11-04 15:20:13 +0000
@@ -2681,4 +2681,22 @@ col_int
 NULL
 NULL
 DROP TABLE t1, t2, t3, t4;
+#
+# Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+#               POINTS TO UNINITIALISED BYTE(S)
+#
+CREATE TABLE t1 (
+col1 varchar(10),
+col2 varchar(1024)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('a','a');
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+col1
+a
+DROP TABLE t1,t2;
+# End of Bug#12997905
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bka_nixbnl.result'
--- a/mysql-test/r/join_cache_bka_nixbnl.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/r/join_cache_bka_nixbnl.result	2011-11-04 15:20:13 +0000
@@ -2681,4 +2681,22 @@ col_int
 NULL
 NULL
 DROP TABLE t1, t2, t3, t4;
+#
+# Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+#               POINTS TO UNINITIALISED BYTE(S)
+#
+CREATE TABLE t1 (
+col1 varchar(10),
+col2 varchar(1024)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('a','a');
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+col1
+a
+DROP TABLE t1,t2;
+# End of Bug#12997905
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bkaunique.result'
--- a/mysql-test/r/join_cache_bkaunique.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/r/join_cache_bkaunique.result	2011-11-04 15:20:13 +0000
@@ -2682,4 +2682,22 @@ col_int
 NULL
 NULL
 DROP TABLE t1, t2, t3, t4;
+#
+# Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+#               POINTS TO UNINITIALISED BYTE(S)
+#
+CREATE TABLE t1 (
+col1 varchar(10),
+col2 varchar(1024)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('a','a');
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+col1
+a
+DROP TABLE t1,t2;
+# End of Bug#12997905
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bnl.result'
--- a/mysql-test/r/join_cache_bnl.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/r/join_cache_bnl.result	2011-11-04 15:20:13 +0000
@@ -2682,4 +2682,22 @@ col_int
 NULL
 NULL
 DROP TABLE t1, t2, t3, t4;
+#
+# Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+#               POINTS TO UNINITIALISED BYTE(S)
+#
+CREATE TABLE t1 (
+col1 varchar(10),
+col2 varchar(1024)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('a','a');
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+col1
+a
+DROP TABLE t1,t2;
+# End of Bug#12997905
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_nojb.result'
--- a/mysql-test/r/join_cache_nojb.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/r/join_cache_nojb.result	2011-11-04 15:20:13 +0000
@@ -2682,4 +2682,22 @@ NULL
 3
 NULL
 DROP TABLE t1, t2, t3, t4;
+#
+# Bug#12997905: VALGRIND: SYSCALL PARAM PWRITE64(BUF) 
+#               POINTS TO UNINITIALISED BYTE(S)
+#
+CREATE TABLE t1 (
+col1 varchar(10),
+col2 varchar(1024)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('a','a');
+CREATE TABLE t2 (i varchar(10)) ENGINE=innodb;
+INSERT INTO t2 VALUES ('a');
+SELECT t1.col1
+FROM t1 JOIN t2 ON t1.col1 = t2.i 
+GROUP BY t1.col2;
+col1
+a
+DROP TABLE t1,t2;
+# End of Bug#12997905
 set optimizer_switch = default;

=== removed file 'mysql-test/suite/binlog/r/binlog_truncate_innodb.result'
--- a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result	2010-05-25 20:01:38 +0000
+++ b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result	1970-01-01 00:00:00 +0000
@@ -1,403 +0,0 @@
-SET @old_binlog_format=@@binlog_format;
-SET BINLOG_FORMAT=ROW;
-RESET MASTER;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-# Even though the isolation level might be permissive, truncate
-# table follows a stricter isolation as its locking is based on
-# (exclusive) metadata locks.
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
-master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-SET BINLOG_FORMAT=STATEMENT;
-RESET MASTER;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-# Truncate is not supported for SBR if the isolation level is
-# READ UNCOMMITTED or READ COMMITTED. These specific isolation
-# levels are tested elsewhere.
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t2 VALUES (1),(2),(3);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-**** Truncate of empty table shall be logged
-TRUNCATE TABLE t1;
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-TRUNCATE TABLE t2;
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t2
-DROP TABLE t1,t2;
-#
-# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
-#
-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-CREATE TABLE t2 (a INT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1),(2);
-SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-# Connection: default
-BEGIN;
-INSERT INTO t2 SELECT * FROM t1;
-# Connection: truncate
-TRUNCATE TABLE t1;
-# Connection: default
-INSERT INTO t2 SELECT * FROM t1;
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-COMMIT;
-# Connection: truncate
-# Reaping TRUNCATE TABLE
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-4
-# Connection: default
-show binlog events from <binlog_start>;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	BEGIN
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t2 SELECT * FROM t1
-master-bin.000001	#	Xid	#	#	COMMIT /* XID */
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE TABLE t1
-DROP TABLE t1,t2;
-SET BINLOG_FORMAT=@old_binlog_format;

=== removed file 'mysql-test/suite/binlog/t/binlog_truncate_innodb.test'
--- a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test	2010-05-25 20:01:38 +0000
+++ b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test	1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
-source include/have_log_bin.inc;
-source include/have_innodb.inc;
-
-let $engine = InnoDB;
-
-SET @old_binlog_format=@@binlog_format;
-
-SET BINLOG_FORMAT=ROW;
-RESET MASTER;
-
-source extra/binlog_tests/binlog_truncate.test;
-
---echo # Even though the isolation level might be permissive, truncate
---echo # table follows a stricter isolation as its locking is based on
---echo # (exclusive) metadata locks.
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-source extra/binlog_tests/binlog_truncate.test;
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-source extra/binlog_tests/binlog_truncate.test;
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-source extra/binlog_tests/binlog_truncate.test;
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-source extra/binlog_tests/binlog_truncate.test;
-
-SET BINLOG_FORMAT=STATEMENT;
-RESET MASTER;
-
-source extra/binlog_tests/binlog_truncate.test;
-
---echo # Truncate is not supported for SBR if the isolation level is
---echo # READ UNCOMMITTED or READ COMMITTED. These specific isolation
---echo # levels are tested elsewhere.
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-source extra/binlog_tests/binlog_truncate.test;
-
-let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-source extra/binlog_tests/binlog_truncate.test;
-
-SET BINLOG_FORMAT=@old_binlog_format;

=== modified file 'mysql-test/suite/binlog/t/disabled.def'
--- a/mysql-test/suite/binlog/t/disabled.def	2011-08-03 18:22:00 +0000
+++ b/mysql-test/suite/binlog/t/disabled.def	2011-11-08 14:54:44 +0000
@@ -9,5 +9,4 @@
 #  Do not use any TAB characters for whitespace.
 #
 ##############################################################################
-binlog_truncate_innodb	: BUG#11764459 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed
 binlog_spurious_ddl_errors  : BUG#11761680 2010-06-03 alik binlog_spurious_ddl_errors.test fails, thus disabled

=== modified file 'mysql-test/suite/opt_trace/include/general.inc'
--- a/mysql-test/suite/opt_trace/include/general.inc	2011-09-21 15:53:58 +0000
+++ b/mysql-test/suite/opt_trace/include/general.inc	2011-11-08 07:51:49 +0000
@@ -311,6 +311,7 @@ select * from information_schema.OPTIMIZ
 # HAVING
 select t1.a,avg(t2.c) as moyenne from t1, t2 where t2.c>-1
   group by t1.a having moyenne<>0;
+--replace_regex /("sort_buffer_size":) [0-9]+/\1 NNN/
 select trace from information_schema.OPTIMIZER_TRACE;
 # impossible HAVING
 select t1.a,avg(t2.c) as moyenne from t1, t2 where t2.c>-1

=== modified file 'mysql-test/suite/opt_trace/include/general2.inc'
--- a/mysql-test/suite/opt_trace/include/general2.inc	2011-09-21 15:53:58 +0000
+++ b/mysql-test/suite/opt_trace/include/general2.inc	2011-11-08 07:51:49 +0000
@@ -159,6 +159,7 @@ ORDER BY f2;
 --echo Maps should say that t2 and t3 depend on t1
 --echo (because of straight_join), they don't, this is
 --echo bug#11766858 and bug#11752239
+--replace_regex /("sort_buffer_size":) [0-9]+/\1 NNN/
 select TRACE from information_schema.OPTIMIZER_TRACE;
 
 DROP TABLES t1,t2,t3;
@@ -171,6 +172,7 @@ DROP TABLES t1,t2,t3;
 create table t1 (a int, b int);
 insert into t1 values (1,1), (2,null), (3, 4);
 select max(x) from (select sum(a) as x from t1 group by b) as teeone;
+--replace_regex /("sort_buffer_size":) [0-9]+/\1 NNN/
 select TRACE from information_schema.OPTIMIZER_TRACE;
 drop table t1;
 
@@ -614,6 +616,7 @@ SELECT SUM(alias2.col_varchar_nokey) , a
 STRAIGHT_JOIN t2 AS alias2 ON alias2.pk = alias1.col_int_key WHERE alias1.pk
 GROUP BY field2 ORDER BY alias1.col_int_key,alias2.pk ;
 eval $query;
+--replace_regex /("sort_buffer_size":) [0-9]+/\1 NNN/
 SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
 
 DROP TABLE t1,t2;

=== modified file 'mysql-test/suite/opt_trace/include/subquery.inc'
--- a/mysql-test/suite/opt_trace/include/subquery.inc	2011-10-18 14:27:48 +0000
+++ b/mysql-test/suite/opt_trace/include/subquery.inc	2011-11-08 07:51:49 +0000
@@ -174,6 +174,7 @@ sq4_alias3.`col_varchar_nokey` <> alias1
 alias1.`col_int_key` not in (214) group by field1,field2,field3,
 field4,field5,field6; 
 
+--replace_regex /("sort_buffer_size":) [0-9]+/\1 NNN/
 select * from information_schema.optimizer_trace;
 set optimizer_switch=@old_opt_switch;
 drop table t1,t2,t3,t4,t5;

=== modified file 'mysql-test/suite/opt_trace/r/filesort_pq.result'
--- a/mysql-test/suite/opt_trace/r/filesort_pq.result	2011-10-13 13:22:45 +0000
+++ b/mysql-test/suite/opt_trace/r/filesort_pq.result	2011-11-07 15:32:36 +0000
@@ -269,6 +269,7 @@ SELECT * FROM t1 ORDER BY f1 ASC, f0 LIM
               "rows": 100,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 25080,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -446,6 +447,7 @@ SELECT * FROM t1 ORDER BY f1 ASC, f0 LIM
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 7068,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -658,6 +660,7 @@ SELECT * FROM t1 ORDER BY f2 DESC, f0 LI
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 13144,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -884,6 +887,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -1120,6 +1124,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -1291,6 +1296,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 11,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 4664,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -1429,6 +1435,7 @@ SELECT CONCAT("hello ", f2) AS foo FROM
               "rows": 3,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 1254,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -1566,6 +1573,7 @@ SELECT * from t1 ORDER BY rand(2) LIMIT
               "rows": 3,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 72,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -1744,6 +1752,7 @@ SELECT * FROM t1 ORDER BY f1 ASC, f0 LIM
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 7068,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -1956,6 +1965,7 @@ SELECT * FROM t1 ORDER BY f2 DESC, f0 LI
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 13144,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -2182,6 +2192,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -2418,6 +2429,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -2589,6 +2601,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 11,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 4664,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -2774,6 +2787,7 @@ ORDER BY f1, f0 LIMIT 30	{
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 7068,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -2926,6 +2940,7 @@ ORDER BY f1, f0 LIMIT 0	{
               "rows": 1,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 228,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -3122,6 +3137,7 @@ ORDER BY f2, f0 LIMIT 20	{
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -3298,6 +3314,7 @@ ORDER BY f2, f0 LIMIT 0	{
               "rows": 1,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 424,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -3484,6 +3501,7 @@ ORDER BY f2, f0 LIMIT 10 OFFSET 10	{
               "rows": 21,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 8904,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -3660,6 +3678,7 @@ ORDER BY f2, f0 LIMIT 0 OFFSET 10	{
               "rows": 11,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 4664,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -3942,6 +3961,7 @@ ORDER BY tmp.f1, f0 LIMIT 30	{
               "rows": 31,
               "examined_rows": 1500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 775,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -4216,6 +4236,7 @@ ORDER BY tmp.f1, f0 LIMIT 30 OFFSET 30	{
               "rows": 61,
               "examined_rows": 1500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 1525,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -4495,6 +4516,7 @@ ORDER BY tmp.f1, f0 LIMIT 30 OFFSET 30	{
               "rows": 61,
               "examined_rows": 1500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 1525,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -4802,6 +4824,7 @@ ORDER BY tmp.f1, f0 LIMIT 30 OFFSET 30	{
               "rows": 61,
               "examined_rows": 1185,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 1525,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -5109,6 +5132,7 @@ SELECT * FROM v1	{
                     "rows": 31,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 7068,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -5405,6 +5429,7 @@ SELECT * FROM v1 ORDER BY f2, f0 LIMIT 3
                     "rows": 101,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 23028,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -5439,6 +5464,7 @@ SELECT * FROM v1 ORDER BY f2, f0 LIMIT 3
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 6851,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -6039,6 +6065,7 @@ LIMIT 30	{
                     "rows": 101,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 23028,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -6077,6 +6104,7 @@ LIMIT 30	{
                     "rows": 101,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 42824,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -6117,6 +6145,7 @@ LIMIT 30	{
               "rows": 31,
               "examined_rows": 325,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 6975,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -6284,6 +6313,7 @@ GROUP BY 1 ORDER BY 2,1 LIMIT 5	{
               "rows": 6,
               "examined_rows": 10,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 198,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -6534,6 +6564,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 31,
               "examined_rows": 500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 13144,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -6718,6 +6749,7 @@ SELECT * FROM t1 WHERE f1>10 ORDER BY f2
               "rows": 31,
               "examined_rows": 500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 13144,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -6903,6 +6935,7 @@ ORDER BY f2, f0 LIMIT 15 OFFSET 15	{
               "rows": 31,
               "examined_rows": 500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 13144,
               "sort_mode": "<sort_key, additional_fields>"
             }
           }
@@ -7194,6 +7227,7 @@ SELECT * FROM v1 ORDER BY f2, f0 LIMIT 3
                     "rows": 101,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 23028,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -7228,6 +7262,7 @@ SELECT * FROM v1 ORDER BY f2, f0 LIMIT 3
               "rows": 31,
               "examined_rows": 100,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 6851,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -7591,6 +7626,7 @@ ORDER BY d1.f2 DESC LIMIT 30	{
                     "rows": 31,
                     "examined_rows": 500,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": 6944,
                     "sort_mode": "<sort_key, additional_fields>"
                   }
                 }
@@ -7619,6 +7655,7 @@ ORDER BY d1.f2 DESC LIMIT 30	{
               "rows": 31,
               "examined_rows": 620,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 6727,
               "sort_mode": "<sort_key, rowid>"
             }
           }
@@ -7881,6 +7918,7 @@ SELECT * FROM t1 WHERE f1 = (SELECT f1 F
                           "rows": 2,
                           "examined_rows": 500,
                           "number_of_tmp_files": 0,
+                          "sort_buffer_size": 36,
                           "sort_mode": "<sort_key, additional_fields>"
                         }
                       }
@@ -11637,6 +11675,7 @@ SELECT * FROM t1 WHERE f1 = (SELECT f1 F
                           "rows": 3,
                           "examined_rows": 500,
                           "number_of_tmp_files": 0,
+                          "sort_buffer_size": 54,
                           "sort_mode": "<sort_key, additional_fields>"
                         }
                       }
@@ -11903,6 +11942,7 @@ SELECT * FROM t1 ORDER BY f2 LIMIT 100	{
               "rows": 101,
               "examined_rows": 438500,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": 21715,
               "sort_mode": "<sort_key, rowid>"
             }
           }

=== modified file 'mysql-test/suite/opt_trace/r/general2_no_prot.result'
--- a/mysql-test/suite/opt_trace/r/general2_no_prot.result	2011-10-13 13:22:45 +0000
+++ b/mysql-test/suite/opt_trace/r/general2_no_prot.result	2011-11-08 07:51:49 +0000
@@ -1119,6 +1119,7 @@ TRACE
               "rows": 4,
               "examined_rows": 4,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }
@@ -1354,6 +1355,7 @@ TRACE
                     "rows": 3,
                     "examined_rows": 3,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": NNN,
                     "sort_mode": "<sort_key, rowid>"
                   } /* filesort_summary */
                 }
@@ -4860,6 +4862,7 @@ GROUP BY field2 ORDER BY alias1.col_int_
               "rows": 8,
               "examined_rows": 8,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/suite/opt_trace/r/general2_ps_prot.result'
--- a/mysql-test/suite/opt_trace/r/general2_ps_prot.result	2011-10-13 13:22:45 +0000
+++ b/mysql-test/suite/opt_trace/r/general2_ps_prot.result	2011-11-08 07:51:49 +0000
@@ -1137,6 +1137,7 @@ TRACE
               "rows": 4,
               "examined_rows": 4,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }
@@ -1372,6 +1373,7 @@ TRACE
                     "rows": 3,
                     "examined_rows": 3,
                     "number_of_tmp_files": 0,
+                    "sort_buffer_size": NNN,
                     "sort_mode": "<sort_key, rowid>"
                   } /* filesort_summary */
                 }
@@ -4913,6 +4915,7 @@ GROUP BY field2 ORDER BY alias1.col_int_
               "rows": 8,
               "examined_rows": 8,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/suite/opt_trace/r/general_no_prot_none.result'
--- a/mysql-test/suite/opt_trace/r/general_no_prot_none.result	2011-10-13 13:22:45 +0000
+++ b/mysql-test/suite/opt_trace/r/general_no_prot_none.result	2011-11-08 07:51:49 +0000
@@ -5835,6 +5835,7 @@ trace
               "rows": 2,
               "examined_rows": 2,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/suite/opt_trace/r/general_ps_prot_none.result'
--- a/mysql-test/suite/opt_trace/r/general_ps_prot_none.result	2011-10-13 13:22:45 +0000
+++ b/mysql-test/suite/opt_trace/r/general_ps_prot_none.result	2011-11-08 07:51:49 +0000
@@ -5793,6 +5793,7 @@ trace
               "rows": 2,
               "examined_rows": 2,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/suite/opt_trace/r/subquery_no_prot.result'
--- a/mysql-test/suite/opt_trace/r/subquery_no_prot.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/suite/opt_trace/r/subquery_no_prot.result	2011-11-08 07:51:49 +0000
@@ -1762,6 +1762,7 @@ field4,field5,field6	{
               "rows": 0,
               "examined_rows": 0,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/suite/opt_trace/r/subquery_ps_prot.result'
--- a/mysql-test/suite/opt_trace/r/subquery_ps_prot.result	2011-10-27 08:52:27 +0000
+++ b/mysql-test/suite/opt_trace/r/subquery_ps_prot.result	2011-11-08 07:51:49 +0000
@@ -1740,6 +1740,7 @@ field4,field5,field6	{
               "rows": 0,
               "examined_rows": 0,
               "number_of_tmp_files": 0,
+              "sort_buffer_size": NNN,
               "sort_mode": "<sort_key, rowid>"
             } /* filesort_summary */
           }

=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def	2011-11-04 09:18:36 +0000
+++ b/mysql-test/t/disabled.def	2011-11-08 06:40:03 +0000
@@ -16,3 +16,4 @@ alter_table-big          : Bug#11748731
 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
 log_tables-big           : Bug#11756699 2010-11-15 mattiasj report already exists
+mysql_embedded           : Bug#12561297 2011-11-08 Mayank Innodb behavior causes this test case to fail.

=== modified file 'mysql-test/t/filesort_debug.test'
--- a/mysql-test/t/filesort_debug.test	2011-02-24 07:18:03 +0000
+++ b/mysql-test/t/filesort_debug.test	2011-11-07 15:32:36 +0000
@@ -28,7 +28,7 @@ DROP TABLE t1;
 CREATE TABLE t1(f0 int auto_increment primary key, f1 int);
 INSERT INTO t1(f1) VALUES (0),(1),(2),(3),(4),(5);
 
-SET session debug= '+d,make_char_array_fail';
+SET session debug= '+d,alloc_sort_buffer_fail';
 CALL mtr.add_suppression("Out of sort memory");
 --error ER_OUT_OF_SORTMEMORY
 SELECT * FROM t1 ORDER BY f1 ASC, f0;

=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp	2011-10-07 06:03:14 +0000
+++ b/mysql-test/valgrind.supp	2011-11-08 14:48:33 +0000
@@ -984,7 +984,7 @@
    fun:my_b_flush_io_cache
    fun:_my_b_write
    fun:_Z*10write_keysP10Sort_paramPPhjP11st_io_cacheS4_
-   fun:_Z*13find_all_keysP10Sort_paramP10SQL_SELECTPPhP11st_io_cacheS6_P13Bounded_queueIhhEPy
+   fun:_Z*13find_all_keysP10Sort_paramP10SQL_SELECTP13Filesort_infoP11st_io_cacheS6_P13Bounded_queueIhhEPy
    fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPyS7_
 }
 
@@ -1023,35 +1023,3 @@
    fun:_Z*10write_keysP10Sort_paramPPhjP11st_io_cacheS4_
    fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPyS7_
 }
-
-# Syscall param write(buf) points to uninitialised byte(s)
-# The '...' wildcard is for 'fun:inline_mysql_file_write' which *may*
-# be inlined.
-{
-   Bug#12879084 VALGRIND FAILURE IN INNODB.INNODB_BUFFER_POOL_LOAD / one
-   Memcheck:Param
-   write(buf)
-   obj:*/libpthread*.so
-   fun:my_write
-   ...
-   fun:my_b_flush_io_cache
-   fun:end_io_cache
-   fun:mi_extra
-   fun:_ZN9ha_myisam5extraE17ha_extra_function
-}
-
-{
-   Bug#12879084 VALGRIND FAILURE IN INNODB.INNODB_BUFFER_POOL_LOAD / two
-   Memcheck:Param
-   write(buf)
-   obj:*/libpthread*.so
-   fun:my_write
-   fun:my_b_flush_io_cache
-   fun:_my_b_write
-   fun:_mi_write_part_record
-   fun:write_dynamic_record
-   fun:_mi_write_blob_record
-   fun:mi_write
-   fun:_ZN9ha_myisam9write_rowEPh
-   fun:_ZN7handler12ha_write_rowEPh
-}

=== modified file 'scripts/mysql_config.pl.in'
--- a/scripts/mysql_config.pl.in	2011-06-30 15:50:45 +0000
+++ b/scripts/mysql_config.pl.in	2011-11-08 14:33:41 +0000
@@ -44,7 +44,6 @@ use strict;
 my @exclude_cflags =
   qw/DDBUG_OFF DSAFE_MUTEX DFORCE_INIT_OF_VARS
      DEXTRA_DEBUG DHAVE_purify O O[0-9] xO[0-9] W[-A-Za-z]*
-     Xa xstrconst xc99=none
      unroll2 ip mp restrict/;
 
 my @exclude_libs = qw/lmtmalloc static-libcxa i-static static-intel/;
@@ -205,11 +204,10 @@ $flags->{embedded_libs} =
 
 $flags->{include} = ["-I$pkgincludedir"];
 $flags->{cflags}  = [@{$flags->{include}},split(" ",'@CFLAGS@')];
+$flags->{cxxflags}= [@{$flags->{include}},split(" ",'@CXXFLAGS@')];
 
 # ----------------------------------------------------------------------
 # Remove some options that a client doesn't have to care about
-# FIXME until we have a --cxxflags, we need to remove -Xa
-#       and -xstrconst to make --cflags usable for Sun Forte C++
 # ----------------------------------------------------------------------
 
 my $filter = join("|", @exclude_cflags);
@@ -219,6 +217,12 @@ foreach my $cflag ( @tmp )
 {
   push(@{$flags->{cflags}}, $cflag) unless $cflag =~ m/^($filter)$/o;
 }
+@tmp = @{$flags->{cxxflags}};           # Copy the flag list
+$flags->{cxxflags} = [];                # Clear it
+foreach my $cxxflag ( @tmp )
+{
+  push(@{$flags->{cxxflags}}, $cxxflag) unless $cxxflag =~ m/^($filter)$/o;
+}
 
 # Same for --libs(_r)
 $filter = join("|", @exclude_libs);
@@ -234,6 +238,7 @@ foreach my $lib_type ( "libs","libs_r","
 
 my $include =       quote_options(@{$flags->{include}});
 my $cflags  =       quote_options(@{$flags->{cflags}});
+my $cxxflags=       quote_options(@{$flags->{cxxflags}});
 my $libs    =       quote_options(@{$flags->{libs}});
 my $libs_r  =       quote_options(@{$flags->{libs_r}});
 my $embedded_libs = quote_options(@{$flags->{embedded_libs}});
@@ -250,6 +255,7 @@ sub usage
 Usage: $0 [OPTIONS]
 Options:
         --cflags         [$cflags]
+        --cxxflags       [$cxxflags]
         --include        [$include]
         --libs           [$libs]
         --libs_r         [$libs_r]
@@ -271,6 +277,7 @@ EOF
 
 GetOptions(
            "cflags"  => sub { print "$cflags\n" },
+           "cxxflags"=> sub { print "$cxxflags\n" },
            "include" => sub { print "$include\n" },
            "libs"    => sub { print "$libs\n" },
            "libs_r"  => sub { print "$libs_r\n" },

=== modified file 'scripts/mysql_config.sh'
--- a/scripts/mysql_config.sh	2011-06-30 15:50:45 +0000
+++ b/scripts/mysql_config.sh	2011-11-08 14:33:41 +0000
@@ -114,6 +114,7 @@ libs=" $ldflags -L$pkglibdir -lmysqlclie
 libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
 libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
 embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
 
 if [ -r "$pkglibdir/libmygcc.a" ]; then
   # When linking against the static library with a different version of GCC
@@ -126,24 +127,22 @@ if [ -r "$pkglibdir/libmygcc.a" ]; then
 fi
 
 cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
+cxxflags="-I$pkgincludedir @CXXFLAGS@ " #note: end space!
 include="-I$pkgincludedir"
 
 # Remove some options that a client doesn't have to care about
-# FIXME until we have a --cxxflags, we need to remove -Xa
-#       and -xstrconst to make --cflags usable for Sun Forte C++
-# FIXME until we have a --cxxflags, we need to remove -AC99
-#       to make --cflags usable for HP C++ (aCC)
 for remove in DDBUG_OFF DSAFE_MUTEX DFORCE_INIT_OF_VARS \
               DEXTRA_DEBUG DHAVE_purify O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
               'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
-              Xa xstrconst "xc99=none" AC99 \
               unroll2 ip mp restrict
 do
   # The first option we might strip will always have a space before it because
   # we set -I$pkgincludedir as the first option
   cflags=`echo "$cflags"|sed -e "s/ -$remove  */ /g"` 
+  cxxflags=`echo "$cxxflags"|sed -e "s/ -$remove  */ /g"` 
 done
 cflags=`echo "$cflags"|sed -e 's/ *\$//'` 
+cxxflags=`echo "$cxxflags"|sed -e 's/ *\$//'` 
 
 # Same for --libs(_r)
 for remove in lmtmalloc static-libcxa i-static static-intel
@@ -164,6 +163,7 @@ usage () {
 Usage: $0 [OPTIONS]
 Options:
         --cflags         [$cflags]
+        --cxxflags       [$cxxflags]
         --include        [$include]
         --libs           [$libs]
         --libs_r         [$libs_r]
@@ -185,6 +185,7 @@ if test $# -le 0; then usage; fi
 while test $# -gt 0; do
         case $1 in
         --cflags)  echo "$cflags" ;;
+        --cxxflags)echo "$cxxflags";;
         --include) echo "$include" ;;
         --libs)    echo "$libs" ;;
         --libs_r)  echo "$libs_r" ;;

=== modified file 'sql/field.h'
--- a/sql/field.h	2011-10-11 04:27:52 +0000
+++ b/sql/field.h	2011-11-04 15:20:13 +0000
@@ -2454,6 +2454,23 @@ public:
   uchar *from_null_ptr,*to_null_ptr;
   my_bool *null_row;
   uint	from_bit,to_bit;
+  /**
+    Number of bytes in the fields pointed to by 'from_ptr' and
+    'to_ptr'. Usually this is the number of bytes that are copied from
+    'from_ptr' to 'to_ptr'.
+
+    For variable-length fields (VARCHAR), the first byte(s) describe
+    the actual length of the text. For VARCHARs with length 
+       < 256 there is 1 length byte 
+       >= 256 there is 2 length bytes
+    Thus, if from_field is VARCHAR(10), from_length (and in most cases
+    to_length) is 11. For VARCHAR(1024), the length is 1026. @see
+    Field_varstring::length_bytes
+
+    Note that for VARCHARs, do_copy() will be do_varstring*() which
+    only copies the length-bytes (1 or 2) + the actual length of the
+    text instead of from/to_length bytes. @see get_copy_func()
+  */
   uint from_length,to_length;
   Field *from_field,*to_field;
   String tmp;					// For items

=== modified file 'sql/field_conv.cc'
--- a/sql/field_conv.cc	2011-07-28 10:54:44 +0000
+++ b/sql/field_conv.cc	2011-11-04 15:20:13 +0000
@@ -709,7 +709,7 @@ Copy_field::get_copy_func(Field *to,Fiel
         if (((Field_varstring*) to)->length_bytes !=
             ((Field_varstring*) from)->length_bytes)
           return do_field_string;
-        if (to_length != from_length)
+        else
           return (((Field_varstring*) to)->length_bytes == 1 ?
                   (from->charset()->mbmaxlen == 1 ? do_varstring1 :
                                                     do_varstring1_mb) :

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2011-10-28 12:45:35 +0000
+++ b/sql/filesort.cc	2011-11-07 15:32:36 +0000
@@ -43,11 +43,11 @@ using std::min;
 
 	/* functions defined in this file */
 
-static void make_char_array(FILESORT_INFO *info, uint fields, uint length);
 static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
                                      uchar *buf);
 static ha_rows find_all_keys(Sort_param *param,SQL_SELECT *select,
-                             uchar **sort_keys, IO_CACHE *buffer_file,
+                             Filesort_info *fs_info,
+                             IO_CACHE *buffer_file,
                              IO_CACHE *tempfile,
                              Bounded_queue<uchar, uchar> *pq,
                              ha_rows *found_rows);
@@ -60,7 +60,7 @@ static int merge_index(Sort_param *param
                        uint maxbuffer,IO_CACHE *tempfile,
                        IO_CACHE *outfile);
 static bool save_index(Sort_param *param,uchar **sort_keys, uint count, 
-                       FILESORT_INFO *table_sort);
+                       Filesort_info *table_sort);
 static uint suffix_length(ulong string_length);
 static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
 		       bool *multi_byte_charset);
@@ -70,7 +70,7 @@ static SORT_ADDON_FIELD *get_addon_field
 static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
                                 uchar *buff);
 static bool check_if_pq_applicable(Opt_trace_context *trace,
-                                   Sort_param *param, FILESORT_INFO *info,
+                                   Sort_param *param, Filesort_info *info,
                                    TABLE *table,
                                    ha_rows records, ulong memory_available);
 
@@ -177,7 +177,6 @@ ha_rows filesort(THD *thd, TABLE *table,
   uint maxbuffer;
   BUFFPEK *buffpek;
   ha_rows num_rows= HA_POS_ERROR;
-  uchar **sort_keys= NULL;
   IO_CACHE tempfile, buffpek_pointers, *outfile; 
   Sort_param param;
   bool multi_byte_charset;
@@ -212,7 +211,7 @@ ha_rows filesort(THD *thd, TABLE *table,
     QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end 
     when index_merge select has finished with it.
   */
-  FILESORT_INFO table_sort= table->sort;
+  Filesort_info table_sort= table->sort;
   table->sort.io_cache= NULL;
   DBUG_ASSERT(table_sort.record_pointers == NULL);
   
@@ -258,18 +257,19 @@ ha_rows filesort(THD *thd, TABLE *table,
                 true,                           // max_at_top
                 NULL,                           // compare_function
                 compare_length,
-                &make_sortkey, &param, table_sort.sort_keys))
+                &make_sortkey, &param, table_sort.get_sort_keys()))
     {
       /*
        If we fail to init pq, we have to give up:
        out of memory means my_malloc() will call my_error().
       */
       DBUG_PRINT("info", ("failed to allocate PQ"));
-      my_free(table_sort.sort_keys);
-      table_sort.sort_keys= NULL;
+      table_sort.free_sort_buffer();
       DBUG_ASSERT(thd->is_error());
       goto err;
     }
+    // For PQ queries (with limit) we initialize all pointers.
+    table_sort.init_record_pointers();
   }
   else
   {
@@ -280,9 +280,9 @@ ha_rows filesort(THD *thd, TABLE *table,
     while (memory_available >= min_sort_memory)
     {
       ha_rows keys= memory_available / (param.rec_length + sizeof(char*));
-      param.max_keys_per_buffer= static_cast<uint>(min(num_rows, keys));
-      make_char_array(&table_sort, param.max_keys_per_buffer, param.rec_length);
-      if (table_sort.sort_keys)
+      param.max_keys_per_buffer= (uint) min(num_rows, keys);
+      table_sort.alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length);
+      if (table_sort.get_sort_keys())
         break;
       ulong old_memory_available= memory_available;
       memory_available= memory_available/4*3;
@@ -297,7 +297,6 @@ ha_rows filesort(THD *thd, TABLE *table,
     }
   }
 
-  sort_keys= table_sort.sort_keys;
   if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
 		       DISK_BUFFER_SIZE, MYF(MY_WME)))
     goto err;
@@ -307,7 +306,9 @@ ha_rows filesort(THD *thd, TABLE *table,
   // New scope, because subquery execution must be traced within an array.
   {
     Opt_trace_array ota(trace, "filesort_execution");
-    num_rows= find_all_keys(&param, select, sort_keys, &buffpek_pointers,
+    num_rows= find_all_keys(&param, select,
+                            &table_sort,
+                            &buffpek_pointers,
                             &tempfile, 
                             pq.is_initialized() ? &pq : NULL,
                             found_rows);
@@ -321,13 +322,15 @@ ha_rows filesort(THD *thd, TABLE *table,
     .add("rows", num_rows)
     .add("examined_rows", param.examined_rows)
     .add("number_of_tmp_files", maxbuffer)
+    .add("sort_buffer_size", table_sort.sort_buffer_size())
     .add_alnum("sort_mode",
                param.addon_field ?
                "<sort_key, additional_fields>" : "<sort_key, rowid>");
 
   if (maxbuffer == 0)			// The whole set is in memory
   {
-    if (save_index(&param, sort_keys, (uint) num_rows, &table_sort))
+    if (save_index(&param, table_sort.get_sort_keys(),
+                   (uint) num_rows, &table_sort))
       goto err;
   }
   else
@@ -363,13 +366,19 @@ ha_rows filesort(THD *thd, TABLE *table,
                                 (param.rec_length + sizeof(char*))) /
                                param.rec_length - 1);
     maxbuffer--;				// Offset from 0
-    if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
+    if (merge_many_buff(&param,
+                        (uchar*) table_sort.get_sort_keys(),
+                        buffpek,&maxbuffer,
 			&tempfile))
       goto err;
     if (flush_io_cache(&tempfile) ||
 	reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
       goto err;
-    if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
+    if (merge_index(&param,
+                    (uchar*) table_sort.get_sort_keys(),
+                    buffpek,
+                    maxbuffer,
+                    &tempfile,
 		    outfile))
       goto err;
   }
@@ -385,8 +394,7 @@ ha_rows filesort(THD *thd, TABLE *table,
   my_free(param.tmp_buffer);
   if (!subselect || !subselect->is_uncacheable())
   {
-    my_free(sort_keys);
-    table_sort.sort_keys= 0;
+    table_sort.free_sort_buffer();
     my_free(buffpek);
     table_sort.buffpek= 0;
     table_sort.buffpek_len= 0;
@@ -450,8 +458,7 @@ void filesort_free_buffers(TABLE *table,
 
   if (full)
   {
-    my_free(table->sort.sort_keys);
-    table->sort.sort_keys= NULL;
+    table->sort.free_sort_buffer();
     my_free(table->sort.buffpek);
     table->sort.buffpek= NULL;
     table->sort.buffpek_len= 0;
@@ -467,36 +474,11 @@ void filesort_free_buffers(TABLE *table,
 /**
   Makes an array of string pointers for info->sort_keys.
 
-  @param info         FILESORT_INFO struct owning the allocated array.
+  @param info         Filesort_info struct owning the allocated array.
   @param num_records  Number of records.
   @param length       Length of each record.
 */
 
-static void make_char_array(FILESORT_INFO *info, uint num_records, uint length)
-{
-  DBUG_ENTER("make_char_array");
-
-  DBUG_PRINT("info", ("num_records %u length %u", num_records, length));
-
-  DBUG_EXECUTE_IF("make_char_array_fail",
-                  DBUG_SET("+d,simulate_out_of_memory"););
-
-  if (!info->sort_keys)
-    info->sort_keys= 
-      (uchar**) my_malloc(num_records * (length + sizeof(uchar*)), MYF(0));
-
-  if (info->sort_keys)
-  {
-    uchar **pos= info->sort_keys;
-    uchar *char_pos= ((uchar*) (pos+num_records)) - length;
-    while (num_records--)
-      *(pos++)= (char_pos+= length);
-  }
-
-  DBUG_VOID_RETURN;
-}
-
-
 /** Read 'count' number of buffer pointers into memory. */
 
 static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
@@ -619,7 +601,7 @@ static void dbug_print_record(TABLE *tab
 */
 
 static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
-                             uchar **sort_keys,
+                             Filesort_info *fs_info,
                              IO_CACHE *buffpek_pointers,
                              IO_CACHE *tempfile,
                              Bounded_queue<uchar, uchar> *pq,
@@ -740,12 +722,13 @@ static ha_rows find_all_keys(Sort_param
       {
         if (idx == param->max_keys_per_buffer)
         {
-          if (write_keys(param,sort_keys, idx, buffpek_pointers, tempfile))
+          if (write_keys(param, fs_info->get_sort_keys(),
+                         idx, buffpek_pointers, tempfile))
              DBUG_RETURN(HA_POS_ERROR);
           idx= 0;
           indexpos++;
         }
-        make_sortkey(param, sort_keys[idx++], ref_pos);
+        make_sortkey(param, fs_info->get_record_buffer(idx++), ref_pos);
       }
     }
     else
@@ -770,11 +753,12 @@ static ha_rows find_all_keys(Sort_param
   DBUG_PRINT("test",("error: %d  indexpos: %d",error,indexpos));
   if (error != HA_ERR_END_OF_FILE)
   {
-    file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
+    file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); // purecov: inspected
     DBUG_RETURN(HA_POS_ERROR);			/* purecov: inspected */
   }
   if (indexpos && idx &&
-      write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
+      write_keys(param, fs_info->get_sort_keys(),
+                 idx, buffpek_pointers, tempfile))
     DBUG_RETURN(HA_POS_ERROR);			/* purecov: inspected */
   const ha_rows retval= 
     my_b_inited(tempfile) ?
@@ -1151,7 +1135,7 @@ static void register_used_fields(Sort_pa
 
 
 static bool save_index(Sort_param *param, uchar **sort_keys, uint count, 
-                       FILESORT_INFO *table_sort)
+                       Filesort_info *table_sort)
 {
   uint offset,res_length;
   uchar *to;
@@ -1204,7 +1188,7 @@ static bool save_index(Sort_param *param
 
 bool check_if_pq_applicable(Opt_trace_context *trace,
                             Sort_param *param,
-                            FILESORT_INFO *filesort_info,
+                            Filesort_info *filesort_info,
                             TABLE *table, ha_rows num_rows,
                             ulong memory_available)
 {
@@ -1248,10 +1232,10 @@ bool check_if_pq_applicable(Opt_trace_co
     // The whole source set fits into memory.
     if (param->max_rows < num_rows/PQ_slowness )
     {
-      make_char_array(filesort_info,
-                      param->max_keys_per_buffer, param->rec_length);
+      filesort_info->alloc_sort_buffer(param->max_keys_per_buffer,
+                                       param->rec_length);
       trace_filesort.add("chosen", true);
-      DBUG_RETURN(filesort_info->sort_keys != NULL);
+      DBUG_RETURN(filesort_info->get_sort_keys() != NULL);
     }
     else
     {
@@ -1265,10 +1249,10 @@ bool check_if_pq_applicable(Opt_trace_co
   // Do we have space for LIMIT rows in memory?
   if (param->max_keys_per_buffer < num_available_keys)
   {
-    make_char_array(filesort_info,
-                    param->max_keys_per_buffer, param->rec_length);
+    filesort_info->alloc_sort_buffer(param->max_keys_per_buffer,
+                                     param->rec_length);
     trace_filesort.add("chosen", true);
-    DBUG_RETURN(filesort_info->sort_keys != NULL);
+    DBUG_RETURN(filesort_info->get_sort_keys() != NULL);
   }
 
   // Try to strip off addon fields.
@@ -1317,10 +1301,9 @@ bool check_if_pq_applicable(Opt_trace_co
       }
 
       trace_addon.add("chosen", true);
-      make_char_array(filesort_info,
-                      param->max_keys_per_buffer,
-                      param->sort_length + param->ref_length);
-      if (filesort_info->sort_keys)
+      filesort_info->alloc_sort_buffer(param->max_keys_per_buffer,
+                                       param->sort_length + param->ref_length);
+      if (filesort_info->get_sort_keys())
       {
         // Make attached data to be references instead of fields.
         my_free(filesort_info->addon_buf);

=== modified file 'sql/filesort_utils.cc'
--- a/sql/filesort_utils.cc	2011-06-30 15:50:45 +0000
+++ b/sql/filesort_utils.cc	2011-11-07 15:32:36 +0000
@@ -16,6 +16,7 @@
 #include "filesort_utils.h"
 #include "sql_const.h"
 #include "sql_sort.h"
+#include "table.h"
 
 
 namespace {
@@ -82,3 +83,36 @@ double get_merge_many_buffs_cost_fast(ha
 }
 
 
+uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length)
+{
+  DBUG_ENTER("alloc_sort_buffer");
+
+  DBUG_EXECUTE_IF("alloc_sort_buffer_fail",
+                  DBUG_SET("+d,simulate_out_of_memory"););
+
+  if (m_idx_array.is_null())
+  {
+    uchar **sort_keys=
+      (uchar**) my_malloc(num_records * (record_length + sizeof(uchar*)),
+                          MYF(0));
+    m_idx_array= Idx_array(sort_keys, num_records);
+    m_record_length= record_length;
+    uchar **start_of_data= m_idx_array.array() + m_idx_array.size();
+    m_start_of_data= reinterpret_cast<uchar*>(start_of_data);
+  }
+  else
+  {
+    DBUG_ASSERT(num_records == m_idx_array.size());
+    DBUG_ASSERT(record_length == m_record_length);
+  }
+  DBUG_RETURN(m_idx_array.array());
+}
+
+
+void Filesort_buffer::free_sort_buffer()
+{
+  my_free(m_idx_array.array());
+  m_idx_array= Idx_array();
+  m_record_length= 0;
+  m_start_of_data= NULL;
+}

=== modified file 'sql/filesort_utils.h'
--- a/sql/filesort_utils.h	2011-06-30 15:50:45 +0000
+++ b/sql/filesort_utils.h	2011-11-07 15:32:36 +0000
@@ -14,8 +14,11 @@
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
 #ifndef FILESORT_UTILS_INCLUDED
+#define FILESORT_UTILS_INCLUDED
 
+#include "my_global.h"
 #include "my_base.h"
+#include "sql_array.h"
 
 /*
   Calculate cost of merge sort
@@ -36,9 +39,79 @@
     See also comments get_merge_many_buffs_cost().
 */
 
-#define FILESORT_UTILS_INCLUDED
 double get_merge_many_buffs_cost_fast(ha_rows num_rows,
                                       ha_rows num_keys_per_buffer,
                                       uint    elem_size);
 
+
+/**
+  A wrapper class around the buffer used by filesort().
+  The buffer is a contiguous chunk of memory,
+  where the first part is <num_records> pointers to the actual data.
+
+  We wrap the buffer in order to be able to do lazy initialization of the
+  pointers: the buffer is often much larger than what we actually need.
+
+  The buffer must be kept available for multiple executions of the
+  same sort operation, so we have explicit allocate and free functions,
+  rather than doing alloc/free in CTOR/DTOR.
+ */
+class Filesort_buffer
+{
+public:
+  Filesort_buffer() :
+    m_idx_array(), m_record_length(0), m_start_of_data(NULL)
+  {}
+
+  /// Initializes a record pointer.
+  uchar *get_record_buffer(uint idx)
+  {
+    m_idx_array[idx]= m_start_of_data + (idx * m_record_length);
+    return m_idx_array[idx];
+  }
+
+  /// Initializes all the record pointers.
+  void init_record_pointers()
+  {
+    for (uint ix= 0; ix < m_idx_array.size(); ++ix)
+      (void) get_record_buffer(ix);
+  }
+
+  /// Returns total size: pointer array + record buffers.
+  size_t sort_buffer_size() const
+  {
+    return m_idx_array.size() * (m_record_length + sizeof(uchar*));
+  }
+
+  /// Allocates the buffer, but does *not* initialize pointers.
+  uchar **alloc_sort_buffer(uint num_records, uint record_length);
+
+  /// Frees the buffer.
+  void free_sort_buffer();
+
+  /// Getter, for calling routines which still use the uchar** interface.
+  uchar **get_sort_keys() { return m_idx_array.array(); }
+
+  /**
+    We need an assignment operator, see filesort().
+    This happens to have the same semantics as the one that would be
+    generated by the compiler. We still implement it here, to show shallow
+    assignment explicitly: we have two objects sharing the same array.
+  */
+  Filesort_buffer &operator=(const Filesort_buffer &rhs)
+  {
+    m_idx_array= rhs.m_idx_array;
+    m_record_length= rhs.m_record_length;
+    m_start_of_data= rhs.m_start_of_data;
+    return *this;
+  }
+
+private:
+  typedef Bounds_checked_array<uchar*> Idx_array;
+
+  Idx_array  m_idx_array;
+  uint       m_record_length;
+  uchar     *m_start_of_data;
+};
+
 #endif  // FILESORT_UTILS_INCLUDED

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2011-10-11 04:27:52 +0000
+++ b/sql/mdl.cc	2011-11-08 09:59:12 +0000
@@ -92,7 +92,7 @@ void MDL_key::init_psi_keys()
 {
   int i;
   int count;
-  PSI_stage_info *info;
+  PSI_stage_info *info __attribute__((unused));
 
   count= array_elements(MDL_key::m_namespace_to_wait_state_name);
   for (i= 0; i<count; i++)

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2011-11-03 16:03:34 +0000
+++ b/sql/mysqld.cc	2011-11-08 04:28:05 +0000
@@ -708,6 +708,7 @@ void set_remaining_args(int argc, char *
 PSI_statement_info stmt_info_new_packet;
 #endif
 
+#ifndef EMBEDDED_LIBRARY
 void net_before_header_psi(struct st_net *net, void *user_data, size_t /* unused: count */)
 {
   THD *thd;
@@ -783,6 +784,7 @@ void init_net_server_extension(THD *thd)
   thd->net.extension= NULL;
 #endif
 }
+#endif /* EMBEDDED_LIBRARY */
 
 /*
   Since buffered_option_error_reporter is only used currently

=== modified file 'sql/opt_trace.h'
--- a/sql/opt_trace.h	2011-10-28 12:45:35 +0000
+++ b/sql/opt_trace.h	2011-11-08 19:52:19 +0000
@@ -1120,14 +1120,6 @@ void opt_trace_disable_if_no_stored_proc
 */
 int fill_optimizer_trace_info(THD *thd, TABLE_LIST *tables, Item *cond);
 
-/**
-   Create fields' descriptions of information_schema.OPTIMIZER_TRACE
-   @retval 0 ok
-   @retval 1 out of memory
-*/
-int make_optimizer_trace_table_for_show(THD *thd,
-                                        st_schema_table *schema_table);
-
 //@}
 
 #else /* defined (OPTIMIZER_TRACE) */

=== modified file 'sql/opt_trace2server.cc'
--- a/sql/opt_trace2server.cc	2011-10-05 13:16:38 +0000
+++ b/sql/opt_trace2server.cc	2011-11-08 19:52:19 +0000
@@ -500,7 +500,6 @@ void opt_trace_disable_if_no_tables_acce
 
 int fill_optimizer_trace_info(THD *thd, TABLE_LIST *tables, Item *cond)
 {
-#ifdef OPTIMIZER_TRACE
   TABLE *table= tables->table;
   Opt_trace_info info;
 
@@ -556,13 +555,9 @@ int fill_optimizer_trace_info(THD *thd,
   }
 
   return 0;
-#else
-  my_error(ER_FEATURE_DISABLED, MYF(0), "optimizer trace",
-           "-DOPTIMIZER_TRACE=1");
-  return 1;
-#endif
 }
 
+#endif // OPTIMIZER_TRACE
 
 ST_FIELD_INFO optimizer_trace_info[]=
 {
@@ -577,30 +572,6 @@ ST_FIELD_INFO optimizer_trace_info[]=
 };
 
 
-int make_optimizer_trace_table_for_show(THD *thd,
-                                        ST_SCHEMA_TABLE *schema_table)
-{
-  Name_resolution_context *context= &thd->lex->select_lex.context;
-
-  for (int i= 0; schema_table->fields_info[i].field_name != NULL; i++)
-  {
-    ST_FIELD_INFO *field_info= &schema_table->fields_info[i];
-    Item_field *field= new Item_field(context,
-                                      NullS, NullS, field_info->field_name);
-    if (field)
-    {
-      field->set_name(field_info->old_name,
-                      static_cast<uint>(strlen(field_info->old_name)),
-                      system_charset_info);
-      if (add_item_to_list(thd, field))
-        return 1;
-    }
-    else
-      return 1;
-  }
-  return 0;
-}
-
 /*
   LiteralsWithIntroducers :
 
@@ -630,5 +601,3 @@ int make_optimizer_trace_table_for_show(
   there would be no problem ('0', 'x', 'E', and 'D' are identical in latin1
   and utf8: they would be preserved during conversion).
 */
-
-#endif // OPTIMIZER_TRACE

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-11-02 23:29:01 +0000
+++ b/sql/sql_class.h	2011-11-08 04:28:05 +0000
@@ -2362,20 +2362,19 @@ public:
 
   /** Current statement instrumentation. */
   PSI_statement_locker *m_statement_psi;
-#ifdef HAVE_PSI_STATEMENT_INTERFACE
+#ifndef EMBEDDED_LIBRARY
   /** Current statement instrumentation state. */
   PSI_statement_locker_state m_statement_state;
-#endif
+#endif /* EMBEDDED_LIBRARY */
   /** Idle instrumentation. */
   PSI_idle_locker *m_idle_psi;
-#ifdef HAVE_PSI_IDLE_INTERFACE
+#ifndef EMBEDDED_LIBRARY
   /** Idle instrumentation state. */
   PSI_idle_locker_state m_idle_state;
-#endif
+#endif /* EMBEDDED_LIBRARY */
   /** True if the server code is IDLE for this connection. */
   bool m_server_idle;
 
-
   /*
     Id of current query. Statement can be reused to execute several queries
     query_id is global in context of the whole MySQL server.

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-11-03 16:03:34 +0000
+++ b/sql/sql_parse.cc	2011-11-08 04:28:05 +0000
@@ -1597,14 +1597,15 @@ bool dispatch_command(enum enum_server_c
 
   thd->reset_query();
   thd->set_command(COM_SLEEP);
-  dec_thread_running();
-  thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
-  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
   /* Performance Schema Interface instrumentation, end */
   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
   thd->m_statement_psi= NULL;
 
+  dec_thread_running();
+  thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
+  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
+
   /* DTRACE instrumentation, end */
   if (MYSQL_QUERY_DONE_ENABLED() || MYSQL_COMMAND_DONE_ENABLED())
   {

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-11-03 16:03:34 +0000
+++ b/sql/sql_select.cc	2011-11-04 15:20:13 +0000
@@ -18468,6 +18468,8 @@ bool instantiate_tmp_table(TABLE *table,
     if (create_myisam_tmp_table(table, keyinfo, start_recinfo, recinfo,
                                 options, big_tables))
       return TRUE;
+    // Make empty record so random data is not written to disk
+    empty_record(table);
   }
   if (open_tmp_table(table))
     return TRUE;

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2011-10-13 07:26:28 +0000
+++ b/sql/sql_show.cc	2011-11-08 19:52:19 +0000
@@ -7840,10 +7840,8 @@ ST_FIELD_INFO tablespaces_fields_info[]=
 };
 
 
-#ifdef OPTIMIZER_TRACE
 /** For creating fields of information_schema.OPTIMIZER_TRACE */
 extern ST_FIELD_INFO optimizer_trace_info[];
-#endif
 
 /*
   Description of ST_FIELD_INFO in table.h
@@ -7870,7 +7868,7 @@ ST_SCHEMA_TABLE schema_tables[]=
 #ifdef HAVE_EVENT_SCHEDULER
   {"EVENTS", events_fields_info, create_schema_table,
    Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
-#else
+#else // for alignment with enum_schema_tables
   {"EVENTS", events_fields_info, create_schema_table,
    0, make_old_format, 0, -1, -1, 0, 0},
 #endif
@@ -7887,8 +7885,10 @@ ST_SCHEMA_TABLE schema_tables[]=
    fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
 #ifdef OPTIMIZER_TRACE
   {"OPTIMIZER_TRACE", optimizer_trace_info, create_schema_table,
-    fill_optimizer_trace_info, make_optimizer_trace_table_for_show,
-    NULL, -1, -1, false, 0},
+   fill_optimizer_trace_info, NULL, NULL, -1, -1, false, 0},
+#else // for alignment with enum_schema_tables
+  {"OPTIMIZER_TRACE", optimizer_trace_info, create_schema_table,
+   NULL, NULL, NULL, -1, -1, false, 0},
 #endif
   {"PARAMETERS", parameters_fields_info, create_schema_table,
    fill_schema_proc, 0, 0, -1, -1, 0, 0},

=== modified file 'sql/table.h'
--- a/sql/table.h	2011-10-18 14:25:42 +0000
+++ b/sql/table.h	2011-11-07 15:32:36 +0000
@@ -28,6 +28,7 @@
 #include "handler.h"                /* row_type, ha_choice, handler */
 #include "mysql_com.h"              /* enum_field_types */
 #include "thr_lock.h"                  /* thr_lock_type */
+#include "filesort_utils.h"
 
 /* Structs that defines the TABLE */
 
@@ -300,10 +301,14 @@ enum tmp_table_type
 };
 enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
 
-typedef struct st_filesort_info
+
+class Filesort_info
 {
+  /// Buffer for sorting keys.
+  Filesort_buffer filesort_buffer;
+
+public:
   IO_CACHE *io_cache;           /* If sorted through filesort */
-  uchar     **sort_keys;        /* Buffer for sorting keys */
   uchar     *buffpek;           /* Buffer for buffpek structures */
   uint      buffpek_len;        /* Max number of buffpeks in the buffer */
   uchar     *addon_buf;         /* Pointer to a buffer if sorted with fields */
@@ -312,7 +317,28 @@ typedef struct st_filesort_info
   void    (*unpack)(struct st_sort_addon_field *, uchar *); /* To unpack back */
   uchar     *record_pointers;    /* If sorted in memory */
   ha_rows   found_records;      /* How many records in sort */
-} FILESORT_INFO;
+
+  /**
+     Accessors for Filesort_buffer (which @c).
+  */
+  uchar *get_record_buffer(uint idx)
+  { return filesort_buffer.get_record_buffer(idx); }
+
+  uchar **get_sort_keys()
+  { return filesort_buffer.get_sort_keys(); }
+
+  uchar **alloc_sort_buffer(uint num_records, uint record_length)
+  { return filesort_buffer.alloc_sort_buffer(num_records, record_length); }
+
+  void free_sort_buffer()
+  { filesort_buffer.free_sort_buffer(); }
+
+  void init_record_pointers()
+  { filesort_buffer.init_record_pointers(); }
+
+  size_t sort_buffer_size() const
+  { return filesort_buffer.sort_buffer_size(); }
+};
 
 
 /*
@@ -1134,7 +1160,7 @@ public:
   REGINFO reginfo;			/* field connections */
   MEM_ROOT mem_root;
   GRANT_INFO grant;
-  FILESORT_INFO sort;
+  Filesort_info sort;
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   partition_info *part_info;            /* Partition related information */
   bool no_partitions_used; /* If true, all partitions have been pruned away */

=== modified file 'storage/innobase/btr/btr0pcur.c'
--- a/storage/innobase/btr/btr0pcur.c	2011-09-26 07:19:04 +0000
+++ b/storage/innobase/btr/btr0pcur.c	2011-11-08 12:35:19 +0000
@@ -247,6 +247,8 @@ btr_pcur_restore_position_func(
 			cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
 			index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
 
+		cursor->latch_mode = latch_mode;
+		cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 		cursor->block_when_stored = btr_pcur_get_block(cursor);
 
 		return(FALSE);

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2011-10-27 08:20:56 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-11-07 12:04:41 +0000
@@ -6314,6 +6314,7 @@ ha_innobase::index_read(
 			(byte*) key_ptr,
 			(ulint) key_len,
 			prebuilt->trx);
+		DBUG_ASSERT(prebuilt->search_tuple->n_fields > 0);
 	} else {
 		/* We position the cursor to the last or the first entry
 		in the index */
@@ -8284,6 +8285,9 @@ ha_innobase::records_in_range(
 					 (const uchar*) 0),
 				(ulint) (min_key ? min_key->length : 0),
 				prebuilt->trx);
+	DBUG_ASSERT(min_key
+		    ? range_start->n_fields > 0
+		    : range_start->n_fields == 0);
 
 	row_sel_convert_mysql_key_to_innobase(
 				range_end, (byte*) key_val_buff2,
@@ -8292,6 +8296,9 @@ ha_innobase::records_in_range(
 					 (const uchar*) 0),
 				(ulint) (max_key ? max_key->length : 0),
 				prebuilt->trx);
+	DBUG_ASSERT(max_key
+		    ? range_end->n_fields > 0
+		    : range_end->n_fields == 0);
 
 	mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
 						HA_READ_KEY_EXACT);

=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c	2011-10-21 15:46:57 +0000
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	2011-11-08 07:02:03 +0000
@@ -248,11 +248,20 @@ ibuf_count_check(
 					list of the ibuf */
 /* @} */
 
+#define IBUF_REC_FIELD_SPACE	0	/*!< in the pre-4.1 format,
+					the page number. later, the space_id */
+#define IBUF_REC_FIELD_MARKER	1	/*!< starting with 4.1, a marker
+					consisting of 1 byte that is 0 */
+#define IBUF_REC_FIELD_PAGE	2	/*!< starting with 4.1, the
+					page number */
+#define IBUF_REC_FIELD_METADATA	3	/* the metadata field */
+#define IBUF_REC_FIELD_USER	4	/* first user field */
+
 /* Various constants for checking the type of an ibuf record and extracting
 data from it. For details, see the description of the record format at the
 top of this file. */
 
-/** @name Format of the fourth column of an insert buffer record
+/** @name Format of the IBUF_REC_FIELD_METADATA of an insert buffer record
 The fourth column in the MySQL 5.5 format contains an operation
 type, counter, and some flags. */
 /* @{ */
@@ -1246,13 +1255,13 @@ ibuf_rec_get_page_no_func(
 	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
-	field = rec_get_nth_field_old(rec, 1, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
 
 	if (len == 1) {
 		/* This is of the >= 4.1.x record format */
 		ut_a(trx_sys_multiple_tablespace_format);
 
-		field = rec_get_nth_field_old(rec, 2, &len);
+		field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len);
 	} else {
 		ut_a(trx_doublewrite_must_reset_space_ids);
 		ut_a(!trx_sys_multiple_tablespace_format);
@@ -1292,13 +1301,13 @@ ibuf_rec_get_space_func(
 	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
-	field = rec_get_nth_field_old(rec, 1, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
 
 	if (len == 1) {
 		/* This is of the >= 4.1.x record format */
 
 		ut_a(trx_sys_multiple_tablespace_format);
-		field = rec_get_nth_field_old(rec, 0, &len);
+		field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
 		ut_a(len == 4);
 
 		return(mach_read_from_4(field));
@@ -1348,9 +1357,9 @@ ibuf_rec_get_info_func(
 	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 	ut_ad(ibuf_inside(mtr));
 	fields = rec_get_n_fields_old(rec);
-	ut_a(fields > 4);
+	ut_a(fields > IBUF_REC_FIELD_USER);
 
-	types = rec_get_nth_field_old(rec, 3, &len);
+	types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
 
 	info_len_local = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
 
@@ -1376,7 +1385,8 @@ ibuf_rec_get_info_func(
 
 	ut_a(op_local < IBUF_OP_COUNT);
 	ut_a((len - info_len_local) ==
-	     (fields - 4) * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+	     (fields - IBUF_REC_FIELD_USER)
+	     * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
 
 	if (op) {
 		*op = op_local;
@@ -1420,7 +1430,7 @@ ibuf_rec_get_op_type_func(
 	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
-	(void) rec_get_nth_field_old(rec, 1, &len);
+	(void) rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
 
 	if (len > 1) {
 		/* This is a < 4.1.x format record */
@@ -1449,12 +1459,12 @@ ibuf_rec_get_counter(
 	const byte*	ptr;
 	ulint		len;
 
-	if (rec_get_n_fields_old(rec) < 4) {
+	if (rec_get_n_fields_old(rec) <= IBUF_REC_FIELD_METADATA) {
 
 		return(ULINT_UNDEFINED);
 	}
 
-	ptr = rec_get_nth_field_old(rec, 3, &len);
+	ptr = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
 
 	if (len >= 2) {
 
@@ -1679,7 +1689,7 @@ ibuf_build_entry_from_ibuf_rec_func(
 	      || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
 	ut_ad(ibuf_inside(mtr));
 
-	data = rec_get_nth_field_old(ibuf_rec, 1, &len);
+	data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len);
 
 	if (len > 1) {
 		/* This a < 4.1.x format record */
@@ -1691,13 +1701,13 @@ ibuf_build_entry_from_ibuf_rec_func(
 
 	ut_a(trx_sys_multiple_tablespace_format);
 	ut_a(*data == 0);
-	ut_a(rec_get_n_fields_old(ibuf_rec) > 4);
+	ut_a(rec_get_n_fields_old(ibuf_rec) > IBUF_REC_FIELD_USER);
 
-	n_fields = rec_get_n_fields_old(ibuf_rec) - 4;
+	n_fields = rec_get_n_fields_old(ibuf_rec) - IBUF_REC_FIELD_USER;
 
 	tuple = dtuple_create(heap, n_fields);
 
-	types = rec_get_nth_field_old(ibuf_rec, 3, &len);
+	types = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
 
 	ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
 
@@ -1711,7 +1721,8 @@ ibuf_build_entry_from_ibuf_rec_func(
 	for (i = 0; i < n_fields; i++) {
 		field = dtuple_get_nth_field(tuple, i);
 
-		data = rec_get_nth_field_old(ibuf_rec, i + 4, &len);
+		data = rec_get_nth_field_old(
+			ibuf_rec, i + IBUF_REC_FIELD_USER, &len);
 
 		dfield_set_data(field, data, len);
 
@@ -1758,7 +1769,7 @@ ibuf_rec_get_size(
 		field_offset = 2;
 		types_offset = DATA_ORDER_NULL_TYPE_BUF_SIZE;
 	} else {
-		field_offset = 4;
+		field_offset = IBUF_REC_FIELD_USER;
 		types_offset = DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
 	}
 
@@ -1819,7 +1830,7 @@ ibuf_rec_get_volume_func(
 	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
 
-	data = rec_get_nth_field_old(ibuf_rec, 1, &len);
+	data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len);
 	pre_4_1 = (len > 1);
 
 	if (pre_4_1) {
@@ -1842,7 +1853,8 @@ ibuf_rec_get_volume_func(
 		ut_a(trx_sys_multiple_tablespace_format);
 		ut_a(*data == 0);
 
-		types = rec_get_nth_field_old(ibuf_rec, 3, &len);
+		types = rec_get_nth_field_old(
+			ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
 
 		ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
 
@@ -1872,7 +1884,8 @@ ibuf_rec_get_volume_func(
 		}
 
 		types += info_len;
-		n_fields = rec_get_n_fields_old(ibuf_rec) - 4;
+		n_fields = rec_get_n_fields_old(ibuf_rec)
+			- IBUF_REC_FIELD_USER;
 	}
 
 	data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1, comp);
@@ -1927,11 +1940,11 @@ ibuf_entry_build(
 
 	n_fields = dtuple_get_n_fields(entry);
 
-	tuple = dtuple_create(heap, n_fields + 4);
+	tuple = dtuple_create(heap, n_fields + IBUF_REC_FIELD_USER);
 
 	/* 1) Space Id */
 
-	field = dtuple_get_nth_field(tuple, 0);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE);
 
 	buf = mem_heap_alloc(heap, 4);
 
@@ -1941,7 +1954,7 @@ ibuf_entry_build(
 
 	/* 2) Marker byte */
 
-	field = dtuple_get_nth_field(tuple, 1);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER);
 
 	buf = mem_heap_alloc(heap, 1);
 
@@ -1953,7 +1966,7 @@ ibuf_entry_build(
 
 	/* 3) Page number */
 
-	field = dtuple_get_nth_field(tuple, 2);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE);
 
 	buf = mem_heap_alloc(heap, 4);
 
@@ -2001,10 +2014,7 @@ ibuf_entry_build(
 		ulint			fixed_len;
 		const dict_field_t*	ifield;
 
-		/* We add 4 below because we have the 4 extra fields at the
-		start of an ibuf record */
-
-		field = dtuple_get_nth_field(tuple, i + 4);
+		field = dtuple_get_nth_field(tuple, i + IBUF_REC_FIELD_USER);
 		entry_field = dtuple_get_nth_field(entry, i);
 		dfield_copy(field, entry_field);
 
@@ -2037,13 +2047,13 @@ ibuf_entry_build(
 
 	/* 4) Type info, part #2 */
 
-	field = dtuple_get_nth_field(tuple, 3);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_METADATA);
 
 	dfield_set_data(field, type_info, ti - type_info);
 
 	/* Set all the types in the new tuple binary */
 
-	dtuple_set_types_binary(tuple, n_fields + 4);
+	dtuple_set_types_binary(tuple, n_fields + IBUF_REC_FIELD_USER);
 
 	return(tuple);
 }
@@ -2103,11 +2113,11 @@ ibuf_new_search_tuple_build(
 
 	ut_a(trx_sys_multiple_tablespace_format);
 
-	tuple = dtuple_create(heap, 3);
+	tuple = dtuple_create(heap, IBUF_REC_FIELD_METADATA);
 
 	/* Store the space id in tuple */
 
-	field = dtuple_get_nth_field(tuple, 0);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE);
 
 	buf = mem_heap_alloc(heap, 4);
 
@@ -2117,7 +2127,7 @@ ibuf_new_search_tuple_build(
 
 	/* Store the new format record marker byte */
 
-	field = dtuple_get_nth_field(tuple, 1);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER);
 
 	buf = mem_heap_alloc(heap, 1);
 
@@ -2127,7 +2137,7 @@ ibuf_new_search_tuple_build(
 
 	/* Store the page number in tuple */
 
-	field = dtuple_get_nth_field(tuple, 2);
+	field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE);
 
 	buf = mem_heap_alloc(heap, 4);
 
@@ -2135,7 +2145,7 @@ ibuf_new_search_tuple_build(
 
 	dfield_set_data(field, buf, 4);
 
-	dtuple_set_types_binary(tuple, 3);
+	dtuple_set_types_binary(tuple, IBUF_REC_FIELD_METADATA);
 
 	return(tuple);
 }
@@ -2822,8 +2832,10 @@ ibuf_get_volume_buffered_hash(
 	ulint		fold;
 	ulint		bitmask;
 
-	len = ibuf_rec_get_size(rec, types, rec_get_n_fields_old(rec) - 4,
-				FALSE, comp);
+	len = ibuf_rec_get_size(
+		rec, types,
+		rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER,
+		FALSE, comp);
 	fold = ut_fold_binary(data, len);
 
 	hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
@@ -2875,8 +2887,8 @@ ibuf_get_volume_buffered_count_func(
 	ut_ad(ibuf_inside(mtr));
 
 	n_fields = rec_get_n_fields_old(rec);
-	ut_ad(n_fields > 4);
-	n_fields -= 4;
+	ut_ad(n_fields > IBUF_REC_FIELD_USER);
+	n_fields -= IBUF_REC_FIELD_USER;
 
 	rec_get_nth_field_offs_old(rec, 1, &len);
 	/* This function is only invoked when buffering new
@@ -2885,7 +2897,7 @@ ibuf_get_volume_buffered_count_func(
 	ut_a(len == 1);
 	ut_ad(trx_sys_multiple_tablespace_format);
 
-	types = rec_get_nth_field_old(rec, 3, &len);
+	types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
 
 	switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
 			    IBUF_REC_INFO_SIZE)) {
@@ -3197,7 +3209,7 @@ ibuf_update_max_tablespace_id(void)
 	} else {
 		rec = btr_pcur_get_rec(&pcur);
 
-		field = rec_get_nth_field_old(rec, 0, &len);
+		field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
 
 		ut_a(len == 4);
 
@@ -3219,10 +3231,12 @@ ibuf_update_max_tablespace_id(void)
 	ibuf_get_entry_counter_low_func(rec,space,page_no)
 #endif
 /****************************************************************//**
-Helper function for ibuf_set_entry_counter. Checks if rec is for (space,
-page_no), and if so, reads counter value from it and returns that + 1.
-Otherwise, returns 0.
-@return	new counter value, or 0 */
+Helper function for ibuf_get_entry_counter_func. Checks if rec is for
+(space, page_no), and if so, reads counter value from it and returns
+that + 1.
+@retval ULINT_UNDEFINED if the record does not contain any counter
+@retval 0 if the record is not for (space, page_no)
+@retval 1 + previous counter value, otherwise */
 static
 ulint
 ibuf_get_entry_counter_low_func(
@@ -3243,7 +3257,7 @@ ibuf_get_entry_counter_low_func(
 	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
-	field = rec_get_nth_field_old(rec, 1, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
 
 	if (UNIV_UNLIKELY(len != 1)) {
 		/* pre-4.1 format */
@@ -3256,7 +3270,7 @@ ibuf_get_entry_counter_low_func(
 	ut_a(trx_sys_multiple_tablespace_format);
 
 	/* Check the tablespace identifier. */
-	field = rec_get_nth_field_old(rec, 0, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
 	ut_a(len == 4);
 
 	if (mach_read_from_4(field) != space) {
@@ -3265,7 +3279,7 @@ ibuf_get_entry_counter_low_func(
 	}
 
 	/* Check the page offset. */
-	field = rec_get_nth_field_old(rec, 2, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len);
 	ut_a(len == 4);
 
 	if (mach_read_from_4(field) != page_no) {
@@ -3274,7 +3288,7 @@ ibuf_get_entry_counter_low_func(
 	}
 
 	/* Check if the record contains a counter field. */
-	field = rec_get_nth_field_old(rec, 3, &len);
+	field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
 
 	switch (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
 	default:
@@ -3290,147 +3304,61 @@ ibuf_get_entry_counter_low_func(
 	}
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
+	ibuf_get_entry_counter_func(space,page_no,rec,mtr,exact_leaf)
+#else /* UNIV_DEBUG */
+# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
+	ibuf_get_entry_counter_func(space,page_no,rec,exact_leaf)
+#endif
+
 /****************************************************************//**
-Set the counter field in entry to the correct value based on the current
+Calculate the counter field for an entry based on the current
 last record in ibuf for (space, page_no).
-@return	FALSE if we should abort this insertion to ibuf */
+@return	the counter field, or ULINT_UNDEFINED
+if we should abort this insertion to ibuf */
 static
-ibool
-ibuf_set_entry_counter(
-/*===================*/
-	dtuple_t*	entry,		/*!< in/out: entry to patch */
+ulint
+ibuf_get_entry_counter_func(
+/*========================*/
 	ulint		space,		/*!< in: space id of entry */
 	ulint		page_no,	/*!< in: page number of entry */
-	btr_pcur_t*	pcur,		/*!< in: pcur positioned on the record
-					found by btr_pcur_open(.., entry,
-					PAGE_CUR_LE, ..., pcur, ...) */
-	ibool		is_optimistic,	/*!< in: is this an optimistic insert */
-	mtr_t*		mtr)		/*!< in: mtr */
+	const rec_t*	rec,		/*!< in: the record preceding the
+					insertion point */
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,		/*!< in: mini-transaction */
+#endif /* UNIV_DEBUG */
+	ibool		only_leaf)	/*!< in: TRUE if this is the only
+					leaf page that can contain entries
+					for (space,page_no), that is, there
+					was no exact match for (space,page_no)
+					in the node pointer */
 {
-	dfield_t*	field;
-	byte*		data;
-	ulint		counter = 0;
-
-	/* pcur points to either a user rec or to a page's infimum record. */
 	ut_ad(ibuf_inside(mtr));
-	ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
-				MTR_MEMO_PAGE_X_FIX));
-	ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index));
-
-	if (btr_pcur_is_on_user_rec(pcur)) {
-
-		counter = ibuf_get_entry_counter_low(
-			mtr, btr_pcur_get_rec(pcur), space, page_no);
-
-		if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
-			/* The record lacks a counter field.
-			Such old records must be merged before
-			new records can be buffered. */
-
-			return(FALSE);
-		}
-	} else if (btr_pcur_is_before_first_in_tree(pcur, mtr)) {
-		/* Ibuf tree is either completely empty, or the insert
-		position is at the very first record of a non-empty tree. In
-		either case we have no previous records for (space,
-		page_no). */
-
-		counter = 0;
-	} else if (btr_pcur_is_before_first_on_page(pcur)) {
-		btr_cur_t*	cursor = btr_pcur_get_btr_cur(pcur);
-
-		if (cursor->low_match < 3) {
-			/* If low_match < 3, we know that the father node
-			pointer did not contain the searched for (space,
-			page_no), which means that the search ended on the
-			right page regardless of the counter value, and
-			since we're at the infimum record, there are no
-			existing records. */
-
-			counter = 0;
-		} else {
-			rec_t*		rec;
-			const page_t*	page;
-			buf_block_t*	block;
-			page_t*		prev_page;
-			ulint		prev_page_no;
-
-			ut_a(cursor->ibuf_cnt != ULINT_UNDEFINED);
-
-			page = btr_pcur_get_page(pcur);
-			prev_page_no = btr_page_get_prev(page, mtr);
-
-			ut_a(prev_page_no != FIL_NULL);
-
-			block = buf_page_get(
-				IBUF_SPACE_ID, 0, prev_page_no,
-				RW_X_LATCH, mtr);
-
-			buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
-
-			prev_page = buf_block_get_frame(block);
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(page_validate(page_align(rec), ibuf->index));
 
-			rec = page_rec_get_prev(
-				page_get_supremum_rec(prev_page));
-
-			ut_ad(page_rec_is_user_rec(rec));
-
-			counter = ibuf_get_entry_counter_low(
-				mtr, rec, space, page_no);
-
-			if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
-				/* The record lacks a counter field.
-				Such old records must be merged before
-				new records can be buffered. */
-
-				return(FALSE);
-			}
-
-			if (counter < cursor->ibuf_cnt) {
-				/* Search ended on the wrong page. */
-
-				if (is_optimistic) {
-					/* In an optimistic insert, we can
-					shift the insert position to the left
-					page, since it only needs an X-latch
-					on the page itself, which the
-					original search acquired for us. */
-
-					btr_cur_position(
-						ibuf->index, rec, block,
-						btr_pcur_get_btr_cur(pcur));
-				} else {
-					/* We can't shift the insert
-					position to the left page in a
-					pessimistic insert since it would
-					require an X-latch on the left
-					page's left page, so we have to
-					abort. */
-
-					return(FALSE);
-				}
-			} else {
-				/* The counter field in the father node is
-				the same as we would insert; we don't know
-				whether the insert should go to this page or
-				the left page (the later fields can differ),
-				so refuse the insert. */
-
-				return(FALSE);
-			}
-		}
+	if (page_rec_is_supremum(rec)) {
+		/* This is just for safety. The record should be a
+		page infimum or a user record. */
+		ut_ad(0);
+		return(ULINT_UNDEFINED);
+	} else if (!page_rec_is_infimum(rec)) {
+		return(ibuf_get_entry_counter_low(mtr, rec, space, page_no));
+	} else if (only_leaf
+		   || fil_page_get_prev(page_align(rec)) == FIL_NULL) {
+		/* The parent node pointer did not contain the
+		searched for (space, page_no), which means that the
+		search ended on the correct page regardless of the
+		counter value, and since we're at the infimum record,
+		there are no existing records. */
+		return(0);
 	} else {
-		/* The cursor is not positioned at or before a user record. */
-		return(FALSE);
+		/* We used to read the previous page here. It would
+		break the latching order, because the caller has
+		buffer-fixed an insert buffer bitmap page. */
+		return(ULINT_UNDEFINED);
 	}
-
-	/* Patch counter value in already built entry. */
-	field = dtuple_get_nth_field(entry, 3);
-	data = dfield_get_data(field);
-
-	mach_write_to_2(data + IBUF_REC_OFFSET_COUNTER, counter);
-
-	return(TRUE);
 }
 
 /*********************************************************************//**
@@ -3639,16 +3567,27 @@ fail_exit:
 		}
 	}
 
-	/* Patch correct counter value to the entry to insert. This can
-	change the insert position, which can result in the need to abort in
-	some cases. */
-	if (!no_counter
-	    && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
-				       mode == BTR_MODIFY_PREV, &mtr)) {
+	if (!no_counter) {
+		/* Patch correct counter value to the entry to
+		insert. This can change the insert position, which can
+		result in the need to abort in some cases. */
+		ulint		counter = ibuf_get_entry_counter(
+			space, page_no, btr_pcur_get_rec(&pcur), &mtr,
+			btr_pcur_get_btr_cur(&pcur)->low_match
+			< IBUF_REC_FIELD_METADATA);
+		dfield_t*	field;
+
+		if (counter == ULINT_UNDEFINED) {
 bitmap_fail:
-		ibuf_mtr_commit(&bitmap_mtr);
+			ibuf_mtr_commit(&bitmap_mtr);
+			goto fail_exit;
+		}
 
-		goto fail_exit;
+		field = dtuple_get_nth_field(
+			ibuf_entry, IBUF_REC_FIELD_METADATA);
+		mach_write_to_2(
+			(byte*) dfield_get_data(field)
+			+ IBUF_REC_OFFSET_COUNTER, counter);
 	}
 
 	/* Set the bitmap bit denoting that the insert buffer contains

=== modified file 'storage/innobase/include/btr0pcur.h'
--- a/storage/innobase/include/btr0pcur.h	2011-09-21 11:01:41 +0000
+++ b/storage/innobase/include/btr0pcur.h	2011-11-08 12:35:19 +0000
@@ -264,14 +264,6 @@ btr_pcur_commit_specify_mtr(
 /*========================*/
 	btr_pcur_t*	pcur,	/*!< in: persistent cursor */
 	mtr_t*		mtr);	/*!< in: mtr to commit */
-/**************************************************************//**
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
-@return	TRUE if detached */
-UNIV_INLINE
-ibool
-btr_pcur_is_detached(
-/*=================*/
-	btr_pcur_t*	pcur);	/*!< in: persistent cursor */
 /*********************************************************//**
 Moves the persistent cursor to the next record in the tree. If no records are
 left, the cursor stays 'after last in tree'.

=== modified file 'storage/innobase/include/btr0pcur.ic'
--- a/storage/innobase/include/btr0pcur.ic	2011-09-21 11:01:41 +0000
+++ b/storage/innobase/include/btr0pcur.ic	2011-11-08 12:35:19 +0000
@@ -389,38 +389,6 @@ btr_pcur_commit_specify_mtr(
 }
 
 /**************************************************************//**
-Sets the pcur latch mode to BTR_NO_LATCHES. */
-UNIV_INLINE
-void
-btr_pcur_detach(
-/*============*/
-	btr_pcur_t*	pcur)	/*!< in: persistent cursor */
-{
-	ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
-
-	pcur->latch_mode = BTR_NO_LATCHES;
-
-	pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
-}
-
-/**************************************************************//**
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
-@return	TRUE if detached */
-UNIV_INLINE
-ibool
-btr_pcur_is_detached(
-/*=================*/
-	btr_pcur_t*	pcur)	/*!< in: persistent cursor */
-{
-	if (pcur->latch_mode == BTR_NO_LATCHES) {
-
-		return(TRUE);
-	}
-
-	return(FALSE);
-}
-
-/**************************************************************//**
 Sets the old_rec_buf field to NULL. */
 UNIV_INLINE
 void

=== modified file 'unittest/gunit/CMakeLists.txt'
--- a/unittest/gunit/CMakeLists.txt	2011-10-28 12:45:35 +0000
+++ b/unittest/gunit/CMakeLists.txt	2011-11-07 15:32:36 +0000
@@ -215,6 +215,7 @@ SET(TESTS
   dbug
   decimal
   dynarray
+  filesort_buffer
   mdl
   mdl_mytap
   my_bitmap

=== added file 'unittest/gunit/filesort_buffer-t.cc'
--- a/unittest/gunit/filesort_buffer-t.cc	1970-01-01 00:00:00 +0000
+++ b/unittest/gunit/filesort_buffer-t.cc	2011-11-07 15:32:36 +0000
@@ -0,0 +1,87 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA */
+
+// First include (the generated) my_config.h, to get correct platform defines,
+// then gtest.h (before any other MySQL headers), to avoid min() macros etc ...
+#include "my_config.h"
+#include <gtest/gtest.h>
+
+#include "filesort_utils.h"
+#include "table.h"
+
+
+namespace {
+
+class FileSortBufferTest : public ::testing::Test
+{
+protected:
+  virtual void TearDown()
+  {
+    fs_info.free_sort_buffer();
+  }
+
+  Filesort_info fs_info;
+};
+
+
+TEST_F(FileSortBufferTest, FileSortBuffer)
+{
+  const char letters[10]= "abcdefghi";
+  uchar **sort_keys= fs_info.alloc_sort_buffer(10, sizeof(char));
+  uchar **null_sort_keys= NULL;
+  EXPECT_NE(null_sort_keys, sort_keys);
+  for (uint ix= 0; ix < 10; ++ix)
+  {
+    uchar *ptr= fs_info.get_record_buffer(ix);
+    *ptr= letters[ix];
+  }
+  uchar *data= *fs_info.get_sort_keys();
+  const char *str= reinterpret_cast<const char*>(data);
+  EXPECT_STREQ(letters, str);
+
+  const size_t expected_size= 10 * (sizeof(char*) + sizeof(char));
+  EXPECT_EQ(expected_size, fs_info.sort_buffer_size());
+}
+
+
+TEST_F(FileSortBufferTest, InitRecordPointers)
+{
+  fs_info.alloc_sort_buffer(10, sizeof(char));
+  fs_info.init_record_pointers();
+  uchar **ptr= fs_info.get_sort_keys();
+  for (uint ix= 0; ix < 10 - 1; ++ix)
+  {
+    uchar **nxt= ptr + 1;
+    EXPECT_EQ(1, *nxt - *ptr);
+    ++ptr;
+  }
+}
+
+
+TEST_F(FileSortBufferTest, AssignmentOperator)
+{
+  fs_info.alloc_sort_buffer(10, sizeof(char));
+  Filesort_info fs_copy;
+  fs_copy= fs_info;
+  for (uint ix= 0; ix < 10 - 1; ++ix)
+  {
+    EXPECT_EQ(fs_copy.get_record_buffer(ix), fs_info.get_record_buffer(ix));
+  }
+  EXPECT_EQ(fs_copy.get_sort_keys(), fs_info.get_sort_keys());
+  EXPECT_EQ(fs_copy.sort_buffer_size(), fs_info.sort_buffer_size());
+}
+
+
+}  // namespace

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-mtr branch (bjorn.munch:3134 to 3137) Bjorn Munch11 Nov