List:Commits« Previous MessageNext Message »
From:Oystein Grovlen Date:June 25 2008 2:50pm
Subject:bzr commit into mysql-6.0-backup branch (oystein.grovlen:2643)
View as plain text  
#At file:///home/og136792/mysql/shared/mysql-6.0-backup-main/

 2643 Oystein Grovlen	2008-06-25 [merge]
      Merge main->mysql-6.0-backup.  No conflicts observed.
added:
  mysql-test/r/innodb-autoinc.result
  mysql-test/r/innodb_bug34053.result
  mysql-test/r/innodb_bug34300.result
  mysql-test/r/innodb_bug35220.result
  mysql-test/suite/bugs/r/rpl_bug33029.result
  mysql-test/suite/bugs/t/rpl_bug33029.test
  mysql-test/t/innodb-autoinc.test
  mysql-test/t/innodb_bug34053.test
  mysql-test/t/innodb_bug34300.test
  mysql-test/t/innodb_bug35220.test
modified:
  Makefile.am
  client/mysql.cc
  config/ac-macros/libevent.m4
  mysql-test/lib/mtr_cases.pl
  mysql-test/r/innodb.result
  mysql-test/r/mysql.result
  mysql-test/r/partition_innodb.result
  mysql-test/r/repair.result
  mysql-test/r/subselect.result
  mysql-test/r/subselect_no_mat.result
  mysql-test/r/subselect_no_opts.result
  mysql-test/r/subselect_no_semijoin.result
  mysql-test/suite/binlog/r/binlog_innodb.result
  mysql-test/suite/rpl/t/disabled.def
  mysql-test/t/innodb.test
  mysql-test/t/mysql_delimiter.sql
  mysql-test/t/partition_innodb.test
  mysql-test/t/subselect.test
  scripts/make_binary_distribution.sh
  sql/slave.cc
  sql/sql_class.cc
  sql/sql_plugin.cc
  sql/sql_select.cc
  sql/sql_table.cc
  sql/structs.h
  storage/innobase/Makefile.am
  storage/innobase/btr/btr0cur.c
  storage/innobase/buf/buf0buf.c
  storage/innobase/dict/dict0dict.c
  storage/innobase/handler/ha_innodb.cc
  storage/innobase/handler/ha_innodb.h
  storage/innobase/include/buf0buf.h
  storage/innobase/include/dict0dict.h
  storage/innobase/include/dict0mem.h
  storage/innobase/include/mach0data.h
  storage/innobase/include/mach0data.ic
  storage/innobase/include/os0sync.h
  storage/innobase/include/read0read.h
  storage/innobase/include/row0mysql.h
  storage/innobase/include/row0sel.h
  storage/innobase/include/srv0srv.h
  storage/innobase/include/sync0arr.h
  storage/innobase/include/sync0rw.h
  storage/innobase/include/sync0rw.ic
  storage/innobase/include/sync0sync.h
  storage/innobase/include/sync0sync.ic
  storage/innobase/include/trx0undo.h
  storage/innobase/include/univ.i
  storage/innobase/include/ut0ut.h
  storage/innobase/os/os0file.c
  storage/innobase/os/os0sync.c
  storage/innobase/plug.in
  storage/innobase/read/read0read.c
  storage/innobase/row/row0mysql.c
  storage/innobase/row/row0sel.c
  storage/innobase/srv/srv0srv.c
  storage/innobase/srv/srv0start.c
  storage/innobase/sync/sync0arr.c
  storage/innobase/sync/sync0rw.c
  storage/innobase/sync/sync0sync.c
  storage/innobase/trx/trx0trx.c
  storage/innobase/trx/trx0undo.c
  storage/innobase/ut/ut0ut.c

=== modified file 'Makefile.am'
--- a/Makefile.am	2008-05-21 10:17:29 +0000
+++ b/Makefile.am	2008-06-16 19:27:44 +0000
@@ -17,9 +17,14 @@
 
 AUTOMAKE_OPTIONS =	foreign
 
-# These are built from source in the Docs directory
+# Files in the first two lines are built from source in the Docs directory,
+# "CMakeLists.txt" is for Windows only,
+# "libevent_configure.m4" is needed in sources but should be evaluated only
+#    if "--with-libevent" is given (handled in "config/ac-macros/libevent.m4").
 EXTRA_DIST =		INSTALL-SOURCE INSTALL-WIN-SOURCE \
