List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:August 30 2011 10:54am
Subject:bzr push into mysql-trunk-mtr branch (bjorn.munch:3108 to 3110)
View as plain text  
 3110 Bjorn Munch	2011-08-30 [merge]
      null upmerge

 3109 Bjorn Munch	2011-08-30 [merge]
      merge from trunk

    modified:
      include/decimal.h
      mysql-test/include/subquery.inc
      mysql-test/include/subquery_sj.inc
      mysql-test/r/alter_table.result
      mysql-test/r/group_by.result
      mysql-test/r/partition_innodb.result
      mysql-test/r/subquery_nomat_nosj.result
      mysql-test/r/subquery_nomat_nosj_bka.result
      mysql-test/r/subquery_nomat_nosj_bka_nobnl.result
      mysql-test/r/subquery_none.result
      mysql-test/r/subquery_none_bka.result
      mysql-test/r/subquery_none_bka_nobnl.result
      mysql-test/r/subquery_sj_all.result
      mysql-test/r/subquery_sj_all_bka.result
      mysql-test/r/subquery_sj_all_bkaunique.result
      mysql-test/r/subquery_sj_dupsweed.result
      mysql-test/r/subquery_sj_dupsweed_bka.result
      mysql-test/r/subquery_sj_dupsweed_bkaunique.result
      mysql-test/r/subquery_sj_firstmatch.result
      mysql-test/r/subquery_sj_firstmatch_bka.result
      mysql-test/r/subquery_sj_firstmatch_bkaunique.result
      mysql-test/r/subquery_sj_loosescan.result
      mysql-test/r/subquery_sj_loosescan_bka.result
      mysql-test/r/subquery_sj_loosescan_bkaunique.result
      mysql-test/r/subquery_sj_mat.result
      mysql-test/r/subquery_sj_mat_bka.result
      mysql-test/r/subquery_sj_mat_bkaunique.result
      mysql-test/r/subquery_sj_mat_nosj.result
      mysql-test/r/subquery_sj_none.result
      mysql-test/r/subquery_sj_none_bka.result
      mysql-test/r/subquery_sj_none_bka_nobnl.result
      mysql-test/r/subquery_sj_none_bkaunique.result
      mysql-test/r/type_newdecimal.result
      mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result
      mysql-test/suite/perfschema/r/socket_summary_by_instance_func_win.result
      mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test
      mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test
      mysql-test/t/alter_table.test
      mysql-test/t/group_by.test
      mysql-test/t/partition_innodb.test
      mysql-test/t/type_newdecimal.test
      mysql-test/valgrind.supp
      sql/filesort.cc
      sql/my_decimal.h
      sql/sql_select.cc
      sql/sql_table.cc
      sql/table.cc
      storage/innobase/btr/btr0btr.c
      storage/innobase/btr/btr0cur.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0checksum.c
      storage/innobase/dict/dict0dict.c
      storage/innobase/dict/dict0load.c
      storage/innobase/dict/dict0stats.c
      storage/innobase/fil/fil0fil.c
      storage/innobase/fsp/fsp0fsp.c
      storage/innobase/include/btr0btr.h
      storage/innobase/include/btr0cur.h
      storage/innobase/include/buf0buf.h
      storage/innobase/include/buf0checksum.h
      storage/innobase/include/buf0types.h
      storage/innobase/include/dict0dict.h
      storage/innobase/include/fsp0fsp.h
      storage/innobase/include/mtr0mtr.h
      storage/innobase/include/mtr0mtr.ic
      storage/innobase/include/srv0srv.h
      storage/innobase/include/sync0sync.ic
      storage/innobase/mtr/mtr0mtr.c
      storage/innobase/page/page0zip.c
      storage/innobase/row/row0ins.c
      storage/innobase/row/row0row.c
      storage/innobase/row/row0upd.c
      storage/innobase/srv/srv0srv.c
      storage/innobase/sync/sync0sync.c
      storage/innobase/trx/trx0undo.c
      strings/decimal.c
      unittest/gunit/my_decimal-t.cc
 3108 Bjorn Munch	2011-08-26 [merge]
      merge some more from trunk

    modified:
      dbug/dbug.c
      mysql-test/collections/default.experimental
      mysql-test/include/range.inc
      mysql-test/r/derived.result
      mysql-test/r/range_icp.result
      mysql-test/r/range_icp_mrr.result
      mysql-test/r/range_mrr.result
      mysql-test/r/range_mrr_cost.result
      mysql-test/r/range_none.result
      mysql-test/suite/rpl/r/rpl_spec_variables.result
      mysql-test/suite/rpl/t/disabled.def
      mysql-test/suite/rpl/t/rpl_spec_variables.test
      mysql-test/t/derived.test
      sql/filesort.cc
      sql/opt_range.cc
      sql/records.cc
      sql/sql_base.cc
      sql/sql_select.cc
      sql/uniques.cc
=== modified file 'include/decimal.h'
--- a/include/decimal.h	2011-06-30 15:46:53 +0000
+++ b/include/decimal.h	2011-08-29 09:34:48 +0000
@@ -21,6 +21,15 @@ typedef enum
   decimal_round_mode;
 typedef int32 decimal_digit_t;
 
+/**
+    intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
+         before the point
+    frac is the number of decimal digits after the point
+    len  is the length of buf (length of allocated space) in decimal_digit_t's,
+         not in bytes
+    sign false means positive, true means negative
+    buf  is an array of decimal_digit_t's
+ */
 typedef struct st_decimal_t {
   int    intg, frac, len;
   my_bool sign;

=== modified file 'mysql-test/include/subquery.inc'
--- a/mysql-test/include/subquery.inc	2011-08-17 10:30:04 +0000
+++ b/mysql-test/include/subquery.inc	2011-08-26 13:26:33 +0000
@@ -4058,6 +4058,37 @@ SET SESSION sql_mode=@old_sql_mode;
 
 DROP TABLE t1, t2;
 
+--echo #
+--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+--echo #
+
+create table t2(i int);
+insert into t2 values(0);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+
+CREATE TABLE t1 (
+  pk int NOT NULL,
+  col_varchar_key varchar(1) DEFAULT NULL,
+  PRIMARY KEY (pk),
+  KEY col_varchar_key (col_varchar_key)
+);
+
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+
+SET SESSION sql_mode=@old_sql_mode;
+
+drop table t2, t1;
+drop view v1;
+
 --echo End of 5.0 tests.
 
 #

=== modified file 'mysql-test/include/subquery_sj.inc'
--- a/mysql-test/include/subquery_sj.inc	2011-06-27 07:17:26 +0000
+++ b/mysql-test/include/subquery_sj.inc	2011-08-25 06:59:49 +0000
@@ -3907,4 +3907,45 @@ eval $query;
 
 DROP TABLE t1, t2;
 
---echo # End of the test for bug#12603183.
+--echo # End of test for bug#12603183.
+
+--echo #
+--echo # Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+--echo #
+
+CREATE TABLE t1 (
+ col_int_key INT NOT NULL,
+ col_datetime_key DATETIME NOT NULL,
+ col_varchar_key VARCHAR(1) NOT NULL,
+ KEY col_int_key (col_int_key),
+ KEY col_datetime_key(col_datetime_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+ (7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+ (9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+ (4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+ (5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+ (1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+ (6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+ (5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+ (204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+ (9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+ (0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+
+CREATE TABLE t2 (
+ col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+                          FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+
+DROP TABLE t1, t2;
+
+--echo # End of test for bug#12818569.

=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result	2011-07-07 10:25:51 +0000
+++ b/mysql-test/r/alter_table.result	2011-08-30 04:28:18 +0000
@@ -1461,3 +1461,17 @@ ALTER TABLE t1 FORCE;
 affected rows: 2
 info: Records: 2  Duplicates: 0  Warnings: 0
 DROP TABLE t1;
+# Bug#11748057 (formerly known as 34972): ALTER TABLE statement doesn't
+#                                         identify correct column name.
+#
+CREATE TABLE t1 (c1 int unsigned , c2 char(100) not null default '');
+ALTER TABLE t1 ADD c3 char(16) NOT NULL DEFAULT '' AFTER c2,
+MODIFY c2 char(100) NOT NULL DEFAULT '' AFTER c1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` int(10) unsigned DEFAULT NULL,
+  `c2` char(100) NOT NULL DEFAULT '',
+  `c3` char(16) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;

=== modified file 'mysql-test/r/group_by.result'
--- a/mysql-test/r/group_by.result	2011-08-17 11:50:34 +0000
+++ b/mysql-test/r/group_by.result	2011-08-30 10:04:45 +0000
@@ -1892,6 +1892,38 @@ a	AVG(t1.b)	t11c	t12c
 1	4.0000	6	6
 2	2.0000	7	7
 DROP TABLE t1;
+#
+# Bug#11765254 (58200): Assertion failed: param.sort_length when grouping
+# by functions
+#
+SET BIG_TABLES=1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0),(0);
+SELECT 1 FROM t1 GROUP BY IF(`a`,'','');
+1
+1
+SELECT 1 FROM t1 GROUP BY TRIM(LEADING RAND() FROM '');
+1
+1
+SELECT 1 FROM t1 GROUP BY SUBSTRING('',SLEEP(0),'');
+1
+1
+Warnings:
+Warning	1292	Truncated incorrect INTEGER value: ''
+Warning	1292	Truncated incorrect INTEGER value: ''
+Warning	1292	Truncated incorrect INTEGER value: ''
+SELECT 1 FROM t1 GROUP BY SUBSTRING(SYSDATE() FROM 'K' FOR 'jxW<');
+1
+1
+Warnings:
+Warning	1292	Truncated incorrect INTEGER value: 'K'
+Warning	1292	Truncated incorrect INTEGER value: 'jxW<'
+Warning	1292	Truncated incorrect INTEGER value: 'K'
+Warning	1292	Truncated incorrect INTEGER value: 'jxW<'
+Warning	1292	Truncated incorrect INTEGER value: 'K'
+Warning	1292	Truncated incorrect INTEGER value: 'jxW<'
+DROP TABLE t1;
+SET BIG_TABLES=0;
 # End of 5.1 tests
 #
 # Bug#49771: Incorrect MIN (date) when minimum value is 0000-00-00

=== modified file 'mysql-test/r/partition_innodb.result'
--- a/mysql-test/r/partition_innodb.result	2010-12-17 11:28:59 +0000
+++ b/mysql-test/r/partition_innodb.result	2011-08-29 07:08:18 +0000
@@ -29,7 +29,8 @@ DROP TABLE t1;
 # Bug#54747: Deadlock between REORGANIZE PARTITION and
 #            SELECT is not detected
 #
-SET @old_innodb_thread_concurrency:= @@innodb_thread_concurrency;
+SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency;
+SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay;
 SET GLOBAL innodb_thread_concurrency = 1;
 CREATE TABLE t1
 (user_num BIGINT,
@@ -60,6 +61,7 @@ COMMIT;
 # con1, reaping ALTER.
 # Disconnecting con1 and switching to default. Cleaning up.
 SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency;
+SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay;
 DROP TABLE t1;
 #
 # Bug#50418: DROP PARTITION does not interact with transactions

=== modified file 'mysql-test/r/subquery_nomat_nosj.result'
--- a/mysql-test/r/subquery_nomat_nosj.result	2011-08-19 11:39:15 +0000
+++ b/mysql-test/r/subquery_nomat_nosj.result	2011-08-30 10:04:45 +0000
@@ -5184,6 +5184,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_nomat_nosj_bka.result'
--- a/mysql-test/r/subquery_nomat_nosj_bka.result	2011-08-19 11:41:38 +0000
+++ b/mysql-test/r/subquery_nomat_nosj_bka.result	2011-08-26 13:26:33 +0000
@@ -5185,6 +5185,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_nomat_nosj_bka_nobnl.result'
--- a/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result	2011-08-19 11:41:38 +0000
+++ b/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result	2011-08-26 13:26:33 +0000
@@ -5185,6 +5185,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_none.result'
--- a/mysql-test/r/subquery_none.result	2011-08-19 11:39:15 +0000
+++ b/mysql-test/r/subquery_none.result	2011-08-30 10:04:45 +0000
@@ -5183,6 +5183,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_none_bka.result'
--- a/mysql-test/r/subquery_none_bka.result	2011-08-19 11:41:38 +0000
+++ b/mysql-test/r/subquery_none_bka.result	2011-08-26 13:26:33 +0000
@@ -5184,6 +5184,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_none_bka_nobnl.result'
--- a/mysql-test/r/subquery_none_bka_nobnl.result	2011-08-19 11:41:38 +0000
+++ b/mysql-test/r/subquery_none_bka_nobnl.result	2011-08-26 13:26:33 +0000
@@ -5184,6 +5184,30 @@ SELECT 1 FROM t1 WHERE 1 < SOME (SELECT
 1
 SET SESSION sql_mode=@old_sql_mode;
 DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS  
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
 End of 5.0 tests.
 create table t_out (subcase char(3),
 a1 char(2), b1 char(2), c1 char(2));

=== modified file 'mysql-test/r/subquery_sj_all.result'
--- a/mysql-test/r/subquery_sj_all.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_all.result	2011-08-25 06:59:49 +0000
@@ -6594,5 +6594,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_all_bka.result'
--- a/mysql-test/r/subquery_sj_all_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_all_bka.result	2011-08-25 06:59:49 +0000
@@ -6595,6 +6595,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_all_bkaunique.result'
--- a/mysql-test/r/subquery_sj_all_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_all_bkaunique.result	2011-08-25 06:59:49 +0000
@@ -6596,6 +6596,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_dupsweed.result'
--- a/mysql-test/r/subquery_sj_dupsweed.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed.result	2011-08-29 13:03:30 +0000
@@ -6594,5 +6594,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_dupsweed_bka.result'
--- a/mysql-test/r/subquery_sj_dupsweed_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed_bka.result	2011-08-29 13:03:30 +0000
@@ -6595,6 +6595,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_dupsweed_bkaunique.result'
--- a/mysql-test/r/subquery_sj_dupsweed_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed_bkaunique.result	2011-08-29 13:03:30 +0000
@@ -6596,6 +6596,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_firstmatch.result'
--- a/mysql-test/r/subquery_sj_firstmatch.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch.result	2011-08-25 06:59:49 +0000
@@ -6595,7 +6595,45 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 #
 # Bug#51457 Firstmatch semijoin strategy gives wrong results for
 #           certain query plans

=== modified file 'mysql-test/r/subquery_sj_firstmatch_bka.result'
--- a/mysql-test/r/subquery_sj_firstmatch_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch_bka.result	2011-08-25 06:59:49 +0000
@@ -6596,7 +6596,45 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 #
 # Bug#51457 Firstmatch semijoin strategy gives wrong results for
 #           certain query plans

=== modified file 'mysql-test/r/subquery_sj_firstmatch_bkaunique.result'
--- a/mysql-test/r/subquery_sj_firstmatch_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch_bkaunique.result	2011-08-25 06:59:49 +0000
@@ -6597,7 +6597,45 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 #
 # Bug#51457 Firstmatch semijoin strategy gives wrong results for
 #           certain query plans

=== modified file 'mysql-test/r/subquery_sj_loosescan.result'
--- a/mysql-test/r/subquery_sj_loosescan.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_loosescan.result	2011-08-29 13:03:30 +0000
@@ -6595,5 +6595,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_loosescan_bka.result'
--- a/mysql-test/r/subquery_sj_loosescan_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_loosescan_bka.result	2011-08-29 13:03:30 +0000
@@ -6596,6 +6596,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_loosescan_bkaunique.result'
--- a/mysql-test/r/subquery_sj_loosescan_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_loosescan_bkaunique.result	2011-08-29 13:03:30 +0000
@@ -6597,6 +6597,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_mat.result'
--- a/mysql-test/r/subquery_sj_mat.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_mat.result	2011-08-29 13:03:30 +0000
@@ -6594,5 +6594,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_mat_bka.result'
--- a/mysql-test/r/subquery_sj_mat_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_mat_bka.result	2011-08-29 13:03:30 +0000
@@ -6595,6 +6595,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_mat_bkaunique.result'
--- a/mysql-test/r/subquery_sj_mat_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_mat_bkaunique.result	2011-08-29 13:03:30 +0000
@@ -6596,6 +6596,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_mat_nosj.result'
--- a/mysql-test/r/subquery_sj_mat_nosj.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_mat_nosj.result	2011-08-25 06:59:49 +0000
@@ -6671,5 +6671,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_none.result'
--- a/mysql-test/r/subquery_sj_none.result	2011-08-03 11:29:20 +0000
+++ b/mysql-test/r/subquery_sj_none.result	2011-08-25 06:59:49 +0000
@@ -6606,5 +6606,43 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_none_bka.result'
--- a/mysql-test/r/subquery_sj_none_bka.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_none_bka.result	2011-08-25 06:59:49 +0000
@@ -6607,6 +6607,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_none_bka_nobnl.result'
--- a/mysql-test/r/subquery_sj_none_bka_nobnl.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_none_bka_nobnl.result	2011-08-29 13:03:30 +0000
@@ -6607,6 +6607,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/subquery_sj_none_bkaunique.result'
--- a/mysql-test/r/subquery_sj_none_bkaunique.result	2011-08-18 09:21:45 +0000
+++ b/mysql-test/r/subquery_sj_none_bkaunique.result	2011-08-25 06:59:49 +0000
@@ -6608,6 +6608,44 @@ w
 -- Notice that Materialize-scan algorithm reports wrong result for this query.
 -- This problem will be filed as a separate bug and dealt with in WL#5561.
 DROP TABLE t1, t2;
-# End of the test for bug#12603183.
+# End of test for bug#12603183.
+#
+# Bug#12818569: Diff nr of rows returned when using IN/ALL+subquery
+#
+CREATE TABLE t1 (
+col_int_key INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_int_key (col_int_key),
+KEY col_datetime_key(col_datetime_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(7,'2004-06-06 04:22:12','v'), (0,'2005-11-13 01:12:31','s'),
+(9,'2002-05-04 01:50:00','l'), (3,'2004-10-27 10:28:45','y'),
+(4,'2006-07-22 05:24:23','c'), (2,'2002-05-16 21:34:03','i'),
+(5,'2008-04-17 10:45:30','h'), (3,'2009-04-21 02:58:02','q'),
+(1,'2008-01-11 11:01:51','a'), (3,'1900-01-01 00:00:00','v'),
+(6,'2007-05-17 18:24:57','u'), (7,'2007-08-07 00:00:00','s'),
+(5,'2001-08-28 00:00:00','y'), (1,'2004-04-16 00:27:28','z'),
+(204,'2005-05-03 07:06:22','h'), (224,'2009-03-11 17:09:50','p'),
+(9,'2007-12-08 01:54:28','e'), (5,'2009-07-28 18:19:54','i'),
+(0,'2008-06-08 00:00:00','y'), (3,'2005-02-09 09:20:26','w');
+CREATE TABLE t2 (
+col_varchar_nokey VARCHAR(1) NOT NULL
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v'), ('y'), ('j'), ('c'), ('d'), ('r');
+SELECT col_varchar_key
+FROM t1
+WHERE col_varchar_key IN (SELECT col_varchar_nokey
+FROM t2)
+ORDER BY col_datetime_key LIMIT 4;
+col_varchar_key
+v
+y
+v
+y
+DROP TABLE t1, t2;
+# End of test for bug#12818569.
 set optimizer_switch=default;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/type_newdecimal.result'
--- a/mysql-test/r/type_newdecimal.result	2011-05-12 04:28:33 +0000
+++ b/mysql-test/r/type_newdecimal.result	2011-08-29 10:28:51 +0000
@@ -1934,3 +1934,14 @@ f1
 0.000000000000000000000000
 DROP TABLE IF EXISTS t1;
 End of 5.1 tests
+#
+# BUG#12911710 - VALGRIND FAILURE IN 
+# ROW-DEBUG:PERFSCHEMA.SOCKET_SUMMARY_BY_INSTANCE_FUNC 
+#
+CREATE TABLE t1(d1 DECIMAL(60,0) NOT NULL,
+d2 DECIMAL(60,0) NOT NULL);
+INSERT INTO t1 (d1, d2) VALUES(0.0, 0.0);
+SELECT d1 * d2 FROM t1;
+d1 * d2
+0
+DROP TABLE t1;

=== modified file 'mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result'
--- a/mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result	2011-08-24 14:09:20 +0000
+++ b/mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result	2011-08-27 12:50:19 +0000
@@ -12,10 +12,8 @@ SET INSTRUMENTED='NO' WHERE PROCESSLIST_
 # 1. Basic checks
 # 1.1 Check that the entry of the disconnected old default session really
 #     disappeared from performance_schema.socket_summary_by_instance.
-# 1.2 Check the impact of TRUNCATE on socket_summary_by_instance.
-#     It must reset all counters.
 TRUNCATE TABLE performance_schema.socket_summary_by_instance;
-# 1.3 Check the base line
+# 1.2 Check the base line
 TRUNCATE TABLE mysqltest.my_socket_summary_by_instance;
 # 2. Variations on Connect
 # 2.1 Connect fails because the user is unknown
@@ -201,4 +199,7 @@ col2
 # 4.6.4 Checks based on comparison of results for connects
 # 4.6.4 The user name length affects the SUM_OF_BYTES_READ value
 # 4.6.5 The database name length affects the SUM_OF_BYTES_READ value
-# 5. Cleanup
+# 5. Check the impact of TRUNCATE on socket_summary_by_instance.
+#    It must reset all counters.
+TRUNCATE TABLE performance_schema.socket_summary_by_instance;
+# 6. Cleanup

=== modified file 'mysql-test/suite/perfschema/r/socket_summary_by_instance_func_win.result'
--- a/mysql-test/suite/perfschema/r/socket_summary_by_instance_func_win.result	2011-08-20 00:36:03 +0000
+++ b/mysql-test/suite/perfschema/r/socket_summary_by_instance_func_win.result	2011-08-27 12:50:19 +0000
@@ -12,10 +12,9 @@ SET INSTRUMENTED='NO' WHERE PROCESSLIST_
 # 1. Basic checks
 # 1.1 Check that the entry of the disconnected old default session really
 #     disappeared from performance_schema.socket_summary_by_instance.
-# 1.2 Check the impact of TRUNCATE on socket_summary_by_instance.
-#     It must reset all counters.
 TRUNCATE TABLE performance_schema.socket_summary_by_instance;
-# 1.3 Check the base line
+# 1.2 Check the base line
+TRUNCATE TABLE mysqltest.my_socket_summary_by_instance;
 # 2. Variations on Connect
 # 2.1 Connect fails because the user is unknown
 #     length of user name = 4 character
@@ -97,13 +96,13 @@ col2
 #     - no change in COUNT_* leads to no change in
 #       SUM_TIMER_* and no change in SUM_NUMBER_OF_BYTES_*
 #     - increased COUNT_READ leads to increased
-#       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
+#       SUM_NUMBER_OF_BYTES_READ
 #     - increased COUNT_WRITE leads to increased
-#       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
-#     - increased COUNT_MISC leads to increased
-#       SUM_TIMER_MISC
-#       Attention: There are exceptions but they are not valid
-#                  for this test.
+#       SUM_NUMBER_OF_BYTES_WRITE
+#     Attention:
+#     The time required for some action might be below timer resolution.
+#     Therefore some increased COUNT_* does not need to lead to an
+#     increased SUM_TIMER_*.
 # 4.2 Results must be stable
 # 4.3 Counters must be 0 in client_connection for the default session
 #     Instrumenting is disabled since a long time and the counter were
@@ -179,7 +178,7 @@ col2
 #         COUNT_MISC = 0 AND SUM_TIMER_MISC = 0 must be valid
 #         because we run through server_unix_socket.
 # 4.5.2.2 For the instance with EVENT_NAME LIKE '%server_unix_socket'
-#         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+#         COUNT_MISC > 0 must be valid.
 # SKIPPED FOR WINDOWS
 # 4.5.3 Connects using for host a value <> 'localhost'
 # 4.5.3.1 For the instance with EVENT_NAME LIKE '%server_unix_socket'
@@ -187,7 +186,7 @@ col2
 #         because we run through server_tcpip_socket.
 # SKIPPED FOR WINDOWS
 # 4.5.3.2 For the instance with EVENT_NAME LIKE '%server_tcpip_socket'
-#         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+#         COUNT_MISC > 0 must be valid.
 # 4.5.4 Failing Connects do not cause any row with EVENT_NAME
 #       LIKE '%client_connection'
 # 4.5.5 Successful Connects cause a new instance with EVENT_NAME
@@ -203,4 +202,7 @@ col2
 # 4.6.4 Checks based on comparison of results for connects
 # 4.6.4 The user name length affects the SUM_OF_BYTES_READ value
 # 4.6.5 The database name length affects the SUM_OF_BYTES_READ value
-# 5. Cleanup
+# 5. Check the impact of TRUNCATE on socket_summary_by_instance.
+#    It must reset all counters.
+TRUNCATE TABLE performance_schema.socket_summary_by_instance;
+# 6. Cleanup

=== modified file 'mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test'
--- a/mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test	2011-08-24 14:09:20 +0000
+++ b/mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test	2011-08-27 12:50:19 +0000
@@ -26,12 +26,12 @@
 #    A new row with EVENT_NAME "client_connection" shows up
 #    is tested in 0 and 4.5.
 # 2. Impact of disconnect
-#    A row with EVENT_NAME "client_connection" disappears up
-#    is tested in 0. and 1.2.
+#    A row with EVENT_NAME "client_connection" disappears
+#    is tested in 0. and 2.
 # 3. Disabling the instrumentation for some thread causes that the
 #    counter for this thread become static is tested in 4.3.
 #    Nearby the beginning of this test and somewhere in the middle.
-# 4. TRUNCATE table resets the counter is tested nearby the beginning.
+# 4. TRUNCATE table resets the counters is tested in 5.
 # 5. Consistency within a row like MIN_* <= AVG_* <= MAX_*
 #    -> include/socket_summary_check.inc which is called at
 #       various places
@@ -457,74 +457,9 @@ WHERE OBJECT_INSTANCE_BEGIN <> @default_
      AND EVENT_NAME LIKE '%client_connection';
 }
 
---echo # 1.2 Check the impact of TRUNCATE on socket_summary_by_instance.
---echo #     It must reset all counters.
-#=======================================================================
-# We did a Connect and executed some statements within our new default session.
-# This specific history must have caused that none of the counters within
-# the client_connection for this session is 0.
-#
-# C_STAR TIMER_WAIT C_READ TIMER_READ BYTES_READ C_WRITE TIMER_WRITE BYTES_WRITE C_MISC TIMER_MISC
-#     26   98238140     15   14874860        645       5    47217170         178      6   36146110
-#
-# Ensure that the counters are <> 0 so that TRUNCATE has a visible effect.
-let $my_rules=
-COUNT_STAR  > 0 AND SUM_TIMER_WAIT  > 0
-AND
-COUNT_READ  > 0 AND SUM_TIMER_READ  > 0 AND SUM_NUMBER_OF_BYTES_READ  > 0
-AND
-COUNT_WRITE > 0 AND SUM_TIMER_WRITE > 0 AND SUM_NUMBER_OF_BYTES_WRITE > 0
-AND
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
-if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
-    WHERE NOT ( $my_rules )
-      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
-{
-   --enable_query_log
-   --enable_result_log
-   --echo # The statistics looks suspicious.
-   --echo # We expect
-   --echo #    $my_rules
-   --echo #
-   eval
-   SELECT
-      COUNT_STAR,  SUM_TIMER_WAIT,
-      COUNT_READ,  SUM_TIMER_READ,  SUM_NUMBER_OF_BYTES_READ,
-      COUNT_WRITE, SUM_TIMER_WRITE, SUM_NUMBER_OF_BYTES_WRITE,
-      COUNT_MISC,  SUM_TIMER_MISC
-   FROM performance_schema.socket_summary_by_instance
-   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
-}
 TRUNCATE TABLE performance_schema.socket_summary_by_instance;
-let $my_rules=
-COUNT_STAR  = 0 AND SUM_TIMER_WAIT  = 0
-AND
-COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0
-AND
-COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0
-AND
-COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0;
-if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
-    WHERE NOT ( $my_rules )
-      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
-{
-   --enable_query_log
-   --enable_result_log
-   --echo # The statistics looks suspicious.
-   --echo # We expect
-   --echo #    $my_rules
-   --echo #
-   eval
-   SELECT
-      COUNT_STAR, SUM_TIMER_WAIT,
-      COUNT_READ,SUM_TIMER_READ,SUM_NUMBER_OF_BYTES_READ,
-      COUNT_WRITE,SUM_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE,
-      COUNT_MISC,SUM_TIMER_MISC
-   FROM performance_schema.socket_summary_by_instance
-   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
-}
 
---echo # 1.3 Check the base line
+--echo # 1.2 Check the base line
 #===============================
 eval $truncate;
 --source ../include/socket_summary_check.inc
@@ -1690,6 +1625,42 @@ if(`SELECT NOT ($my_rules)
    let $print_details= 1;
 }
 
+--echo # 5. Check the impact of TRUNCATE on socket_summary_by_instance.
+--echo #    It must reset all counters.
+#=======================================================================
+# We do not need to check if the majority of counters is <> 0 because if
+# we ever hit such a bad state than a lot of the preceding checks would
+# have already failed and reported this.
+TRUNCATE TABLE performance_schema.socket_summary_by_instance;
+let $my_rules=
+COUNT_STAR  = 0 AND SUM_TIMER_WAIT  = 0
+AND
+COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0
+AND
+COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0
+AND
+COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0;
+if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
+    WHERE NOT ( $my_rules )
+      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
+{
+   --enable_query_log
+   --enable_result_log
+   --echo # The statistics looks suspicious.
+   --echo # We expect
+   --echo #    $my_rules
+   --echo #
+   eval
+   SELECT
+      COUNT_STAR, SUM_TIMER_WAIT,
+      COUNT_READ,SUM_TIMER_READ,SUM_NUMBER_OF_BYTES_READ,
+      COUNT_WRITE,SUM_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE,
+      COUNT_MISC,SUM_TIMER_MISC
+   FROM performance_schema.socket_summary_by_instance
+   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
+}
+
+
 if($print_details)
 {
    --enable_query_log
@@ -1698,7 +1669,6 @@ if($print_details)
    --echo # Dump detailed differences after - before statement execution
    --echo # 1. The statement executing connection and hopefully noone else
    SELECT @default_object_instance_begin;
-   # SELECT EVENT_NAME,
    SELECT EVENT_NAME, OBJECT_INSTANCE_BEGIN,
           COUNT_READ,  SUM_NUMBER_OF_BYTES_READ,
           COUNT_WRITE, SUM_NUMBER_OF_BYTES_WRITE,
@@ -1738,7 +1708,7 @@ if($print_details)
    --horizontal_results
 }
 
---echo # 5. Cleanup
+--echo # 6. Cleanup
 #==================
 # Cleanup
 --disable_query_log

=== modified file 'mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test'
--- a/mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test	2011-08-24 14:09:20 +0000
+++ b/mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test	2011-08-27 12:50:19 +0000
@@ -26,12 +26,12 @@
 #    A new row with EVENT_NAME "client_connection" shows up
 #    is tested in 0 and 4.5.
 # 2. Impact of disconnect
-#    A row with EVENT_NAME "client_connection" disappears up
-#    is tested in 0. and 1.2.
+#    A row with EVENT_NAME "client_connection" disappears
+#    is tested in 0. and 2.
 # 3. Disabling the instrumentation for some thread causes that the
 #    counter for this thread become static is tested in 4.3.
 #    Nearby the beginning of this test and somewhere in the middle.
-# 4. TRUNCATE table resets the counter is tested nearby the beginning.
+# 4. TRUNCATE table resets the counters is tested in 5.
 # 5. Consistency within a row like MIN_* <= AVG_* <= MAX_*
 #    -> include/socket_summary_check.inc which is called at
 #       various places
@@ -459,74 +459,9 @@ WHERE OBJECT_INSTANCE_BEGIN <> @default_
      AND EVENT_NAME LIKE '%client_connection';
 }
 
---echo # 1.2 Check the impact of TRUNCATE on socket_summary_by_instance.
---echo #     It must reset all counters.
-#=======================================================================
-# We did a Connect and executed some statements within our new default session.
-# This specific history must have caused that none of the counters within
-# the client_connection for this session is 0.
-#
-# C_STAR TIMER_WAIT C_READ TIMER_READ BYTES_READ C_WRITE TIMER_WRITE BYTES_WRITE C_MISC TIMER_MISC
-#     26   98238140     15   14874860        645       5    47217170         178      6   36146110
-#
-# Ensure that the counters are <> 0 so that TRUNCATE has a visible effect.
-let $my_rules=
-COUNT_STAR  > 0 AND SUM_TIMER_WAIT  > 0
-AND
-COUNT_READ  > 0 AND SUM_TIMER_READ  > 0 AND SUM_NUMBER_OF_BYTES_READ  > 0
-AND
-COUNT_WRITE > 0 AND SUM_TIMER_WRITE > 0 AND SUM_NUMBER_OF_BYTES_WRITE > 0
-AND
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
-if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
-    WHERE NOT ( $my_rules )
-      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
-{
-   --enable_query_log
-   --enable_result_log
-   --echo # The statistics looks suspicious.
-   --echo # We expect
-   --echo #    $my_rules
-   --echo #
-   eval
-   SELECT
-      COUNT_STAR,  SUM_TIMER_WAIT,
-      COUNT_READ,  SUM_TIMER_READ,  SUM_NUMBER_OF_BYTES_READ,
-      COUNT_WRITE, SUM_TIMER_WRITE, SUM_NUMBER_OF_BYTES_WRITE,
-      COUNT_MISC,  SUM_TIMER_MISC
-   FROM performance_schema.socket_summary_by_instance
-   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
-}
 TRUNCATE TABLE performance_schema.socket_summary_by_instance;
-let $my_rules=
-COUNT_STAR  = 0 AND SUM_TIMER_WAIT  = 0
-AND
-COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0
-AND
-COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0
-AND
-COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0;
-if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
-    WHERE NOT ( $my_rules )
-      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
-{
-   --enable_query_log
-   --enable_result_log
-   --echo # The statistics looks suspicious.
-   --echo # We expect
-   --echo #    $my_rules
-   --echo #
-   eval
-   SELECT
-      COUNT_STAR, SUM_TIMER_WAIT,
-      COUNT_READ,SUM_TIMER_READ,SUM_NUMBER_OF_BYTES_READ,
-      COUNT_WRITE,SUM_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE,
-      COUNT_MISC,SUM_TIMER_MISC
-   FROM performance_schema.socket_summary_by_instance
-   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
-}
 
---echo # 1.3 Check the base line
+--echo # 1.2 Check the base line
 #===============================
 eval $truncate;
 --source ../include/socket_summary_check.inc
@@ -1702,6 +1637,42 @@ if(`SELECT NOT ($my_rules)
    let $print_details= 1;
 }
 
+--echo # 5. Check the impact of TRUNCATE on socket_summary_by_instance.
+--echo #    It must reset all counters.
+#=======================================================================
+# We do not need to check if the majority of counters is <> 0 because if
+# we ever hit such a bad state than a lot of the preceding checks would
+# have already failed and reported this.
+TRUNCATE TABLE performance_schema.socket_summary_by_instance;
+let $my_rules=
+COUNT_STAR  = 0 AND SUM_TIMER_WAIT  = 0
+AND
+COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0
+AND
+COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0
+AND
+COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0;
+if(`SELECT COUNT(*) FROM performance_schema.socket_summary_by_instance
+    WHERE NOT ( $my_rules )
+      AND OBJECT_INSTANCE_BEGIN = @default_object_instance_begin`)
+{
+   --enable_query_log
+   --enable_result_log
+   --echo # The statistics looks suspicious.
+   --echo # We expect
+   --echo #    $my_rules
+   --echo #
+   eval
+   SELECT
+      COUNT_STAR, SUM_TIMER_WAIT,
+      COUNT_READ,SUM_TIMER_READ,SUM_NUMBER_OF_BYTES_READ,
+      COUNT_WRITE,SUM_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE,
+      COUNT_MISC,SUM_TIMER_MISC
+   FROM performance_schema.socket_summary_by_instance
+   WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
+}
+
+
 if($print_details)
 {
    --enable_query_log
@@ -1710,7 +1681,6 @@ if($print_details)
    --echo # Dump detailed differences after - before statement execution
    --echo # 1. The statement executing connection and hopefully noone else
    SELECT @default_object_instance_begin;
-   # SELECT EVENT_NAME,
    SELECT EVENT_NAME, OBJECT_INSTANCE_BEGIN,
           COUNT_READ,  SUM_NUMBER_OF_BYTES_READ,
           COUNT_WRITE, SUM_NUMBER_OF_BYTES_WRITE,
@@ -1750,7 +1720,7 @@ if($print_details)
    --horizontal_results
 }
 
---echo # 5. Cleanup
+--echo # 6. Cleanup
 #==================
 # Cleanup
 --disable_query_log

=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test	2011-07-07 10:25:51 +0000
+++ b/mysql-test/t/alter_table.test	2011-08-30 04:28:18 +0000
@@ -1244,3 +1244,14 @@ ALTER TABLE t1 FORCE;
 --disable_info
 
 DROP TABLE t1;
+
+--echo # Bug#11748057 (formerly known as 34972): ALTER TABLE statement doesn't
+--echo #                                         identify correct column name.
+--echo #
+
+CREATE TABLE t1 (c1 int unsigned , c2 char(100) not null default '');
+ALTER TABLE t1 ADD c3 char(16) NOT NULL DEFAULT '' AFTER c2,
+               MODIFY c2 char(100) NOT NULL DEFAULT '' AFTER c1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+

=== modified file 'mysql-test/t/group_by.test'
--- a/mysql-test/t/group_by.test	2011-08-15 09:13:05 +0000
+++ b/mysql-test/t/group_by.test	2011-08-30 09:01:05 +0000
@@ -1285,6 +1285,20 @@ FROM t1 GROUP BY a;
 
 DROP TABLE t1;
 
+--echo #
+--echo # Bug#11765254 (58200): Assertion failed: param.sort_length when grouping
+--echo # by functions
+--echo #
+
+SET BIG_TABLES=1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0),(0);
+SELECT 1 FROM t1 GROUP BY IF(`a`,'','');
+SELECT 1 FROM t1 GROUP BY TRIM(LEADING RAND() FROM '');
+SELECT 1 FROM t1 GROUP BY SUBSTRING('',SLEEP(0),'');
+SELECT 1 FROM t1 GROUP BY SUBSTRING(SYSDATE() FROM 'K' FOR 'jxW<');
+DROP TABLE t1;
+SET BIG_TABLES=0;
 
 --echo # End of 5.1 tests
 

=== modified file 'mysql-test/t/partition_innodb.test'
--- a/mysql-test/t/partition_innodb.test	2010-12-17 11:28:59 +0000
+++ b/mysql-test/t/partition_innodb.test	2011-08-29 07:08:18 +0000
@@ -39,7 +39,8 @@ DROP TABLE t1;
 --echo #            SELECT is not detected
 --echo #
 
-SET @old_innodb_thread_concurrency:= @@innodb_thread_concurrency;
+SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency;
+SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay;
 SET GLOBAL innodb_thread_concurrency = 1;
 
 CREATE TABLE t1
@@ -88,6 +89,7 @@ COMMIT;
 --connection default
 
 SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency;
+SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay;
 DROP TABLE t1;
 
 

=== modified file 'mysql-test/t/type_newdecimal.test'
--- a/mysql-test/t/type_newdecimal.test	2011-05-12 04:28:33 +0000
+++ b/mysql-test/t/type_newdecimal.test	2011-08-29 10:28:51 +0000
@@ -1535,3 +1535,17 @@ DROP TABLE IF EXISTS t1;
 
 
 --echo End of 5.1 tests
+
+--echo #
+--echo # BUG#12911710 - VALGRIND FAILURE IN 
+--echo # ROW-DEBUG:PERFSCHEMA.SOCKET_SUMMARY_BY_INSTANCE_FUNC 
+--echo #
+
+CREATE TABLE t1(d1 DECIMAL(60,0) NOT NULL,
+                d2 DECIMAL(60,0) NOT NULL);
+
+INSERT INTO t1 (d1, d2) VALUES(0.0, 0.0);
+SELECT d1 * d2 FROM t1;
+
+DROP TABLE t1;
+

=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp	2011-06-30 15:50:45 +0000
+++ b/mysql-test/valgrind.supp	2011-08-30 09:19:06 +0000
@@ -957,3 +957,42 @@
    fun:buf_buddy_free_low
    fun:buf_buddy_free
 }
+
+# Note the wildcard in the (mangled) function signatures of
+# write_keys() and find_all_keys().
+# They both return ha_rows, which is platform dependent.
+{
+   Bug#12856915 VALGRIND FAILURE IN FILESORT/CREATE_SORT_INDEX / one
+   Memcheck:Param
+   write(buf)
+   obj:*/libpthread*.so
+   fun:my_write
+   fun:inline_mysql_file_write
+   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:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPyS7_
+}
+
+## {
+##    Bug#12856915 VALGRIND FAILURE IN FILESORT/CREATE_SORT_INDEX / two
+##    Memcheck:Param
+##    write(buf)
+##    obj:*/libpthread*.so
+##    fun:my_write
+##    fun:my_b_flush_io_cache
+##    fun:_Z15merge_many_buffP13st_sort_paramPhP10st_buffpekPjP11st_io_cache
+##    fun:_Z8filesortP3THDP8st_tableP13st_sort_fieldjP10SQL_SELECTybPy
+## }
+
+## {
+##    Bug#12856915 VALGRIND FAILURE IN FILESORT/CREATE_SORT_INDEX / three
+##    Memcheck:Param
+##    write(buf)
+##    obj:*/libpthread*.so
+##    fun:my_write
+##    fun:inline_mysql_file_write
+##    fun:my_b_flush_io_cache
+##    fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPy
+## }

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2011-08-25 10:54:34 +0000
+++ b/sql/filesort.cc	2011-08-30 09:01:05 +0000
@@ -189,8 +189,6 @@ ha_rows filesort(THD *thd, TABLE *table,
                           table,
                           thd->variables.max_length_for_sort_data,
                           max_rows, sort_positions);
-  /* filesort cannot handle zero-length records. */
-  DBUG_ASSERT(param.sort_length);
 
   table_sort.addon_buf= 0;
   table_sort.addon_length= param.addon_length;
@@ -284,6 +282,9 @@ ha_rows filesort(THD *thd, TABLE *table,
   }
   else
   {
+    /* filesort cannot handle zero-length records during merge. */
+    DBUG_ASSERT(param.sort_length != 0);
+
     if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
     {
       my_free(table_sort.buffpek);
@@ -1040,21 +1041,10 @@ static void make_sortkey(register Sort_p
       if (addonf->null_bit && field->is_null())
       {
         nulls[addonf->null_offset]|= addonf->null_bit;
-#ifdef HAVE_purify
-	memset(to, 0, addonf->length);
-#endif
       }
       else
       {
-#ifdef HAVE_purify
-        uchar *end= field->pack(to, field->ptr);
-	uint length= (uint) ((to + addonf->length) - end);
-	DBUG_ASSERT((int) length >= 0);
-	if (length)
-	  memset(end, 0, length);
-#else
         (void) field->pack(to, field->ptr);
-#endif
       }
       to+= addonf->length;
     }

=== modified file 'sql/my_decimal.h'
--- a/sql/my_decimal.h	2011-07-07 09:45:10 +0000
+++ b/sql/my_decimal.h	2011-08-29 10:28:51 +0000
@@ -124,12 +124,8 @@ public:
   {
     len= DECIMAL_BUFF_LENGTH;
     buf= buffer;
-#if !defined (HAVE_purify) && !defined(DBUG_OFF)
-    /* Set buffer to 'random' value to find wrong buffer usage */
-    for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
-      buffer[i]= i;
-#endif
   }
+
   my_decimal()
   {
     init();

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-08-25 10:54:34 +0000
+++ b/sql/sql_select.cc	2011-08-30 10:04:45 +0000
@@ -3460,29 +3460,30 @@ JOIN::exec()
     }
     {
       if (group)
-	curr_join->m_select_limit= HA_POS_ERROR;
+        curr_join->m_select_limit= HA_POS_ERROR;
       else
       {
-	/*
-	  We can abort sorting after thd->select_limit rows if we there is no
-	  WHERE clause for any tables after the sorted one.
-	*/
-	JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
-	JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
-	for (; curr_table < end_table ; curr_table++)
-	{
-	  /*
-	    table->keyuse is set in the case there was an original WHERE clause
-	    on the table that was optimized away.
-	  */
-	  if (curr_table->condition() ||
-	      (curr_table->keyuse && !curr_table->first_inner))
-	  {
-	    /* We have to sort all rows */
-	    curr_join->m_select_limit= HA_POS_ERROR;
-	    break;
-	  }
-	}
+        /*
+          We can abort sorting after thd->select_limit rows if there are no
+          filter conditions for any tables after the sorted one.
+          Filter conditions come in several forms:
+           - as a condition item attached to the join_tab,
+           - as a keyuse attached to the join_tab (ref access),
+           - as a semi-join equality attached to materialization semi-join nest.
+        */
+        JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
+        JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
+        for (; curr_table < end_table ; curr_table++)
+        {
+          if (curr_table->condition() ||
+              (curr_table->keyuse && !curr_table->first_inner) ||
+              curr_table->get_sj_strategy() == SJ_OPT_MATERIALIZE_LOOKUP)
+          {
+            /* We have to sort all rows */
+            curr_join->m_select_limit= HA_POS_ERROR;
+            break;
+          }
+        }
       }
       if (curr_join->join_tab == join_tab && save_join_tab())
       {

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-08-19 13:04:28 +0000
+++ b/sql/sql_table.cc	2011-08-30 04:28:18 +0000
@@ -5614,10 +5614,22 @@ mysql_prepare_alter_table(THD *thd, TABL
     if (def)
     {						// Field is changed
       def->field=field;
+      /*
+        Add column being updated to the list of new columns.
+        Note that columns with AFTER clauses are added to the end
+        of the list for now. Their positions will be corrected later.
+      */
+      new_create_list.push_back(def);
       if (!def->after)
       {
-	new_create_list.push_back(def);
-	def_it.remove();
+        /*
+          If this ALTER TABLE doesn't have an AFTER clause for the modified
+          column then remove this column from the list of columns to be
+          processed. So later we can iterate over the columns remaining
+          in this list and process modified columns with AFTER clause or
+          add new columns.
+        */
+        def_it.remove();
       }
     }
     else
@@ -5677,25 +5689,43 @@ mysql_prepare_alter_table(THD *thd, TABL
     }
     if (!def->after)
       new_create_list.push_back(def);
-    else if (def->after == first_keyword)
-    {
-      new_create_list.push_front(def);
-    }
     else
     {
       Create_field *find;
-      find_it.rewind();
-      while ((find=find_it++))			// Add new columns
+      if (def->change)
       {
-	if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
-	  break;
+        find_it.rewind();
+        /*
+          For columns being modified with AFTER clause we should first remove
+          these columns from the list and then add them back at their correct
+          positions.
+        */
+        while ((find=find_it++))
+        {
+          if (!my_strcasecmp(system_charset_info, def->field_name, find->field_name))
+          {
+            find_it.remove();
+            break;
+          }
+        }
       }
-      if (!find)
+      if (def->after == first_keyword)
+        new_create_list.push_front(def);
+      else
       {
-	my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
-        goto err;
+        find_it.rewind();
+        while ((find=find_it++))
+        {
+          if (!my_strcasecmp(system_charset_info, def->after, find->field_name))
+            break;
+        }
+        if (!find)
+        {
+          my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
+          goto err;
+        }
+        find_it.after(def);			// Put column after this
       }
-      find_it.after(def);			// Put element after this
     }
   }
   if (alter_info->alter_list.elements)
@@ -7072,8 +7102,8 @@ bool mysql_alter_table(THD *thd,char *ne
     */
     char path[FN_REFLEN];
     TABLE *t_table;
-    build_table_filename(path + 1, sizeof(path) - 1, new_db, table_name, "", 0);
-    t_table= open_table_uncached(thd, path, new_db, tmp_name, FALSE);
+    build_table_filename(path, sizeof(path) - 1, new_db, new_name, "", 0);
+    t_table= open_table_uncached(thd, path, new_db, new_name, FALSE);
     if (t_table)
     {
       intern_close_table(t_table);

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-08-24 14:47:26 +0000
+++ b/sql/table.cc	2011-08-26 13:26:33 +0000
@@ -4511,6 +4511,7 @@ Item *Field_iterator_table::create_item(
   {
     select->non_agg_fields.push_back(item);
     item->marker= select->cur_pos_in_select_list;
+    select->set_non_agg_field_used(true);
   }
   return item;
 }

=== modified file 'storage/innobase/btr/btr0btr.c'
--- a/storage/innobase/btr/btr0btr.c	2011-08-15 09:34:39 +0000
+++ b/storage/innobase/btr/btr0btr.c	2011-08-29 08:45:30 +0000
@@ -907,28 +907,29 @@ btr_page_alloc_for_ibuf(
 /**************************************************************//**
 Allocates a new file page to be used in an index tree. NOTE: we assume
 that the caller has made the reservation for free extents!
-@return	new allocated block, x-latched; NULL if out of space */
-UNIV_INTERN
-buf_block_t*
-btr_page_alloc(
-/*===========*/
+@return	allocated page number, FIL_NULL if out of space */
+static __attribute__((nonnull(1,5), warn_unused_result))
+ulint
+btr_page_alloc_low(
+/*===============*/
 	dict_index_t*	index,		/*!< in: index */
 	ulint		hint_page_no,	/*!< in: hint of a good page */
 	byte		file_direction,	/*!< in: direction where a possible
 					page split is made */
 	ulint		level,		/*!< in: level where the page is placed
 					in the tree */
-	mtr_t*		mtr)		/*!< in: mtr */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mini-transaction
+					in which the page should be
+					initialized (may be the same
+					as mtr), or NULL if it should
+					not be initialized (the page
+					at hint was previously freed
+					in mtr) */
 {
 	fseg_header_t*	seg_header;
 	page_t*		root;
-	buf_block_t*	new_block;
-	ulint		new_page_no;
-
-	if (dict_index_is_ibuf(index)) {
-
-		return(btr_page_alloc_for_ibuf(index, mtr));
-	}
 
 	root = btr_root_get(index, mtr);
 
@@ -942,8 +943,42 @@ btr_page_alloc(
 	reservation for free extents, and thus we know that a page can
 	be allocated: */
 
-	new_page_no = fseg_alloc_free_page_general(seg_header, hint_page_no,
-						   file_direction, TRUE, mtr);
+	return(fseg_alloc_free_page_general(
+		       seg_header, hint_page_no, file_direction,
+		       TRUE, mtr, init_mtr));
+}
+
+/**************************************************************//**
+Allocates a new file page to be used in an index tree. NOTE: we assume
+that the caller has made the reservation for free extents!
+@return	new allocated block, x-latched; NULL if out of space */
+UNIV_INTERN
+buf_block_t*
+btr_page_alloc(
+/*===========*/
+	dict_index_t*	index,		/*!< in: index */
+	ulint		hint_page_no,	/*!< in: hint of a good page */
+	byte		file_direction,	/*!< in: direction where a possible
+					page split is made */
+	ulint		level,		/*!< in: level where the page is placed
+					in the tree */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mini-transaction
+					for x-latching and initializing
+					the page */
+{
+	buf_block_t*	new_block;
+	ulint		new_page_no;
+
+	if (dict_index_is_ibuf(index)) {
+
+		return(btr_page_alloc_for_ibuf(index, mtr));
+	}
+
+	new_page_no = btr_page_alloc_low(
+		index, hint_page_no, file_direction, level, mtr, init_mtr);
+
 	if (new_page_no == FIL_NULL) {
 
 		return(NULL);
@@ -951,9 +986,16 @@ btr_page_alloc(
 
 	new_block = buf_page_get(dict_index_get_space(index),
 				 dict_table_zip_size(index->table),
-				 new_page_no, RW_X_LATCH, mtr);
+				 new_page_no, RW_X_LATCH, init_mtr);
 	buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
 
+	if (mtr->freed_clust_leaf) {
+		mtr_memo_release(mtr, new_block, MTR_MEMO_FREE_CLUST_LEAF);
+		ut_ad(!mtr_memo_contains(mtr, new_block,
+					 MTR_MEMO_FREE_CLUST_LEAF));
+	}
+
+	ut_ad(btr_freed_leaves_validate(mtr));
 	return(new_block);
 }
 
@@ -1066,6 +1108,15 @@ btr_page_free_low(
 	fseg_free_page(seg_header,
 		       buf_block_get_space(block),
 		       buf_block_get_page_no(block), mtr);
+
+	/* The page was marked free in the allocation bitmap, but it
+	should remain buffer-fixed until mtr_commit(mtr) or until it
+	is explicitly freed from the mini-transaction. */
+	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+	/* TODO: Discard any operations on the page from the redo log
+	and remove the block from the flush list and the buffer pool.
+	This would free up buffer pool earlier and reduce writes to
+	both the tablespace and the redo log. */
 }
 
 /**************************************************************//**
@@ -1079,12 +1130,139 @@ btr_page_free(
 	buf_block_t*	block,	/*!< in: block to be freed, x-latched */
 	mtr_t*		mtr)	/*!< in: mtr */
 {
-	ulint		level;
-
-	level = btr_page_get_level(buf_block_get_frame(block), mtr);
+	const page_t*	page	= buf_block_get_frame(block);
+	ulint		level	= btr_page_get_level(page, mtr);
 
+	ut_ad(fil_page_get_type(block->frame) == FIL_PAGE_INDEX);
 	btr_page_free_low(index, block, level, mtr);
+
+	/* The handling of MTR_MEMO_FREE_CLUST_LEAF assumes this. */
+	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+
+	if (level == 0 && dict_index_is_clust(index)) {
+		/* We may have to call btr_mark_freed_leaves() to
+		temporarily mark the block nonfree for invoking
+		btr_store_big_rec_extern_fields_func() after an
+		update. Remember that the block was freed. */
+		mtr->freed_clust_leaf = TRUE;
+		mtr_memo_push(mtr, block, MTR_MEMO_FREE_CLUST_LEAF);
+	}
+
+	ut_ad(btr_freed_leaves_validate(mtr));
+}
+
+/**************************************************************//**
+Marks all MTR_MEMO_FREE_CLUST_LEAF pages nonfree or free.
+For invoking btr_store_big_rec_extern_fields() after an update,
+we must temporarily mark freed clustered index pages allocated, so
+that off-page columns will not be allocated from them. Between the
+btr_store_big_rec_extern_fields() and mtr_commit() we have to
+mark the pages free again, so that no pages will be leaked. */
+UNIV_INTERN
+void
+btr_mark_freed_leaves(
+/*==================*/
+	dict_index_t*	index,	/*!< in/out: clustered index */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	ibool		nonfree)/*!< in: TRUE=mark nonfree, FALSE=mark freed */
+{
+	/* This is loosely based on mtr_memo_release(). */
+
+	ulint	offset;
+
+	ut_ad(dict_index_is_clust(index));
+	ut_ad(mtr->magic_n == MTR_MAGIC_N);
+	ut_ad(mtr->state == MTR_ACTIVE);
+
+	if (!mtr->freed_clust_leaf) {
+		return;
+	}
+
+	offset = dyn_array_get_data_size(&mtr->memo);
+
+	while (offset > 0) {
+		mtr_memo_slot_t*	slot;
+		buf_block_t*		block;
+
+		offset -= sizeof *slot;
+
+		slot = dyn_array_get_element(&mtr->memo, offset);
+
+		if (slot->type != MTR_MEMO_FREE_CLUST_LEAF) {
+			continue;
+		}
+
+		/* Because btr_page_alloc() does invoke
+		mtr_memo_release on MTR_MEMO_FREE_CLUST_LEAF, all
+		blocks tagged with MTR_MEMO_FREE_CLUST_LEAF in the
+		memo must still be clustered index leaf tree pages. */
+		block = slot->object;
+		ut_a(buf_block_get_space(block)
+		     == dict_index_get_space(index));
+		ut_a(fil_page_get_type(buf_block_get_frame(block))
+		     == FIL_PAGE_INDEX);
+		ut_a(page_is_leaf(buf_block_get_frame(block)));
+
+		if (nonfree) {
+			/* Allocate the same page again. */
+			ulint	page_no;
+			page_no = btr_page_alloc_low(
+				index, buf_block_get_page_no(block),
+				FSP_NO_DIR, 0, mtr, NULL);
+			ut_a(page_no == buf_block_get_page_no(block));
+		} else {
+			/* Assert that the page is allocated and free it. */
+			btr_page_free_low(index, block, 0, mtr);
+		}
+	}
+
+	ut_ad(btr_freed_leaves_validate(mtr));
+}
+
+#ifdef UNIV_DEBUG
+/**************************************************************//**
+Validates all pages marked MTR_MEMO_FREE_CLUST_LEAF.
+@see btr_mark_freed_leaves()
+@return TRUE */
+UNIV_INTERN
+ibool
+btr_freed_leaves_validate(
+/*======================*/
+	mtr_t*	mtr)	/*!< in: mini-transaction */
+{
+	ulint	offset;
+
+	ut_ad(mtr->magic_n == MTR_MAGIC_N);
+	ut_ad(mtr->state == MTR_ACTIVE);
+
+	offset = dyn_array_get_data_size(&mtr->memo);
+
+	while (offset > 0) {
+		const mtr_memo_slot_t*	slot;
+		const buf_block_t*	block;
+
+		offset -= sizeof *slot;
+
+		slot = dyn_array_get_element(&mtr->memo, offset);
+
+		if (slot->type != MTR_MEMO_FREE_CLUST_LEAF) {
+			continue;
+		}
+
+		ut_a(mtr->freed_clust_leaf);
+		/* Because btr_page_alloc() does invoke
+		mtr_memo_release on MTR_MEMO_FREE_CLUST_LEAF, all
+		blocks tagged with MTR_MEMO_FREE_CLUST_LEAF in the
+		memo must still be clustered index leaf tree pages. */
+		block = slot->object;
+		ut_a(fil_page_get_type(buf_block_get_frame(block))
+		     == FIL_PAGE_INDEX);
+		ut_a(page_is_leaf(buf_block_get_frame(block)));
+	}
+
+	return(TRUE);
 }
+#endif /* UNIV_DEBUG */
 
 /**************************************************************//**
 Sets the child node file address in a node pointer. */
@@ -1812,7 +1990,7 @@ btr_root_raise_and_insert(
 
 	level = btr_page_get_level(root, mtr);
 
-	new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr);
+	new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr);
 	new_page = buf_block_get_frame(new_block);
 	new_page_zip = buf_block_get_page_zip(new_block);
 	ut_a(!new_page_zip == !root_page_zip);
@@ -2548,7 +2726,7 @@ func_start:
 
 	/* 2. Allocate a new page to the index */
 	new_block = btr_page_alloc(cursor->index, hint_page_no, direction,
-				   btr_page_get_level(page, mtr), mtr);
+				   btr_page_get_level(page, mtr), mtr, mtr);
 	new_page = buf_block_get_frame(new_block);
 	new_page_zip = buf_block_get_page_zip(new_block);
 	btr_page_create(new_block, new_page_zip, cursor->index,

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2011-08-15 09:34:39 +0000
+++ b/storage/innobase/btr/btr0cur.c	2011-08-29 08:45:30 +0000
@@ -2530,39 +2530,6 @@ return_after_reservations:
 	return(err);
 }
 
-/**************************************************************//**
-Commits and restarts a mini-transaction so that it will retain an
-x-lock on index->lock and the cursor page. */
-UNIV_INTERN
-void
-btr_cur_mtr_commit_and_start(
-/*=========================*/
-	btr_cur_t*	cursor,	/*!< in: cursor */
-	mtr_t*		mtr)	/*!< in/out: mini-transaction */
-{
-	buf_block_t*	block;
-
-	block = btr_cur_get_block(cursor);
-
-	ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(cursor->index),
-				MTR_MEMO_X_LOCK));
-	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
-	/* Keep the locks across the mtr_commit(mtr). */
-	rw_lock_x_lock(dict_index_get_lock(cursor->index));
-	rw_lock_x_lock(&block->lock);
-	mutex_enter(&block->mutex);
-	buf_block_buf_fix_inc(block, __FILE__, __LINE__);
-	mutex_exit(&block->mutex);
-	/* Write out the redo log. */
-	mtr_commit(mtr);
-	mtr_start(mtr);
-	/* Reassociate the locks with the mini-transaction.
-	They will be released on mtr_commit(mtr). */
-	mtr_memo_push(mtr, dict_index_get_lock(cursor->index),
-		      MTR_MEMO_X_LOCK);
-	mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
-}
-
 /*==================== B-TREE DELETE MARK AND UNMARK ===============*/
 
 /****************************************************************//**
@@ -4189,6 +4156,9 @@ btr_store_big_rec_extern_fields_func(
 					the "external storage" flags in offsets
 					will not correspond to rec when
 					this function returns */
+	const big_rec_t*big_rec_vec,	/*!< in: vector containing fields
+					to be stored externally */
+
 #ifdef UNIV_DEBUG
 	mtr_t*		local_mtr,	/*!< in: mtr containing the
 					latch to rec and to the tree */
@@ -4197,9 +4167,11 @@ btr_store_big_rec_extern_fields_func(
 	ibool		update_in_place,/*! in: TRUE if the record is updated
 					in place (not delete+insert) */
 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-	const big_rec_t*big_rec_vec)	/*!< in: vector containing fields
-					to be stored externally */
-
+	mtr_t*		alloc_mtr)	/*!< in/out: in an insert, NULL;
+					in an update, local_mtr for
+					allocating BLOB pages and
+					updating BLOB pointers; alloc_mtr
+					must not have freed any leaf pages */
 {
 	ulint	rec_page_no;
 	byte*	field_ref;
@@ -4218,6 +4190,9 @@ btr_store_big_rec_extern_fields_func(
 
 	ut_ad(rec_offs_validate(rec, index, offsets));
 	ut_ad(rec_offs_any_extern(offsets));
+	ut_ad(local_mtr);
+	ut_ad(!alloc_mtr || alloc_mtr == local_mtr);
+	ut_ad(!update_in_place || alloc_mtr);
 	ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
 				MTR_MEMO_X_LOCK));
 	ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
@@ -4233,6 +4208,25 @@ btr_store_big_rec_extern_fields_func(
 	rec_page_no = buf_block_get_page_no(rec_block);
 	ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
 
+	if (alloc_mtr) {
+		/* Because alloc_mtr will be committed after
+		mtr, it is possible that the tablespace has been
+		extended when the B-tree record was updated or
+		inserted, or it will be extended while allocating
+		pages for big_rec.
+
+		TODO: In mtr (not alloc_mtr), write a redo log record
+		about extending the tablespace to its current size,
+		and remember the current size. Whenever the tablespace
+		grows as pages are allocated, write further redo log
+		records to mtr. (Currently tablespace extension is not
+		covered by the redo log. If it were, the record would
+		only be written to alloc_mtr, which is committed after
+		mtr.) */
+	} else {
+		alloc_mtr = &mtr;
+	}
+
 	if (UNIV_LIKELY_NULL(page_zip)) {
 		int	err;
 
@@ -4309,7 +4303,7 @@ btr_store_big_rec_extern_fields_func(
 			}
 
 			block = btr_page_alloc(index, hint_page_no,
-					       FSP_NO_DIR, 0, &mtr);
+					       FSP_NO_DIR, 0, alloc_mtr, &mtr);
 			if (UNIV_UNLIKELY(block == NULL)) {
 
 				mtr_commit(&mtr);
@@ -4436,11 +4430,15 @@ btr_store_big_rec_extern_fields_func(
 					goto next_zip_page;
 				}
 
-				rec_block = buf_page_get(space_id, zip_size,
-							 rec_page_no,
-							 RW_X_LATCH, &mtr);
-				buf_block_dbg_add_level(rec_block,
-							SYNC_NO_ORDER_CHECK);
+				if (alloc_mtr == &mtr) {
+					rec_block = buf_page_get(
+						space_id, zip_size,
+						rec_page_no,
+						RW_X_LATCH, &mtr);
+					buf_block_dbg_add_level(
+						rec_block,
+						SYNC_NO_ORDER_CHECK);
+				}
 
 				if (err == Z_STREAM_END) {
 					mach_write_to_4(field_ref
@@ -4474,7 +4472,8 @@ btr_store_big_rec_extern_fields_func(
 
 				page_zip_write_blob_ptr(
 					page_zip, rec, index, offsets,
-					big_rec_vec->fields[i].field_no, &mtr);
+					big_rec_vec->fields[i].field_no,
+					alloc_mtr);
 
 next_zip_page:
 				prev_page_no = page_no;
@@ -4519,19 +4518,23 @@ next_zip_page:
 
 				extern_len -= store_len;
 
-				rec_block = buf_page_get(space_id, zip_size,
-							 rec_page_no,
-							 RW_X_LATCH, &mtr);
-				buf_block_dbg_add_level(rec_block,
-							SYNC_NO_ORDER_CHECK);
+				if (alloc_mtr == &mtr) {
+					rec_block = buf_page_get(
+						space_id, zip_size,
+						rec_page_no,
+						RW_X_LATCH, &mtr);
+					buf_block_dbg_add_level(
+						rec_block,
+						SYNC_NO_ORDER_CHECK);
+				}
 
 				mlog_write_ulint(field_ref + BTR_EXTERN_LEN, 0,
-						 MLOG_4BYTES, &mtr);
+						 MLOG_4BYTES, alloc_mtr);
 				mlog_write_ulint(field_ref
 						 + BTR_EXTERN_LEN + 4,
 						 big_rec_vec->fields[i].len
 						 - extern_len,
-						 MLOG_4BYTES, &mtr);
+						 MLOG_4BYTES, alloc_mtr);
 
 				if (prev_page_no == FIL_NULL) {
 					btr_blob_dbg_add_blob(
@@ -4541,18 +4544,19 @@ next_zip_page:
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_SPACE_ID,
-							 space_id,
-							 MLOG_4BYTES, &mtr);
+							 space_id, MLOG_4BYTES,
+							 alloc_mtr);
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_PAGE_NO,
-							 page_no,
-							 MLOG_4BYTES, &mtr);
+							 page_no, MLOG_4BYTES,
+							 alloc_mtr);
 
 					mlog_write_ulint(field_ref
 							 + BTR_EXTERN_OFFSET,
 							 FIL_PAGE_DATA,
-							 MLOG_4BYTES, &mtr);
+							 MLOG_4BYTES,
+							 alloc_mtr);
 				}
 
 				prev_page_no = page_no;

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/buf/buf0buf.c	2011-08-29 08:45:30 +0000
@@ -41,7 +41,6 @@ Created 11/5/1995 Heikki Tuuri
 #include "fil0fil.h"
 #ifndef UNIV_HOTBACKUP
 #include "buf0buddy.h"
-#include "buf0checksum.h"
 #include "lock0lock.h"
 #include "btr0sea.h"
 #include "ibuf0ibuf.h"
@@ -53,6 +52,7 @@ Created 11/5/1995 Heikki Tuuri
 #include "log0recv.h"
 #include "page0zip.h"
 #include "srv0mon.h"
+#include "buf0checksum.h"
 
 /*
 		IMPLEMENTATION OF THE BUFFER POOL
@@ -1795,34 +1795,6 @@ buf_page_set_accessed_make_young(
 	}
 }
 
-/********************************************************************//**
-Resets the check_index_page_at_flush field of a page if found in the buffer
-pool. */
-UNIV_INTERN
-void
-buf_reset_check_index_page_at_flush(
-/*================================*/
-	ulint	space,	/*!< in: space id */
-	ulint	offset)	/*!< in: page number */
-{
-	buf_block_t*	block;
-	buf_pool_t*	buf_pool = buf_pool_get(space, offset);
-	rw_lock_t*	hash_lock;
-
-	block = buf_block_hash_get_s_locked(buf_pool, space, offset,
-					    &hash_lock);
-
-	if (block) {
-		if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE) {
-			ut_ad(!buf_pool_watch_is_sentinel(buf_pool,
-							  &block->page));
-			block->check_index_page_at_flush = FALSE;
-		}
-
-		rw_lock_s_unlock(hash_lock);
-	}
-}
-
 /********************************************************************//**
 Returns the current state of is_hashed of a page. FALSE if the page is
 not in the pool. NOTE that this operation does not fix the page in the

=== modified file 'storage/innobase/buf/buf0checksum.c'
--- a/storage/innobase/buf/buf0checksum.c	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/buf/buf0checksum.c	2011-08-29 07:14:48 +0000
@@ -29,6 +29,13 @@ Created Aug 11, 2011 Vasil Dimov
 #include "srv0srv.h" /* SRV_CHECKSUM_* */
 #include "ut0crc32.h" /* ut_crc32() */
 #include "ut0rnd.h" /* ut_fold_binary() */
+#include "buf0types.h"
+
+/** the macro MYSQL_SYSVAR_ENUM() requires "long unsigned int" and if we
+use srv_checksum_algorithm_t here then we get a compiler error:
+ha_innodb.cc:12251: error: cannot convert 'srv_checksum_algorithm_t*' to
+  'long unsigned int*' in initialization */
+UNIV_INTERN ulong	srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_INNODB;
 
 /********************************************************************//**
 Calculates a page CRC32 which is stored to the page when it is written

=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/dict/dict0dict.c	2011-08-29 10:12:32 +0000
@@ -5268,7 +5268,8 @@ UNIV_INTERN
 void
 dict_set_corrupted_index_cache_only(
 /*================================*/
-	dict_index_t*	index)		/*!< in/out: index */
+	dict_index_t*	index,		/*!< in/out: index */
+	dict_table_t*	table)		/*!< in/out: table */
 {
 	ut_ad(index);
 	ut_ad(mutex_own(&dict_sys->mutex));
@@ -5278,7 +5279,14 @@ dict_set_corrupted_index_cache_only(
 	/* Mark the table as corrupted only if the clustered index
 	is corrupted */
 	if (dict_index_is_clust(index)) {
-		index->table->corrupted = TRUE;
+		dict_table_t*	corrupt_table;
+
+		corrupt_table = table ? table : index->table;
+		ut_ad(!index->table || !table || index->table  == table);
+
+		if (corrupt_table) {
+			corrupt_table->corrupted = TRUE;
+		}
 	}
 
 	index->type |= DICT_CORRUPT;

=== modified file 'storage/innobase/dict/dict0load.c'
--- a/storage/innobase/dict/dict0load.c	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/dict/dict0load.c	2011-08-29 10:12:32 +0000
@@ -1455,7 +1455,8 @@ dict_load_indexes(
 				dictionary cache for such metadata corruption,
 				since we would always be able to set it
 				when loading the dictionary cache */
-				dict_set_corrupted_index_cache_only(index);
+				dict_set_corrupted_index_cache_only(
+					index, table);
 
 				fprintf(stderr,
 					"InnoDB: Index is corrupt but forcing"

=== modified file 'storage/innobase/dict/dict0stats.c'
--- a/storage/innobase/dict/dict0stats.c	2011-08-23 07:02:19 +0000
+++ b/storage/innobase/dict/dict0stats.c	2011-08-29 12:58:11 +0000
@@ -2797,7 +2797,7 @@ test_dict_stats_save()
 	enum db_err	ret;
 
 	/* craft a dummy dict_table_t */
-	table.name = TEST_DATABASE_NAME "/" TEST_TABLE_NAME;
+	table.name = (char*) (TEST_DATABASE_NAME "/" TEST_TABLE_NAME);
 	table.stat_n_rows = TEST_N_ROWS;
 	table.stat_clustered_index_size = TEST_CLUSTERED_INDEX_SIZE;
 	table.stat_sum_of_other_index_sizes = TEST_SUM_OF_OTHER_INDEX_SIZES;
@@ -2961,7 +2961,7 @@ test_dict_stats_fetch_from_ps()
 	enum db_err	ret;
 
 	/* craft a dummy dict_table_t */
-	table.name = TEST_DATABASE_NAME "/" TEST_TABLE_NAME;
+	table.name = (char*) (TEST_DATABASE_NAME "/" TEST_TABLE_NAME);
 	UT_LIST_INIT(table.indexes);
 	UT_LIST_ADD_LAST(indexes, table.indexes, &index1);
 	UT_LIST_ADD_LAST(indexes, table.indexes, &index2);

=== modified file 'storage/innobase/fil/fil0fil.c'
--- a/storage/innobase/fil/fil0fil.c	2011-07-25 09:54:47 +0000
+++ b/storage/innobase/fil/fil0fil.c	2011-08-29 07:14:48 +0000
@@ -47,6 +47,7 @@ Created 10/25/1995 Heikki Tuuri
 # include "sync0sync.h"
 # include "os0sync.h"
 #else /* !UNIV_HOTBACKUP */
+# include "srv0srv.h"
 static ulint srv_data_read, srv_data_written;
 #endif /* !UNIV_HOTBACKUP */
 

=== modified file 'storage/innobase/fsp/fsp0fsp.c'
--- a/storage/innobase/fsp/fsp0fsp.c	2011-04-27 21:49:19 +0000
+++ b/storage/innobase/fsp/fsp0fsp.c	2011-08-29 08:45:30 +0000
@@ -312,8 +312,9 @@ fsp_fill_free_list(
 					descriptor page and ibuf bitmap page;
 					then we do not allocate more extents */
 	ulint		space,		/*!< in: space */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr);		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
+	UNIV_COLD __attribute__((nonnull));
 /**********************************************************************//**
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
@@ -326,14 +327,20 @@ fseg_alloc_free_page_low(
 	ulint		space,	/*!< in: space */
 	ulint		zip_size,/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
-	fseg_inode_t*	seg_inode, /*!< in: segment inode */
+	fseg_inode_t*	seg_inode, /*!< in/out: segment inode */
 	ulint		hint,	/*!< in: hint of which page would be desirable */
 	byte		direction, /*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
 				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr);	/*!< in: mtr handle */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mini-transaction in which the
+				page should be initialized
+				(may be the same as mtr), or NULL if it
+				should not be initialized (the page at hint
+				was previously freed in mtr) */
+	__attribute__((warn_unused_result, nonnull(3,6)));
 #endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************************//**
@@ -701,17 +708,18 @@ list, if not free limit == space size. T
 descriptor defined, as they are uninitialized above the free limit.
 @return pointer to the extent descriptor, NULL if the page does not
 exist in the space or if the offset exceeds the free limit */
-UNIV_INLINE
+UNIV_INLINE __attribute__((nonnull, warn_unused_result))
 xdes_t*
 xdes_get_descriptor_with_space_hdr(
 /*===============================*/
-	fsp_header_t*	sp_header,/*!< in/out: space header, x-latched */
-	ulint		space,	/*!< in: space id */
-	ulint		offset,	/*!< in: page offset;
-				if equal to the free limit,
-				we try to add new extents to
-				the space free list */
-	mtr_t*		mtr)	/*!< in: mtr handle */
+	fsp_header_t*	sp_header,	/*!< in/out: space header, x-latched
+					in mtr */
+	ulint		space,		/*!< in: space id */
+	ulint		offset,		/*!< in: page offset; if equal
+					to the free limit, we try to
+					add new extents to the space
+					free list */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	limit;
 	ulint	size;
@@ -719,11 +727,9 @@ xdes_get_descriptor_with_space_hdr(
 	ulint	descr_page_no;
 	page_t*	descr_page;
 
-	ut_ad(mtr);
 	ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
 				MTR_MEMO_X_LOCK));
-	ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
-	      || mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
 	ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
 	/* Read free limit and space size */
 	limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
@@ -773,7 +779,7 @@ is necessary to make the descriptor defi
 above the free limit.
 @return pointer to the extent descriptor, NULL if the page does not
 exist in the space or if the offset exceeds the free limit */
-static
+static __attribute__((nonnull, warn_unused_result))
 xdes_t*
 xdes_get_descriptor(
 /*================*/
@@ -782,7 +788,7 @@ xdes_get_descriptor(
 			or 0 for uncompressed pages */
 	ulint	offset,	/*!< in: page offset; if equal to the free limit,
 			we try to add new extents to the space free list */
-	mtr_t*	mtr)	/*!< in: mtr handle */
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 {
 	buf_block_t*	block;
 	fsp_header_t*	sp_header;
@@ -1128,14 +1134,14 @@ fsp_header_get_tablespace_size(void)
 Tries to extend a single-table tablespace so that a page would fit in the
 data file.
 @return	TRUE if success */
-static
+static UNIV_COLD __attribute__((nonnull, warn_unused_result))
 ibool
 fsp_try_extend_data_file_with_pages(
 /*================================*/
 	ulint		space,		/*!< in: space */
 	ulint		page_no,	/*!< in: page number */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ibool	success;
 	ulint	actual_size;
@@ -1160,7 +1166,7 @@ fsp_try_extend_data_file_with_pages(
 /***********************************************************************//**
 Tries to extend the last data file of a tablespace if it is auto-extending.
 @return	FALSE if not auto-extending */
-static
+static UNIV_COLD __attribute__((nonnull))
 ibool
 fsp_try_extend_data_file(
 /*=====================*/
@@ -1170,8 +1176,8 @@ fsp_try_extend_data_file(
 					the actual file size rounded down to
 					megabyte */
 	ulint		space,		/*!< in: space */
-	fsp_header_t*	header,		/*!< in: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	fsp_header_t*	header,		/*!< in/out: space header */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	size;
 	ulint	zip_size;
@@ -1307,7 +1313,7 @@ fsp_fill_free_list(
 					then we do not allocate more extents */
 	ulint		space,		/*!< in: space */
 	fsp_header_t*	header,		/*!< in/out: space header */
-	mtr_t*		mtr)		/*!< in: mtr */
+	mtr_t*		mtr)		/*!< in/out: mini-transaction */
 {
 	ulint	limit;
 	ulint	size;
@@ -1497,9 +1503,46 @@ fsp_alloc_free_extent(
 }
 
 /**********************************************************************//**
+Allocates a single free page from a space. */
+static __attribute__((nonnull))
+void
+fsp_alloc_from_free_frag(
+/*=====================*/
+	fsp_header_t*	header,	/*!< in/out: tablespace header */
+	xdes_t*		descr,	/*!< in/out: extent descriptor */
+	ulint		bit,	/*!< in: slot to allocate in the extent */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
+{
+	ulint		frag_n_used;
+
+	ut_ad(xdes_get_state(descr, mtr) == XDES_FREE_FRAG);
+	ut_a(xdes_get_bit(descr, XDES_FREE_BIT, bit, mtr));
+	xdes_set_bit(descr, XDES_FREE_BIT, bit, FALSE, mtr);
+
+	/* Update the FRAG_N_USED field */
+	frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES,
+				     mtr);
+	frag_n_used++;
+	mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES,
+			 mtr);
+	if (xdes_is_full(descr, mtr)) {
+		/* The fragment is full: move it to another list */
+		flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
+			    mtr);
+		xdes_set_state(descr, XDES_FULL_FRAG, mtr);
+
+		flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
+			      mtr);
+		mlog_write_ulint(header + FSP_FRAG_N_USED,
+				 frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES,
+				 mtr);
+	}
+}
+
+/**********************************************************************//**
 Allocates a single free page from a space. The page is marked as used.
 @return	the page offset, FIL_NULL if no page could be allocated */
-static
+static __attribute__((nonnull, warn_unused_result))
 ulint
 fsp_alloc_free_page(
 /*================*/
@@ -1507,19 +1550,22 @@ fsp_alloc_free_page(
 	ulint	zip_size,/*!< in: compressed page size in bytes
 			or 0 for uncompressed pages */
 	ulint	hint,	/*!< in: hint of which page would be desirable */
-	mtr_t*	mtr)	/*!< in: mtr handle */
+	mtr_t*	mtr,	/*!< in/out: mini-transaction */
+	mtr_t*	init_mtr)/*!< in/out: mini-transaction in which the
+			page should be initialized
+			(may be the same as mtr) */
 {
 	fsp_header_t*	header;
 	fil_addr_t	first;
 	xdes_t*		descr;
 	buf_block_t*	block;
 	ulint		free;
-	ulint		frag_n_used;
 	ulint		page_no;
 	ulint		space_size;
 	ibool		success;
 
 	ut_ad(mtr);
+	ut_ad(init_mtr);
 
 	header = fsp_get_space_header(space, zip_size, mtr);
 
@@ -1601,38 +1647,19 @@ fsp_alloc_free_page(
 		}
 	}
 
-	xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr);
-
-	/* Update the FRAG_N_USED field */
-	frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES,
-				     mtr);
-	frag_n_used++;
-	mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES,
-			 mtr);
-	if (xdes_is_full(descr, mtr)) {
-		/* The fragment is full: move it to another list */
-		flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
-			    mtr);
-		xdes_set_state(descr, XDES_FULL_FRAG, mtr);
-
-		flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
-			      mtr);
-		mlog_write_ulint(header + FSP_FRAG_N_USED,
-				 frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES,
-				 mtr);
-	}
+	fsp_alloc_from_free_frag(header, descr, free, mtr);
 
 	/* Initialize the allocated page to the buffer pool, so that it can
 	be obtained immediately with buf_page_get without need for a disk
 	read. */
 
-	buf_page_create(space, page_no, zip_size, mtr);
+	buf_page_create(space, page_no, zip_size, init_mtr);
 
-	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
+	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, init_mtr);
 	buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
 	/* Prior contents of the page should be ignored */
-	fsp_init_file_page(block, mtr);
+	fsp_init_file_page(block, init_mtr);
 
 	return(page_no);
 }
@@ -1868,7 +1895,7 @@ fsp_alloc_seg_inode_page(
 	zip_size = dict_table_flags_to_zip_size(
 		mach_read_from_4(FSP_SPACE_FLAGS + space_header));
 
-	page_no = fsp_alloc_free_page(space, zip_size, 0, mtr);
+	page_no = fsp_alloc_free_page(space, zip_size, 0, mtr, mtr);
 
 	if (page_no == FIL_NULL) {
 
@@ -2277,7 +2304,7 @@ fseg_create_general(
 
 	if (page == 0) {
 		page = fseg_alloc_free_page_low(space, zip_size,
-						inode, 0, FSP_UP, mtr);
+						inode, 0, FSP_UP, mtr, mtr);
 
 		if (page == FIL_NULL) {
 
@@ -2523,14 +2550,19 @@ fseg_alloc_free_page_low(
 	ulint		space,	/*!< in: space */
 	ulint		zip_size,/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
-	fseg_inode_t*	seg_inode, /*!< in: segment inode */
+	fseg_inode_t*	seg_inode, /*!< in/out: segment inode */
 	ulint		hint,	/*!< in: hint of which page would be desirable */
 	byte		direction, /*!< in: if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
 				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr)	/*!< in: mtr handle */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mini-transaction in which the
+				page should be initialized
+				(may be the same as mtr), or NULL if it
+				should not be initialized (the page at hint
+				was previously freed in mtr) */
 {
 	fsp_header_t*	space_header;
 	ulint		space_size;
@@ -2541,7 +2573,6 @@ fseg_alloc_free_page_low(
 	ulint		ret_page;	/*!< the allocated page offset, FIL_NULL
 					if could not be allocated */
 	xdes_t*		ret_descr;	/*!< the extent of the allocated page */
-	ibool		frag_page_allocated = FALSE;
 	ibool		success;
 	ulint		n;
 
@@ -2563,6 +2594,8 @@ fseg_alloc_free_page_low(
 	if (descr == NULL) {
 		/* Hint outside space or too high above free limit: reset
 		hint */
+		ut_a(init_mtr);
+		/* The file space header page is always allocated. */
 		hint = 0;
 		descr = xdes_get_descriptor(space, zip_size, hint, mtr);
 	}
@@ -2573,15 +2606,20 @@ fseg_alloc_free_page_low(
 	    && mach_read_from_8(descr + XDES_ID) == seg_id
 	    && (xdes_get_bit(descr, XDES_FREE_BIT,
 			     hint % FSP_EXTENT_SIZE, mtr) == TRUE)) {
-
+take_hinted_page:
 		/* 1. We can take the hinted page
 		=================================*/
 		ret_descr = descr;
 		ret_page = hint;
+		/* Skip the check for extending the tablespace. If the
+		page hint were not within the size of the tablespace,
+		we would have got (descr == NULL) above and reset the hint. */
+		goto got_hinted_page;
 		/*-----------------------------------------------------------*/
-	} else if ((xdes_get_state(descr, mtr) == XDES_FREE)
-		   && ((reserved - used) < reserved / FSEG_FILLFACTOR)
-		   && (used >= FSEG_FRAG_LIMIT)) {
+	} else if (xdes_get_state(descr, mtr) == XDES_FREE
+		   && (!init_mtr
+		       || ((reserved - used < reserved / FSEG_FILLFACTOR)
+			   && used >= FSEG_FRAG_LIMIT))) {
 
 		/* 2. We allocate the free extent from space and can take
 		=========================================================
@@ -2599,8 +2637,20 @@ fseg_alloc_free_page_low(
 		/* Try to fill the segment free list */
 		fseg_fill_free_list(seg_inode, space, zip_size,
 				    hint + FSP_EXTENT_SIZE, mtr);
-		ret_page = hint;
+		goto take_hinted_page;
 		/*-----------------------------------------------------------*/
+	} else if (!init_mtr) {
+		ut_a(xdes_get_state(descr, mtr) == XDES_FREE_FRAG);
+		fsp_alloc_from_free_frag(space_header, descr,
+					 hint % FSP_EXTENT_SIZE, mtr);
+		ret_page = hint;
+		ret_descr = NULL;
+
+		/* Put the page in the fragment page array of the segment */
+		n = fseg_find_free_frag_page_slot(seg_inode, mtr);
+		ut_a(n != FIL_NULL);
+		fseg_set_nth_frag_page_no(seg_inode, n, ret_page, mtr);
+		goto got_hinted_page;
 	} else if ((direction != FSP_NO_DIR)
 		   && ((reserved - used) < reserved / FSEG_FILLFACTOR)
 		   && (used >= FSEG_FRAG_LIMIT)
@@ -2659,11 +2709,10 @@ fseg_alloc_free_page_low(
 	} else if (used < FSEG_FRAG_LIMIT) {
 		/* 6. We allocate an individual page from the space
 		===================================================*/
-		ret_page = fsp_alloc_free_page(space, zip_size, hint, mtr);
+		ret_page = fsp_alloc_free_page(space, zip_size, hint,
+					       mtr, init_mtr);
 		ret_descr = NULL;
 
-		frag_page_allocated = TRUE;
-
 		if (ret_page != FIL_NULL) {
 			/* Put the page in the fragment page array of the
 			segment */
@@ -2673,6 +2722,10 @@ fseg_alloc_free_page_low(
 			fseg_set_nth_frag_page_no(seg_inode, n, ret_page,
 						  mtr);
 		}
+
+		/* fsp_alloc_free_page() invoked fsp_init_file_page()
+		already. */
+		return(ret_page);
 		/*-----------------------------------------------------------*/
 	} else {
 		/* 7. We allocate a new extent and take its first page
@@ -2720,26 +2773,34 @@ fseg_alloc_free_page_low(
 		}
 	}
 
-	if (!frag_page_allocated) {
+got_hinted_page:
+	{
 		/* Initialize the allocated page to buffer pool, so that it
 		can be obtained immediately with buf_page_get without need
 		for a disk read */
 		buf_block_t*	block;
 		ulint		zip_size = dict_table_flags_to_zip_size(
 			mach_read_from_4(FSP_SPACE_FLAGS + space_header));
+		mtr_t*		block_mtr = init_mtr ? init_mtr : mtr;
 
-		block = buf_page_create(space, ret_page, zip_size, mtr);
+		block = buf_page_create(space, ret_page, zip_size, block_mtr);
 		buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
 		if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size,
 							ret_page, RW_X_LATCH,
-							mtr))) {
+							block_mtr))) {
 			ut_error;
 		}
 
-		/* The prior contents of the page should be ignored */
-		fsp_init_file_page(block, mtr);
+		if (init_mtr) {
+			/* The prior contents of the page should be ignored */
+			fsp_init_file_page(block, init_mtr);
+		}
+	}
 
+	/* ret_descr == NULL if the block was allocated from free_frag
+	(XDES_FREE_FRAG) */
+	if (ret_descr != NULL) {
 		/* At this point we know the extent and the page offset.
 		The extent is still in the appropriate list (FSEG_NOT_FULL
 		or FSEG_FREE), and the page is not yet marked as used. */
@@ -2752,8 +2813,6 @@ fseg_alloc_free_page_low(
 		fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr);
 	}
 
-	buf_reset_check_index_page_at_flush(space, ret_page);
-
 	return(ret_page);
 }
 
@@ -2766,7 +2825,7 @@ UNIV_INTERN
 ulint
 fseg_alloc_free_page_general(
 /*=========================*/
-	fseg_header_t*	seg_header,/*!< in: segment header */
+	fseg_header_t*	seg_header,/*!< in/out: segment header */
 	ulint		hint,	/*!< in: hint of which page would be desirable */
 	byte		direction,/*!< in: if the new page is needed because
 				of an index page split, and records are
@@ -2778,7 +2837,11 @@ fseg_alloc_free_page_general(
 				with fsp_reserve_free_extents, then there
 				is no need to do the check for this individual
 				page */
-	mtr_t*		mtr)	/*!< in: mtr handle */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction handle */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized,
+				or NULL if this is a "fake allocation" of
+				a page that was previously freed in mtr */
 {
 	fseg_inode_t*	inode;
 	ulint		space;
@@ -2817,7 +2880,8 @@ fseg_alloc_free_page_general(
 	}
 
 	page_no = fseg_alloc_free_page_low(space, zip_size,
-					   inode, hint, direction, mtr);
+					   inode, hint, direction,
+					   mtr, init_mtr);
 	if (!has_done_reservation) {
 		fil_space_release_free_extents(space, n_reserved);
 	}
@@ -2826,28 +2890,6 @@ fseg_alloc_free_page_general(
 }
 
 /**********************************************************************//**
-Allocates a single free page from a segment. This function implements
-the intelligent allocation strategy which tries to minimize file space
-fragmentation.
-@return	allocated page offset, FIL_NULL if no page could be allocated */
-UNIV_INTERN
-ulint
-fseg_alloc_free_page(
-/*=================*/
-	fseg_header_t*	seg_header,/*!< in: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
-	byte		direction,/*!< in: if the new page is needed because
-				of an index page split, and records are
-				inserted there in order, into which
-				direction they go alphabetically: FSP_DOWN,
-				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr)	/*!< in: mtr handle */
-{
-	return(fseg_alloc_free_page_general(seg_header, hint, direction,
-					    FALSE, mtr));
-}
-
-/**********************************************************************//**
 Checks that we have at least 2 frag pages free in the first extent of a
 single-table tablespace, and they are also physically initialized to the data
 file. That is we have already extended the data file so that those pages are

=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h	2011-08-15 09:34:39 +0000
+++ b/storage/innobase/include/btr0btr.h	2011-08-29 08:45:30 +0000
@@ -568,7 +568,12 @@ btr_page_alloc(
 					page split is made */
 	ulint		level,		/*!< in: level where the page is placed
 					in the tree */
-	mtr_t*		mtr);		/*!< in: mtr */
+	mtr_t*		mtr,		/*!< in/out: mini-transaction
+					for the allocation */
+	mtr_t*		init_mtr)	/*!< in/out: mini-transaction
+					for x-latching and initializing
+					the page */
+	__attribute__((nonnull, warn_unused_result));
 /**************************************************************//**
 Frees a file page used in an index tree. NOTE: cannot free field external
 storage pages because the page must contain info on its level. */
@@ -591,6 +596,33 @@ btr_page_free_low(
 	buf_block_t*	block,	/*!< in: block to be freed, x-latched */
 	ulint		level,	/*!< in: page level */
 	mtr_t*		mtr);	/*!< in: mtr */
+/**************************************************************//**
+Marks all MTR_MEMO_FREE_CLUST_LEAF pages nonfree or free.
+For invoking btr_store_big_rec_extern_fields() after an update,
+we must temporarily mark freed clustered index pages allocated, so
+that off-page columns will not be allocated from them. Between the
+btr_store_big_rec_extern_fields() and mtr_commit() we have to
+mark the pages free again, so that no pages will be leaked. */
+UNIV_INTERN
+void
+btr_mark_freed_leaves(
+/*==================*/
+	dict_index_t*	index,	/*!< in/out: clustered index */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	ibool		nonfree)/*!< in: TRUE=mark nonfree, FALSE=mark freed */
+	UNIV_COLD __attribute__((nonnull));
+#ifdef UNIV_DEBUG
+/**************************************************************//**
+Validates all pages marked MTR_MEMO_FREE_CLUST_LEAF.
+@see btr_mark_freed_leaves()
+@return TRUE */
+UNIV_INTERN
+ibool
+btr_freed_leaves_validate(
+/*======================*/
+	mtr_t*	mtr)	/*!< in: mini-transaction */
+	__attribute__((nonnull, warn_unused_result));
+#endif /* UNIV_DEBUG */
 #ifdef UNIV_BTR_PRINT
 /*************************************************************//**
 Prints size info of a B-tree. */

=== modified file 'storage/innobase/include/btr0cur.h'
--- a/storage/innobase/include/btr0cur.h	2011-06-16 09:26:09 +0000
+++ b/storage/innobase/include/btr0cur.h	2011-08-29 08:45:30 +0000
@@ -329,16 +329,6 @@ btr_cur_pessimistic_update(
 	que_thr_t*	thr,	/*!< in: query thread */
 	mtr_t*		mtr);	/*!< in: mtr; must be committed before
 				latching any further pages */
-/*****************************************************************
-Commits and restarts a mini-transaction so that it will retain an
-x-lock on index->lock and the cursor page. */
-UNIV_INTERN
-void
-btr_cur_mtr_commit_and_start(
-/*=========================*/
-	btr_cur_t*	cursor,	/*!< in: cursor */
-	mtr_t*		mtr)	/*!< in/out: mini-transaction */
-	UNIV_COLD __attribute__((nonnull));
 /***********************************************************//**
 Marks a clustered index record deleted. Writes an undo log record to
 undo log on this delete marking. Writes in the trx id field the id
@@ -531,6 +521,8 @@ btr_store_big_rec_extern_fields_func(
 					the "external storage" flags in offsets
 					will not correspond to rec when
 					this function returns */
+	const big_rec_t*big_rec_vec,	/*!< in: vector containing fields
+					to be stored externally */
 #ifdef UNIV_DEBUG
 	mtr_t*		local_mtr,	/*!< in: mtr containing the
 					latch to rec and to the tree */
@@ -539,9 +531,12 @@ btr_store_big_rec_extern_fields_func(
 	ibool		update_in_place,/*! in: TRUE if the record is updated
 					in place (not delete+insert) */
 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
-	const big_rec_t*big_rec_vec)	/*!< in: vector containing fields
-					to be stored externally */
-	__attribute__((nonnull));
+	mtr_t*		alloc_mtr)	/*!< in/out: in an insert, NULL;
+					in an update, local_mtr for
+					allocating BLOB pages and
+					updating BLOB pointers; alloc_mtr
+					must not have freed any leaf pages */
+	__attribute__((nonnull(1,2,3,4,5), warn_unused_result));
 
 /** Stores the fields in big_rec_vec to the tablespace and puts pointers to
 them in rec.  The extern flags in rec will have to be set beforehand.
@@ -550,21 +545,22 @@ file segment of the index tree.
 @param index	in: clustered index; MUST be X-latched by mtr
 @param b	in/out: block containing rec; MUST be X-latched by mtr
 @param rec	in/out: clustered index record
-@param offsets	in: rec_get_offsets(rec, index);
+@param offs	in: rec_get_offsets(rec, index);
 		the "external storage" flags in offsets will not be adjusted
+@param big	in: vector containing fields to be stored externally
 @param mtr	in: mini-transaction that holds x-latch on index and b
 @param upd	in: TRUE if the record is updated in place (not delete+insert)
-@param big	in: vector containing fields to be stored externally
+@param rmtr	in/out: in updates, the mini-transaction that holds rec
 @return	DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
 #ifdef UNIV_DEBUG
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
+# define btr_store_big_rec_extern_fields(index,b,rec,offs,big,mtr,upd,rmtr) \
+	btr_store_big_rec_extern_fields_func(index,b,rec,offs,big,mtr,upd,rmtr)
 #elif defined UNIV_BLOB_LIGHT_DEBUG
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
+# define btr_store_big_rec_extern_fields(index,b,rec,offs,big,mtr,upd,rmtr) \
+	btr_store_big_rec_extern_fields_func(index,b,rec,offs,big,upd,rmtr)
 #else
-# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
-	btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
+# define btr_store_big_rec_extern_fields(index,b,rec,offs,big,mtr,upd,rmtr) \
+	btr_store_big_rec_extern_fields_func(index,b,rec,offs,big,rmtr)
 #endif
 
 /*******************************************************************//**

=== modified file 'storage/innobase/include/buf0buf.h'
--- a/storage/innobase/include/buf0buf.h	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/include/buf0buf.h	2011-08-29 08:45:30 +0000
@@ -500,15 +500,6 @@ buf_page_peek(
 /*==========*/
 	ulint	space,	/*!< in: space id */
 	ulint	offset);/*!< in: page number */
-/********************************************************************//**
-Resets the check_index_page_at_flush field of a page if found in the buffer
-pool. */
-UNIV_INTERN
-void
-buf_reset_check_index_page_at_flush(
-/*================================*/
-	ulint	space,	/*!< in: space id */
-	ulint	offset);/*!< in: page number */
 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
 /********************************************************************//**
 Sets file_page_was_freed TRUE if the page is found in the buffer pool.

=== modified file 'storage/innobase/include/buf0checksum.h'
--- a/storage/innobase/include/buf0checksum.h	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/include/buf0checksum.h	2011-08-29 07:14:48 +0000
@@ -28,7 +28,7 @@ Created Aug 11, 2011 Vasil Dimov
 
 #include "univ.i"
 
-#include "srv0srv.h" /* srv_checksum_algorithm_t */
+#include "buf0types.h"
 
 /********************************************************************//**
 Calculates a page CRC32 which is stored to the page when it is written
@@ -75,4 +75,6 @@ buf_checksum_algorithm_name(
 /*========================*/
 	srv_checksum_algorithm_t	algo);	/*!< in: algorithm */
 
+extern ulong	srv_checksum_algorithm;
+
 #endif /* buf0checksum_h */

=== modified file 'storage/innobase/include/buf0types.h'
--- a/storage/innobase/include/buf0types.h	2011-08-10 06:26:39 +0000
+++ b/storage/innobase/include/buf0types.h	2011-08-29 07:14:48 +0000
@@ -59,6 +59,25 @@ enum buf_io_fix {
 	BUF_IO_WRITE			/**< write pending */
 };
 
+/** Alternatives for srv_checksum_algorithm, which can be changed by
+setting innodb_checksum_algorithm */
+enum srv_checksum_algorithm_enum {
+	SRV_CHECKSUM_ALGORITHM_CRC32,		/*!< Write crc32, allow crc32,
+						innodb or none when reading */
+	SRV_CHECKSUM_ALGORITHM_STRICT_CRC32,	/*!< Write crc32, allow crc32
+						when reading */
+	SRV_CHECKSUM_ALGORITHM_INNODB,		/*!< Write innodb, allow crc32,
+						innodb or none when reading */
+	SRV_CHECKSUM_ALGORITHM_STRICT_INNODB,	/*!< Write innodb, allow
+						innodb when reading */
+	SRV_CHECKSUM_ALGORITHM_NONE,		/*!< Write none, allow crc32,
+						innodb or none when reading */
+	SRV_CHECKSUM_ALGORITHM_STRICT_NONE,	/*!< Write none, allow none
+						when reading */
+};
+
+typedef enum srv_checksum_algorithm_enum	srv_checksum_algorithm_t;
+
 /** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
 /* @{ */
 #define BUF_BUDDY_LOW_SHIFT	UNIV_ZIP_SIZE_SHIFT_MIN

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/include/dict0dict.h	2011-08-29 10:12:32 +0000
@@ -1354,7 +1354,8 @@ UNIV_INTERN
 void
 dict_set_corrupted_index_cache_only(
 /*================================*/
-	dict_index_t*	index);		/*!< in/out: index */
+	dict_index_t*	index,		/*!< in/out: index */
+	dict_table_t*	table);		/*!< in/out: table */
 
 /**********************************************************************//**
 Flags a table with specified space_id corrupted in the table dictionary

=== modified file 'storage/innobase/include/fsp0fsp.h'
--- a/storage/innobase/include/fsp0fsp.h	2011-04-27 21:49:19 +0000
+++ b/storage/innobase/include/fsp0fsp.h	2011-08-29 08:45:30 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -166,19 +166,18 @@ fseg_n_reserved_pages(
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize
 file space fragmentation.
-@return	the allocated page offset FIL_NULL if no page could be allocated */
-UNIV_INTERN
-ulint
-fseg_alloc_free_page(
-/*=================*/
-	fseg_header_t*	seg_header, /*!< in: segment header */
-	ulint		hint,	/*!< in: hint of which page would be desirable */
-	byte		direction, /*!< in: if the new page is needed because
+@param[in/out] seg_header	segment header
+@param[in] hint			hint of which page would be desirable
+@param[in] direction		if the new page is needed because
 				of an index page split, and records are
 				inserted there in order, into which
 				direction they go alphabetically: FSP_DOWN,
-				FSP_UP, FSP_NO_DIR */
-	mtr_t*		mtr);	/*!< in: mtr handle */
+				FSP_UP, FSP_NO_DIR
+@param[in/out] mtr		mini-transaction
+@return	the allocated page offset FIL_NULL if no page could be allocated */
+#define fseg_alloc_free_page(seg_header, hint, direction, mtr)		\
+	fseg_alloc_free_page_general(seg_header, hint, direction,	\
+				     FALSE, mtr, mtr)
 /**********************************************************************//**
 Allocates a single free page from a segment. This function implements
 the intelligent allocation strategy which tries to minimize file space
@@ -188,7 +187,7 @@ UNIV_INTERN
 ulint
 fseg_alloc_free_page_general(
 /*=========================*/
-	fseg_header_t*	seg_header,/*!< in: segment header */
+	fseg_header_t*	seg_header,/*!< in/out: segment header */
 	ulint		hint,	/*!< in: hint of which page would be desirable */
 	byte		direction,/*!< in: if the new page is needed because
 				of an index page split, and records are
@@ -200,7 +199,12 @@ fseg_alloc_free_page_general(
 				with fsp_reserve_free_extents, then there
 				is no need to do the check for this individual
 				page */
-	mtr_t*		mtr);	/*!< in: mtr handle */
+	mtr_t*		mtr,	/*!< in/out: mini-transaction */
+	mtr_t*		init_mtr)/*!< in/out: mtr or another mini-transaction
+				in which the page should be initialized,
+				or NULL if this is a "fake allocation" of
+				a page that was previously freed in mtr */
+	__attribute__((warn_unused_result, nonnull(1,5)));
 /**********************************************************************//**
 Reserves free pages from a tablespace. All mini-transactions which may
 use several pages from the tablespace should call this function beforehand

=== modified file 'storage/innobase/include/mtr0mtr.h'
--- a/storage/innobase/include/mtr0mtr.h	2011-05-04 09:54:04 +0000
+++ b/storage/innobase/include/mtr0mtr.h	2011-08-29 08:45:30 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -53,6 +53,8 @@ first 3 values must be RW_S_LATCH, RW_X_
 #define MTR_MEMO_MODIFY		54
 #define	MTR_MEMO_S_LOCK		55
 #define	MTR_MEMO_X_LOCK		56
+/** The mini-transaction freed a clustered index leaf page. */
+#define MTR_MEMO_FREE_CLUST_LEAF	57
 
 /** @name Log item types
 The log items are declared 'byte' so that the compiler can warn if val
@@ -380,12 +382,16 @@ struct mtr_struct{
 #endif
 	dyn_array_t	memo;	/*!< memo stack for locks etc. */
 	dyn_array_t	log;	/*!< mini-transaction log */
-	ibool		inside_ibuf;
+	unsigned	inside_ibuf:1;
 				/*!< TRUE if inside ibuf changes */
-	ibool		modifications;
-				/* TRUE if the mtr made modifications to
-				buffer pool pages */
-	ibool		made_dirty;/*!< TRUE if mtr has made at least
+	unsigned	modifications:1;
+				/*!< TRUE if the mini-transaction
+				modified buffer pool pages */
+	unsigned	freed_clust_leaf:1;
+				/*!< TRUE if MTR_MEMO_FREE_CLUST_LEAF
+				was logged in the mini-transaction */
+	unsigned	made_dirty:1;
+				/*!< TRUE if mtr has made at least
 				one buffer pool page dirty */
 	ulint		n_log_recs;
 				/* count of how many page initial log records

=== modified file 'storage/innobase/include/mtr0mtr.ic'
--- a/storage/innobase/include/mtr0mtr.ic	2011-05-31 08:18:27 +0000
+++ b/storage/innobase/include/mtr0mtr.ic	2011-08-29 08:45:30 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -53,10 +53,11 @@ mtr_start(
 	dyn_array_create(&(mtr->log));
 
 	mtr->log_mode = MTR_LOG_ALL;
-	mtr->modifications = FALSE;
 	mtr->inside_ibuf = FALSE;
-	mtr->n_log_recs = 0;
+	mtr->modifications = FALSE;
+	mtr->freed_clust_leaf = FALSE;
 	mtr->made_dirty = FALSE;
+	mtr->n_log_recs = 0;
 
 	ut_d(mtr->state = MTR_ACTIVE);
 	ut_d(mtr->magic_n = MTR_MAGIC_N);
@@ -77,7 +78,8 @@ mtr_memo_push(
 
 	ut_ad(object);
 	ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
-	ut_ad(type <= MTR_MEMO_X_LOCK);
+	ut_ad(type <= MTR_MEMO_FREE_CLUST_LEAF);
+	ut_ad(type != MTR_MEMO_FREE_CLUST_LEAF || mtr->freed_clust_leaf);
 	ut_ad(mtr);
 	ut_ad(mtr->magic_n == MTR_MAGIC_N);
 	ut_ad(mtr->state == MTR_ACTIVE);

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/include/srv0srv.h	2011-08-29 07:14:48 +0000
@@ -49,25 +49,7 @@ Created 10/10/1995 Heikki Tuuri
 #include "que0types.h"
 #include "trx0types.h"
 #include "srv0conc.h"
-
-/** Alternatives for srv_checksum_algorithm, which can be changed by
-setting innodb_checksum_algorithm */
-enum srv_checksum_algorithm_enum {
-	SRV_CHECKSUM_ALGORITHM_CRC32,		/*!< Write crc32, allow crc32,
-						innodb or none when reading */
-	SRV_CHECKSUM_ALGORITHM_STRICT_CRC32,	/*!< Write crc32, allow crc32
-						when reading */
-	SRV_CHECKSUM_ALGORITHM_INNODB,		/*!< Write innodb, allow crc32,
-						innodb or none when reading */
-	SRV_CHECKSUM_ALGORITHM_STRICT_INNODB,	/*!< Write innodb, allow
-						innodb when reading */
-	SRV_CHECKSUM_ALGORITHM_NONE,		/*!< Write none, allow crc32,
-						innodb or none when reading */
-	SRV_CHECKSUM_ALGORITHM_STRICT_NONE,	/*!< Write none, allow none
-						when reading */
-};
-
-typedef enum srv_checksum_algorithm_enum	srv_checksum_algorithm_t;
+#include "buf0checksum.h"
 
 extern const char*	srv_main_thread_op_info;
 
@@ -125,22 +107,12 @@ extern FILE*	srv_misc_tmpfile;
 
 extern char*	srv_data_home;
 
-/** Server undo tablespaces directory, can be absolute path. */
-extern char*	srv_undo_dir;
-
-/** Number of undo tablespaces to use. */
-extern ulong	srv_undo_tablespaces;
-
-/* The number of undo segments to use */
-extern ulong	srv_undo_logs;
-
 #ifdef UNIV_LOG_ARCHIVE
 extern char*	srv_arch_dir;
 #endif /* UNIV_LOG_ARCHIVE */
 
 /** store to its own file each table created by an user; data
 dictionary tables are in the system tablespace 0 */
-#ifndef UNIV_HOTBACKUP
 extern my_bool	srv_file_per_table;
 /** Sleep delay for threads waiting to enter InnoDB. In micro-seconds. */
 extern	ulong	srv_thread_sleep_delay;
@@ -148,9 +120,6 @@ extern	ulong	srv_thread_sleep_delay;
 /** Maximum sleep delay (in micro-seconds), value of 0 disables it.*/
 extern	ulong	srv_adaptive_max_sleep_delay;
 #endif /* HAVE_ATOMIC_BUILTINS */
-#else
-extern ibool	srv_file_per_table;
-#endif /* HAVE_ATOMIC_BUILTINS */
 
 /** The file format to use on new *.ibd files. */
 extern ulint	srv_file_format;
@@ -169,8 +138,18 @@ Currently we support native aio on windo
 extern my_bool	srv_use_native_aio;
 #ifdef __WIN__
 extern ibool	srv_use_native_conditions;
-#endif
+#endif /* __WIN__ */
 #endif /* !UNIV_HOTBACKUP */
+
+/** Server undo tablespaces directory, can be absolute path. */
+extern char*	srv_undo_dir;
+
+/** Number of undo tablespaces to use. */
+extern ulong	srv_undo_tablespaces;
+
+/* The number of undo segments to use */
+extern ulong	srv_undo_logs;
+
 extern ulint	srv_n_data_files;
 extern char**	srv_data_file_names;
 extern ulint*	srv_data_file_sizes;

=== modified file 'storage/innobase/include/sync0sync.ic'
--- a/storage/innobase/include/sync0sync.ic	2011-07-06 18:58:53 +0000
+++ b/storage/innobase/include/sync0sync.ic	2011-08-29 08:58:34 +0000
@@ -270,15 +270,16 @@ pfs_mutex_enter_nowait_func(
 	PSI_mutex_locker_state		state;
 
 	locker = PSI_CALL(get_thread_mutex_locker)(
-			&state, mutex->pfs_psi, PSI_MUTEX_LOCK);
+			&state, mutex->pfs_psi, PSI_MUTEX_TRYLOCK);
 	if (UNIV_LIKELY(locker != NULL)) {
 		PSI_CALL(start_mutex_wait)(locker, file_name, line);
 		ret = mutex_enter_nowait_func(mutex, file_name, line);
-		PSI_CALL(end_mutex_wait)(locker, 0);
+		PSI_CALL(end_mutex_wait)(locker, (int) ret);
 		return(ret);
 	}
 
 	ret = mutex_enter_nowait_func(mutex, file_name, line);
+
 	return(ret);
 }
 /******************************************************************//**

=== modified file 'storage/innobase/mtr/mtr0mtr.c'
--- a/storage/innobase/mtr/mtr0mtr.c	2011-05-31 08:18:27 +0000
+++ b/storage/innobase/mtr/mtr0mtr.c	2011-08-29 08:45:30 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -87,12 +87,11 @@ mtr_memo_slot_release(
 			buf_page_release((buf_block_t*)object, type);
 		} else if (type == MTR_MEMO_S_LOCK) {
 			rw_lock_s_unlock((rw_lock_t*)object);
-#ifdef UNIV_DEBUG
 		} else if (type != MTR_MEMO_X_LOCK) {
-			ut_ad(type == MTR_MEMO_MODIFY);
+			ut_ad(type == MTR_MEMO_MODIFY
+			      || type == MTR_MEMO_FREE_CLUST_LEAF);
 			ut_ad(mtr_memo_contains(mtr, object,
 						MTR_MEMO_PAGE_X_FIX));
-#endif /* UNIV_DEBUG */
 		} else {
 			rw_lock_x_unlock((rw_lock_t*)object);
 		}

=== modified file 'storage/innobase/page/page0zip.c'
--- a/storage/innobase/page/page0zip.c	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/page/page0zip.c	2011-08-29 07:14:48 +0000
@@ -47,6 +47,7 @@ Created June 2005 by Marko Makela
 # include "srv0srv.h"
 # include "ut0crc32.h"
 #else /* !UNIV_HOTBACKUP */
+# include "buf0checksum.h"
 # define lock_move_reorganize_page(block, temp_block)	((void) 0)
 # define buf_LRU_stat_inc_unzip()			((void) 0)
 #endif /* !UNIV_HOTBACKUP */

=== modified file 'storage/innobase/row/row0ins.c'
--- a/storage/innobase/row/row0ins.c	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/row/row0ins.c	2011-08-29 08:45:30 +0000
@@ -2091,15 +2091,20 @@ row_ins_index_entry_low(
 			if (big_rec) {
 				ut_a(err == DB_SUCCESS);
 				/* Write out the externally stored
-				columns while still x-latching
-				index->lock and block->lock. We have
-				to mtr_commit(mtr) first, so that the
-				redo log will be written in the
-				correct order. Otherwise, we would run
-				into trouble on crash recovery if mtr
-				freed B-tree pages on which some of
-				the big_rec fields will be written. */
-				btr_cur_mtr_commit_and_start(&cursor, &mtr);
+				columns, but allocate the pages and
+				write the pointers using the
+				mini-transaction of the record update.
+				If any pages were freed in the update,
+				temporarily mark them allocated so
+				that off-page columns will not
+				overwrite them. We must do this,
+				because we will write the redo log for
+				the BLOB writes before writing the
+				redo log for the record update. Thus,
+				redo log application at crash recovery
+				will see BLOBs being written to free pages. */
+
+				btr_mark_freed_leaves(index, &mtr, TRUE);
 
 				rec = btr_cur_get_rec(&cursor);
 				offsets = rec_get_offsets(
@@ -2108,7 +2113,8 @@ row_ins_index_entry_low(
 
 				err = btr_store_big_rec_extern_fields(
 					index, btr_cur_get_block(&cursor),
-					rec, offsets, &mtr, FALSE, big_rec);
+					rec, offsets, big_rec, &mtr,
+					FALSE, &mtr);
 				/* If writing big_rec fails (for
 				example, because of DB_OUT_OF_FILE_SPACE),
 				the record will be corrupted. Even if
@@ -2121,6 +2127,9 @@ row_ins_index_entry_low(
 				undo log, and thus the record cannot
 				be rolled back. */
 				ut_a(err == DB_SUCCESS);
+				/* Free the pages again
+				in order to avoid a leak. */
+				btr_mark_freed_leaves(index, &mtr, FALSE);
 				goto stored_big_rec;
 			}
 		} else {
@@ -2162,7 +2171,7 @@ function_exit:
 
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(&cursor),
-			rec, offsets, &mtr, FALSE, big_rec);
+			rec, offsets, big_rec, &mtr, FALSE, NULL);
 
 stored_big_rec:
 		if (modify) {
@@ -2437,7 +2446,7 @@ row_ins(
 		node->index = dict_table_get_next_index(node->index);
 		node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
 
-		/* Skip corrupted secondar index and its entry */
+		/* Skip corrupted secondary index and its entry */
 		while (node->index && dict_index_is_corrupted(node->index)) {
 
 			node->index = dict_table_get_next_index(node->index);

=== modified file 'storage/innobase/row/row0row.c'
--- a/storage/innobase/row/row0row.c	2011-07-26 03:21:33 +0000
+++ b/storage/innobase/row/row0row.c	2011-08-29 12:58:11 +0000
@@ -243,19 +243,20 @@ row_build(
 	}
 
 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
-	/* This condition can occur during crash recovery before
-	trx_rollback_active() has completed execution.
-
-	This condition is possible if the server crashed
-	during an insert or update before
-	btr_store_big_rec_extern_fields() did mtr_commit() all
-	BLOB pointers to the clustered index record.
-
-	If the record contains a null BLOB pointer, look up the
-	transaction that holds the implicit lock on this record, and
-	assert that it was recovered (and will soon be rolled back). */
-	ut_a(!rec_offs_any_null_extern(rec, offsets)
-	     || trx_assert_recovered(row_get_rec_trx_id(rec, index, offsets)));
+	if (rec_offs_any_null_extern(rec, offsets)) {
+		/* This condition can occur during crash recovery
+		before trx_rollback_active() has completed execution.
+
+		This condition is possible if the server crashed
+		during an insert or update-by-delete-and-insert before
+		btr_store_big_rec_extern_fields() did mtr_commit() all
+		BLOB pointers to the freshly inserted clustered index
+		record. */
+		ut_a(trx_assert_recovered(
+			     row_get_rec_trx_id(rec, index, offsets)));
+		ut_a(trx_undo_roll_ptr_is_insert(
+			     row_get_rec_roll_ptr(rec, index, offsets)));
+	}
 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
 	if (type != ROW_COPY_POINTERS) {
@@ -1023,6 +1024,8 @@ test_row_raw_format_int()
 	ulint	ret;
 	char	buf[128];
 	ibool	format_in_hex;
+	speedo_t speedo;
+	ulint	i;
 
 #define CALL_AND_TEST(data, data_len, prtype, buf, buf_size,\
 		      ret_expected, buf_expected, format_in_hex_expected)\
@@ -1205,9 +1208,6 @@ test_row_raw_format_int()
 
 	/* speed test */
 
-	speedo_t	speedo;
-	ulint		i;
-
 	speedo_reset(&speedo);
 
 	for (i = 0; i < 1000000; i++) {

=== modified file 'storage/innobase/row/row0upd.c'
--- a/storage/innobase/row/row0upd.c	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/row/row0upd.c	2011-08-29 08:45:30 +0000
@@ -2004,21 +2004,22 @@ row_upd_clust_rec(
 		rec_offs_init(offsets_);
 
 		ut_a(err == DB_SUCCESS);
-		/* Write out the externally stored columns while still
-		x-latching index->lock and block->lock. We have to
-		mtr_commit(mtr) first, so that the redo log will be
-		written in the correct order. Otherwise, we would run
-		into trouble on crash recovery if mtr freed B-tree
-		pages on which some of the big_rec fields will be
-		written. */
-		btr_cur_mtr_commit_and_start(btr_cur, mtr);
+		/* Write out the externally stored columns, but
+		allocate the pages and write the pointers using the
+		mini-transaction of the record update. If any pages
+		were freed in the update, temporarily mark them
+		allocated so that off-page columns will not overwrite
+		them. We must do this, because we write the redo log
+		for the BLOB writes before writing the redo log for
+		the record update. */
 
+		btr_mark_freed_leaves(index, mtr, TRUE);
 		rec = btr_cur_get_rec(btr_cur);
 		err = btr_store_big_rec_extern_fields(
 			index, btr_cur_get_block(btr_cur), rec,
 			rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
-			mtr, TRUE, big_rec);
+			big_rec, mtr, TRUE, mtr);
 		/* If writing big_rec fails (for example, because of
 		DB_OUT_OF_FILE_SPACE), the record will be corrupted.
 		Even if we did not update any externally stored
@@ -2028,6 +2029,8 @@ row_upd_clust_rec(
 		to the undo log, and thus the record cannot be rolled
 		back. */
 		ut_a(err == DB_SUCCESS);
+		/* Free the pages again in order to avoid a leak. */
+		btr_mark_freed_leaves(index, mtr, FALSE);
 	}
 
 	mtr_commit(mtr);

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/srv/srv0srv.c	2011-08-29 07:14:48 +0000
@@ -358,12 +358,6 @@ batch flushing i.e.: LRU flushing and fl
 of the pages are used for single page flushing. */
 UNIV_INTERN ulong	srv_doublewrite_batch_size	= 120;
 
-/** the macro MYSQL_SYSVAR_ENUM() requires "long unsigned int" and if we
-use srv_checksum_algorithm_t here then we get a compiler error:
-ha_innodb.cc:12251: error: cannot convert 'srv_checksum_algorithm_t*' to
-  'long unsigned int*' in initialization */
-UNIV_INTERN ulong	srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_INNODB;
-
 UNIV_INTERN ulong	srv_replication_delay		= 0;
 
 /*-------------------------------------------*/

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	2011-08-15 09:34:39 +0000
+++ b/storage/innobase/sync/sync0sync.c	2011-08-26 19:27:04 +0000
@@ -1345,7 +1345,13 @@ sync_thread_add_level(
 					     TRUE));
 		break;
 	case SYNC_IBUF_TREE_NODE_NEW:
-		ut_a(sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+		/* ibuf_add_free_page() allocates new pages for the
+		change buffer while only holding the tablespace
+		x-latch. These pre-allocated new pages may only be
+		taken in use while holding ibuf_mutex, in
+		btr_page_alloc_for_ibuf(). */
+		ut_a(sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
+		     || sync_thread_levels_contain(array, SYNC_FSP));
 		break;
 	case SYNC_IBUF_INDEX_TREE:
 		if (sync_thread_levels_contain(array, SYNC_FSP)) {

=== modified file 'storage/innobase/trx/trx0undo.c'
--- a/storage/innobase/trx/trx0undo.c	2011-07-26 11:08:42 +0000
+++ b/storage/innobase/trx/trx0undo.c	2011-08-29 08:45:30 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -920,7 +920,7 @@ trx_undo_add_page(
 	page_no = fseg_alloc_free_page_general(header_page + TRX_UNDO_SEG_HDR
 					       + TRX_UNDO_FSEG_HEADER,
 					       undo->top_page_no + 1, FSP_UP,
-					       TRUE, mtr);
+					       TRUE, mtr, mtr);
 
 	fil_space_release_free_extents(undo->space, n_reserved);
 

=== modified file 'strings/decimal.c'
--- a/strings/decimal.c	2011-08-26 07:06:35 +0000
+++ b/strings/decimal.c	2011-08-29 10:28:51 +0000
@@ -1412,11 +1412,18 @@ int bin2decimal(const uchar *from, decim
     buf++;
   }
   my_afree(d_copy);
+
+  /*
+    No digits? We have read the number zero, of unspecified precision.
+    Make it a proper zero, with non-zero precision.
+  */
+  if (to->intg == 0 && to->frac == 0)
+    decimal_make_zero(to);
   return error;
 
 err:
   my_afree(d_copy);
-  decimal_make_zero(((decimal_t*) to));
+  decimal_make_zero(to);
   return(E_DEC_BAD_NUM);
 }
 

=== modified file 'unittest/gunit/my_decimal-t.cc'
--- a/unittest/gunit/my_decimal-t.cc	2011-07-18 08:06:21 +0000
+++ b/unittest/gunit/my_decimal-t.cc	2011-08-29 10:28:51 +0000
@@ -221,7 +221,36 @@ TEST_F(DecimalTest, Modulo)
       << " got xxx:" << buff_x
       ;
   }
+}
+
+
+TEST_F(DecimalTest, BinaryConversion)
+{
+  const int prec= 60;
+  const int scale= 0;
+  EXPECT_EQ(E_DEC_OK, chars_2_decimal("000000000", &d1));
+  int binary_size= my_decimal_get_binary_size(prec, scale);
+  uchar *bin= new uchar[binary_size];
+
+  // Convert to binary, and back.
+  EXPECT_EQ(E_DEC_OK, my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
+                                        &d1, bin, prec, scale));
+  EXPECT_EQ(E_DEC_OK, binary2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
+                                        bin, &d2, prec, scale));
+  EXPECT_GT(d2.precision(), 0U);
+  EXPECT_EQ(0, my_decimal_cmp(&d1, &d2));
 
+  // 0.0 * 0.0
+  my_decimal product;
+  EXPECT_EQ(E_DEC_OK, my_decimal_mul(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
+                                     &product, &d2, &d2));
+  // 0.0 * (-0.0)
+  my_decimal neg_prod;
+  my_decimal d3(d2);
+  d3.sign(true);
+  EXPECT_EQ(E_DEC_OK, my_decimal_mul(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
+                                     &neg_prod, &d2, &d3));
+  delete[] bin;
 }
 
 }

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-mtr branch (bjorn.munch:3108 to 3110) Bjorn Munch30 Aug