-			README COPYING EXCEPTIONS-CLIENT CMakeLists.txt
+			README COPYING EXCEPTIONS-CLIENT \
+			CMakeLists.txt \
+			config/ac-macros/libevent_configure.m4
 
 SUBDIRS =		. include @docs_dirs@ @zlib_dir@ \
 			@readline_topdir@ sql-common scripts \

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2008-04-01 10:45:05 +0000
+++ b/client/mysql.cc	2008-06-20 19:24:46 +0000
@@ -1848,7 +1848,7 @@ static int read_and_execute(bool interac
         the very beginning of a text file when
         you save the file using "Unicode UTF-8" format.
       */
-      if (!line_number &&
+      if (line && !line_number &&
            (uchar) line[0] == 0xEF &&
            (uchar) line[1] == 0xBB &&
            (uchar) line[2] == 0xBF)
@@ -2128,37 +2128,6 @@ static bool add_line(String &buffer,char
 	continue;
       }
     }
-    else if (!*ml_comment && !*in_string &&
-             (end_of_line - pos) >= 10 &&
-             !my_strnncoll(charset_info, (uchar*) pos, 10,
-                           (const uchar*) "delimiter ", 10))
-    {
-      // Flush previously accepted characters
-      if (out != line)
-      {
-        buffer.append(line, (uint32) (out - line));
-        out= line;
-      }
-
-      // Flush possible comments in the buffer
-      if (!buffer.is_empty())
-      {
-        if (com_go(&buffer, 0) > 0) // < 0 is not fatal
-          DBUG_RETURN(1);
-        buffer.length(0);
-      }
-
-      /*
-        Delimiter wants the get rest of the given line as argument to
-        allow one to change ';' to ';;' and back
-      */
-      buffer.append(pos);
-      if (com_delimiter(&buffer, pos) > 0)
-        DBUG_RETURN(1);
-
-      buffer.length(0);
-      break;
-    }
     else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
     {
       // Found a statement. Continue parsing after the delimiter

=== modified file 'config/ac-macros/libevent.m4'
--- a/config/ac-macros/libevent.m4	2008-04-28 23:56:34 +0000
+++ b/config/ac-macros/libevent.m4	2008-06-16 19:27:44 +0000
@@ -22,7 +22,8 @@ AC_DEFUN([MYSQL_USE_BUNDLED_LIBEVENT], [
   AC_DEFINE([HAVE_LIBEVENT], [1], [If we want to use libevent and have connection pooling])
   AC_MSG_RESULT([using bundled libevent])
 
-  dnl Use builtin include to workaround path problems on older versions of aclocal.
+  dnl Get the upstream file with the original libevent configure macros.
+  dnl Use builtin include for this, to work around path problems in old versions of aclocal.
   builtin([include],[config/ac-macros/libevent_configure.m4])
 ])
 

=== modified file 'mysql-test/lib/mtr_cases.pl'
--- a/mysql-test/lib/mtr_cases.pl	2008-02-11 16:11:22 +0000
+++ b/mysql-test/lib/mtr_cases.pl	2008-06-18 03:30:29 +0000
@@ -773,6 +773,13 @@ sub collect_one_test_case($$$$$$$$$) {
 	if ( $::used_default_engine =~ /^innodb/i );
     }
 
+    #enable federated for this test
+    if ($tinfo->{'federated_test'})
+    {
+      push(@{$tinfo->{'master_opt'}}, "--loose-federated");
+      push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
+    }
+
     if ( $tinfo->{'big_test'} and ! $::opt_big_test )
     {
       $tinfo->{'skip'}= 1;
@@ -891,6 +898,8 @@ our @tags=
  ["include/have_ndb_extra.inc", "ndb_extra", 1],
  ["include/ndb_master-slave.inc", "ndb_test", 1],
  ["require_manager", "require_manager", 1],
+ ["include/federated.inc", "federated_test", 1],
+ ["include/have_federated_db.inc", "federated_test", 1],
 );
 
 sub mtr_options_from_test_file($$) {

=== added file 'mysql-test/r/innodb-autoinc.result'
--- a/mysql-test/r/innodb-autoinc.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb-autoinc.result	2008-06-12 00:08:07 +0000
@@ -0,0 +1,89 @@
+drop table if exists t1;
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (9223372036854775807, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+9223372036854775807	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (127, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+127	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (255, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+255	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (32767, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+32767	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (65535, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+65535	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (8388607, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+8388607	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16777215, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+16777215	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (2147483647, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+2147483647	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (4294967295, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+4294967295	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (9223372036854775807, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+9223372036854775807	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (18446744073709551615, null);
+INSERT INTO t1 (c2) VALUES ('innodb');
+Got one of the listed errors
+SELECT * FROM t1;
+c1	c2
+18446744073709551615	NULL
+DROP TABLE t1;

=== modified file 'mysql-test/r/innodb.result'
--- a/mysql-test/r/innodb.result	2008-05-14 09:24:14 +0000
+++ b/mysql-test/r/innodb.result	2008-06-12 00:08:07 +0000
@@ -1727,10 +1727,10 @@ Variable_name	Value
 Innodb_page_size	16384
 show status like "Innodb_rows_deleted";
 Variable_name	Value
-Innodb_rows_deleted	70
+Innodb_rows_deleted	71
 show status like "Innodb_rows_inserted";
 Variable_name	Value
-Innodb_rows_inserted	1082
+Innodb_rows_inserted	1084
 show status like "Innodb_rows_updated";
 Variable_name	Value
 Innodb_rows_updated	885
@@ -3218,3 +3218,54 @@ a
 2
 DROP TABLE t1;
 DROP TABLE t2;
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+update t1 set j = 2;
+affected rows: 1
+info: Rows matched: 2  Changed: 1  Warnings: 0
+drop table t1;
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+from information_schema.tables
+where table_schema='test' and table_name = 't1';
+table_comment	data_free_is_set
+this is a comment	1
+drop table t1;
+CREATE TABLE t1 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 VARCHAR(128) NOT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+CREATE TABLE t2 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 INT(10) UNSIGNED DEFAULT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 int default NULL,
+c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+TRUNCATE TABLE t1;
+affected rows: 0
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+affected rows: 5
+info: Records: 5  Duplicates: 0  Warnings: 0
+TRUNCATE TABLE t1;
+affected rows: 0
+DROP TABLE t1;
+Variable_name	Value
+Handler_update	0
+Variable_name	Value
+Handler_delete	0
+Variable_name	Value
+Handler_update	1
+Variable_name	Value
+Handler_delete	1

=== added file 'mysql-test/r/innodb_bug34053.result'
--- a/mysql-test/r/innodb_bug34053.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug34053.result	2008-06-12 00:08:07 +0000
@@ -0,0 +1 @@
+SET storage_engine=InnoDB;

=== added file 'mysql-test/r/innodb_bug34300.result'
--- a/mysql-test/r/innodb_bug34300.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug34300.result	2008-06-12 00:08:07 +0000
@@ -0,0 +1,4 @@
+f4	f8
+xxx	zzz
+f4	f8
+xxx	zzz

=== added file 'mysql-test/r/innodb_bug35220.result'
--- a/mysql-test/r/innodb_bug35220.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug35220.result	2008-06-12 00:08:07 +0000
@@ -0,0 +1 @@
+SET storage_engine=InnoDB;

=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result	2007-11-27 17:23:39 +0000
+++ b/mysql-test/r/mysql.result	2008-06-20 19:24:46 +0000
@@ -38,6 +38,8 @@ t2
 t3
 Tables_in_test
 t1
+delimiter
+1
 _
 Test delimiter : from command line
 a

=== modified file 'mysql-test/r/partition_innodb.result'
--- a/mysql-test/r/partition_innodb.result	2008-03-27 19:02:15 +0000
+++ b/mysql-test/r/partition_innodb.result	2008-06-12 00:08:07 +0000
@@ -13,33 +13,33 @@ DROP TABLE t1;
 create table t1 (a int) engine=innodb partition by hash(a) ;
 show table status like 't1';
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	2	8192	16384	0	0	0	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	2	8192	16384	0	0	<datafree>	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 drop table t1;
 create table t1 (a int)
 engine = innodb
 partition by key (a);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	2	8192	16384	0	0	0	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	2	8192	16384	0	0	<datafree>	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 insert into t1 values (0), (1), (2), (3);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	4	4096	16384	0	0	0	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	4	4096	16384	0	0	<datafree>	NULL	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 drop table t1;
 create table t1 (a int auto_increment primary key)
 engine = innodb
 partition by key (a);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	2	8192	16384	0	0	0	1	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	2	8192	16384	0	0	<datafree>	1	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 insert into t1 values (NULL), (NULL), (NULL), (NULL);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	4	4096	16384	0	0	0	5	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	4	4096	16384	0	0	<datafree>	5	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 insert into t1 values (NULL), (NULL), (NULL), (NULL);
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	InnoDB	10	Compact	8	2048	16384	0	0	0	9	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
+t1	InnoDB	10	Compact	8	2048	16384	0	0	<datafree>	9	NULL	NULL	NULL	latin1_swedish_ci	NULL	partitioned	
 drop table t1;
 create table t1 (a int)
 partition by key (a)

=== modified file 'mysql-test/r/repair.result'
--- a/mysql-test/r/repair.result	2008-05-12 19:38:57 +0000
+++ b/mysql-test/r/repair.result	2008-06-18 03:30:29 +0000
@@ -130,7 +130,7 @@ test.t1	check	error	Table upgrade requir
 # REPAIR old table USE_FRM should fail
 REPAIR TABLE t1 USE_FRM;
 Table	Op	Msg_type	Msg_text
-t1	repair	error	Failed reparing incompatible .FRM file
+t1	repair	error	Failed repairing incompatible .frm file
 # Run REPAIR TABLE to upgrade .frm file
 REPAIR TABLE t1;
 Table	Op	Msg_type	Msg_text

=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result	2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect.result	2008-06-20 19:24:46 +0000
@@ -4593,6 +4593,13 @@ SELECT * FROM t1 WHERE _utf8'a' = ANY (S
 s1
 a
 DROP TABLE t1;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a	b
+DROP TABLE t1,t2;
 CREATE TABLE t1( a INT );
 INSERT INTO t1 VALUES (1),(2);
 CREATE TABLE t2( a INT, b INT );

=== modified file 'mysql-test/r/subselect_no_mat.result'
--- a/mysql-test/r/subselect_no_mat.result	2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_mat.result	2008-06-21 09:05:07 +0000
@@ -4597,6 +4597,13 @@ SELECT * FROM t1 WHERE _utf8'a' = ANY (S
 s1
 a
 DROP TABLE t1;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a	b
+DROP TABLE t1,t2;
 CREATE TABLE t1( a INT );
 INSERT INTO t1 VALUES (1),(2);
 CREATE TABLE t2( a INT, b INT );

=== modified file 'mysql-test/r/subselect_no_opts.result'
--- a/mysql-test/r/subselect_no_opts.result	2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_opts.result	2008-06-21 09:05:07 +0000
@@ -4597,6 +4597,13 @@ SELECT * FROM t1 WHERE _utf8'a' = ANY (S
 s1
 a
 DROP TABLE t1;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a	b
+DROP TABLE t1,t2;
 CREATE TABLE t1( a INT );
 INSERT INTO t1 VALUES (1),(2);
 CREATE TABLE t2( a INT, b INT );

=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result	2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result	2008-06-21 09:05:07 +0000
@@ -4597,6 +4597,13 @@ SELECT * FROM t1 WHERE _utf8'a' = ANY (S
 s1
 a
 DROP TABLE t1;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a	b
+DROP TABLE t1,t2;
 CREATE TABLE t1( a INT );
 INSERT INTO t1 VALUES (1),(2);
 CREATE TABLE t2( a INT, b INT );

=== modified file 'mysql-test/suite/binlog/r/binlog_innodb.result'
--- a/mysql-test/suite/binlog/r/binlog_innodb.result	2008-05-15 20:56:38 +0000
+++ b/mysql-test/suite/binlog/r/binlog_innodb.result	2008-06-12 00:08:07 +0000
@@ -110,7 +110,6 @@ master-bin.000001	#	Table_map	#	#	table_
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
-master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Xid	#	#	COMMIT /* XID */
 master-bin.000001	#	Query	#	#	use `test`; BEGIN

=== added file 'mysql-test/suite/bugs/r/rpl_bug33029.result'
--- a/mysql-test/suite/bugs/r/rpl_bug33029.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/r/rpl_bug33029.result	2008-06-19 18:47:59 +0000
@@ -0,0 +1,15 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table `t1` (`id` int not null auto_increment primary key);
+create trigger `trg` before insert on `t1` for each row begin end;
+set @@global.debug="+d,simulate_bug33029";
+stop slave;
+start slave;
+insert into `t1` values ();
+select * from t1;
+id
+1

=== added file 'mysql-test/suite/bugs/t/rpl_bug33029.test'
--- a/mysql-test/suite/bugs/t/rpl_bug33029.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/t/rpl_bug33029.test	2008-06-19 18:47:59 +0000
@@ -0,0 +1,25 @@
+#
+# Bug #36443 Server crashes when executing insert when insert trigger on table
+#
+# Emulating the former bug#33029 situation to see that there is no crash anymore.
+# 
+
+
+source include/master-slave.inc;
+
+create table `t1` (`id` int not null auto_increment primary key);
+create trigger `trg` before insert on `t1` for each row begin end;
+
+sync_slave_with_master;
+set @@global.debug="+d,simulate_bug33029";
+
+stop slave;
+start slave;
+
+connection master;
+
+insert into `t1` values ();
+
+sync_slave_with_master;
+select * from t1;
+

=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def	2008-05-19 08:32:08 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def	2008-06-20 19:24:46 +0000
@@ -29,4 +29,4 @@ rpl_log_pos                : Bug#8693 Te
 rpl_row_basic_7ndb         : BUG#33360 2007-12-19 mats rpl_ndb_idempotent fails due to null field for table on slave side
 rpl_redirect               : Failure is sporadic and and the test is superfluous (mats)
 rpl_innodb_bug28430        : Failure on Solaris Bug #36793
-
+rpl_server_id1             : Bug #36818 rpl_server_id1 fails expecting slave has stopped (azundris)

=== added file 'mysql-test/t/innodb-autoinc.test'
--- a/mysql-test/t/innodb-autoinc.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb-autoinc.test	2008-06-12 00:08:07 +0000
@@ -0,0 +1,107 @@
+-- source include/have_innodb.inc
+# embedded server ignores 'delayed', so skip this
+-- source include/not_embedded.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Bug #34335
+#
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (9223372036854775807, null);
+-- error ER_DUP_ENTRY,1062
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+## Test AUTOINC overflow
+##
+
+# TINYINT
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (127, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (255, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# SMALLINT
+#
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (32767, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (65535, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# MEDIUMINT
+#
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (8388607, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16777215, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# INT
+#
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (2147483647, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (4294967295, null);
+-- error ER_DUP_ENTRY,1062
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# BIGINT
+#
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (9223372036854775807, null);
+-- error ER_DUP_ENTRY,1062
+-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (18446744073709551615, null);
+-- error ER_AUTOINC_READ_FAILED,1467
+INSERT INTO t1 (c2) VALUES ('innodb');
+SELECT * FROM t1;
+DROP TABLE t1;

=== modified file 'mysql-test/t/innodb.test'
--- a/mysql-test/t/innodb.test	2008-05-14 09:24:14 +0000
+++ b/mysql-test/t/innodb.test	2008-06-12 00:08:07 +0000
@@ -2381,6 +2381,96 @@ DROP TABLE t1;
 DROP TABLE t2;
 DISCONNECT c1;
 DISCONNECT c2;
+CONNECTION default;
+
+#
+# Bug #29157 UPDATE, changed rows incorrect
+#
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+--enable_info
+update t1 set j = 2;
+--disable_info
+drop table t1;
+
+#
+# Bug #32440 InnoDB free space info does not appear in SHOW TABLE STATUS or
+# I_S
+#
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+  from information_schema.tables
+  where table_schema='test' and table_name = 't1';
+drop table t1;
+
+#
+# Bug 34920 test
+#
+CONNECTION default;
+CREATE TABLE t1 (
+	c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+	c2 VARCHAR(128) NOT NULL,
+	PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+
+CREATE TABLE t2 (
+	c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+	c2 INT(10) UNSIGNED DEFAULT NULL,
+	PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+DROP TABLE t2;
+DROP TABLE t1;
+# End 34920 test
+#
+# Bug #29507 TRUNCATE shows to many rows effected
+#
+CONNECTION default;
+CREATE TABLE t1 (c1 int default NULL,
+		 c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--enable_info
+TRUNCATE TABLE t1;
+
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+TRUNCATE TABLE t1;
+
+--disable_info
+DROP TABLE t1;
+#
+# Bug#35537 Innodb doesn't increment handler_update and handler_delete.
+#
+-- disable_query_log
+-- disable_result_log
+
+CONNECT (c1,localhost,root,,);
+
+DROP TABLE IF EXISTS bug35537;
+CREATE TABLE bug35537 (
+  c1 int
+) ENGINE=InnoDB;
+
+INSERT INTO bug35537 VALUES (1);
+
+-- enable_result_log
+
+SHOW SESSION STATUS LIKE 'Handler_update%';
+SHOW SESSION STATUS LIKE 'Handler_delete%';
+
+UPDATE bug35537 SET c1 = 2 WHERE c1 = 1;
+DELETE FROM bug35537 WHERE c1 = 2;
+
+SHOW SESSION STATUS LIKE 'Handler_update%';
+SHOW SESSION STATUS LIKE 'Handler_delete%';
+
+DROP TABLE bug35537;
+
+DISCONNECT c1;
+CONNECTION default;
 
 #######################################################################
 #                                                                     #

=== added file 'mysql-test/t/innodb_bug34053.test'
--- a/mysql-test/t/innodb_bug34053.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug34053.test	2008-06-12 00:08:07 +0000
@@ -0,0 +1,50 @@
+#
+# Make sure http://bugs.mysql.com/34053 remains fixed.
+#
+
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+SET storage_engine=InnoDB;
+
+# we do not really care about what gets printed, we are only
+# interested in getting success or failure according to our
+# expectations
+-- disable_query_log
+-- disable_result_log
+
+GRANT USAGE ON *.* TO 'shane'@'localhost' IDENTIFIED BY '12345';
+FLUSH PRIVILEGES;
+
+-- connect (con1,localhost,shane,12345,)
+
+-- connection con1
+-- error ER_SPECIFIC_ACCESS_DENIED_ERROR
+CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
+-- error ER_SPECIFIC_ACCESS_DENIED_ERROR
+CREATE TABLE innodb_mem_validate (a INT) ENGINE=INNODB;
+CREATE TABLE innodb_monitorx (a INT) ENGINE=INNODB;
+DROP TABLE innodb_monitorx;
+CREATE TABLE innodb_monito (a INT) ENGINE=INNODB;
+DROP TABLE innodb_monito;
+CREATE TABLE xinnodb_monitor (a INT) ENGINE=INNODB;
+DROP TABLE xinnodb_monitor;
+CREATE TABLE nnodb_monitor (a INT) ENGINE=INNODB;
+DROP TABLE nnodb_monitor;
+
+-- connection default
+CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
+CREATE TABLE innodb_mem_validate (a INT) ENGINE=INNODB;
+
+-- connection con1
+-- error ER_SPECIFIC_ACCESS_DENIED_ERROR
+DROP TABLE innodb_monitor;
+-- error ER_SPECIFIC_ACCESS_DENIED_ERROR
+DROP TABLE innodb_mem_validate;
+
+-- connection default
+DROP TABLE innodb_monitor;
+DROP TABLE innodb_mem_validate;
+DROP USER 'shane'@'localhost';
+
+-- disconnect con1

=== added file 'mysql-test/t/innodb_bug34300.test'
--- a/mysql-test/t/innodb_bug34300.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug34300.test	2008-06-12 00:08:07 +0000
@@ -0,0 +1,30 @@
+#
+# Bug#34300 Tinyblob & tinytext fields currupted after export/import and alter in 5.1
+# http://bugs.mysql.com/34300
+#
+
+-- source include/have_innodb.inc
+
+-- disable_query_log
+-- disable_result_log
+
+SET @@max_allowed_packet=16777216;
+
+DROP TABLE IF EXISTS bug34300;
+CREATE TABLE bug34300 (
+  f4 TINYTEXT,
+  f6 MEDIUMTEXT,
+  f8 TINYBLOB
+) ENGINE=InnoDB;
+
+INSERT INTO bug34300 VALUES ('xxx', repeat('a', 8459264), 'zzz');
+
+-- enable_result_log
+
+SELECT f4, f8 FROM bug34300;
+
+ALTER TABLE bug34300 ADD COLUMN (f10 INT);
+
+SELECT f4, f8 FROM bug34300;
+
+DROP TABLE bug34300;

=== added file 'mysql-test/t/innodb_bug35220.test'
--- a/mysql-test/t/innodb_bug35220.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug35220.test	2008-06-12 00:08:07 +0000
@@ -0,0 +1,16 @@
+#
+# Bug#35220 ALTER TABLE too picky on reserved word "foreign"
+# http://bugs.mysql.com/35220
+#
+
+-- source include/have_innodb.inc
+
+SET storage_engine=InnoDB;
+
+# we care only that the following SQL commands do not produce errors
+-- disable_query_log
+-- disable_result_log
+
+CREATE TABLE bug35220 (foreign_col INT, dummy_cant_delete_all_columns INT);
+ALTER TABLE bug35220 DROP foreign_col;
+DROP TABLE bug35220;

=== modified file 'mysql-test/t/mysql_delimiter.sql'
--- a/mysql-test/t/mysql_delimiter.sql	2006-11-22 06:27:06 +0000
+++ b/mysql-test/t/mysql_delimiter.sql	2008-06-20 16:58:14 +0000
@@ -59,3 +59,9 @@ source t/mysql_delimiter_19799.sql
 use test//
 show tables//
 delimiter ; # Reset delimiter
+
+#
+# Bug #33812: mysql client incorrectly parsing DELIMITER
+#
+select a as delimiter from t1
+delimiter ; # Reset delimiter

=== modified file 'mysql-test/t/partition_innodb.test'
--- a/mysql-test/t/partition_innodb.test	2008-03-27 19:02:15 +0000
+++ b/mysql-test/t/partition_innodb.test	2008-06-12 00:08:07 +0000
@@ -20,6 +20,7 @@ DROP TABLE t1;
 # Bug #14673: Wrong InnoDB default row format
 #
 create table t1 (a int) engine=innodb partition by hash(a) ;
+--replace_column 10 <datafree>
 show table status like 't1';
 drop table t1;
 
@@ -29,18 +30,23 @@ drop table t1;
 create table t1 (a int)
 engine = innodb
 partition by key (a);
+--replace_column 10 <datafree>
 show table status;
 insert into t1 values (0), (1), (2), (3);
+--replace_column 10 <datafree>
 show table status;
 drop table t1;
 
 create table t1 (a int auto_increment primary key)
 engine = innodb
 partition by key (a);
+--replace_column 10 <datafree>
 show table status;
 insert into t1 values (NULL), (NULL), (NULL), (NULL);
+--replace_column 10 <datafree>
 show table status;
 insert into t1 values (NULL), (NULL), (NULL), (NULL);
+--replace_column 10 <datafree>
 show table status;
 drop table t1;
 

=== modified file 'mysql-test/t/subselect.test'
--- a/mysql-test/t/subselect.test	2008-05-22 18:40:15 +0000
+++ b/mysql-test/t/subselect.test	2008-06-20 19:24:46 +0000
@@ -3422,6 +3422,19 @@ SELECT * FROM t1 WHERE _utf8'a' = ANY (S
 DROP TABLE t1;
 
 #
+# Bug #37004: NOT IN subquery with MAX over an empty set
+#
+
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+
+DROP TABLE t1,t2;
+
+#
 # Bug#33204: INTO is allowed in subselect, causing inconsistent results
 #
 CREATE TABLE t1( a INT );

=== modified file 'scripts/make_binary_distribution.sh'
--- a/scripts/make_binary_distribution.sh	2008-05-13 13:58:07 +0000
+++ b/scripts/make_binary_distribution.sh	2008-06-18 03:30:29 +0000
@@ -14,36 +14,61 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-# This is a script to create a TAR or ZIP binary distribution out of a
-# built source tree. The output file will be put at the top level of
-# the source tree, as "mysql-<vsn>....{tar.gz,zip}"
+##############################################################################
 #
-# The temporary directory path given to "--tmp=<path>" has to be
-# absolute and with no spaces.
+#  This is a script to create a TAR or ZIP binary distribution out of a
+#  built source tree. The output file will be put at the top level of
+#  the source tree, as "mysql-<vsn>....{tar.gz,zip}"
+#
+#  Note that the structure created by this script is slightly different from
+#  what a normal "make install" would produce. No extra "mysql" sub directory
+#  will be created, i.e. no "$prefix/include/mysql", "$prefix/lib/mysql" or
+#  "$prefix/share/mysql".  This is because the build system explicitly calls
+#  make with pkgdatadir=<datadir>, etc.
+#
+#  In GNU make/automake terms
+#
+#    "pkglibdir"     is set to the same as "libdir"
+#    "pkgincludedir" is set to the same as "includedir"
+#    "pkgdatadir"    is set to the same as "datadir"
+#    "pkgplugindir"  is set to "$pkglibdir/plugin"
+#    "pkgsuppdir"    is set to "@prefix@/support-files",
+#                    normally the same as "datadir"
+#
+#  The temporary directory path given to "--tmp=<path>" has to be
+#  absolute and with no spaces.
+#
+#  Note that for best result, the original "make" should be done with
+#  the same arguments as used for "make install" below, especially the
+#  'pkglibdir', as the RPATH should to be set correctly.
+#
+##############################################################################
+
+##############################################################################
+#
+#  Read the command line arguments that control this script
+#
+##############################################################################
 
 machine=@MACHINE_TYPE@
 system=@SYSTEM_TYPE@
-version=@VERSION@
 SOURCE=`pwd`
 CP="cp -p"
 MV="mv"
 
-STRIP=1
-DEBUG=0
+STRIP=1				# Option ignored
 SILENT=0
-MACHINE=""
 PLATFORM=""
 TMP=/tmp
 SUFFIX=""
-NDBCLUSTER=""
+NDBCLUSTER=""			# Option ignored
 
 for arg do
   case "$arg" in
-    --debug)    DEBUG=1;;
     --tmp=*)    TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;;
     --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;;
     --no-strip) STRIP=0 ;;
-    --machine=*) MACHINE=`echo "$arg" | sed -e "s;--machine=;;"` ;;
+    --machine=*) machine=`echo "$arg" | sed -e "s;--machine=;;"` ;;
     --platform=*) PLATFORM=`echo "$arg" | sed -e "s;--platform=;;"` ;;
     --silent)   SILENT=1 ;;
     --with-ndbcluster) NDBCLUSTER=1 ;;
@@ -54,53 +79,52 @@ for arg do
   esac
 done
 
-# Remove vendor from $system
-system=`echo $system | sed -e 's/[a-z]*-\(.*\)/\1/g'`
-
-# Map OS names to "our" OS names (eg. darwin6.8 -> osx10.2)
-system=`echo $system | sed -e 's/darwin6.*/osx10.2/g'`
-system=`echo $system | sed -e 's/darwin7.*/osx10.3/g'`
-system=`echo $system | sed -e 's/darwin8.*/osx10.4/g'`
-system=`echo $system | sed -e 's/\(aix4.3\).*/\1/g'`
-system=`echo $system | sed -e 's/\(aix5.1\).*/\1/g'`
-system=`echo $system | sed -e 's/\(aix5.2\).*/\1/g'`
-system=`echo $system | sed -e 's/\(aix5.3\).*/\1/g'`
-system=`echo $system | sed -e 's/osf5.1b/tru64/g'`
-system=`echo $system | sed -e 's/linux-gnu/linux/g'`
-system=`echo $system | sed -e 's/solaris2.\([0-9]*\)/solaris\1/g'`
-system=`echo $system | sed -e 's/sco3.2v\(.*\)/openserver\1/g'`
+# ----------------------------------------------------------------------
+# Adjust "system" output from "uname" to be more human readable
+# ----------------------------------------------------------------------
+
+if [ x"$PLATFORM" = x"" ] ; then
+  # FIXME move this to the build tools
+  # Remove vendor from $system
+  system=`echo $system | sed -e 's/[a-z]*-\(.*\)/\1/g'`
+
+  # Map OS names to "our" OS names (eg. darwin6.8 -> osx10.2)
+  system=`echo $system | sed -e 's/darwin6.*/osx10.2/g'`
+  system=`echo $system | sed -e 's/darwin7.*/osx10.3/g'`
+  system=`echo $system | sed -e 's/darwin8.*/osx10.4/g'`
+  system=`echo $system | sed -e 's/\(aix4.3\).*/\1/g'`
+  system=`echo $system | sed -e 's/\(aix5.1\).*/\1/g'`
+  system=`echo $system | sed -e 's/\(aix5.2\).*/\1/g'`
+  system=`echo $system | sed -e 's/\(aix5.3\).*/\1/g'`
+  system=`echo $system | sed -e 's/osf5.1b/tru64/g'`
+  system=`echo $system | sed -e 's/linux-gnu/linux/g'`
+  system=`echo $system | sed -e 's/solaris2.\([0-9]*\)/solaris\1/g'`
+  system=`echo $system | sed -e 's/sco3.2v\(.*\)/openserver\1/g'`
 
-if [ x"$MACHINE" != x"" ] ; then
-  machine=$MACHINE
+  PLATFORM="$system-$machine"
 fi
 
-if [ x"$PLATFORM" != x"" ] ; then
-  platform="$PLATFORM"
-else
-  platform="$system-$machine"
-fi
+# Print the platform name for build logs
+echo "PLATFORM NAME: $PLATFORM"
+
+case $PLATFORM in
+  *netware*) BASE_SYSTEM="netware" ;;
+esac
 
-# FIXME This should really be integrated with automake and not duplicate the
-# installation list.
+# Change the distribution to a long descriptive name
+NEW_NAME=mysql@MYSQL_SERVER_SUFFIX@-@VERSION@-$PLATFORM$SUFFIX
 
+# ----------------------------------------------------------------------
+# Define BASE, and remove the old BASE directory if any
+# ----------------------------------------------------------------------
 BASE=$TMP/my_dist$SUFFIX
-
 if [ -d $BASE ] ; then
  rm -rf $BASE
 fi
 
-BS=""
-BIN_FILES=""
-BASE_SYSTEM="any"
-MYSQL_SHARE=$BASE/share/mysql
-
-case $system in
-  *netware*)
-    BASE_SYSTEM="netware"
-    BS=".nlm"
-    MYSQL_SHARE=$BASE/share
-    ;;
-esac
+# ----------------------------------------------------------------------
+# Find the TAR to use
+# ----------------------------------------------------------------------
 
 # This is needed to prefer GNU tar over platform tar because that can't
 # always handle long filenames
@@ -127,24 +151,149 @@ which_1 ()
 }
 
 tar=`which_1 gnutar gtar`
-if [ "$?" = "1" -o x"$tar" = x"" ] ; then
+if [ $? -ne 0 -o x"$tar" = x"" ] ; then
   tar=tar
 fi
 
 
+##############################################################################
+#
+#  Handle the Unix/Linux packaging using "make install"
+#
+##############################################################################
+
+if [ x"$BASE_SYSTEM" != x"netware" ] ; then
+
+  # ----------------------------------------------------------------------
+  # Terminate on any base level error
+  # ----------------------------------------------------------------------
+  set -e
+
+  # ----------------------------------------------------------------------
+  # Really ugly, one script, "mysql_install_db", needs prefix set to ".",
+  # i.e. makes access relative the current directory. This matches
+  # the documentation, so better not change this. And for another script,
+  # "mysql.server", we make some relative, others not.
+  # ----------------------------------------------------------------------
+
+  cd scripts
+  rm -f mysql_install_db
+  @MAKE@ mysql_install_db \
+    prefix=. \
+    bindir=./bin \
+    sbindir=./bin \
+    scriptdir=./bin \
+    libexecdir=./bin \
+    pkgdatadir=./share \
+    localstatedir=./data
+  cd ..
+
+  cd support-files
+  rm -f mysql.server
+  @MAKE@ mysql.server \
+    bindir=./bin \
+    sbindir=./bin \
+    scriptdir=./bin \
+    libexecdir=./bin \
+    pkgdatadir=@pkgdatadir@
+  cd ..
+
+  # ----------------------------------------------------------------------
+  # Do a install that we later are to pack. Use the same paths as in
+  # the build for the relevant directories.
+  # ----------------------------------------------------------------------
+  @MAKE@ DESTDIR=$BASE install \
+    pkglibdir=@pkglibdir@ \
+    pkgincludedir=@pkgincludedir@ \
+    pkgdatadir=@pkgdatadir@ \
+    pkgplugindir=@pkgplugindir@ \
+    pkgsuppdir=@pkgsuppdir@ \
+    mandir=@mandir@ \
+    infodir=@infodir@
+
+  # ----------------------------------------------------------------------
+  # Rename top directory, and set DEST to the new directory
+  # ----------------------------------------------------------------------
+  mv $BASE@prefix@ $BASE/$NEW_NAME
+  DEST=$BASE/$NEW_NAME
+
+  # ----------------------------------------------------------------------
+  # If we compiled with gcc, copy libgcc.a to the dist as libmygcc.a
+  # ----------------------------------------------------------------------
+  if [ x"@GXX@" = x"yes" ] ; then
+    gcclib=`@CC@ @CFLAGS@ --print-libgcc-file 2>/dev/null` || true
+    if [ -z "$gcclib" ] ; then
+      echo "Warning: Compiler doesn't tell libgcc.a!"
+    elif [ -f "$gcclib" ] ; then
+      $CP $gcclib $DEST/lib/libmygcc.a
+    else
+      echo "Warning: Compiler result '$gcclib' not found / no file!"
+    fi
+  fi
+
+  # FIXME let this script be in "bin/", where it is in the RPMs?
+  # http://dev.mysql.com/doc/refman/5.1/en/mysql-install-db-problems.html
+  mkdir $DEST/scripts
+  mv $DEST/bin/mysql_install_db $DEST/scripts/
+
+  # Note, no legacy "safe_mysqld" link to "mysqld_safe" in 5.1
+
+  # Copy readme and license files
+  cp README Docs/INSTALL-BINARY  $DEST/
+  if [ -f COPYING -a -f EXCEPTIONS-CLIENT ] ; then
+    cp COPYING EXCEPTIONS-CLIENT $DEST/
+  elif [ -f LICENSE.mysql ] ; then
+    cp LICENSE.mysql $DEST/
+  else
+    echo "ERROR: no license files found"
+    exit 1
+  fi
+
+  # FIXME should be handled by make file, and to other dir
+  mkdir -p $DEST/bin $DEST/support-files
+  cp scripts/mysqlaccess.conf $DEST/bin/
+  cp support-files/magic      $DEST/support-files/
+
+  # Create empty data directories, set permission (FIXME why?)
+  mkdir       $DEST/data $DEST/data/mysql $DEST/data/test
+  chmod o-rwx $DEST/data $DEST/data/mysql $DEST/data/test
+
+  # ----------------------------------------------------------------------
+  # Create the result tar file
+  # ----------------------------------------------------------------------
+
+  echo "Using $tar to create archive"
+  OPT=cvf
+  if [ x$SILENT = x1 ] ; then
+    OPT=cf
+  fi
+
+  echo "Creating and compressing archive"
+  rm -f $NEW_NAME.tar.gz
+  (cd $BASE ; $tar $OPT -  $NEW_NAME) | gzip -9 > $NEW_NAME.tar.gz
+  echo "$NEW_NAME.tar.gz created"
+
+  echo "Removing temporary directory"
+  rm -rf $BASE
+  exit 0
+fi
+
+
+##############################################################################
+#
+#  Handle the Netware case, until integrated above
+#
+##############################################################################
+
+BS=".nlm"
+MYSQL_SHARE=$BASE/share
+
 mkdir $BASE $BASE/bin $BASE/docs \
  $BASE/include $BASE/lib $BASE/support-files $BASE/share $BASE/scripts \
  $BASE/mysql-test $BASE/mysql-test/t  $BASE/mysql-test/r \
  $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/mysql-test/lib \
  $BASE/mysql-test/suite
 
-if [ $BASE_SYSTEM != "netware" ] ; then
- mkdir $BASE/share/mysql $BASE/tests $BASE/sql-bench $BASE/man \
-  $BASE/man/man1 $BASE/man/man8 $BASE/data $BASE/data/mysql $BASE/data/test
-
- chmod o-rwx $BASE/data $BASE/data/*
-fi
-
 # Copy files if they exists, warn for those that don't.
 # Note that when listing files to copy, we might list the file name
 # twice, once in the directory location where it is built, and a
@@ -176,12 +325,13 @@ copyfileto $BASE COPYING COPYING.LIB REA
 BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
   extra/resolveip$BS extra/my_print_defaults$BS \
   extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \
-  myisam/myisamchk$BS myisam/myisampack$BS myisam/myisamlog$BS \
-  myisam/myisam_ftdump$BS \
+  storage/myisam/myisamchk$BS storage/myisam/myisampack$BS \
+  storage/myisam/myisamlog$BS storage/myisam/myisam_ftdump$BS \
   sql/mysqld$BS sql/mysqld-debug$BS \
   sql/mysql_tzinfo_to_sql$BS \
   server-tools/instance-manager/mysqlmanager$BS \
   client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
+  client/mysqlslap$BS \
   client/mysqldump$BS client/mysqlimport$BS \
   client/mysqltest$BS client/mysqlcheck$BS \
   client/mysqlbinlog$BS client/mysql_upgrade$BS \
@@ -191,42 +341,16 @@ BIN_FILES="extra/comp_err$BS extra/repla
   ";
 
 # Platform-specific bin dir files:
-if [ $BASE_SYSTEM = "netware" ] ; then
-  BIN_FILES="$BIN_FILES \
+BIN_FILES="$BIN_FILES \
     netware/mysqld_safe$BS netware/mysql_install_db$BS \
-    netware/init_db.sql netware/test_db.sql netware/mysql_explain_log$BS \
+    netware/init_db.sql netware/test_db.sql \
     netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql \
     ";
-# For all other platforms:
-else
-  BIN_FILES="$BIN_FILES \
-    server-tools/instance-manager/.libs/mysqlmanager \
-    client/mysqltestmanagerc \
-    client/mysqltestmanager-pwgen tools/mysqltestmanager \
-    client/.libs/mysql client/.libs/mysqlshow client/.libs/mysqladmin \
-    client/.libs/mysqldump client/.libs/mysqlimport \
-    client/.libs/mysqltest client/.libs/mysqlcheck \
-    client/.libs/mysqlbinlog client/.libs/mysqltestmanagerc \
-    client/.libs/mysqltestmanager-pwgen tools/.libs/mysqltestmanager \
-    tests/.libs/mysql_client_test \
-    libmysqld/examples/.libs/mysql_client_test_embedded \
-    libmysqld/examples/.libs/mysqltest_embedded \
-  ";
-fi
 
 copyfileto $BASE/bin $BIN_FILES
 
-if [ x$STRIP = x1 ] ; then
-  strip $BASE/bin/*
-fi
-
-# Copy not binary files
-copyfileto $BASE/bin sql/mysqld.sym.gz
-
-if [ $BASE_SYSTEM = "netware" ] ; then
-    $CP netware/*.pl $BASE/scripts
-    $CP scripts/mysqlhotcopy $BASE/scripts/mysqlhotcopy.pl
-fi
+$CP netware/*.pl $BASE/scripts
+$CP scripts/mysqlhotcopy $BASE/scripts/mysqlhotcopy.pl
 
 copyfileto $BASE/lib \
   libmysql/.libs/libmysqlclient.a \
@@ -248,31 +372,17 @@ copyfileto $BASE/lib \
   zlib/.libs/libz.a
 
 # convert the .a to .lib for NetWare
-if [ $BASE_SYSTEM = "netware" ] ; then
-    for i in $BASE/lib/*.a
-    do
-      libname=`basename $i .a`
-      $MV $i $BASE/lib/$libname.lib
-    done
-    rm -f $BASE/lib/*.la
-fi
+for i in $BASE/lib/*.a
+do
+  libname=`basename $i .a`
+  $MV $i $BASE/lib/$libname.lib
+done
+rm -f $BASE/lib/*.la
 
-copyfileto $BASE/include include/*
 
-rm -f $BASE/include/Makefile* $BASE/include/*.in $BASE/include/config-win.h
-if [ $BASE_SYSTEM != "netware" ] ; then
-  rm -f $BASE/include/config-netware.h
-fi
+copyfileto $BASE/include config.h include/*
 
-if [ $BASE_SYSTEM != "netware" ] ; then
-  if [ -d tests ] ; then
-    $CP tests/*.res tests/*.tst tests/*.pl $BASE/tests
-  fi
-  if [ -d man ] ; then
-    $CP man/*.1 $BASE/man/man1
-    $CP man/*.8 $BASE/man/man8
-  fi
-fi
+rm -f $BASE/include/Makefile* $BASE/include/*.in $BASE/include/config-win.h
 
 copyfileto $BASE/support-files support-files/*
 
@@ -291,43 +401,29 @@ copyfileto $BASE/mysql-test \
 $CP mysql-test/lib/*.pl  $BASE/mysql-test/lib
 $CP mysql-test/t/*.def $BASE/mysql-test/t
 $CP mysql-test/include/*.inc $BASE/mysql-test/include
+$CP mysql-test/include/*.sql $BASE/mysql-test/include
 $CP mysql-test/include/*.test $BASE/mysql-test/include
 $CP mysql-test/t/*.def $BASE/mysql-test/t
+$CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \
+    mysql-test/std_data/*.MYD mysql-test/std_data/*.MYI \
+    mysql-test/std_data/*.pem mysql-test/std_data/Moscow_leap \
+    mysql-test/std_data/Index.xml \
+    mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \
+    mysql-test/std_data/*.cnf mysql-test/std_data/*.MY* \
+    $BASE/mysql-test/std_data
 $CP mysql-test/t/*.test mysql-test/t/*.imtest \
     mysql-test/t/*.disabled mysql-test/t/*.opt \
     mysql-test/t/*.slave-mi mysql-test/t/*.sh mysql-test/t/*.sql $BASE/mysql-test/t
 $CP mysql-test/r/*.result mysql-test/r/*.require \
     $BASE/mysql-test/r
 
-# Copy the additional suites and data "as is", they are in flux
-$tar cf - mysql-test/suite    | ( cd $BASE ; $tar xf - )
-$tar cf - mysql-test/std_data | ( cd $BASE ; $tar xf - )
+# Copy the additional suites "as is", they are in flux
+$tar cf - mysql-test/suite | ( cd $BASE ; $tar xf - )
 # Clean up if we did this from a bk tree
 if [ -d mysql-test/SCCS ] ; then
   find $BASE/mysql-test -name SCCS -print | xargs rm -rf
 fi
 
-if [ $BASE_SYSTEM != "netware" ] ; then
-  chmod a+x $BASE/bin/*
-  copyfileto $BASE/bin scripts/*
-  $BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ \
-      ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ \
-      @HOSTNAME@ \@pkgdatadir\@ ./share \
-      < scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db
-  $BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \
-      \@sbindir\@ ./bin \@libexecdir\@ ./bin \
-      \@MYSQLD_USER\@ @MYSQLD_USER@ \@localstatedir\@ /usr/local/mysql/data \
-      \@HOSTNAME\@ @HOSTNAME@ \
-      < support-files/mysql.server.sh > $BASE/support-files/mysql.server
-  $BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/mysqld_safe
-  mv $BASE/support-files/binary-configure $BASE/configure
-  chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-log-rotate \
-      $BASE/support-files/*.server $BASE/configure
-  $CP -r sql-bench/* $BASE/sql-bench
-  rm -f $BASE/sql-bench/*.sh $BASE/sql-bench/Makefile* $BASE/lib/*.la
-  rm -f $BASE/bin/*.sql
-fi
-
 rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh \
     $BASE/bin/mysql_install_db $BASE/bin/make_binary_distribution \
     $BASE/bin/setsomevars $BASE/support-files/Makefile* \
@@ -336,29 +432,19 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in
 #
 # Copy system dependent files
 #
-if [ $BASE_SYSTEM = "netware" ] ; then
-  ./scripts/fill_help_tables < ./Docs/manual.texi >> ./netware/init_db.sql
-fi
+./scripts/fill_help_tables < ./Docs/manual.texi >> ./netware/init_db.sql
 
 #
 # Remove system dependent files
 #
-if [ $BASE_SYSTEM = "netware" ] ; then
-  rm -f $BASE/support-files/magic \
+rm -f   $BASE/support-files/magic \
         $BASE/support-files/mysql.server \
         $BASE/support-files/mysql*.spec \
         $BASE/support-files/mysql-log-rotate \
         $BASE/support-files/binary-configure \
         $BASE/support-files/build-tags \
 	$BASE/support-files/MySQL-shared-compat.spec \
-        $BASE/support-files/ndb-config-2-node.ini \
         $BASE/INSTALL-BINARY
-fi
-
-# Make safe_mysqld a symlink to mysqld_safe for backwards portability
-if [ $BASE_SYSTEM != "netware" ] ; then
-  (cd $BASE/bin ; ln -s mysqld_safe safe_mysqld )
-fi
 
 # Clean up if we did this from a bk tree
 if [ -d $BASE/sql-bench/SCCS ] ; then
@@ -366,78 +452,17 @@ if [ -d $BASE/sql-bench/SCCS ] ; then
   find $BASE/sql-bench -name SCCS -print | xargs rm -rf
 fi
 
-# NDB Cluster
-if [ x$NDBCLUSTER = x1 ]; then
-  ( cd ndb            ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
-  ( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
-  $CP $BASE/ndb-stage@bindir@/* $BASE/bin/.
-  $CP $BASE/ndb-stage@libexecdir@/* $BASE/bin/.
-  $CP $BASE/ndb-stage@pkglibdir@/* $BASE/lib/.
-  $CP $BASE/ndb-stage@pkgdatadir@/* $BASE/share/mysql/.
-  $CP -r $BASE/ndb-stage@pkgincludedir@/ndb $BASE/include
-  $CP -r $BASE/ndb-stage@prefix@/mysql-test/ndb $BASE/mysql-test/. || exit 1
-  rm -rf $BASE/ndb-stage
-fi
-
-# Change the distribution to a long descriptive name
-NEW_NAME=mysql@MYSQL_SERVER_SUFFIX@-$version-$platform$SUFFIX
-
-# Print the platform name for build logs
-echo "PLATFORM NAME: $platform"
-
 BASE2=$TMP/$NEW_NAME
 rm -rf $BASE2
 mv $BASE $BASE2
 BASE=$BASE2
+
 #
-# If we are compiling with gcc, copy libgcc.a to the distribution as libmygcc.a
+# Create a zip file for NetWare users
 #
-
-if [ x"@GXX@" = x"yes" ] ; then
-  gcclib=`@CC@ @CFLAGS@ --print-libgcc-file 2>/dev/null` || true
-  if [ -z "$gcclib" ] ; then
-    echo "Warning: Compiler doesn't tell libgcc.a!"
-  elif [ -f "$gcclib" ] ; then
-    $CP $gcclib $BASE/lib/libmygcc.a
-  else
-    echo "Warning: Compiler result '$gcclib' not found / no file!"
-  fi
-fi
-
-#if we are debugging, do not do tar/gz
-if [ x$DEBUG = x1 ] ; then
- exit
-fi
-
-if [ $BASE_SYSTEM != "netware" ] ; then
-
-  #
-  # Create the result tar file
-  #
-
-  echo "Using $tar to create archive"
-
-  OPT=cvf
-  if [ x$SILENT = x1 ] ; then
-    OPT=cf
-  fi
-
-  echo "Creating and compressing archive"
-  rm -f $NEW_NAME.tar.gz
-  (cd $TMP ; $tar $OPT -  $NEW_NAME) | gzip -9 > $NEW_NAME.tar.gz
-  echo "$NEW_NAME.tar.gz created"
-
-else
-
-  #
-  # Create a zip file for NetWare users
-  #
-
-  rm -f $NEW_NAME.zip
-  (cd $TMP; zip -r "$SOURCE/$NEW_NAME.zip" $NEW_NAME)
-  echo "$NEW_NAME.zip created"
-
-fi
+rm -f $NEW_NAME.zip
+(cd $TMP; zip -r "$SOURCE/$NEW_NAME.zip" $NEW_NAME)
+echo "$NEW_NAME.zip created"
 
 echo "Removing temporary directory"
 rm -rf $BASE

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2008-05-08 16:01:15 +0000
+++ b/sql/slave.cc	2008-06-23 11:55:24 +0000
@@ -4024,6 +4024,7 @@ bool rpl_master_erroneous_autoinc(THD *t
   if (active_mi && active_mi->rli.sql_thd == thd)
   {
     Relay_log_info *rli= &active_mi->rli;
+    DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
     return rpl_master_has_bug(rli, 33029, FALSE);
   }
   return FALSE;

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-05-27 19:47:15 +0000
+++ b/sql/sql_class.cc	2008-06-25 14:49:43 +0000
@@ -2960,8 +2960,8 @@ void THD::reset_sub_statement_state(Sub_
    */
   if (rpl_master_erroneous_autoinc(this))
   {
-    backup->auto_inc_intervals_forced= auto_inc_intervals_forced;
-    auto_inc_intervals_forced.empty();
+    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
+    auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
   }
 #endif
   
@@ -3009,8 +3009,8 @@ void THD::restore_sub_statement_state(Su
    */
   if (rpl_master_erroneous_autoinc(this))
   {
-    auto_inc_intervals_forced= backup->auto_inc_intervals_forced;
-    backup->auto_inc_intervals_forced.empty();
+    backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
+    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
   }
 #endif
 

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2008-05-08 16:01:15 +0000
+++ b/sql/sql_plugin.cc	2008-06-18 03:30:29 +0000
@@ -1146,9 +1146,10 @@ int plugin_init(int *argc, char **argv, 
   {
     for (plugin= *builtins; plugin->info; plugin++)
     {
-      /* by default, only ndbcluster is disabled */
+      /* by default, ndbcluster and federated are disabled */
       def_enabled=
-        my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0;
+        my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0 &&
+        my_strcasecmp(&my_charset_latin1, plugin->name, "FEDERATED") != 0;
       bzero(&tmp, sizeof(tmp));
       tmp.plugin= plugin;
       tmp.name.str= (char *)plugin->name;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2008-05-23 05:03:07 +0000
+++ b/sql/sql_select.cc	2008-06-20 19:24:46 +0000
@@ -1479,6 +1479,7 @@ JOIN::optimize()
       {
         DBUG_PRINT("info",("No matching min/max row"));
 	zero_result_cause= "No matching min/max row";
+        tables= 0;
 	error=0;
 	DBUG_RETURN(0);
       }
@@ -1492,6 +1493,7 @@ JOIN::optimize()
       {
         DBUG_PRINT("info",("No matching min/max row"));
         zero_result_cause= "No matching min/max row";
+        tables= 0;
         error=0;
         DBUG_RETURN(0);
       }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-06-04 13:20:03 +0000
+++ b/sql/sql_table.cc	2008-06-25 14:49:43 +0000
@@ -3978,7 +3978,7 @@ static int prepare_for_repair(THD *thd, 
   if (table->s->frm_version != FRM_VER_TRUE_VARCHAR)
   {
     error= send_check_errmsg(thd, table_list, "repair",
-                             "Failed reparing incompatible .FRM file");
+                             "Failed repairing incompatible .frm file");
     goto end;
   }
 

=== modified file 'sql/structs.h'
--- a/sql/structs.h	2008-04-01 15:13:57 +0000
+++ b/sql/structs.h	2008-06-23 11:55:24 +0000
@@ -320,31 +320,22 @@ private:
   */
   Discrete_interval        *current;
   uint                  elements; // number of elements
-
-  /* helper function for copy construct and assignment operator */
-  void copy_(const Discrete_intervals_list& from)
-  {
-    for (Discrete_interval *i= from.head; i; i= i->next)
-    {
-      Discrete_interval j= *i;
-      append(&j);
-    }
+  void set_members(Discrete_interval *h, Discrete_interval *t,
+                   Discrete_interval *c, uint el)
+  {  
+    head= h;
+    tail= t;
+    current= c;
+    elements= el;
   }
+  void operator=(Discrete_intervals_list &);  /* prevent use of these */
+  Discrete_intervals_list(const Discrete_intervals_list &);
+
 public:
   Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
-  Discrete_intervals_list(const Discrete_intervals_list& from)
-  {
-    copy_(from);
-  }
-  void operator=(const Discrete_intervals_list& from)
-  {
-    empty();
-    copy_(from);
-  }
   void empty_no_free()
   {
-    head= current= NULL;
-    elements= 0;
+    set_members(NULL, NULL, NULL, 0);
   }
   void empty()
   {
@@ -356,7 +347,24 @@ public:
     }
     empty_no_free();
   }
-
+  void copy_shallow(const Discrete_intervals_list * dli)
+  {
+    head= dli->get_head();
+    tail= dli->get_tail();
+    current= dli->get_current();
+    elements= dli->nb_elements();
+  }
+  void swap (Discrete_intervals_list * dli)
+  {
+    Discrete_interval *h, *t, *c;
+    uint el;
+    h= dli->get_head();
+    t= dli->get_tail();
+    c= dli->get_current();
+    el= dli->nb_elements();
+    dli->copy_shallow(this);
+    set_members(h, t, c, el);
+  }
   const Discrete_interval* get_next()
   {
     Discrete_interval *tmp= current;
@@ -370,4 +378,7 @@ public:
   ulonglong minimum()     const { return (head ? head->minimum() : 0); };
   ulonglong maximum()     const { return (head ? tail->maximum() : 0); };
   uint      nb_elements() const { return elements; }
+  Discrete_interval* get_head() const { return head; };
+  Discrete_interval* get_tail() const { return tail; };
+  Discrete_interval* get_current() const { return current; };
 };

=== modified file 'storage/innobase/Makefile.am'
--- a/storage/innobase/Makefile.am	2008-05-14 09:24:14 +0000
+++ b/storage/innobase/Makefile.am	2008-06-20 19:24:46 +0000
@@ -15,21 +15,21 @@
 
 # Process this file with automake to create Makefile.in
 
-MYSQLDATAdir =          $(localstatedir)
-MYSQLSHAREdir =         $(pkgdatadir)
-MYSQLBASEdir=           $(prefix)
-MYSQLLIBdir=            $(pkglibdir)
-pkgplugindir =		$(pkglibdir)/plugin
-INCLUDES =              -I$(top_srcdir)/include -I$(top_builddir)/include \
+MYSQLDATAdir=		$(localstatedir)
+MYSQLSHAREdir=		$(pkgdatadir)
+MYSQLBASEdir=		$(prefix)
+MYSQLLIBdir=		$(pkglibdir)
+pkgplugindir=		$(pkglibdir)/plugin
+INCLUDES=		-I$(top_srcdir)/include -I$(top_builddir)/include \
 			-I$(top_srcdir)/regex \
 			-I$(top_srcdir)/storage/innobase/include \
 			-I$(top_srcdir)/sql \
-                        -I$(srcdir)
+			-I$(srcdir)
 
-DEFS =			@DEFS@
+DEFS=			@DEFS@
 
 
-noinst_HEADERS = include/btr0btr.h include/btr0btr.ic			\
+noinst_HEADERS=		include/btr0btr.h include/btr0btr.ic		\
 			include/btr0cur.h include/btr0cur.ic		\
 			include/btr0pcur.h include/btr0pcur.ic		\
 			include/btr0sea.h include/btr0sea.ic		\
@@ -121,9 +121,9 @@ noinst_HEADERS = include/btr0btr.h inclu
 			include/ut0list.ic include/ut0wqueue.h		\
 			include/ha_prototypes.h handler/ha_innodb.h
 
-EXTRA_LIBRARIES =	libinnobase.a
-noinst_LIBRARIES =	@plugin_innobase_static_target@
-libinnobase_a_SOURCES =	btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c	\
+EXTRA_LIBRARIES=	libinnobase.a
+noinst_LIBRARIES=	@plugin_innobase_static_target@
+libinnobase_a_SOURCES=	btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c	\
 			btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c	\
 			buf/buf0lru.c buf/buf0rea.c data/data0data.c	\
 			data/data0type.c dict/dict0boot.c		\
@@ -156,17 +156,17 @@ libinnobase_a_SOURCES =	btr/btr0btr.c bt
 			handler/ha_innodb.cc
 
 libinnobase_a_CXXFLAGS=	$(AM_CFLAGS)
-libinnobase_a_CFLAGS  =	$(AM_CFLAGS)
+libinnobase_a_CFLAGS=	$(AM_CFLAGS)
 
-EXTRA_LTLIBRARIES =	ha_innodb.la
-pkglib_LTLIBRARIES =	@plugin_innobase_shared_target@
+EXTRA_LTLIBRARIES=	ha_innodb.la
+pkgplugin_LTLIBRARIES=	@plugin_innobase_shared_target@
 
-ha_innodb_la_LDFLAGS =	-module -rpath $(pkgplugindir)
-ha_innodb_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_innodb_la_CFLAGS  =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_innodb_la_SOURCES =	$(libinnobase_a_SOURCES)
+ha_innodb_la_LDFLAGS=	-module -rpath $(pkgplugindir)
+ha_innodb_la_CXXFLAGS=	$(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_la_CFLAGS=	$(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_la_SOURCES=	$(libinnobase_a_SOURCES)
 
-EXTRA_DIST =		CMakeLists.txt plug.in \
+EXTRA_DIST=		CMakeLists.txt plug.in \
 			pars/make_bison.sh pars/make_flex.sh \
 			pars/pars0grm.y pars/pars0lex.l
 

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/btr/btr0cur.c	2008-06-12 00:08:07 +0000
@@ -52,7 +52,7 @@ can be released by page reorganize, then
 
 #define BTR_CUR_PAGE_REORGANIZE_LIMIT	(UNIV_PAGE_SIZE / 32)
 
-/* When estimating number of different kay values in an index sample
+/* When estimating number of different key values in an index, sample
 this many index pages */
 #define BTR_KEY_VAL_ESTIMATE_N_PAGES	8
 

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2008-02-01 10:55:39 +0000
+++ b/storage/innobase/buf/buf0buf.c	2008-06-12 00:08:07 +0000
@@ -2328,7 +2328,6 @@ buf_print(void)
 
 	ut_a(buf_validate());
 }
-#endif /* UNIV_DEBUG */
 
 /*************************************************************************
 Returns the number of latched pages in the buffer pool. */
@@ -2361,6 +2360,7 @@ buf_get_latched_pages_number(void)
 
 	return(fixed_pages_number);
 }
+#endif /* UNIV_DEBUG */
 
 /*************************************************************************
 Returns the number of pending buf pool ios. */

=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/dict/dict0dict.c	2008-06-12 00:08:07 +0000
@@ -429,7 +429,7 @@ void
 dict_table_autoinc_initialize(
 /*==========================*/
 	dict_table_t*	table,	/* in: table */
-	ib_longlong	value)	/* in: next value to assign to a row */
+	ib_ulonglong	value)	/* in: next value to assign to a row */
 {
 	ut_ad(mutex_own(&table->autoinc_mutex));
 
@@ -441,7 +441,7 @@ dict_table_autoinc_initialize(
 Reads the next autoinc value (== autoinc counter value), 0 if not yet
 initialized. */
 
-ib_longlong
+ib_ulonglong
 dict_table_autoinc_read(
 /*====================*/
 				/* out: value for a new row, or 0 */
@@ -470,7 +470,7 @@ dict_table_autoinc_update(
 /*======================*/
 
 	dict_table_t*	table,	/* in: table */
-	ib_longlong	value)	/* in: value which was assigned to a row */
+	ib_ulonglong	value)	/* in: value which was assigned to a row */
 {
 	if (table->autoinc_inited && value > table->autoinc) {
 
@@ -3395,7 +3395,7 @@ loop:
 
 	ptr = dict_accept(cs, ptr, "FOREIGN", &success);
 
-	if (!success) {
+	if (!success || !my_isspace(cs, *ptr)) {
 
 		goto loop;
 	}

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2008-05-22 18:40:15 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2008-06-12 00:08:07 +0000
@@ -135,7 +135,7 @@ static my_bool	innobase_locks_unsafe_for
 static my_bool	innobase_rollback_on_timeout		= FALSE;
 static my_bool	innobase_create_status_file		= FALSE;
 static my_bool innobase_stats_on_metadata		= TRUE;
-static my_bool	innobase_use_adaptive_hash_indexes	= TRUE;
+static my_bool	innobase_adaptive_hash_index	= TRUE;
 
 static char*	internal_innobase_data_file_path	= NULL;
 
@@ -340,8 +340,10 @@ static SHOW_VAR innodb_status_variables[
   (char*) &export_vars.innodb_buffer_pool_pages_flushed,  SHOW_LONG},
   {"buffer_pool_pages_free",
   (char*) &export_vars.innodb_buffer_pool_pages_free,	  SHOW_LONG},
+#ifdef UNIV_DEBUG
   {"buffer_pool_pages_latched",
   (char*) &export_vars.innodb_buffer_pool_pages_latched,  SHOW_LONG},
+#endif /* UNIV_DEBUG */
   {"buffer_pool_pages_misc",
   (char*) &export_vars.innodb_buffer_pool_pages_misc,	  SHOW_LONG},
   {"buffer_pool_pages_total",
@@ -606,7 +608,9 @@ convert_error_code_to_mysql(
 		tell it also to MySQL so that MySQL knows to empty the
 		cached binlog for this transaction */
 
-                thd_mark_transaction_to_rollback(thd, TRUE);
+		if (thd) {
+			thd_mark_transaction_to_rollback(thd, TRUE);
+		}
 
 		return(HA_ERR_LOCK_DEADLOCK);
 	} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
@@ -615,8 +619,10 @@ convert_error_code_to_mysql(
 		latest SQL statement in a lock wait timeout. Previously, we
 		rolled back the whole transaction. */
 
-                thd_mark_transaction_to_rollback(thd,
-                                             (bool)row_rollback_on_timeout);
+		if (thd) {
+			thd_mark_transaction_to_rollback(
+				thd, (bool)row_rollback_on_timeout);
+		}
 
 		return(HA_ERR_LOCK_WAIT_TIMEOUT);
 
@@ -668,7 +674,9 @@ convert_error_code_to_mysql(
  		tell it also to MySQL so that MySQL knows to empty the
  		cached binlog for this transaction */
 
-                thd_mark_transaction_to_rollback(thd, TRUE);
+		if (thd) {
+			thd_mark_transaction_to_rollback(thd, TRUE);
+		}
 
     		return(HA_ERR_LOCK_TABLE_FULL);
 	} else if (error == DB_TOO_MANY_CONCURRENT_TRXS) {
@@ -1635,7 +1643,7 @@ innobase_init(
 	srv_stats_on_metadata = (ibool) innobase_stats_on_metadata;
 
 	srv_use_adaptive_hash_indexes =
-		(ibool) innobase_use_adaptive_hash_indexes;
+		(ibool) innobase_adaptive_hash_index;
 
 	srv_print_verbose_log = mysqld_embedded ? 0 : 1;
 
@@ -2283,6 +2291,8 @@ ha_innobase::open(
 	dict_table_t*	ib_table;
 	char		norm_name[1000];
 	THD*		thd;
+	ulint		retries = 0;
+	char*		is_part = NULL;
 
 	DBUG_ENTER("ha_innobase::open");
 
@@ -2316,11 +2326,29 @@ ha_innobase::open(
 		DBUG_RETURN(1);
 	}
 
+	/* We look for pattern #P# to see if the table is partitioned
+	MySQL table. The retry logic for partitioned tables is a
+	workaround for http://bugs.mysql.com/bug.php?id=33349. Look
+	at support issue https://support.mysql.com/view.php?id=21080
+	for more details. */
+	is_part = strstr(norm_name, "#P#");
+retry:
 	/* Get pointer to a table object in InnoDB dictionary cache */
-
 	ib_table = dict_table_get(norm_name, TRUE);
-
+	
 	if (NULL == ib_table) {
+		if (is_part && retries < 10) {
+			++retries;
+			os_thread_sleep(100000);
+			goto retry;
+		}
+
+		if (is_part) {
+			sql_print_error("Failed to open table %s after "
+					"%lu attemtps.\n", norm_name,
+					retries);
+		}
+
 		sql_print_error("Cannot find or open table %s from\n"
 				"the internal data dictionary of InnoDB "
 				"though the .frm file for the\n"
@@ -3305,7 +3333,8 @@ ha_innobase::innobase_autoinc_lock(void)
 		old style only if another transaction has already acquired
 		the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
 		etc. type of statement. */
-		if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
+		if (thd_sql_command(user_thd) == SQLCOM_INSERT
+		    || thd_sql_command(user_thd) == SQLCOM_REPLACE) {
 			dict_table_t*	table = prebuilt->table;
 
 			/* Acquire the AUTOINC mutex. */
@@ -3576,7 +3605,19 @@ no_commit:
 			if (auto_inc > prebuilt->last_value) {
 set_max_autoinc:
 				ut_a(prebuilt->table->autoinc_increment > 0);
-				auto_inc += prebuilt->table->autoinc_increment;
+
+				ulonglong	have;
+				ulonglong	need;
+
+				/* Check for overflow conditions. */
+				need = prebuilt->table->autoinc_increment;
+				have = ~0x0ULL - auto_inc;
+
+				if (have < need) {
+					need = have;
+				}
+
+				auto_inc += need;
 
 				err = innobase_set_max_autoinc(auto_inc);
 
@@ -3771,6 +3812,8 @@ ha_innobase::update_row(
 
 	ut_a(prebuilt->trx == trx);
 
+	ha_statistic_increment(&SSV::ha_update_count);
+
 	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
 		table->timestamp_field->set_time();
 
@@ -3826,6 +3869,16 @@ ha_innobase::update_row(
 
 	error = convert_error_code_to_mysql(error, user_thd);
 
+	if (error == 0 /* success */
+	    && uvect->n_fields == 0 /* no columns were updated */) {
+
+		/* This is the same as success, but instructs
+		MySQL that the row is not really updated and it
+		should not increase the count of updated rows.
+		This is fix for http://bugs.mysql.com/29157 */
+		error = HA_ERR_RECORD_IS_THE_SAME;
+	}
+
 	/* Tell InnoDB server that there might be work for
 	utility threads: */
 
@@ -3850,6 +3903,8 @@ ha_innobase::delete_row(
 
 	ut_a(prebuilt->trx == trx);
 
+	ha_statistic_increment(&SSV::ha_delete_count);
+
 	/* Only if the table has an AUTOINC column */
 	if (table->found_next_number_field && record == table->record[0]) {
 		ulonglong	dummy = 0;
@@ -4653,6 +4708,12 @@ innodb_check_for_record_too_big_error(
 	}
 }
 
+/* limit innodb monitor access to users with PROCESS privilege.
+See http://bugs.mysql.com/32710 for expl. why we choose PROCESS. */
+#define IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name, thd) \
+	(row_is_magic_monitor_table(table_name) \
+	 && check_global_access(thd, PROCESS_ACL))
+
 /*********************************************************************
 Creates a table definition to an InnoDB database. */
 static
@@ -4689,6 +4750,12 @@ create_table_def(
 	DBUG_ENTER("create_table_def");
 	DBUG_PRINT("enter", ("table_name: %s", table_name));
 
+	ut_a(trx->mysql_thd != NULL);
+	if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
+						  (THD*) trx->mysql_thd)) {
+		DBUG_RETURN(HA_ERR_GENERIC);
+	}
+
 	n_cols = form->s->fields;
 
 	/* We pass 0 as the space id, and determine at a lower level the space
@@ -4967,6 +5034,29 @@ ha_innobase::create(
 	DBUG_ENTER("ha_innobase::create");
 
 	DBUG_ASSERT(thd != NULL);
+	DBUG_ASSERT(create_info != NULL);
+
+#ifdef __WIN__
+	/* Names passed in from server are in two formats:
+	1. <database_name>/<table_name>: for normal table creation
+	2. full path: for temp table creation, or sym link
+
+	When srv_file_per_table is on, check for full path pattern, i.e.
+	X:\dir\...,		X is a driver letter, or
+	\\dir1\dir2\...,	UNC path
+	returns error if it is in full path format, but not creating a temp.
+	table. Currently InnoDB does not support symbolic link on Windows. */
+
+	if (srv_file_per_table
+	    && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
+
+		if ((name[1] == ':')
+		    || (name[0] == '\\' && name[1] == '\\')) {
+			sql_print_error("Cannot create table %s\n", name);
+			DBUG_RETURN(HA_ERR_GENERIC);
+		}
+	}
+#endif
 
 	if (form->s->fields > 1000) {
 		/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
@@ -5101,8 +5191,15 @@ ha_innobase::create(
 
 	DBUG_ASSERT(innobase_table != 0);
 
-	if ((create_info->used_fields & HA_CREATE_USED_AUTO) &&
-	   (create_info->auto_increment_value != 0)) {
+	/* Note: We can't call update_thd() as prebuilt will not be
+	setup at this stage and so we use thd. */
+
+	/* We need to copy the AUTOINC value from the old table if
+	this is an ALTER TABLE. */
+
+	if (((create_info->used_fields & HA_CREATE_USED_AUTO)
+	    || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
+	    && create_info->auto_increment_value != 0) {
 
 		/* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 		CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
@@ -5229,6 +5326,14 @@ ha_innobase::delete_table(
 
 	DBUG_ENTER("ha_innobase::delete_table");
 
+	/* Strangely, MySQL passes the table name without the '.frm'
+	extension, in contrast to ::create */
+	normalize_table_name(norm_name, name);
+
+	if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
+		DBUG_RETURN(HA_ERR_GENERIC);
+	}
+
 	/* Get the transaction associated with the current thd, or create one
 	if not yet created */
 
@@ -5262,11 +5367,6 @@ ha_innobase::delete_table(
 
 	assert(name_len < 1000);
 
-	/* Strangely, MySQL passes the table name without the '.frm'
-	extension, in contrast to ::create */
-
-	normalize_table_name(norm_name, name);
-
 	/* Drop the table in InnoDB */
 
 	error = row_drop_table_for_mysql(norm_name, trx,
@@ -5756,6 +5856,13 @@ ha_innobase::info(
 			n_rows++;
 		}
 
+		/* Fix bug#29507: TRUNCATE shows too many rows affected.
+		Do not show the estimates for TRUNCATE command. */
+		if (thd_sql_command(user_thd) == SQLCOM_TRUNCATE) {
+
+			n_rows = 0;
+		}
+
 		stats.records = (ha_rows)n_rows;
 		stats.deleted = 0;
 		stats.data_file_length = ((ulonglong)
@@ -5764,7 +5871,9 @@ ha_innobase::info(
 		stats.index_file_length = ((ulonglong)
 				ib_table->stat_sum_of_other_index_sizes)
 					* UNIV_PAGE_SIZE;
-		stats.delete_length = 0;
+		stats.delete_length =
+			fsp_get_available_space_in_free_extents(
+				ib_table->space) * 1024;
 		stats.check_time = 0;
 
 		if (stats.records == 0) {
@@ -5847,7 +5956,7 @@ ha_innobase::info(
 	}
 
 	if (flag & HA_STATUS_AUTO && table->found_next_number_field) {
-		longlong	auto_inc;
+		ulonglong	auto_inc;
 		int		ret;
 
 		/* The following function call can the first time fail in
@@ -7211,9 +7320,9 @@ ha_innobase::innobase_read_and_init_auto
 /*=========================================*/
 						/* out: 0 or generic MySQL
 						error code */
-        longlong*	value)			/* out: the autoinc value */
+        ulonglong*	value)			/* out: the autoinc value */
 {
-	longlong	auto_inc;
+	ulonglong	auto_inc;
 	ibool		stmt_start;
 	int		mysql_error = 0;
 	dict_table_t*	innodb_table = prebuilt->table;
@@ -7264,7 +7373,9 @@ ha_innobase::innobase_read_and_init_auto
 			index, autoinc_col_name, &auto_inc);
 
 		if (error == DB_SUCCESS) {
-			++auto_inc;
+			if (auto_inc < ~0x0ULL) {
+				++auto_inc;
+			}
 			dict_table_autoinc_initialize(innodb_table, auto_inc);
 		} else {
 			ut_print_timestamp(stderr);
@@ -7303,6 +7414,7 @@ On return if there is no error then the 
 
 ulong
 ha_innobase::innobase_get_auto_increment(
+/*=====================================*/
 	ulonglong*	value)		/* out: autoinc value */
 {
 	ulong		error;
@@ -7316,14 +7428,14 @@ ha_innobase::innobase_get_auto_increment
 		error = innobase_autoinc_lock();
 
 		if (error == DB_SUCCESS) {
-			ib_longlong	autoinc;
+			ulonglong	autoinc;
 
 			/* Determine the first value of the interval */
 			autoinc = dict_table_autoinc_read(prebuilt->table);
 
 			/* We need to initialize the AUTO-INC value, for
 			that we release all locks.*/
-			if (autoinc <= 0) {
+			if (autoinc == 0) {
 				trx_t*		trx;
 
 				trx = prebuilt->trx;
@@ -7342,14 +7454,11 @@ ha_innobase::innobase_get_auto_increment
 				mysql_error = innobase_read_and_init_auto_inc(
 					&autoinc);
 
-				if (!mysql_error) {
-					/* Should have read the proper value */
-					ut_a(autoinc > 0);
-				} else {
+				if (mysql_error) {
 					error = DB_ERROR;
 				}
 			} else {
-				*value = (ulonglong) autoinc;
+				*value = autoinc;
 			}
 		/* A deadlock error during normal processing is OK
 		and can be ignored. */
@@ -7434,10 +7543,19 @@ ha_innobase::get_auto_increment(
 	/* With old style AUTOINC locking we only update the table's
 	AUTOINC counter after attempting to insert the row. */
 	if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
+		ulonglong	have;
+		ulonglong	need;
+
+		/* Check for overflow conditions. */
+		need = *nb_reserved_values * increment;
+		have = ~0x0ULL - *first_value;
+
+		if (have < need) {
+			need = have;
+		}
 
 		/* Compute the last value in the interval */
-		prebuilt->last_value = *first_value +
-		    (*nb_reserved_values * increment);
+		prebuilt->last_value = *first_value + need;
 
 		ut_a(prebuilt->last_value >= *first_value);
 
@@ -7911,7 +8029,7 @@ bool ha_innobase::check_if_incompatible_
 	}
 
 	/* Check that row format didn't change */
-	if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+	if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) &&
 		get_row_type() != info->row_type) {
 
 		return COMPATIBLE_DATA_NO;
@@ -8026,9 +8144,10 @@ static MYSQL_SYSVAR_BOOL(stats_on_metada
   "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
   NULL, NULL, TRUE);
 
-static MYSQL_SYSVAR_BOOL(use_adaptive_hash_indexes, innobase_use_adaptive_hash_indexes,
+static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index,
   PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
-  "Enable the InnoDB adaptive hash indexes (enabled by default)",
+  "Enable InnoDB adaptive hash index (enabled by default).  "
+  "Disable with --skip-innodb-adaptive-hash-index.",
   NULL, NULL, TRUE);
 
 static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
@@ -8118,10 +8237,11 @@ static MYSQL_SYSVAR_STR(data_file_path, 
 
 static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-  "The AUTOINC lock modes supported by InnoDB:\n"
-  "  0 => Old style AUTOINC locking (for backward compatibility)\n"
-  "  1 => New style AUTOINC locking\n"
-  "  2 => No AUTOINC locking (unsafe for SBR)",
+  "The AUTOINC lock modes supported by InnoDB:               "
+  "0 => Old style AUTOINC locking (for backward"
+  " compatibility)                                           "
+  "1 => New style AUTOINC locking                            "
+  "2 => No AUTOINC locking (unsafe for SBR)",
   NULL, NULL,
   AUTOINC_NEW_STYLE_LOCKING,	/* Default setting */
   AUTOINC_OLD_STYLE_LOCKING,	/* Minimum value */
@@ -8159,7 +8279,7 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(open_files),
   MYSQL_SYSVAR(rollback_on_timeout),
   MYSQL_SYSVAR(stats_on_metadata),
-  MYSQL_SYSVAR(use_adaptive_hash_indexes),
+  MYSQL_SYSVAR(adaptive_hash_index),
   MYSQL_SYSVAR(status_file),
   MYSQL_SYSVAR(support_xa),
   MYSQL_SYSVAR(sync_spin_loops),

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/handler/ha_innodb.h	2008-06-12 00:08:07 +0000
@@ -72,7 +72,7 @@ class ha_innobase: public handler
 	int update_thd(THD* thd);
 	int change_active_index(uint keynr);
 	int general_fetch(uchar* buf, uint direction, uint match_mode);
-	int innobase_read_and_init_auto_inc(longlong* ret);
+	int innobase_read_and_init_auto_inc(ulonglong* ret);
 	ulong innobase_autoinc_lock();
 	ulong innobase_set_max_autoinc(ulonglong auto_inc);
 	ulong innobase_reset_autoinc(ulonglong auto_inc);

=== modified file 'storage/innobase/include/buf0buf.h'
--- a/storage/innobase/include/buf0buf.h	2008-02-01 10:55:39 +0000
+++ b/storage/innobase/include/buf0buf.h	2008-06-12 00:08:07 +0000
@@ -495,7 +495,15 @@ Prints info of the buffer pool data stru
 void
 buf_print(void);
 /*============*/
+
+/*************************************************************************
+Returns the number of latched pages in the buffer pool. */
+
+ulint
+buf_get_latched_pages_number(void);
+/*==============================*/
 #endif /* UNIV_DEBUG */
+
 /************************************************************************
 Prints a page to stderr. */
 
@@ -503,12 +511,7 @@ void
 buf_page_print(
 /*===========*/
 	byte*	read_buf);	/* in: a database page */
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
 
-ulint
-buf_get_latched_pages_number(void);
-/*==============================*/
 /*************************************************************************
 Returns the number of pending buf pool ios. */
 

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/dict0dict.h	2008-06-12 00:08:07 +0000
@@ -185,12 +185,12 @@ void
 dict_table_autoinc_initialize(
 /*==========================*/
 	dict_table_t*	table,	/* in: table */
-	ib_longlong	value);	/* in: next value to assign to a row */
+	ib_ulonglong	value);	/* in: next value to assign to a row */
 /************************************************************************
 Reads the next autoinc value (== autoinc counter value), 0 if not yet
 initialized. */
 
-ib_longlong
+ib_ulonglong
 dict_table_autoinc_read(
 /*====================*/
 				/* out: value for a new row, or 0 */
@@ -204,7 +204,7 @@ dict_table_autoinc_update(
 /*======================*/
 
 	dict_table_t*	table,	/* in: table */
-	ib_longlong	value);	/* in: value which was assigned to a row */
+	ib_ulonglong	value);	/* in: value which was assigned to a row */
 /************************************************************************
 Release the autoinc lock.*/
 

=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/dict0mem.h	2008-06-12 00:08:07 +0000
@@ -409,7 +409,7 @@ struct dict_table_struct{
 				/* TRUE if the autoinc counter has been
 				inited; MySQL gets the init value by executing
 				SELECT MAX(auto inc column) */
-	ib_longlong	autoinc;/* autoinc counter value to give to the
+	ib_ulonglong	autoinc;/* autoinc counter value to give to the
 				next inserted row */
 
 	ib_longlong	autoinc_increment;

=== modified file 'storage/innobase/include/mach0data.h'
--- a/storage/innobase/include/mach0data.h	2007-11-06 22:42:58 +0000
+++ b/storage/innobase/include/mach0data.h	2008-06-12 00:08:07 +0000
@@ -331,10 +331,10 @@ mach_write_to_2_little_endian(
 Convert integral type from storage byte order (big endian) to
 host byte order. */
 UNIV_INLINE
-void
+ullint
 mach_read_int_type(
 /*===============*/
-	byte*		dest,		/* out: where to write */
+					/* out: integer value */
 	const byte*	src,		/* in: where to read from */
 	ulint		len,		/* in: length of src */
 	ibool		unsigned_type);	/* in: signed or unsigned flag */

=== modified file 'storage/innobase/include/mach0data.ic'
--- a/storage/innobase/include/mach0data.ic	2007-11-06 22:42:58 +0000
+++ b/storage/innobase/include/mach0data.ic	2008-06-12 00:08:07 +0000
@@ -696,33 +696,39 @@ mach_write_to_2_little_endian(
 Convert integral type from storage byte order (big endian) to
 host byte order. */
 UNIV_INLINE
-void
+ullint
 mach_read_int_type(
 /*===============*/
-	byte*		dest,		/* out: where to write */
+					/* out: integer value */
 	const byte*	src,		/* in: where to read from */
 	ulint		len,		/* in: length of src */
 	ibool		unsigned_type)	/* in: signed or unsigned flag */
 {
-#ifdef WORDS_BIGENDIAN
-	memcpy(dest, src, len);
+	/* XXX this can be optimized on big-endian machines */
 
-	if (!unsigned_type) {
-		dest[0] ^= 128;
+	ullint	ret;
+	uint	i;
+
+	if (unsigned_type || (src[0] & 0x80)) {
+
+		ret = 0x0000000000000000ULL;
+	} else {
+
+		ret = 0xFFFFFFFFFFFFFF00ULL;
 	}
-#else
-	byte*		ptr;
 
-	/* Convert integer data from Innobase to a little-endian format,
-	sign bit restored to normal. */
+	if (unsigned_type) {
 
-	for (ptr = dest + len; ptr != dest; ++src) {
-		--ptr;
-		*ptr = *src;
+		ret |= src[0];
+	} else {
+
+		ret |= src[0] ^ 0x80;
 	}
 
-	if (!unsigned_type) {
-		dest[len - 1] ^= 128;
+	for (i = 1; i < len; i++) {
+		ret <<= 8;
+		ret |= src[i];
 	}
-#endif
+
+	return(ret);
 }

=== modified file 'storage/innobase/include/os0sync.h'
--- a/storage/innobase/include/os0sync.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/os0sync.h	2008-06-12 00:08:07 +0000
@@ -112,9 +112,13 @@ os_event_set(
 	os_event_t	event);	/* in: event to set */
 /**************************************************************
 Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event. */
+stop to wait for the event.
+The return value should be passed to os_even_wait_low() if it is desired
+that this thread should not wait in case of an intervening call to
+os_event_set() between this os_event_reset() and the
+os_event_wait_low() call. See comments for os_event_wait_low(). */
 
-void
+ib_longlong
 os_event_reset(
 /*===========*/
 	os_event_t	event);	/* in: event to reset */
@@ -125,16 +129,38 @@ void
 os_event_free(
 /*==========*/
 	os_event_t	event);	/* in: event to free */
+
 /**************************************************************
 Waits for an event object until it is in the signaled state. If
 srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
 waiting thread when the event becomes signaled (or immediately if the
-event is already in the signaled state). */
+event is already in the signaled state).
+
+Typically, if the event has been signalled after the os_event_reset()
+we'll return immediately because event->is_set == TRUE.
+There are, however, situations (e.g.: sync_array code) where we may
+lose this information. For example:
+
+thread A calls os_event_reset()
+thread B calls os_event_set()   [event->is_set == TRUE]
+thread C calls os_event_reset() [event->is_set == FALSE]
+thread A calls os_event_wait()  [infinite wait!]
+thread C calls os_event_wait()  [infinite wait!]
+
+Where such a scenario is possible, to avoid infinite wait, the
+value returned by os_event_reset() should be passed in as
+reset_sig_count. */
+
+#define os_event_wait(event) os_event_wait_low((event), 0)
+
+void
+os_event_wait_low(
+/*==============*/
+	os_event_t	event,		/* in: event to wait */
+	ib_longlong	reset_sig_count);/* in: zero or the value
+					returned by previous call of
+					os_event_reset(). */
 
-void
-os_event_wait(
-/*==========*/
-	os_event_t	event);	/* in: event to wait */
 /**************************************************************
 Waits for an event object until it is in the signaled state or
 a timeout is exceeded. In Unix the timeout is always infinite. */

=== modified file 'storage/innobase/include/read0read.h'
--- a/storage/innobase/include/read0read.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/read0read.h	2008-06-12 00:08:07 +0000
@@ -111,10 +111,6 @@ struct read_view_struct{
 	dulint	undo_no;	/* (0, 0) or if type is VIEW_HIGH_GRANULARITY
 				transaction undo_no when this high-granularity
 				consistent read view was created */
-	ibool	can_be_too_old;	/* TRUE if the system has had to purge old
-				versions which this read view should be able
-				to access: the read view can bump into the
-				DB_MISSING_HISTORY error */
 	dulint	low_limit_no;	/* The view does not need to see the undo
 				logs for transactions whose transaction number
 				is strictly smaller (<) than this value: they

=== modified file 'storage/innobase/include/row0mysql.h'
--- a/storage/innobase/include/row0mysql.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/row0mysql.h	2008-06-12 00:08:07 +0000
@@ -319,7 +319,7 @@ row_mysql_unfreeze_data_dictionary(
 /*===============================*/
 	trx_t*	trx);	/* in: transaction */
 /*************************************************************************
-Drops a table for MySQL. If the name of the table ends in
+Creates a table for MySQL. If the name of the table ends in
 one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
 "innodb_table_monitor", then this will also start the printing of monitor
 output by the master thread. If the table name ends in "innodb_mem_validate",
@@ -464,6 +464,16 @@ row_check_table_for_mysql(
 	row_prebuilt_t*	prebuilt);	/* in: prebuilt struct in MySQL
 					handle */
 
+/*************************************************************************
+Determines if a table is a magic monitor table. */
+
+ibool
+row_is_magic_monitor_table(
+/*=======================*/
+					/* out: TRUE if monitor table */
+	const char*	table_name);	/* in: name of the table, in the
+					form database/table_name */
+
 /* A struct describing a place for an individual column in the MySQL
 row format which is presented to the table handler in ha_innobase.
 This template struct is used to speed up row transformations between
@@ -671,7 +681,7 @@ struct row_prebuilt_struct {
 					fetched row in fetch_cache */
 	ulint		n_fetch_cached;	/* number of not yet fetched rows
 					in fetch_cache */
-	mem_heap_t*	blob_heap;	/* in SELECTS BLOB fie lds are copied
+	mem_heap_t*	blob_heap;	/* in SELECTS BLOB fields are copied
 					to this heap */
 	mem_heap_t*	old_vers_heap;	/* memory heap where a previous
 					version is built in consistent read */

=== modified file 'storage/innobase/include/row0sel.h'
--- a/storage/innobase/include/row0sel.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/row0sel.h	2008-06-12 00:08:07 +0000
@@ -181,7 +181,7 @@ row_search_max_autoinc(
 					error code */
 	dict_index_t*	index,		/* in: index to search */
 	const char*	col_name,	/* in: autoinc column name */
-	ib_longlong*	value);		/* out: AUTOINC value read */
+	ib_ulonglong*	value);		/* out: AUTOINC value read */
 
 /* A structure for caching column values for prefetched rows */
 struct sel_buf_struct{

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	2008-03-31 09:37:03 +0000
+++ b/storage/innobase/include/srv0srv.h	2008-06-12 00:08:07 +0000
@@ -249,11 +249,7 @@ extern srv_sys_t*	srv_sys;
 
 /* Alternatives for the file flush option in Unix; see the InnoDB manual
 about what these mean */
-#define SRV_UNIX_FDATASYNC	1	/* This is the default; it is
-					currently mapped to a call of
-					fsync() because fdatasync() seemed
-					to corrupt files in Linux and
-					Solaris */
+#define SRV_UNIX_FSYNC		1	/* This is the default */
 #define SRV_UNIX_O_DSYNC	2
 #define SRV_UNIX_LITTLESYNC	3
 #define SRV_UNIX_NOSYNC		4
@@ -505,7 +501,9 @@ struct export_var_struct{
 	ulint innodb_buffer_pool_pages_dirty;
 	ulint innodb_buffer_pool_pages_misc;
 	ulint innodb_buffer_pool_pages_free;
+#ifdef UNIV_DEBUG
 	ulint innodb_buffer_pool_pages_latched;
+#endif /* UNIV_DEBUG */
 	ulint innodb_buffer_pool_read_requests;
 	ulint innodb_buffer_pool_reads;
 	ulint innodb_buffer_pool_wait_free;

=== modified file 'storage/innobase/include/sync0arr.h'
--- a/storage/innobase/include/sync0arr.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/sync0arr.h	2008-06-12 00:08:07 +0000
@@ -66,26 +66,21 @@ sync_array_wait_event(
 	sync_array_t*	arr,	/* in: wait array */
 	ulint		index);	 /* in: index of the reserved cell */
 /**********************************************************************
-Frees the cell safely by reserving the sync array mutex and decrementing
-n_reserved if necessary. Should only be called from mutex_spin_wait. */
+Frees the cell. NOTE! sync_array_wait_event frees the cell
+automatically! */
 
 void
-sync_array_free_cell_protected(
-/*===========================*/
+sync_array_free_cell(
+/*=================*/
 	sync_array_t*	arr,	/* in: wait array */
 	ulint		index);	/* in: index of the cell in array */
 /**************************************************************************
-Looks for the cells in the wait array which refer
-to the wait object specified,
-and sets their corresponding events to the signaled state. In this
-way releases the threads waiting for the object to contend for the object.
-It is possible that no such cell is found, in which case does nothing. */
+Note that one of the wait objects was signalled. */
 
 void
-sync_array_signal_object(
-/*=====================*/
-	sync_array_t*	arr,	/* in: wait array */
-	void*		object);/* in: wait object */
+sync_array_object_signalled(
+/*========================*/
+	sync_array_t*	arr);	/* in: wait array */
 /**************************************************************************
 If the wakeup algorithm does not work perfectly at semaphore relases,
 this function will do the waking (see the comment in mutex_exit). This

=== modified file 'storage/innobase/include/sync0rw.h'
--- a/storage/innobase/include/sync0rw.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/sync0rw.h	2008-06-12 00:08:07 +0000
@@ -421,6 +421,18 @@ blocked by readers, a writer may queue f
 field. Then no new readers are allowed in. */
 
 struct rw_lock_struct {
+	os_event_t	event;	/* Used by sync0arr.c for thread queueing */
+
+#ifdef __WIN__
+	os_event_t	wait_ex_event;	/* This windows specific event is
+				used by the thread which has set the
+				lock state to RW_LOCK_WAIT_EX. The
+				rw_lock design guarantees that this
+				thread will be the next one to proceed
+				once the current the event gets
+				signalled. See LEMMA 2 in sync0sync.c */
+#endif
+
 	ulint	reader_count;	/* Number of readers who have locked this
 				lock in the shared mode */
 	ulint	writer;		/* This field is set to RW_LOCK_EX if there

=== modified file 'storage/innobase/include/sync0rw.ic'
--- a/storage/innobase/include/sync0rw.ic	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/sync0rw.ic	2008-06-12 00:08:07 +0000
@@ -381,7 +381,11 @@ rw_lock_s_unlock_func(
 	mutex_exit(mutex);
 
 	if (UNIV_UNLIKELY(sg)) {
-		sync_array_signal_object(sync_primary_wait_array, lock);
+#ifdef __WIN__
+		os_event_set(lock->wait_ex_event);
+#endif
+		os_event_set(lock->event);
+		sync_array_object_signalled(sync_primary_wait_array);
 	}
 
 	ut_ad(rw_lock_validate(lock));
@@ -461,7 +465,11 @@ rw_lock_x_unlock_func(
 	mutex_exit(&(lock->mutex));
 
 	if (UNIV_UNLIKELY(sg)) {
-		sync_array_signal_object(sync_primary_wait_array, lock);
+#ifdef __WIN__
+		os_event_set(lock->wait_ex_event);
+#endif
+		os_event_set(lock->event);
+		sync_array_object_signalled(sync_primary_wait_array);
 	}
 
 	ut_ad(rw_lock_validate(lock));

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/sync0sync.h	2008-06-12 00:08:07 +0000
@@ -470,6 +470,7 @@ Do not use its fields directly! The stru
 implementation of a mutual exclusion semaphore. */
 
 struct mutex_struct {
+	os_event_t	event;	/* Used by sync0arr.c for the wait queue */
 	ulint	lock_word;	/* This ulint is the target of the atomic
 				test-and-set instruction in Win32 */
 #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)

=== modified file 'storage/innobase/include/sync0sync.ic'
--- a/storage/innobase/include/sync0sync.ic	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/sync0sync.ic	2008-06-12 00:08:07 +0000
@@ -211,7 +211,7 @@ mutex_exit(
 	perform the read first, which could leave a waiting
 	thread hanging indefinitely.
 
-	Our current solution call every 10 seconds
+	Our current solution call every second
 	sync_arr_wake_threads_if_sema_free()
 	to wake up possible hanging threads if
 	they are missed in mutex_signal_object. */

=== modified file 'storage/innobase/include/trx0undo.h'
--- a/storage/innobase/include/trx0undo.h	2008-03-31 09:37:03 +0000
+++ b/storage/innobase/include/trx0undo.h	2008-06-12 00:08:07 +0000
@@ -240,6 +240,7 @@ trx_undo_set_state_at_finish(
 /*=========================*/
 				/* out: undo log segment header page,
 				x-latched */
+	trx_rseg_t*	rseg,	/* in: rollback segment memory object */
 	trx_t*		trx,	/* in: transaction */
 	trx_undo_t*	undo,	/* in: undo log memory copy */
 	mtr_t*		mtr);	/* in: mtr */

=== modified file 'storage/innobase/include/univ.i'
--- a/storage/innobase/include/univ.i	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/include/univ.i	2008-06-12 00:08:07 +0000
@@ -212,8 +212,11 @@ typedef long int		lint;
 
 #ifdef __WIN__
 typedef __int64			ib_longlong;
+typedef unsigned __int64	ib_ulonglong;
 #else
+/* Note: longlong and ulonglong come from MySQL headers. */
 typedef longlong		ib_longlong;
+typedef ulonglong               ib_ulonglong;
 #endif
 
 typedef unsigned long long int	ullint;

=== modified file 'storage/innobase/include/ut0ut.h'
--- a/storage/innobase/include/ut0ut.h	2007-11-06 22:42:58 +0000
+++ b/storage/innobase/include/ut0ut.h	2008-06-12 00:08:07 +0000
@@ -145,11 +145,15 @@ ib_time_t
 ut_time(void);
 /*=========*/
 /**************************************************************
-Returns system time. */
+Returns system time.
+Upon successful completion, the value 0 is returned; otherwise the
+value -1 is returned and the global variable errno is set to indicate the
+error. */
 
-void
+int
 ut_usectime(
 /*========*/
+			/* out: 0 on success, -1 otherwise */
 	ulint*	sec,	/* out: seconds since the Epoch */
 	ulint*	ms);	/* out: microseconds since the Epoch+*sec */
 /**************************************************************

=== modified file 'storage/innobase/os/os0file.c'
--- a/storage/innobase/os/os0file.c	2008-03-31 09:37:03 +0000
+++ b/storage/innobase/os/os0file.c	2008-06-12 00:08:07 +0000
@@ -22,8 +22,6 @@ Created 10/21/1995 Heikki Tuuri
 #include <errno.h>
 #endif /* UNIV_HOTBACKUP */
 
-#undef HAVE_FDATASYNC
-
 #ifdef POSIX_ASYNC_IO
 /* We assume in this case that the OS has standard Posix aio (at least SunOS
 2.6, HP-UX 11i and AIX 4.3 have) */
@@ -1269,9 +1267,19 @@ try_again:
 	if (file == INVALID_HANDLE_VALUE) {
 		*success = FALSE;
 
-		retry = os_file_handle_error(name,
-					     create_mode == OS_FILE_CREATE ?
-					     "create" : "open");
+		/* When srv_file_per_table is on, file creation failure may not
+		be critical to the whole instance. Do not crash the server in
+		case of unknown errors. */
+		if (srv_file_per_table) {
+			retry = os_file_handle_error_no_exit(name,
+						create_mode == OS_FILE_CREATE ?
+						"create" : "open");
+		} else {
+			retry = os_file_handle_error(name,
+						create_mode == OS_FILE_CREATE ?
+						"create" : "open");
+		}
+
 		if (retry) {
 			goto try_again;
 		}
@@ -1346,9 +1354,19 @@ try_again:
 	if (file == -1) {
 		*success = FALSE;
 
-		retry = os_file_handle_error(name,
-					     create_mode == OS_FILE_CREATE ?
-					     "create" : "open");
+		/* When srv_file_per_table is on, file creation failure may not
+		be critical to the whole instance. Do not crash the server in
+		case of unknown errors. */
+		if (srv_file_per_table) {
+			retry = os_file_handle_error_no_exit(name,
+						create_mode == OS_FILE_CREATE ?
+						"create" : "open");
+		} else {
+			retry = os_file_handle_error(name,
+						create_mode == OS_FILE_CREATE ?
+						"create" : "open");
+		}
+
 		if (retry) {
 			goto try_again;
 		} else {
@@ -1812,6 +1830,55 @@ os_file_set_eof(
 #endif /* __WIN__ */
 }
 
+#ifndef __WIN__
+/***************************************************************************
+Wrapper to fsync(2) that retries the call on some errors.
+Returns the value 0 if successful; otherwise the value -1 is returned and
+the global variable errno is set to indicate the error. */
+
+static
+int
+os_file_fsync(
+/*==========*/
+				/* out: 0 if success, -1 otherwise */
+	os_file_t	file)	/* in: handle to a file */
+{
+	int	ret;
+	int	failures;
+	ibool	retry;
+
+	failures = 0;
+
+	do {
+		ret = fsync(file);
+
+		os_n_fsyncs++;
+
+		if (ret == -1 && errno == ENOLCK) {
+
+			if (failures % 100 == 0) {
+
+				ut_print_timestamp(stderr);
+				fprintf(stderr,
+					"  InnoDB: fsync(): "
+					"No locks available; retrying\n");
+			}
+
+			os_thread_sleep(200000 /* 0.2 sec */);
+
+			failures++;
+
+			retry = TRUE;
+		} else {
+
+			retry = FALSE;
+		}
+	} while (retry);
+
+	return(ret);
+}
+#endif /* !__WIN__ */
+
 /***************************************************************************
 Flushes the write buffers of a given file to the disk. */
 
@@ -1869,23 +1936,19 @@ os_file_flush(
 		/* If we are not on an operating system that supports this,
 		then fall back to a plain fsync. */
 
-		ret = fsync(file);
+		ret = os_file_fsync(file);
 	} else {
 		ret = fcntl(file, F_FULLFSYNC, NULL);
 
 		if (ret) {
 			/* If we are not on a file system that supports this,
 			then fall back to a plain fsync. */
-			ret = fsync(file);
+			ret = os_file_fsync(file);
 		}
 	}
-#elif HAVE_FDATASYNC
-	ret = fdatasync(file);
 #else
-	/*	fprintf(stderr, "Flushing to file %p\n", file); */
-	ret = fsync(file);
+	ret = os_file_fsync(file);
 #endif
-	os_n_fsyncs++;
 
 	if (ret == 0) {
 		return(TRUE);

=== modified file 'storage/innobase/os/os0sync.c'
--- a/storage/innobase/os/os0sync.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/os/os0sync.c	2008-06-12 00:08:07 +0000
@@ -21,6 +21,7 @@ Created 9/6/1995 Heikki Tuuri
 
 /* Type definition for an operating system mutex struct */
 struct os_mutex_struct{
+	os_event_t	event;	/* Used by sync0arr.c for queing threads */
 	void*		handle;	/* OS handle to mutex */
 	ulint		count;	/* we use this counter to check
 				that the same thread does not
@@ -35,6 +36,7 @@ struct os_mutex_struct{
 /* Mutex protecting counts and the lists of OS mutexes and events */
 os_mutex_t	os_sync_mutex;
 ibool		os_sync_mutex_inited	= FALSE;
+ibool		os_sync_free_called	= FALSE;
 
 /* This is incremented by 1 in os_thread_create and decremented by 1 in
 os_thread_exit */
@@ -50,6 +52,10 @@ ulint	os_event_count		= 0;
 ulint	os_mutex_count		= 0;
 ulint	os_fast_mutex_count	= 0;
 
+/* Because a mutex is embedded inside an event and there is an
+event embedded inside a mutex, on free, this generates a recursive call.
+This version of the free event function doesn't acquire the global lock */
+static void os_event_free_internal(os_event_t	event);
 
 /*************************************************************
 Initializes global event and OS 'slow' mutex lists. */
@@ -76,6 +82,7 @@ os_sync_free(void)
 	os_event_t	event;
 	os_mutex_t	mutex;
 
+	os_sync_free_called = TRUE;
 	event = UT_LIST_GET_FIRST(os_event_list);
 
 	while (event) {
@@ -99,6 +106,7 @@ os_sync_free(void)
 
 		mutex = UT_LIST_GET_FIRST(os_mutex_list);
 	}
+	os_sync_free_called = FALSE;
 }
 
 /*************************************************************
@@ -144,17 +152,31 @@ os_event_create(
 	ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
 #endif
 	event->is_set = FALSE;
-	event->signal_count = 0;
+
+	/* We return this value in os_event_reset(), which can then be
+	be used to pass to the os_event_wait_low(). The value of zero
+	is reserved in os_event_wait_low() for the case when the
+	caller does not want to pass any signal_count value. To
+	distinguish between the two cases we initialize signal_count
+	to 1 here. */
+	event->signal_count = 1;
 #endif /* __WIN__ */
 
-	/* Put to the list of events */
-	os_mutex_enter(os_sync_mutex);
+	/* The os_sync_mutex can be NULL because during startup an event
+	can be created [ because it's embedded in the mutex/rwlock ] before
+	this module has been initialized */
+	if (os_sync_mutex != NULL) {
+		os_mutex_enter(os_sync_mutex);
+	}
 
+	/* Put to the list of events */
 	UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
 
 	os_event_count++;
 
-	os_mutex_exit(os_sync_mutex);
+	if (os_sync_mutex != NULL) {
+		os_mutex_exit(os_sync_mutex);
+	}
 
 	return(event);
 }
@@ -231,13 +253,20 @@ os_event_set(
 
 /**************************************************************
 Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event. */
+stop to wait for the event.
+The return value should be passed to os_even_wait_low() if it is desired
+that this thread should not wait in case of an intervening call to
+os_event_set() between this os_event_reset() and the
+os_event_wait_low() call. See comments for os_event_wait_low(). */
 
-void
+ib_longlong
 os_event_reset(
 /*===========*/
+				/* out: current signal_count. */
 	os_event_t	event)	/* in: event to reset */
 {
+	ib_longlong	ret = 0;
+
 #ifdef __WIN__
 	ut_a(event);
 
@@ -252,9 +281,40 @@ os_event_reset(
 	} else {
 		event->is_set = FALSE;
 	}
+	ret = event->signal_count;
 
 	os_fast_mutex_unlock(&(event->os_mutex));
 #endif
+	return(ret);
+}
+
+/**************************************************************
+Frees an event object, without acquiring the global lock. */
+static
+void
+os_event_free_internal(
+/*===================*/
+	os_event_t	event)	/* in: event to free */
+{
+#ifdef __WIN__
+	ut_a(event);
+
+	ut_a(CloseHandle(event->handle));
+#else
+	ut_a(event);
+
+	/* This is to avoid freeing the mutex twice */
+	os_fast_mutex_free(&(event->os_mutex));
+
+	ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
+#endif
+	/* Remove from the list of events */
+
+	UT_LIST_REMOVE(os_event_list, os_event_list, event);
+
+	os_event_count--;
+
+	ut_free(event);
 }
 
 /**************************************************************
@@ -293,18 +353,38 @@ os_event_free(
 Waits for an event object until it is in the signaled state. If
 srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
 waiting thread when the event becomes signaled (or immediately if the
-event is already in the signaled state). */
+event is already in the signaled state).
+
+Typically, if the event has been signalled after the os_event_reset()
+we'll return immediately because event->is_set == TRUE.
+There are, however, situations (e.g.: sync_array code) where we may
+lose this information. For example:
+
+thread A calls os_event_reset()
+thread B calls os_event_set()   [event->is_set == TRUE]
+thread C calls os_event_reset() [event->is_set == FALSE]
+thread A calls os_event_wait()  [infinite wait!]
+thread C calls os_event_wait()  [infinite wait!]
+
+Where such a scenario is possible, to avoid infinite wait, the
+value returned by os_event_reset() should be passed in as
+reset_sig_count. */
 
 void
-os_event_wait(
-/*==========*/
-	os_event_t	event)	/* in: event to wait */
+os_event_wait_low(
+/*==============*/
+	os_event_t	event,		/* in: event to wait */
+	ib_longlong	reset_sig_count)/* in: zero or the value
+					returned by previous call of
+					os_event_reset(). */
 {
 #ifdef __WIN__
 	DWORD	err;
 
 	ut_a(event);
 
+	UT_NOT_USED(reset_sig_count);
+
 	/* Specify an infinite time limit for waiting */
 	err = WaitForSingleObject(event->handle, INFINITE);
 
@@ -318,7 +398,11 @@ os_event_wait(
 
 	os_fast_mutex_lock(&(event->os_mutex));
 
-	old_signal_count = event->signal_count;
+	if (reset_sig_count) {
+		old_signal_count = reset_sig_count;
+	} else {
+		old_signal_count = event->signal_count;
+	}
 
 	for (;;) {
 		if (event->is_set == TRUE
@@ -458,6 +542,7 @@ os_mutex_create(
 
 	mutex_str->handle = mutex;
 	mutex_str->count = 0;
+	mutex_str->event = os_event_create(NULL);
 
 	if (os_sync_mutex_inited) {
 		/* When creating os_sync_mutex itself we cannot reserve it */
@@ -534,6 +619,10 @@ os_mutex_free(
 {
 	ut_a(mutex);
 
+	if (!os_sync_free_called) {
+		os_event_free_internal(mutex->event);
+	}
+
 	if (os_sync_mutex_inited) {
 		os_mutex_enter(os_sync_mutex);
 	}

=== modified file 'storage/innobase/plug.in'
--- a/storage/innobase/plug.in	2008-05-14 09:24:14 +0000
+++ b/storage/innobase/plug.in	2008-06-12 00:08:07 +0000
@@ -15,25 +15,30 @@ MYSQL_PLUGIN_ACTIONS(innobase,  [
   AC_CHECK_FUNCS(localtime_r)
   AC_C_BIGENDIAN
   case "$target_os" in
-         lin*)
-           CFLAGS="$CFLAGS -DUNIV_LINUX";;
-         hpux10*)
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX -DUNIV_HPUX10";;
-         hp*)
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX";;
-         aix*)
-           CFLAGS="$CFLAGS -DUNIV_AIX";;
-         irix*)
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
-         osf*)
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
-	 *solaris*|*SunOS*)
-           CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
-         sysv5uw7*)
-           # Problem when linking on SCO
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
-         openbsd*)
-           CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
+	lin*)
+		CFLAGS="$CFLAGS -DUNIV_LINUX";;
+	hpux10*)
+		CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX -DUNIV_HPUX10";;
+	hp*)
+		CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX";;
+	aix*)
+		CFLAGS="$CFLAGS -DUNIV_AIX";;
+	irix*|osf*|sysv5uw7*|openbsd*)
+		CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
+	*solaris*|*SunOS*)
+		CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
   esac
+  INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
+  case "$target_cpu" in
+	x86_64)
+		# The AMD64 ABI forbids absolute addresses in shared libraries
+		;;
+	*86)
+		# Use absolute addresses on IA-32
+		INNODB_DYNAMIC_CFLAGS="$INNODB_DYNAMIC_CFLAGS -prefer-non-pic"
+		;;
+  esac
+  AC_SUBST(INNODB_DYNAMIC_CFLAGS)
   ])
 
+# vim: set ft=config:

=== modified file 'storage/innobase/read/read0read.c'
--- a/storage/innobase/read/read0read.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/read/read0read.c	2008-06-12 00:08:07 +0000
@@ -212,7 +212,6 @@ read_view_oldest_copy_or_open_new(
 	view_copy->low_limit_no = old_view->low_limit_no;
 	view_copy->low_limit_id = old_view->low_limit_id;
 
-	view_copy->can_be_too_old = FALSE;
 
 	if (n > 0) {
 		/* The last active transaction has the smallest id: */
@@ -258,8 +257,6 @@ read_view_open_now(
 	view->low_limit_no = trx_sys->max_trx_id;
 	view->low_limit_id = view->low_limit_no;
 
-	view->can_be_too_old = FALSE;
-
 	n = 0;
 	trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
 
@@ -432,8 +429,6 @@ read_cursor_view_create_for_mysql(
 	view->low_limit_no = trx_sys->max_trx_id;
 	view->low_limit_id = view->low_limit_no;
 
-	view->can_be_too_old = FALSE;
-
 	n = 0;
 	trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
 

=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/row/row0mysql.c	2008-06-12 00:08:07 +0000
@@ -57,6 +57,12 @@ static const char S_innodb_tablespace_mo
 static const char S_innodb_table_monitor[] = "innodb_table_monitor";
 static const char S_innodb_mem_validate[] = "innodb_mem_validate";
 
+/* Evaluates to true if str1 equals str2_onstack, used for comparing
+the above strings. */
+#define STR_EQ(str1, str1_len, str2_onstack) \
+	((str1_len) == sizeof(str2_onstack) \
+	 && memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
+
 /***********************************************************************
 Determine if the given name is a name reserved for MySQL system tables. */
 static
@@ -1728,7 +1734,7 @@ row_mysql_unlock_data_dictionary(
 }
 
 /*************************************************************************
-Drops a table for MySQL. If the name of the table ends in
+Creates a table for MySQL. If the name of the table ends in
 one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
 "innodb_table_monitor", then this will also start the printing of monitor
 output by the master thread. If the table name ends in "innodb_mem_validate",
@@ -1809,9 +1815,7 @@ row_create_table_for_mysql(
 	table_name++;
 	table_name_len = strlen(table_name) + 1;
 
-	if (table_name_len == sizeof S_innodb_monitor
-	    && !memcmp(table_name, S_innodb_monitor,
-		       sizeof S_innodb_monitor)) {
+	if (STR_EQ(table_name, table_name_len, S_innodb_monitor)) {
 
 		/* Table equals "innodb_monitor":
 		start monitor prints */
@@ -1822,28 +1826,24 @@ row_create_table_for_mysql(
 		of InnoDB monitor prints */
 
 		os_event_set(srv_lock_timeout_thread_event);
-	} else if (table_name_len == sizeof S_innodb_lock_monitor
-		   && !memcmp(table_name, S_innodb_lock_monitor,
-			      sizeof S_innodb_lock_monitor)) {
+	} else if (STR_EQ(table_name, table_name_len,
+			  S_innodb_lock_monitor)) {
 
 		srv_print_innodb_monitor = TRUE;
 		srv_print_innodb_lock_monitor = TRUE;
 		os_event_set(srv_lock_timeout_thread_event);
-	} else if (table_name_len == sizeof S_innodb_tablespace_monitor
-		   && !memcmp(table_name, S_innodb_tablespace_monitor,
-			      sizeof S_innodb_tablespace_monitor)) {
+	} else if (STR_EQ(table_name, table_name_len,
+			  S_innodb_tablespace_monitor)) {
 
 		srv_print_innodb_tablespace_monitor = TRUE;
 		os_event_set(srv_lock_timeout_thread_event);
-	} else if (table_name_len == sizeof S_innodb_table_monitor
-		   && !memcmp(table_name, S_innodb_table_monitor,
-			      sizeof S_innodb_table_monitor)) {
+	} else if (STR_EQ(table_name, table_name_len,
+			  S_innodb_table_monitor)) {
 
 		srv_print_innodb_table_monitor = TRUE;
 		os_event_set(srv_lock_timeout_thread_event);
-	} else if (table_name_len == sizeof S_innodb_mem_validate
-		   && !memcmp(table_name, S_innodb_mem_validate,
-			      sizeof S_innodb_mem_validate)) {
+	} else if (STR_EQ(table_name, table_name_len,
+			  S_innodb_mem_validate)) {
 		/* We define here a debugging feature intended for
 		developers */
 
@@ -1963,6 +1963,7 @@ row_create_index_for_mysql(
 	ulint		err;
 	ulint		i, j;
 	ulint		len;
+	char*		table_name;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -1972,6 +1973,11 @@ row_create_index_for_mysql(
 
 	trx->op_info = "creating index";
 
+	/* Copy the table name because we may want to drop the
+	table later, after the index object is freed (inside
+	que_run_threads()) and thus index->table_name is not available. */
+	table_name = mem_strdup(index->table_name);
+
 	trx_start_if_not_started(trx);
 
 	/* Check that the same column does not appear twice in the index.
@@ -2044,13 +2050,15 @@ error_handling:
 
 		trx_general_rollback_for_mysql(trx, FALSE, NULL);
 
-		row_drop_table_for_mysql(index->table_name, trx, FALSE);
+		row_drop_table_for_mysql(table_name, trx, FALSE);
 
 		trx->error_state = DB_SUCCESS;
 	}
 
 	trx->op_info = "";
 
+	mem_free(table_name);
+
 	return((int) err);
 }
 
@@ -3312,6 +3320,66 @@ funct_exit:
 	return((int) err);
 }
 
+/***********************************************************************
+Drop all foreign keys in a database, see Bug#18942.
+Called at the end of row_drop_database_for_mysql(). */
+static
+ulint
+drop_all_foreign_keys_in_db(
+/*========================*/
+				/* out: error code or DB_SUCCESS */
+	const char*	name,	/* in: database name which ends to '/' */
+	trx_t*		trx)	/* in: transaction handle */
+{
+	pars_info_t*	pinfo;
+	ulint		err;
+
+	ut_a(name[strlen(name) - 1] == '/');
+
+	pinfo = pars_info_create();
+
+	pars_info_add_str_literal(pinfo, "dbname", name);
+
+/* true if for_name is not prefixed with dbname */
+#define TABLE_NOT_IN_THIS_DB \
+"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname"
+
+	err = que_eval_sql(pinfo,
+			   "PROCEDURE DROP_ALL_FOREIGN_KEYS_PROC () IS\n"
+			   "foreign_id CHAR;\n"
+			   "for_name CHAR;\n"
+			   "found INT;\n"
+			   "DECLARE CURSOR cur IS\n"
+			   "SELECT ID, FOR_NAME FROM SYS_FOREIGN\n"
+			   "WHERE FOR_NAME >= :dbname\n"
+			   "LOCK IN SHARE MODE\n"
+			   "ORDER BY FOR_NAME;\n"
+			   "BEGIN\n"
+			   "found := 1;\n"
+			   "OPEN cur;\n"
+			   "WHILE found = 1 LOOP\n"
+			   "        FETCH cur INTO foreign_id, for_name;\n"
+			   "        IF (SQL % NOTFOUND) THEN\n"
+			   "                found := 0;\n"
+			   "        ELSIF (" TABLE_NOT_IN_THIS_DB ") THEN\n"
+			   "                found := 0;\n"
+			   "        ELSIF (1=1) THEN\n"
+			   "                DELETE FROM SYS_FOREIGN_COLS\n"
+			   "                WHERE ID = foreign_id;\n"
+			   "                DELETE FROM SYS_FOREIGN\n"
+			   "                WHERE ID = foreign_id;\n"
+			   "        END IF;\n"
+			   "END LOOP;\n"
+			   "CLOSE cur;\n"
+			   "COMMIT WORK;\n"
+			   "END;\n",
+			   FALSE, /* do not reserve dict mutex,
+				  we are already holding it */
+			   trx);
+
+	return(err);
+}
+
 /*************************************************************************
 Drops a database for MySQL. */
 
@@ -3382,6 +3450,19 @@ loop:
 		}
 	}
 
+	if (err == DB_SUCCESS) {
+		/* after dropping all tables try to drop all leftover
+		foreign keys in case orphaned ones exist */
+		err = (int) drop_all_foreign_keys_in_db(name, trx);
+
+		if (err != DB_SUCCESS) {
+			fputs("InnoDB: DROP DATABASE ", stderr);
+			ut_print_name(stderr, trx, TRUE, name);
+			fprintf(stderr, " failed with error %d while "
+				"dropping all foreign keys", err);
+		}
+	}
+
 	trx_commit_for_mysql(trx);
 
 	row_mysql_unlock_data_dictionary(trx);
@@ -4057,3 +4138,33 @@ row_check_table_for_mysql(
 
 	return(ret);
 }
+
+/*************************************************************************
+Determines if a table is a magic monitor table. */
+
+ibool
+row_is_magic_monitor_table(
+/*=======================*/
+					/* out: TRUE if monitor table */
+	const char*	table_name)	/* in: name of the table, in the
+					form database/table_name */
+{
+	const char*	name; /* table_name without database/ */
+	ulint		len;
+
+	name = strchr(table_name, '/');
+	ut_a(name != NULL);
+	name++;
+	len = strlen(name) + 1;
+
+	if (STR_EQ(name, len, S_innodb_monitor)
+	    || STR_EQ(name, len, S_innodb_lock_monitor)
+	    || STR_EQ(name, len, S_innodb_tablespace_monitor)
+	    || STR_EQ(name, len, S_innodb_table_monitor)
+	    || STR_EQ(name, len, S_innodb_mem_validate)) {
+
+		return(TRUE);
+	}
+
+	return(FALSE);
+}

=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/row/row0sel.c	2008-06-12 00:08:07 +0000
@@ -2645,6 +2645,25 @@ row_sel_store_mysql_rec(
 
 			data = rec_get_nth_field(rec, offsets,
 						 templ->rec_field_no, &len);
+
+			if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
+			    && len != UNIV_SQL_NULL) {
+
+				/* It is a BLOB field locally stored in the
+				InnoDB record: we MUST copy its contents to
+				prebuilt->blob_heap here because later code
+				assumes all BLOB values have been copied to a
+				safe place. */
+
+				if (prebuilt->blob_heap == NULL) {
+					prebuilt->blob_heap = mem_heap_create(
+						UNIV_PAGE_SIZE);
+				}
+
+				data = memcpy(mem_heap_alloc(
+						prebuilt->blob_heap, len),
+						data, len);
+			}
 		}
 
 		if (len != UNIV_SQL_NULL) {
@@ -3583,7 +3602,9 @@ shortcut_fails_too_big_rec:
 
 	if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
 	    && prebuilt->select_lock_type != LOCK_NONE
-	    && trx->mysql_query_str && trx->mysql_thd) {
+	    && trx->mysql_thd != NULL
+	    && trx->mysql_query_str != NULL
+	    && *trx->mysql_query_str != NULL) {
 
 		/* Scan the MySQL query string; check if SELECT is the first
 		word there */
@@ -4582,7 +4603,7 @@ row_search_check_if_query_cache_permitte
 Read the AUTOINC column from the current row. If the value is less than
 0 and the type is not unsigned then we reset the value to 0. */
 static
-ib_longlong
+ib_ulonglong
 row_search_autoinc_read_column(
 /*===========================*/
 					/* out: value read from the column */
@@ -4593,10 +4614,8 @@ row_search_autoinc_read_column(
 {
 	ulint		len;
 	const byte*	data;
-	ib_longlong	value;
+	ib_ulonglong	value;
 	mem_heap_t*	heap = NULL;
-	/* Our requirement is that dest should be word aligned. */
-	byte		dest[sizeof(value)];
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 	ulint*		offsets	= offsets_;
 
@@ -4614,41 +4633,14 @@ row_search_autoinc_read_column(
 	ut_a(len != UNIV_SQL_NULL);
 	ut_a(len <= sizeof value);
 
-	mach_read_int_type(dest, data, len, unsigned_type);
-
-	/* The assumption here is that the AUTOINC value can't be negative
-	and that dest is word aligned. */
-	switch (len) {
-	case 8:
-		value = *(ib_longlong*) dest;
-		break;
-
-	case 4:
-		value = *(ib_uint32_t*) dest;
-		break;
-
-	case 3:
-		value = *(ib_uint32_t*) dest;
-		value &= 0xFFFFFF;
-		break;
-
-	case 2:
-		value = *(uint16 *) dest;
-		break;
-
-	case 1:
-		value = *dest;
-		break;
-
-	default:
-		ut_error;
-	}
+	value = mach_read_int_type(data, len, unsigned_type);
 
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
-	if (!unsigned_type && value < 0) {
+	/* We assume that the autoinc counter can't be negative. */
+	if (!unsigned_type && (ib_longlong) value < 0) {
 		value = 0;
 	}
 
@@ -4687,7 +4679,7 @@ row_search_max_autoinc(
 					column name can't be found in index */
 	dict_index_t*	index,		/* in: index to search */
 	const char*	col_name,	/* in: name of autoinc column */
-	ib_longlong*	value)		/* out: AUTOINC value read */
+	ib_ulonglong*	value)		/* out: AUTOINC value read */
 {
 	ulint		i;
 	ulint		n_cols;

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/srv/srv0srv.c	2008-06-12 00:08:07 +0000
@@ -192,7 +192,7 @@ a heavier load on the I/O sub system. */
 ulong	srv_insert_buffer_batch_size = 20;
 
 char*	srv_file_flush_method_str = NULL;
-ulint	srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
+ulint	srv_unix_file_flush_method = SRV_UNIX_FSYNC;
 ulint	srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 
 ulint	srv_max_n_open_files	  = 300;
@@ -1453,8 +1453,11 @@ srv_suspend_mysql_thread(
 		srv_n_lock_wait_count++;
 		srv_n_lock_wait_current_count++;
 
-		ut_usectime(&sec, &ms);
-		start_time = (ib_longlong)sec * 1000000 + ms;
+		if (ut_usectime(&sec, &ms) == -1) {
+			start_time = -1;
+		} else {
+			start_time = (ib_longlong)sec * 1000000 + ms;
+		}
 	}
 	/* Wake the lock timeout monitor thread, if it is suspended */
 
@@ -1508,14 +1511,20 @@ srv_suspend_mysql_thread(
 	wait_time = ut_difftime(ut_time(), slot->suspend_time);
 
 	if (thr->lock_state == QUE_THR_LOCK_ROW) {
-		ut_usectime(&sec, &ms);
-		finish_time = (ib_longlong)sec * 1000000 + ms;
+		if (ut_usectime(&sec, &ms) == -1) {
+			finish_time = -1;
+		} else {
+			finish_time = (ib_longlong)sec * 1000000 + ms;
+		}
 
 		diff_time = (ulint) (finish_time - start_time);
 
 		srv_n_lock_wait_current_count--;
 		srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
-		if (diff_time > srv_n_lock_max_wait_time) {
+		if (diff_time > srv_n_lock_max_wait_time &&
+		    /* only update the variable if we successfully
+		    retrieved the start and finish times. See Bug#36819. */
+		    start_time != -1 && finish_time != -1) {
 			srv_n_lock_max_wait_time = diff_time;
 		}
 	}
@@ -1825,8 +1834,10 @@ srv_export_innodb_status(void)
 		= UT_LIST_GET_LEN(buf_pool->flush_list);
 	export_vars.innodb_buffer_pool_pages_free
 		= UT_LIST_GET_LEN(buf_pool->free);
+#ifdef UNIV_DEBUG
 	export_vars.innodb_buffer_pool_pages_latched
 		= buf_get_latched_pages_number();
+#endif /* UNIV_DEBUG */
 	export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
 
 	export_vars.innodb_buffer_pool_pages_misc = buf_pool->max_size
@@ -1904,12 +1915,6 @@ loop:
 
 	os_thread_sleep(1000000);
 
-	/* In case mutex_exit is not a memory barrier, it is
-	theoretically possible some threads are left waiting though
-	the semaphore is already released. Wake up those threads: */
-
-	sync_arr_wake_threads_if_sema_free();
-
 	current_time = time(NULL);
 
 	time_elapsed = difftime(current_time, last_monitor_time);
@@ -2106,9 +2111,15 @@ loop:
 		srv_refresh_innodb_monitor_stats();
 	}
 
+	/* In case mutex_exit is not a memory barrier, it is
+	theoretically possible some threads are left waiting though
+	the semaphore is already released. Wake up those threads: */
+	
+	sync_arr_wake_threads_if_sema_free();
+
 	if (sync_array_print_long_waits()) {
 		fatal_cnt++;
-		if (fatal_cnt > 5) {
+		if (fatal_cnt > 10) {
 
 			fprintf(stderr,
 				"InnoDB: Error: semaphore wait has lasted"
@@ -2128,7 +2139,7 @@ loop:
 
 	fflush(stderr);
 
-	os_thread_sleep(2000000);
+	os_thread_sleep(1000000);
 
 	if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
 

=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c	2008-03-31 09:37:03 +0000
+++ b/storage/innobase/srv/srv0start.c	2008-06-12 00:08:07 +0000
@@ -202,13 +202,13 @@ srv_parse_data_file_paths_and_sizes(
 
 		str = srv_parse_megabytes(str, &size);
 
-		if (0 == memcmp(str, ":autoextend",
-				(sizeof ":autoextend") - 1)) {
+		if (0 == strncmp(str, ":autoextend",
+				 (sizeof ":autoextend") - 1)) {
 
 			str += (sizeof ":autoextend") - 1;
 
-			if (0 == memcmp(str, ":max:",
-					(sizeof ":max:") - 1)) {
+			if (0 == strncmp(str, ":max:",
+					 (sizeof ":max:") - 1)) {
 
 				str += (sizeof ":max:") - 1;
 
@@ -290,14 +290,15 @@ srv_parse_data_file_paths_and_sizes(
 		(*data_file_names)[i] = path;
 		(*data_file_sizes)[i] = size;
 
-		if (0 == memcmp(str, ":autoextend",
-				(sizeof ":autoextend") - 1)) {
+		if (0 == strncmp(str, ":autoextend",
+				 (sizeof ":autoextend") - 1)) {
 
 			*is_auto_extending = TRUE;
 
 			str += (sizeof ":autoextend") - 1;
 
-			if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
+			if (0 == strncmp(str, ":max:",
+					 (sizeof ":max:") - 1)) {
 
 				str += (sizeof ":max:") - 1;
 
@@ -1122,12 +1123,12 @@ innobase_start_or_create_for_mysql(void)
 	if (srv_file_flush_method_str == NULL) {
 		/* These are the default options */
 
-		srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
+		srv_unix_file_flush_method = SRV_UNIX_FSYNC;
 
 		srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 #ifndef __WIN__
-	} else if (0 == ut_strcmp(srv_file_flush_method_str, "fdatasync")) {
-		srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
+	} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
+		srv_unix_file_flush_method = SRV_UNIX_FSYNC;
 
 	} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
 		srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;

=== modified file 'storage/innobase/sync/sync0arr.c'
--- a/storage/innobase/sync/sync0arr.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/sync/sync0arr.c	2008-06-12 00:08:07 +0000
@@ -40,24 +40,23 @@ because we can do with a very small numb
 say 200. In NT 3.51, allocating events seems to be a quadratic
 algorithm, because 10 000 events are created fast, but
 100 000 events takes a couple of minutes to create.
-*/
+
+As of 5.0.30 the above mentioned design is changed. Since now
+OS can handle millions of wait events efficiently, we no longer
+have this concept of each cell of wait array having one event.
+Instead, now the event that a thread wants to wait on is embedded
+in the wait object (mutex or rw_lock). We still keep the global
+wait array for the sake of diagnostics and also to avoid infinite
+wait The error_monitor thread scans the global wait array to signal
+any waiting threads who have missed the signal. */
 
 /* A cell where an individual thread may wait suspended
 until a resource is released. The suspending is implemented
 using an operating system event semaphore. */
 struct sync_cell_struct {
-	/* State of the cell. SC_WAKING_UP means
-	sync_array_struct->n_reserved has been decremented, but the thread
-	in this cell has not waken up yet. When it does, it will set the
-	state to SC_FREE. Note that this is done without the protection of
-	any mutex. */
-	enum { SC_FREE, SC_RESERVED, SC_WAKING_UP } state;
-
 	void*		wait_object;	/* pointer to the object the
-					thread is waiting for; this is not
-					reseted to NULL when a cell is
-					freed. */
-
+					thread is waiting for; if NULL
+					the cell is free for use */
 	mutex_t*	old_wait_mutex;	/* the latest wait mutex in cell */
 	rw_lock_t*	old_wait_rw_lock;/* the latest wait rw-lock in cell */
 	ulint		request_type;	/* lock type requested on the
@@ -71,13 +70,23 @@ struct sync_cell_struct {
 	ibool		waiting;	/* TRUE if the thread has already
 					called sync_array_event_wait
 					on this cell */
-	ibool		event_set;	/* TRUE if the event is set */
-	os_event_t	event;		/* operating system event
-					semaphore handle */
+	ib_longlong	signal_count;	/* We capture the signal_count
+					of the wait_object when we
+					reset the event. This value is
+					then passed on to os_event_wait
+					and we wait only if the event
+					has not been signalled in the
+					period between the reset and
+					wait call. */
 	time_t		reservation_time;/* time when the thread reserved
 					the wait cell */
 };
 
+/* NOTE: It is allowed for a thread to wait
+for an event allocated for the array without owning the
+protecting mutex (depending on the case: OS or database mutex), but
+all changes (set or reset) to the state of the event must be made
+while owning the mutex. */
 struct sync_array_struct {
 	ulint		n_reserved;	/* number of currently reserved
 					cells in the wait array */
@@ -220,12 +229,9 @@ sync_array_create(
 
 	for (i = 0; i < n_cells; i++) {
 		cell = sync_array_get_nth_cell(arr, i);
-		cell->state = SC_FREE;
-		cell->wait_object = NULL;
-
-		/* Create an operating system event semaphore with no name */
-		cell->event = os_event_create(NULL);
-		cell->event_set = FALSE; /* it is created in reset state */
+	cell->wait_object = NULL;
+		cell->waiting = FALSE;
+		cell->signal_count = 0;
 	}
 
 	return(arr);
@@ -239,19 +245,12 @@ sync_array_free(
 /*============*/
 	sync_array_t*	arr)	/* in, own: sync wait array */
 {
-	ulint		i;
-	sync_cell_t*	cell;
 	ulint		protection;
 
 	ut_a(arr->n_reserved == 0);
 
 	sync_array_validate(arr);
 
-	for (i = 0; i < arr->n_cells; i++) {
-		cell = sync_array_get_nth_cell(arr, i);
-		os_event_free(cell->event);
-	}
-
 	protection = arr->protection;
 
 	/* Release the mutex protecting the wait array complex */
@@ -285,8 +284,7 @@ sync_array_validate(
 
 	for (i = 0; i < arr->n_cells; i++) {
 		cell = sync_array_get_nth_cell(arr, i);
-
-		if (cell->state == SC_RESERVED) {
+		if (cell->wait_object != NULL) {
 			count++;
 		}
 	}
@@ -296,6 +294,29 @@ sync_array_validate(
 	sync_array_exit(arr);
 }
 
+/***********************************************************************
+Puts the cell event in reset state. */
+static
+ib_longlong
+sync_cell_event_reset(
+/*==================*/
+				/* out: value of signal_count
+				at the time of reset. */
+	ulint		type,	/* in: lock type mutex/rw_lock */
+	void*		object) /* in: the rw_lock/mutex object */
+{
+	if (type == SYNC_MUTEX) {
+		return(os_event_reset(((mutex_t *) object)->event));
+#ifdef __WIN__
+	} else if (type == RW_LOCK_WAIT_EX) {
+		return(os_event_reset(
+		       ((rw_lock_t *) object)->wait_ex_event));
+#endif
+	} else {
+		return(os_event_reset(((rw_lock_t *) object)->event));
+	}
+}
+
 /**********************************************************************
 Reserves a wait array cell for waiting for an object.
 The event of the cell is reset to nonsignalled state. */
@@ -324,21 +345,9 @@ sync_array_reserve_cell(
 	for (i = 0; i < arr->n_cells; i++) {
 		cell = sync_array_get_nth_cell(arr, i);
 
-		if (cell->state == SC_FREE) {
-
-			/* We do not check cell->event_set because it is
-			set outside the protection of the sync array mutex
-			and we had a bug regarding it, and since resetting
-			an event when it is not needed does no harm it is
-			safer always to do it. */
-
-			cell->event_set = FALSE;
-			os_event_reset(cell->event);
-
-			cell->state = SC_RESERVED;
-			cell->reservation_time = time(NULL);
-			cell->thread = os_thread_get_curr_id();
+		if (cell->wait_object == NULL) {
 
+			cell->waiting = FALSE;
 			cell->wait_object = object;
 
 			if (type == SYNC_MUTEX) {
@@ -348,7 +357,6 @@ sync_array_reserve_cell(
 			}
 
 			cell->request_type = type;
-			cell->waiting = FALSE;
 
 			cell->file = file;
 			cell->line = line;
@@ -359,6 +367,16 @@ sync_array_reserve_cell(
 
 			sync_array_exit(arr);
 
+			/* Make sure the event is reset and also store
+			the value of signal_count at which the event
+			was reset. */
+			cell->signal_count = sync_cell_event_reset(type,
+								object);
+
+			cell->reservation_time = time(NULL);
+
+			cell->thread = os_thread_get_curr_id();
+
 			return;
 		}
 	}
@@ -369,68 +387,6 @@ sync_array_reserve_cell(
 }
 
 /**********************************************************************
-Frees the cell. Note that we don't have any mutex reserved when calling
-this. */
-static
-void
-sync_array_free_cell(
-/*=================*/
-	sync_array_t*	arr,	/* in: wait array */
-	ulint		index)	/* in: index of the cell in array */
-{
-	sync_cell_t*	cell;
-
-	cell = sync_array_get_nth_cell(arr, index);
-
-	ut_a(cell->state == SC_WAKING_UP);
-	ut_a(cell->wait_object != NULL);
-
-	cell->state = SC_FREE;
-}
-
-/**********************************************************************
-Frees the cell safely by reserving the sync array mutex and decrementing
-n_reserved if necessary. Should only be called from mutex_spin_wait. */
-
-void
-sync_array_free_cell_protected(
-/*===========================*/
-	sync_array_t*	arr,	/* in: wait array */
-	ulint		index)	/* in: index of the cell in array */
-{
-	sync_cell_t*	cell;
-
-	sync_array_enter(arr);
-
-	cell = sync_array_get_nth_cell(arr, index);
-
-	ut_a(cell->state != SC_FREE);
-	ut_a(cell->wait_object != NULL);
-
-	/* We only need to decrement n_reserved if it has not already been
-	done by sync_array_signal_object. */
-	if (cell->state == SC_RESERVED) {
-		ut_a(arr->n_reserved > 0);
-		arr->n_reserved--;
-	} else if (cell->state == SC_WAKING_UP) {
-		/* This is tricky; if we don't wait for the event to be
-		signaled, signal_object can set the state of a cell to
-		SC_WAKING_UP, mutex_spin_wait can call this and set the
-		state to SC_FREE, and then signal_object gets around to
-		calling os_set_event for the cell but since it's already
-		been freed things break horribly. */
-
-		sync_array_exit(arr);
-		os_event_wait(cell->event);
-		sync_array_enter(arr);
-	}
-
-	cell->state = SC_FREE;
-
-	sync_array_exit(arr);
-}
-
-/**********************************************************************
 This function should be called when a thread starts to wait on
 a wait array cell. In the debug version this function checks
 if the wait for a semaphore will result in a deadlock, in which
@@ -447,15 +403,28 @@ sync_array_wait_event(
 
 	ut_a(arr);
 
+	sync_array_enter(arr);
+
 	cell = sync_array_get_nth_cell(arr, index);
 
-	ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
 	ut_a(cell->wait_object);
 	ut_a(!cell->waiting);
 	ut_ad(os_thread_get_curr_id() == cell->thread);
 
-	event = cell->event;
-	cell->waiting = TRUE;
+	if (cell->request_type == SYNC_MUTEX) {
+		event = ((mutex_t*) cell->wait_object)->event;
+#ifdef __WIN__
+	/* On windows if the thread about to wait is the one which
+	has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
+	it waits on a special event i.e.: wait_ex_event. */
+	} else if (cell->request_type == RW_LOCK_WAIT_EX) {
+		event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
+#endif
+	} else {
+		event = ((rw_lock_t*) cell->wait_object)->event;
+	}
+
+		cell->waiting = TRUE;
 
 #ifdef UNIV_SYNC_DEBUG
 
@@ -464,7 +433,6 @@ sync_array_wait_event(
 	recursively sync_array routines, leading to trouble.
 	rw_lock_debug_mutex freezes the debug lists. */
 
-	sync_array_enter(arr);
 	rw_lock_debug_mutex_enter();
 
 	if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
@@ -474,16 +442,16 @@ sync_array_wait_event(
 	}
 
 	rw_lock_debug_mutex_exit();
-	sync_array_exit(arr);
 #endif
-	os_event_wait(event);
+	sync_array_exit(arr);
+
+	os_event_wait_low(event, cell->signal_count);
 
 	sync_array_free_cell(arr, index);
 }
 
 /**********************************************************************
-Reports info of a wait array cell. Note: sync_array_print_long_waits()
-calls this without mutex protection. */
+Reports info of a wait array cell. */
 static
 void
 sync_array_cell_print(
@@ -503,17 +471,8 @@ sync_array_cell_print(
 		(ulong) os_thread_pf(cell->thread), cell->file,
 		(ulong) cell->line,
 		difftime(time(NULL), cell->reservation_time));
-	fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state);
-
-	/* If the memory area pointed to by old_wait_mutex /
-	old_wait_rw_lock has been freed, this can crash. */
-
-	if (cell->state != SC_RESERVED) {
-		/* If cell has this state, then even if we are holding the sync
-		array mutex, the wait object may get freed meanwhile. Do not
-		print the wait object then. */
 
-	} else if (type == SYNC_MUTEX) {
+	if (type == SYNC_MUTEX) {
 		/* We use old_wait_mutex in case the cell has already
 		been freed meanwhile */
 		mutex = cell->old_wait_mutex;
@@ -531,7 +490,11 @@ sync_array_cell_print(
 #endif /* UNIV_SYNC_DEBUG */
 			(ulong) mutex->waiters);
 
-	} else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) {
+	} else if (type == RW_LOCK_EX
+#ifdef __WIN__
+		   || type == RW_LOCK_WAIT_EX
+#endif
+		   || type == RW_LOCK_SHARED) {
 
 		fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
 
@@ -565,8 +528,8 @@ sync_array_cell_print(
 		ut_error;
 	}
 
-	if (cell->event_set) {
-		fputs("wait is ending\n", file);
+	if (!cell->waiting) {
+		fputs("wait has ended\n", file);
 	}
 }
 
@@ -589,7 +552,7 @@ sync_array_find_thread(
 
 		cell = sync_array_get_nth_cell(arr, i);
 
-		if ((cell->state == SC_RESERVED)
+		if (cell->wait_object != NULL
 		    && os_thread_eq(cell->thread, thread)) {
 
 			return(cell);	/* Found */
@@ -679,7 +642,7 @@ sync_array_detect_deadlock(
 
 	depth++;
 
-	if (cell->event_set || !cell->waiting) {
+	if (!cell->waiting) {
 
 		return(FALSE); /* No deadlock here */
 	}
@@ -704,10 +667,8 @@ sync_array_detect_deadlock(
 						       depth);
 			if (ret) {
 				fprintf(stderr,
-					"Mutex %p owned by thread %lu"
-					" file %s line %lu\n",
-					(void*) mutex,
-					(ulong) os_thread_pf(mutex->thread_id),
+			"Mutex %p owned by thread %lu file %s line %lu\n",
+					mutex, (ulong) os_thread_pf(mutex->thread_id),
 					mutex->file_name, (ulong) mutex->line);
 				sync_array_cell_print(stderr, cell);
 
@@ -717,7 +678,8 @@ sync_array_detect_deadlock(
 
 		return(FALSE); /* No deadlock */
 
-	} else if (cell->request_type == RW_LOCK_EX) {
+	} else if (cell->request_type == RW_LOCK_EX
+		   || cell->request_type == RW_LOCK_WAIT_EX) {
 
 		lock = cell->wait_object;
 
@@ -816,7 +778,8 @@ sync_arr_cell_can_wake_up(
 			return(TRUE);
 		}
 
-	} else if (cell->request_type == RW_LOCK_EX) {
+	} else if (cell->request_type == RW_LOCK_EX
+		   || cell->request_type == RW_LOCK_WAIT_EX) {
 
 		lock = cell->wait_object;
 
@@ -845,101 +808,47 @@ sync_arr_cell_can_wake_up(
 	return(FALSE);
 }
 
-/**************************************************************************
-Looks for the cells in the wait array which refer to the wait object
-specified, and sets their corresponding events to the signaled state. In this
-way releases the threads waiting for the object to contend for the object.
-It is possible that no such cell is found, in which case does nothing. */
+/**********************************************************************
+Frees the cell. NOTE! sync_array_wait_event frees the cell
+automatically! */
 
 void
-sync_array_signal_object(
-/*=====================*/
+sync_array_free_cell(
+/*=================*/
 	sync_array_t*	arr,	/* in: wait array */
-	void*		object)	/* in: wait object */
+	ulint		index)  /* in: index of the cell in array */
 {
 	sync_cell_t*	cell;
-	ulint		count;
-	ulint		i;
-	ulint		res_count;
-
-	/* We store the addresses of cells we need to signal and signal
-	them only after we have released the sync array's mutex (for
-	performance reasons). cell_count is the number of such cells, and
-	cell_ptr points to the first one. If there are less than
-	UT_ARR_SIZE(cells) of them, cell_ptr == &cells[0], otherwise
-	cell_ptr points to malloc'd memory that we must free. */
-
-	sync_cell_t*	cells[100];
-	sync_cell_t**	cell_ptr = &cells[0];
-	ulint		cell_count = 0;
-	ulint		cell_max_count = UT_ARR_SIZE(cells);
-
-	ut_a(100 == cell_max_count);
 
 	sync_array_enter(arr);
 
-	arr->sg_count++;
-
-	i = 0;
-	count = 0;
-
-	/* We need to store this to a local variable because it is modified
-	inside the loop */
-	res_count = arr->n_reserved;
-
-	while (count < res_count) {
+	cell = sync_array_get_nth_cell(arr, index);
 
-		cell = sync_array_get_nth_cell(arr, i);
+	ut_a(cell->wait_object != NULL);
 
-		if (cell->state == SC_RESERVED) {
+	cell->waiting = FALSE;
+	cell->wait_object =  NULL;
+	cell->signal_count = 0;
 
-			count++;
-			if (cell->wait_object == object) {
-				cell->state = SC_WAKING_UP;
+	ut_a(arr->n_reserved > 0);
+	arr->n_reserved--;
 
-				ut_a(arr->n_reserved > 0);
-				arr->n_reserved--;
+	sync_array_exit(arr);
+}
 
-				if (cell_count == cell_max_count) {
-					sync_cell_t** old_cell_ptr = cell_ptr;
-					size_t old_size, new_size;
-
-					old_size = cell_max_count
-						* sizeof(sync_cell_t*);
-					cell_max_count *= 2;
-					new_size = cell_max_count
-						* sizeof(sync_cell_t*);
-
-					cell_ptr = malloc(new_size);
-					ut_a(cell_ptr);
-					memcpy(cell_ptr, old_cell_ptr,
-					       old_size);
-
-					if (old_cell_ptr != &cells[0]) {
-						free(old_cell_ptr);
-					}
-				}
+/**************************************************************************
+Increments the signalled count. */
 
-				cell_ptr[cell_count] = cell;
-				cell_count++;
-			}
-		}
+void
+sync_array_object_signalled(
+/*========================*/
+	sync_array_t*	arr)	/* in: wait array */
+{
+	sync_array_enter(arr);
 
-		i++;
-	}
+	arr->sg_count++;
 
 	sync_array_exit(arr);
-
-	for (i = 0; i < cell_count; i++) {
-		cell = cell_ptr[i];
-
-		cell->event_set = TRUE;
-		os_event_set(cell->event);
-	}
-
-	if (cell_ptr != &cells[0]) {
-		free(cell_ptr);
-	}
 }
 
 /**************************************************************************
@@ -959,33 +868,41 @@ sync_arr_wake_threads_if_sema_free(void)
 	sync_cell_t*	cell;
 	ulint		count;
 	ulint		i;
-	ulint		res_count;
 
 	sync_array_enter(arr);
 
 	i = 0;
 	count = 0;
 
-	/* We need to store this to a local variable because it is modified
-	inside the loop */
-
-	res_count = arr->n_reserved;
-
-	while (count < res_count) {
+	while (count < arr->n_reserved) {
 
 		cell = sync_array_get_nth_cell(arr, i);
 
-		if (cell->state == SC_RESERVED) {
+		if (cell->wait_object != NULL) {
 
 			count++;
 
 			if (sync_arr_cell_can_wake_up(cell)) {
-				cell->state = SC_WAKING_UP;
-				cell->event_set = TRUE;
-				os_event_set(cell->event);
 
-				ut_a(arr->n_reserved > 0);
-				arr->n_reserved--;
+				if (cell->request_type == SYNC_MUTEX) {
+					mutex_t*	mutex;
+
+					mutex = cell->wait_object;
+					os_event_set(mutex->event);
+#ifdef __WIN__
+				} else if (cell->request_type
+					   == RW_LOCK_WAIT_EX) {
+					rw_lock_t*	lock;
+
+					lock = cell->wait_object;
+					os_event_set(lock->wait_ex_event);
+#endif
+				} else {
+					rw_lock_t*	lock;
+
+					lock = cell->wait_object;
+					os_event_set(lock->event);
+				}
 			}
 		}
 
@@ -1015,7 +932,7 @@ sync_array_print_long_waits(void)
 
 		cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
 
-		if ((cell->state != SC_FREE)
+		if (cell->wait_object != NULL && cell->waiting
 		    && difftime(time(NULL), cell->reservation_time) > 240) {
 			fputs("InnoDB: Warning: a long semaphore wait:\n",
 			      stderr);
@@ -1023,7 +940,7 @@ sync_array_print_long_waits(void)
 			noticed = TRUE;
 		}
 
-		if ((cell->state != SC_FREE)
+		if (cell->wait_object != NULL && cell->waiting
 		    && difftime(time(NULL), cell->reservation_time)
 		    > fatal_timeout) {
 			fatal = TRUE;
@@ -1072,20 +989,25 @@ sync_array_output_info(
 				mutex */
 {
 	sync_cell_t*	cell;
+	ulint		count;
 	ulint		i;
 
 	fprintf(file,
-		"OS WAIT ARRAY INFO: reservation count %ld,"
-		" signal count %ld\n",
-		(long) arr->res_count,
-		(long) arr->sg_count);
-	for (i = 0; i < arr->n_cells; i++) {
+		"OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
+						(long) arr->res_count, (long) arr->sg_count);
+	i = 0;
+	count = 0;
+
+	while (count < arr->n_reserved) {
 
 		cell = sync_array_get_nth_cell(arr, i);
 
-		if (cell->state != SC_FREE) {
+	if (cell->wait_object != NULL) {
+		count++;
 			sync_array_cell_print(file, cell);
 		}
+
+		i++;
 	}
 }
 

=== modified file 'storage/innobase/sync/sync0rw.c'
--- a/storage/innobase/sync/sync0rw.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/sync/sync0rw.c	2008-06-12 00:08:07 +0000
@@ -151,6 +151,11 @@ rw_lock_create_func(
 	lock->last_x_file_name = "not yet reserved";
 	lock->last_s_line = 0;
 	lock->last_x_line = 0;
+	lock->event = os_event_create(NULL);
+
+#ifdef __WIN__
+	lock->wait_ex_event = os_event_create(NULL);
+#endif
 
 	mutex_enter(&rw_lock_list_mutex);
 
@@ -184,6 +189,11 @@ rw_lock_free(
 	mutex_free(rw_lock_get_mutex(lock));
 
 	mutex_enter(&rw_lock_list_mutex);
+	os_event_free(lock->event);
+
+#ifdef __WIN__
+	os_event_free(lock->wait_ex_event);
+#endif
 
 	if (UT_LIST_GET_PREV(list, lock)) {
 		ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
@@ -544,7 +554,15 @@ lock_loop:
 	rw_x_system_call_count++;
 
 	sync_array_reserve_cell(sync_primary_wait_array,
-				lock, RW_LOCK_EX,
+				lock,
+#ifdef __WIN__
+				/* On windows RW_LOCK_WAIT_EX signifies
+				that this thread should wait on the
+				special wait_ex_event. */
+				(state == RW_LOCK_WAIT_EX)
+				 ? RW_LOCK_WAIT_EX :
+#endif
+				RW_LOCK_EX,
 				file_name, line,
 				&index);
 

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/sync/sync0sync.c	2008-06-12 00:08:07 +0000
@@ -95,17 +95,47 @@ have happened that the thread which was 
 it and did not see the waiters byte set to 1, a case which would lead the
 other thread to an infinite wait.
 
-LEMMA 1: After a thread resets the event of the cell it reserves for waiting
-========
-for a mutex, some thread will eventually call sync_array_signal_object with
-the mutex as an argument. Thus no infinite wait is possible.
+LEMMA 1: After a thread resets the event of a mutex (or rw_lock), some
+=======
+thread will eventually call os_event_set() on that particular event.
+Thus no infinite wait is possible in this case.
 
 Proof:	After making the reservation the thread sets the waiters field in the
 mutex to 1. Then it checks that the mutex is still reserved by some thread,
 or it reserves the mutex for itself. In any case, some thread (which may be
 also some earlier thread, not necessarily the one currently holding the mutex)
 will set the waiters field to 0 in mutex_exit, and then call
-sync_array_signal_object with the mutex as an argument.
+os_event_set() with the mutex as an argument.
+Q.E.D.
+
+LEMMA 2: If an os_event_set() call is made after some thread has called
+=======
+the os_event_reset() and before it starts wait on that event, the call
+will not be lost to the second thread. This is true even if there is an
+intervening call to os_event_reset() by another thread.
+Thus no infinite wait is possible in this case.
+
+Proof (non-windows platforms): os_event_reset() returns a monotonically
+increasing value of signal_count. This value is increased at every
+call of os_event_set() If thread A has called os_event_reset() followed
+by thread B calling os_event_set() and then some other thread C calling
+os_event_reset(), the is_set flag of the event will be set to FALSE;
+but now if thread A calls os_event_wait_low() with the signal_count
+value returned from the earlier call of os_event_reset(), it will
+return immediately without waiting.
+Q.E.D.
+
+Proof (windows): If there is a writer thread which is forced to wait for
+the lock, it may be able to set the state of rw_lock to RW_LOCK_WAIT_EX
+The design of rw_lock ensures that there is one and only one thread
+that is able to change the state to RW_LOCK_WAIT_EX and this thread is
+guaranteed to acquire the lock after it is released by the current
+holders and before any other waiter gets the lock.
+On windows this thread waits on a separate event i.e.: wait_ex_event.
+Since only one thread can wait on this event there is no chance
+of this event getting reset before the writer starts wait on it.
+Therefore, this thread is guaranteed to catch the os_set_event()
+signalled unconditionally at the release of the lock.
 Q.E.D. */
 
 /* The number of system calls made in this module. Intended for performance
@@ -217,6 +247,7 @@ mutex_create_func(
 	os_fast_mutex_init(&(mutex->os_fast_mutex));
 	mutex->lock_word = 0;
 #endif
+	mutex->event = os_event_create(NULL);
 	mutex_set_waiters(mutex, 0);
 #ifdef UNIV_DEBUG
 	mutex->magic_n = MUTEX_MAGIC_N;
@@ -300,6 +331,8 @@ mutex_free(
 		mutex_exit(&mutex_list_mutex);
 	}
 
+	os_event_free(mutex->event);
+
 #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
 	os_fast_mutex_free(&(mutex->os_fast_mutex));
 #endif
@@ -509,8 +542,7 @@ spin_loop:
 		if (mutex_test_and_set(mutex) == 0) {
 			/* Succeeded! Free the reserved wait cell */
 
-			sync_array_free_cell_protected(sync_primary_wait_array,
-						       index);
+			sync_array_free_cell(sync_primary_wait_array, index);
 
 			ut_d(mutex->thread_id = os_thread_get_curr_id());
 #ifdef UNIV_SYNC_DEBUG
@@ -591,8 +623,8 @@ mutex_signal_object(
 
 	/* The memory order of resetting the waiters field and
 	signaling the object is important. See LEMMA 1 above. */
-
-	sync_array_signal_object(sync_primary_wait_array, mutex);
+	os_event_set(mutex->event);
+	sync_array_object_signalled(sync_primary_wait_array);
 }
 
 #ifdef UNIV_SYNC_DEBUG
@@ -1130,6 +1162,7 @@ sync_thread_add_level(
 		break;
 	case SYNC_TREE_NODE:
 		ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
+		     || sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
 		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
 		break;
 	case SYNC_TREE_NODE_NEW:

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	2008-05-15 20:56:38 +0000
+++ b/storage/innobase/trx/trx0trx.c	2008-06-12 00:08:07 +0000
@@ -757,8 +757,8 @@ trx_commit_off_kernel(
 		mutex_enter(&(rseg->mutex));
 
 		if (trx->insert_undo != NULL) {
-			trx_undo_set_state_at_finish(trx, trx->insert_undo,
-						     &mtr);
+			trx_undo_set_state_at_finish(
+				rseg, trx, trx->insert_undo, &mtr);
 		}
 
 		undo = trx->update_undo;
@@ -774,7 +774,7 @@ trx_commit_off_kernel(
 			transaction commit for this transaction. */
 
 			update_hdr_page = trx_undo_set_state_at_finish(
-				trx, undo, &mtr);
+				rseg, trx, undo, &mtr);
 
 			/* We have to do the cleanup for the update log while
 			holding the rseg mutex because update log headers
@@ -933,6 +933,7 @@ trx_commit_off_kernel(
 	trx->rseg = NULL;
 	trx->undo_no = ut_dulint_zero;
 	trx->last_sql_stat_start.least_undo_no = ut_dulint_zero;
+	trx->mysql_query_str = NULL;
 
 	ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
 	ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0);

=== modified file 'storage/innobase/trx/trx0undo.c'
--- a/storage/innobase/trx/trx0undo.c	2008-03-31 09:37:03 +0000
+++ b/storage/innobase/trx/trx0undo.c	2008-06-12 00:08:07 +0000
@@ -1725,6 +1725,7 @@ trx_undo_set_state_at_finish(
 /*=========================*/
 				/* out: undo log segment header page,
 				x-latched */
+	trx_rseg_t*	rseg,	/* in: rollback segment memory object */
 	trx_t*		trx __attribute__((unused)), /* in: transaction */
 	trx_undo_t*	undo,	/* in: undo log memory copy */
 	mtr_t*		mtr)	/* in: mtr */
@@ -1734,7 +1735,10 @@ trx_undo_set_state_at_finish(
 	page_t*		undo_page;
 	ulint		state;
 
-	ut_ad(trx && undo && mtr);
+	ut_ad(trx);
+	ut_ad(undo);
+	ut_ad(mtr);
+	ut_ad(mutex_own(&rseg->mutex));
 
 	if (undo->id >= TRX_RSEG_N_SLOTS) {
 		fprintf(stderr, "InnoDB: Error: undo->id is %lu\n",
@@ -1748,9 +1752,23 @@ trx_undo_set_state_at_finish(
 	seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
 	page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
 
-	if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
-	    < TRX_UNDO_PAGE_REUSE_LIMIT) {
-		state = TRX_UNDO_CACHED;
+	if (undo->size == 1
+	    && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
+	       < TRX_UNDO_PAGE_REUSE_LIMIT) {
+
+		/* This is a heuristic to avoid the problem of all UNDO
+		slots ending up in one of the UNDO lists. Previously if
+		the server crashed with all the slots in one of the lists,
+		transactions that required the slots of a different type
+		would fail for lack of slots. */
+
+		if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
+		    && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
+
+			state = TRX_UNDO_CACHED;
+		} else {
+			state = TRX_UNDO_TO_FREE;
+		}
 
 	} else if (undo->type == TRX_UNDO_INSERT) {
 

=== modified file 'storage/innobase/ut/ut0ut.c'
--- a/storage/innobase/ut/ut0ut.c	2007-11-06 22:42:58 +0000
+++ b/storage/innobase/ut/ut0ut.c	2008-06-12 00:08:07 +0000
@@ -112,19 +112,45 @@ ut_time(void)
 }
 
 /**************************************************************
-Returns system time. */
+Returns system time.
+Upon successful completion, the value 0 is returned; otherwise the
+value -1 is returned and the global variable errno is set to indicate the
+error. */
 
-void
+int
 ut_usectime(
 /*========*/
+			/* out: 0 on success, -1 otherwise */
 	ulint*	sec,	/* out: seconds since the Epoch */
 	ulint*	ms)	/* out: microseconds since the Epoch+*sec */
 {
 	struct timeval	tv;
+	int		ret;
+	int		errno_gettimeofday;
+	int		i;
+
+	for (i = 0; i < 10; i++) {
+
+		ret = ut_gettimeofday(&tv, NULL);
+
+		if (ret == -1) {
+			errno_gettimeofday = errno;
+			ut_print_timestamp(stderr);
+			fprintf(stderr, "  InnoDB: gettimeofday(): %s\n",
+				strerror(errno_gettimeofday));
+			os_thread_sleep(100000);  /* 0.1 sec */
+			errno = errno_gettimeofday;
+		} else {
+			break;
+		}
+	}
+
+	if (ret != -1) {
+		*sec = (ulint) tv.tv_sec;
+		*ms  = (ulint) tv.tv_usec;
+	}
 
-	ut_gettimeofday(&tv, NULL);
-	*sec = (ulint) tv.tv_sec;
-	*ms  = (ulint) tv.tv_usec;
+	return(ret);
 }
 
 /**************************************************************

Thread
bzr commit into mysql-6.0-backup branch (oystein.grovlen:2643) Oystein Grovlen25 Jun