List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:August 28 2008 8:45am
Subject:bzr commit into mysql-6.0 branch (kgeorge:2808)
View as plain text  
#At file:///home/kgeorge/mysql/bzr/merge-6.0-bugteam/

 2808 Georgi Kodinov	2008-08-28 [merge]
      merged 6.0-main -> 6.0-bugteam
added:
  mysql-test/include/wait_for_slave_sql_error_and_skip.inc
  mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
  mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt
  mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test
modified:
  configure.in
  libmysql/CMakeLists.txt
  mysql-test/extra/binlog_tests/database.test
  mysql-test/include/have_falcon.inc
  mysql-test/r/multi_update.result
  mysql-test/suite/binlog/r/binlog_database.result
  mysql-test/suite/falcon/r/falcon_bug_22165.result
  mysql-test/suite/falcon/t/falcon_bug_22165.test
  sql/log_event.cc
  sql/log_event.h
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_db.cc
  sql/sql_parse.cc
  sql/sql_update.cc
  storage/falcon/BackLog.cpp
  storage/falcon/CMakeLists.txt
  storage/falcon/Configuration.cpp
  storage/falcon/IO.cpp
  storage/falcon/Index.cpp
  storage/falcon/Index2RootPage.cpp
  storage/falcon/IndexRootPage.cpp
  storage/falcon/Interlock.h
  storage/falcon/MemMgr.cpp
  storage/falcon/RepositoryVolume.cpp
  storage/falcon/Statement.cpp
  storage/falcon/StorageDatabase.cpp
  storage/falcon/StorageDatabase.h
  storage/falcon/StorageTable.cpp
  storage/falcon/StorageTable.h
  storage/falcon/StorageTableShare.cpp
  storage/falcon/StorageTableShare.h
  storage/falcon/Table.cpp
  storage/falcon/Table.h
  storage/falcon/TableSpace.cpp
  storage/falcon/Transaction.cpp
  storage/falcon/Transaction.h
  storage/falcon/TransactionManager.cpp
  storage/falcon/ha_falcon.cpp
  storage/falcon/ha_falcon.h
  storage/falcon/plug.in
  storage/maria/CMakeLists.txt

=== modified file 'configure.in'
--- a/configure.in	2008-08-26 19:16:28 +0000
+++ b/configure.in	2008-08-28 08:44:13 +0000
@@ -1797,6 +1797,9 @@ if test "x$mysql_cv_gcc_atomic_builtins"
             [Define to 1 if compiler provides atomic builtins.])
 fi
 
+# Check if we have the atomic_* functions on Solaris
+AC_CHECK_FUNC(atomic_cas_32, AC_DEFINE([HAVE_SOLARIS_ATOMIC], [1], [Define to 1 if Solaris support atomic functions.]))
+
 # Force static compilation to avoid linking problems/get more speed
 AC_ARG_WITH(mysqld-ldflags,
     [  --with-mysqld-ldflags   Extra linking arguments for mysqld],

=== modified file 'libmysql/CMakeLists.txt'
--- a/libmysql/CMakeLists.txt	2008-05-29 15:44:11 +0000
+++ b/libmysql/CMakeLists.txt	2008-08-26 18:57:58 +0000
@@ -98,7 +98,7 @@ SET(CLIENT_SOURCES   ../mysys/array.c ..
                      ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c 
                      ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c 
                      ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/mf_qsort.c
-		     ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES})
+		     ../mysys/my_getsystime.c  ${LIB_SOURCES})
 
 # Need to set USE_TLS for building the DLL, since __declspec(thread)
 # approach to thread local storage does not work properly in DLLs.

=== modified file 'mysql-test/extra/binlog_tests/database.test'
--- a/mysql-test/extra/binlog_tests/database.test	2007-11-16 14:55:22 +0000
+++ b/mysql-test/extra/binlog_tests/database.test	2008-08-27 08:40:11 +0000
@@ -13,3 +13,18 @@ create trigger tr1 before insert on t1 f
 create procedure sp1 (a int) insert into t1 values(a);
 drop database testing_1;
 source include/show_binlog_events.inc;
+
+# BUG#38773: DROP DATABASE cause switch to stmt-mode when there are
+# temporary tables open
+
+use test;
+reset master;
+create temporary table tt1 (a int);
+create table t1 (a int);
+insert into t1 values (1);
+disable_warnings;
+drop database if exists mysqltest1;
+enable_warnings;
+insert into t1 values (1);
+drop table tt1, t1;
+source include/show_binlog_events.inc;

=== modified file 'mysql-test/include/have_falcon.inc'
--- a/mysql-test/include/have_falcon.inc	2008-03-30 13:57:32 +0000
+++ b/mysql-test/include/have_falcon.inc	2008-08-15 11:06:08 +0000
@@ -1,5 +1,18 @@
+##
+## Checks for the presence of the Falcon storage engine (plugin)
+## by querying the INFORMATION_SCHEMA.ENGINES table.
+##
+## If Falcon is not available, the test using this include file
+## is skipped.
+##
+
+# Do not echo these statements to test results
 --disable_query_log
-# Ignore errors when trying to install the Falcon plugin
---require r/true.require
-SELECT (support = 'YES' OR support = 'DEFAULT' OR support = 'ENABLED') AS `TRUE` FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'Falcon';
+
+# Check if Falcon is available
+let $have_falcon = `SELECT (support = 'YES' OR support = 'DEFAULT' OR support = 'ENABLED') AS 'HAVE_FALCON' FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'Falcon'`;
+if (!$have_falcon)
+{
+  skip Test needs the Falcon storage engine;
+}
 --enable_query_log

=== added file 'mysql-test/include/wait_for_slave_sql_error_and_skip.inc'
--- a/mysql-test/include/wait_for_slave_sql_error_and_skip.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc	2008-08-26 12:29:33 +0000
@@ -0,0 +1,24 @@
+# ==== Purpose ====
+#
+# Wait for slave SQL error, skip the erroneous statement and restart
+# slave
+#
+# ==== Usage ====
+#
+# let show_sql_error=0|1;
+# source include/wait_for_slave_sql_error_and_skip.inc;
+
+echo --source include/wait_for_slave_sql_error_and_skip.inc;
+connection slave;
+source include/wait_for_slave_sql_error.inc;
+if ($show_sql_error)
+{
+  let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+  echo Last_SQL_Error = $error;
+}
+
+# skip the erroneous statement
+set global sql_slave_skip_counter=1;
+start slave;
+source include/wait_for_slave_to_start.inc;
+connection master;

=== modified file 'mysql-test/r/multi_update.result'
--- a/mysql-test/r/multi_update.result	2008-04-01 15:13:57 +0000
+++ b/mysql-test/r/multi_update.result	2008-08-26 12:29:33 +0000
@@ -627,7 +627,7 @@ a	b
 4	4
 show master status /* there must be the UPDATE query event */;
 File	Position	Binlog_Do_DB	Binlog_Ignore_DB
-master-bin.000001	198		
+master-bin.000001	207		
 delete from t1;
 delete from t2;
 insert into t1 values (1,2),(3,4),(4,4);
@@ -637,7 +637,7 @@ UPDATE t2,t1  SET t2.a=t2.b where t2.a=t
 ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
 show master status /* there must be the UPDATE query event */;
 File	Position	Binlog_Do_DB	Binlog_Ignore_DB
-master-bin.000001	213		
+master-bin.000001	222		
 drop table t1, t2;
 set @@session.binlog_format= @sav_binlog_format;
 drop table if exists t1, t2, t3;

=== modified file 'mysql-test/suite/binlog/r/binlog_database.result'
--- a/mysql-test/suite/binlog/r/binlog_database.result	2008-05-16 15:35:15 +0000
+++ b/mysql-test/suite/binlog/r/binlog_database.result	2008-08-27 08:40:11 +0000
@@ -17,6 +17,22 @@ master-bin.000001	#	Query	#	#	use `testi
 master-bin.000001	#	Query	#	#	use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int)
 insert into t1 values(a)
 master-bin.000001	#	Query	#	#	drop database testing_1
+use test;
+reset master;
+create temporary table tt1 (a int);
+create table t1 (a int);
+insert into t1 values (1);
+drop database if exists mysqltest1;
+insert into t1 values (1);
+drop table tt1, t1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create temporary table tt1 (a int)
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int)
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values (1)
+master-bin.000001	#	Query	#	#	drop database if exists mysqltest1
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values (1)
+master-bin.000001	#	Query	#	#	use `test`; drop table tt1, t1
 set binlog_format=mixed;
 reset master;
 create database testing_1;
@@ -36,6 +52,22 @@ master-bin.000001	#	Query	#	#	use `testi
 master-bin.000001	#	Query	#	#	use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int)
 insert into t1 values(a)
 master-bin.000001	#	Query	#	#	drop database testing_1
+use test;
+reset master;
+create temporary table tt1 (a int);
+create table t1 (a int);
+insert into t1 values (1);
+drop database if exists mysqltest1;
+insert into t1 values (1);
+drop table tt1, t1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create temporary table tt1 (a int)
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int)
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values (1)
+master-bin.000001	#	Query	#	#	drop database if exists mysqltest1
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values (1)
+master-bin.000001	#	Query	#	#	use `test`; drop table tt1, t1
 set binlog_format=row;
 reset master;
 create database testing_1;
@@ -55,6 +87,27 @@ master-bin.000001	#	Query	#	#	use `testi
 master-bin.000001	#	Query	#	#	use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int)
 insert into t1 values(a)
 master-bin.000001	#	Query	#	#	drop database testing_1
+use test;
+reset master;
+create temporary table tt1 (a int);
+create table t1 (a int);
+insert into t1 values (1);
+drop database if exists mysqltest1;
+insert into t1 values (1);
+drop table tt1, t1;
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int)
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	use `test`; COMMIT
+master-bin.000001	#	Query	#	#	drop database if exists mysqltest1
+master-bin.000001	#	Query	#	#	use `test`; BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	use `test`; COMMIT
+master-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
 show databases;
 Database
 information_schema

=== modified file 'mysql-test/suite/falcon/r/falcon_bug_22165.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_22165.result	2008-08-04 15:53:52 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_22165.result	2008-08-21 13:18:06 +0000
@@ -16,7 +16,10 @@ while v < 10 do
 START TRANSACTION;
 INSERT INTO t1 (a, b) VALUES (v, 'a');
 UPDATE t1 SET c = current_timestamp WHERE a = v;
-COMMIT;
+IF (v < 5)  
+THEN COMMIT;
+ELSE ROLLBACK; 
+END IF;
 SET v = v + 1;
 end while;
 end//

=== modified file 'mysql-test/suite/falcon/t/falcon_bug_22165.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_22165.test	2008-08-04 15:53:52 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_22165.test	2008-08-21 13:18:06 +0000
@@ -30,7 +30,10 @@ begin
     START TRANSACTION;
     INSERT INTO t1 (a, b) VALUES (v, 'a');
     UPDATE t1 SET c = current_timestamp WHERE a = v;
-    COMMIT;
+	IF (v < 5)  
+	  	THEN COMMIT;
+	  	ELSE ROLLBACK; 
+ 	END IF;
     SET v = v + 1;
   end while;
 end//
@@ -57,7 +60,7 @@ while ($i)
   --reap
   connection conn2;
   --reap
-  
+
   dec $i;
 }
 --enable_query_log

=== added file 'mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result'
--- a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	2008-08-26 12:29:33 +0000
@@ -0,0 +1,151 @@
+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, a int);
+CREATE TABLE t2 (id int, b int);
+CREATE TABLE t3 (id int, c int);
+CREATE TABLE t4 (id int, d int);
+CREATE TABLE t5 (id int, e int);
+CREATE TABLE t6 (id int, f int);
+CREATE TABLE t7 (id int, g int);
+CREATE TABLE t8 (id int, h int);
+CREATE TABLE t9 (id int, i int);
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t3 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3);
+[on slave]
+SHOW TABLES LIKE 't%';
+Tables_in_test (t%)
+t1
+t2
+t3
+[on master]
+UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1;
+UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1;
+UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1;
+UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1;
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1;
+UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1;
+UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1;
+UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1;
+UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1;
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t4' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1;
+--source include/wait_for_slave_sql_error_and_skip.inc
+Last_SQL_Error = Error 'Table 'test.t7' doesn't exist' on query. Default database: 'test'. Query: 'UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1'
+set global sql_slave_skip_counter=1;
+start slave;
+[on slave]
+show tables like 't%';
+Tables_in_test (t%)
+t1
+t2
+t3
+SELECT * FROM t1;
+id	a
+1	1
+2	2
+3	3
+SELECT * FROM t2;
+id	b
+1	1
+2	2
+3	3
+SELECT * FROM t3;
+id	c
+1	1
+2	2
+3	3
+[on master]
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;

=== added file 'mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt	2008-08-26 12:29:33 +0000
@@ -0,0 +1 @@
+--replicate-do-table=test.t1 --replicate-do-table=test.t2 --replicate-do-table=test.t3 --replicate-ignore-table=test.t4 --replicate-ignore-table=test.t5 --replicate-ignore-table=test.t6

=== added file 'mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test'
--- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test	2008-08-26 12:29:33 +0000
@@ -0,0 +1,205 @@
+# Test evaluation of replication table filter rules
+#
+# ==== Purpose ====
+#
+# Test if replication table filter rules are properly evaluated when
+# some of the tables referenced by the multiple-table update do not
+# exist on slave.
+#
+# ==== Method ====
+#
+# Master creates tables t1, t2, t3, t4, t5, t6, t7, t8, t9 and the
+# slave is started with the following replication table filter rules:
+#
+# --replicate-do-table=t1
+# --replicate-do-table=t2
+# --replicate-do-table=t3
+#
+# and
+#
+# --replicate-ignore-table=t4
+# --replicate-ignore-table=t5
+# --replicate-ignore-table=t6
+#
+# So the slave only replicate changes to tables t1, t2 and t3 and only
+# these tables exist on slave.
+#
+# From now on, tables t1, t2, and t3 are referenced as do tables,
+# tables t4, t5, t6 are referenced as ignore tables, and tables t7,
+# t8, t9 are referenced as other tables.
+#
+# All multi-table update tests reference tables that are not do
+# tables, which do not exist on slave. And the following situations
+# of multi-table update will be tested:
+#
+# 1. Do tables are not referenced at all
+# 2. Do tables are not referenced for update
+# 3. Ignore tables are referenced for update before do tables
+# 4. Only do tables are referenced for update
+# 5. Do tables and other tables are referenced for update
+# 6. Do tables are referenced for update before ignore tables
+#
+# For 1, 2 and 3, the statement should be ignored by slave, for 4, 5
+# and 6 the statement should be accepted by slave and cause an error
+# because of non-exist tables.
+#
+# ==== Related bugs ====
+#
+# BUG#37051 Replication rules not evaluated correctly
+
+
+source include/have_binlog_format_statement.inc;
+source include/master-slave.inc;
+
+# These tables are mentioned in do-table rules
+CREATE TABLE t1 (id int, a int);
+CREATE TABLE t2 (id int, b int);
+CREATE TABLE t3 (id int, c int);
+
+# These tables are mentioned in ignore-table rules
+CREATE TABLE t4 (id int, d int);
+CREATE TABLE t5 (id int, e int);
+CREATE TABLE t6 (id int, f int);
+
+# These tables are not mentioned in do-table or ignore-table rules
+CREATE TABLE t7 (id int, g int);
+CREATE TABLE t8 (id int, h int);
+CREATE TABLE t9 (id int, i int);
+
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t3 VALUES (1, 1), (2, 2), (3, 3);
+
+INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3);
+
+INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3);
+
+# Only t1, t2, t3 should be replicated to slave
+sync_slave_with_master;
+echo [on slave];
+SHOW TABLES LIKE 't%';
+
+connection master;
+echo [on master];
+
+#
+# Do tables are not referenced, these statements should be ignored by
+# slave.
+#
+UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1;
+UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1;
+UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1;
+UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1;
+
+#
+# Do tables are not referenced for update, these statements should be
+# ignored by slave.
+#
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1;
+UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1;
+UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1;
+
+#
+# Ignore tables are referenced for update before do tables, these
+# statements should be ignore by slave.
+#
+UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1;
+UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1;
+UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1;
+UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1;
+
+# Sync slave to make sure all above statements are correctly ignored,
+# if any of the above statement are not ignored, it would cause error
+# and stop slave sql thread.
+sync_slave_with_master;
+connection master;
+
+# Parameter for include/wait_for_slave_sql_error_and_skip.inc, ask it
+# to show SQL error message
+let show_sql_error=1;
+
+#
+# Only do tables are referenced for update, these statements should
+# cause error on slave
+#
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+#
+# Do tables and other tables are referenced for update, these
+# statements should cause error on slave
+#
+UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+#
+# Do tables are referenced for update before ignore tables
+#
+UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1;
+source include/wait_for_slave_sql_error_and_skip.inc;
+
+sync_slave_with_master;
+echo [on slave];
+
+# We should only have tables t1, t2, t3 on slave
+show tables like 't%';
+
+# The rows in these tables should remain untouched
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+
+# Clean up
+connection master;
+echo [on master];
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+source include/master-slave-end.inc;

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2008-08-25 08:12:02 +0000
+++ b/sql/log_event.cc	2008-08-27 18:54:03 +0000
@@ -2050,6 +2050,11 @@ void Query_log_event::pack_info(Protocol
 static void write_str_with_code_and_len(char **dst, const char *src,
                                         int len, uint code)
 {
+  /*
+    only 1 byte to store the length of catalog, so it should not
+    surpass 255
+  */
+  DBUG_ASSERT(len <= 255);
   DBUG_ASSERT(src);
   *((*dst)++)= code;
   *((*dst)++)= (uchar) len;
@@ -2069,21 +2074,8 @@ static void write_str_with_code_and_len(
 
 bool Query_log_event::write(IO_CACHE* file)
 {
-  /**
-    @todo if catalog can be of length FN_REFLEN==512, then we are not
-    replicating it correctly, since the length is stored in a byte
-    /sven
-  */
-  uchar buf[QUERY_HEADER_LEN+
-            1+4+           // code of flags2 and flags2
-            1+8+           // code of sql_mode and sql_mode
-            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
-            1+4+           // code of autoinc and the 2 autoinc variables
-            1+6+           // code of charset and charset
-            1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
-            1+2+           // code of lc_time_names and lc_time_names_number
-            1+2            // code of charset_database and charset_database_number
-            ], *start, *start_of_status;
+  uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
+  uchar *start, *start_of_status;
   ulong event_length;
 
   if (!query)
@@ -2189,10 +2181,8 @@ bool Query_log_event::write(IO_CACHE* fi
   {
     /* In the TZ sys table, column Name is of length 64 so this should be ok */
     DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
-    *start++= Q_TIME_ZONE_CODE;
-    *start++= time_zone_len;
-    memcpy(start, time_zone_str, time_zone_len);
-    start+= time_zone_len;
+    write_str_with_code_and_len((char **)(&start),
+                                time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
   }
   if (lc_time_names_number)
   {
@@ -2208,7 +2198,17 @@ bool Query_log_event::write(IO_CACHE* fi
     int2store(start, charset_database_number);
     start+= 2;
   }
+  if (table_map_for_update)
+  {
+    *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
+    int8store(start, table_map_for_update);
+    start+= 8;
+  }
   /*
+    NOTE: When adding new status vars, please don't forget to update
+    the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update function
+    code_name in this file.
+   
     Here there could be code like
     if (command-line-option-which-says-"log_this_variable" && inited)
     {
@@ -2285,7 +2285,8 @@ Query_log_event::Query_log_event(THD* th
    auto_increment_increment(thd_arg->variables.auto_increment_increment),
    auto_increment_offset(thd_arg->variables.auto_increment_offset),
    lc_time_names_number(thd_arg->variables.lc_time_names->number),
-   charset_database_number(0)
+   charset_database_number(0),
+   table_map_for_update((ulonglong)thd_arg->table_map_for_update)
 {
   time_t end_time;
 
@@ -2414,6 +2415,7 @@ code_name(int code)
   case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
   case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
   case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
+  case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
   }
   sprintf(buf, "CODE#%d", code);
   return buf;
@@ -2450,7 +2452,8 @@ Query_log_event::Query_log_event(const c
    db(NullS), catalog_len(0), status_vars_len(0),
    flags2_inited(0), sql_mode_inited(0), charset_inited(0),
    auto_increment_increment(1), auto_increment_offset(1),
-   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
+   time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
+   table_map_for_update(0)
 {
   ulong data_len;
   uint32 tmp;
@@ -2592,6 +2595,11 @@ Query_log_event::Query_log_event(const c
       charset_database_number= uint2korr(pos);
       pos+= 2;
       break;
+    case Q_TABLE_MAP_FOR_UPDATE_CODE:
+      CHECK_SPACE(pos, end, 8);
+      table_map_for_update= uint8korr(pos);
+      pos+= 8;
+      break;
     default:
       /* That's why you must write status vars in growing order of code */
       DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
@@ -2999,6 +3007,8 @@ int Query_log_event::do_apply_event(Rela
       else
         thd->variables.collation_database= thd->db_charset;
       
+      thd->table_map_for_update= (table_map)table_map_for_update;
+      
       /* Execute the query (note that we bypass dispatch_command()) */
       const char* found_semicolon= NULL;
       mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2008-08-22 06:48:55 +0000
+++ b/sql/log_event.h	2008-08-27 18:54:03 +0000
@@ -246,12 +246,15 @@ struct sql_ex_info
   packet (i.e. a query) sent from client to master;
   First, an auxiliary log_event status vars estimation:
 */
-#define MAX_SIZE_LOG_EVENT_STATUS (4 /* flags2 */   + \
-                                   8 /* sql mode */ + \
-                                   1 + 1 + 255 /* catalog */ + \
-                                   4 /* autoinc */ + \
-                                   6 /* charset */ + \
-                                   MAX_TIME_ZONE_NAME_LENGTH)
+#define MAX_SIZE_LOG_EVENT_STATUS (1 + 4          /* type, flags2 */   + \
+                                   1 + 8          /* type, sql_mode */ + \
+                                   1 + 1 + 255    /* type, length, catalog */ + \
+                                   1 + 4          /* type, auto_increment */ + \
+                                   1 + 6          /* type, charset */ + \
+                                   1 + 1 + 255    /* type, length, time_zone */ + \
+                                   1 + 2          /* type, lc_time_names_number */ + \
+                                   1 + 2          /* type, charset_database_number */ + \
+                                   1 + 8          /* type, table_map_for_update */)
 #define MAX_LOG_EVENT_HEADER   ( /* in order of Query_log_event::write */ \
   LOG_EVENT_HEADER_LEN + /* write_header */ \
   QUERY_HEADER_LEN     + /* write_data */   \
@@ -315,6 +318,8 @@ struct sql_ex_info
 #define Q_LC_TIME_NAMES_CODE    7
 
 #define Q_CHARSET_DATABASE_CODE 8
+
+#define Q_TABLE_MAP_FOR_UPDATE_CODE 9
 /* Intvar event post-header */
 
 #define I_TYPE_OFFSET        0
@@ -1490,6 +1495,22 @@ protected:
     This field is written if it is not 0.
     </td>
   </tr>
+  <tr>
+    <td>table_map_for_update</td>
+    <td>Q_TABLE_MAP_FOR_UPDATE_CODE == 9</td>
+    <td>8 byte integer</td>
+
+    <td>The value of the table map that is to be updated by the
+    multi-table update query statement. Every bit of this variable
+    represents a table, and is set to 1 if the corresponding table is
+    to be updated by this statement.
+
+    The value of this variable is set when executing a multi-table update
+    statement and used by slave to apply filter rules without opening
+    all the tables on slave. This is required because some tables may
+    not exist on slave because of the filter rules.
+    </td>
+  </tr>
   </table>
 
   @subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions
@@ -1506,6 +1527,9 @@ protected:
 
   * See Q_CHARSET_DATABASE_CODE in the table above.
 
+  * When adding new status vars, please don't forget to update the
+  MAX_SIZE_LOG_EVENT_STATUS, and update function code_name
+
 */
 class Query_log_event: public Log_event
 {
@@ -1583,6 +1607,11 @@ public:
   const char *time_zone_str;
   uint lc_time_names_number; /* 0 means en_US */
   uint charset_database_number;
+  /*
+    map for tables that will be updated for a multi-table update query
+    statement, for other query statements, this will be zero.
+  */
+  ulonglong table_map_for_update;
 
 #ifndef MYSQL_CLIENT
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-08-26 19:16:28 +0000
+++ b/sql/sql_class.cc	2008-08-28 08:44:13 +0000
@@ -513,6 +513,7 @@ THD::THD()
    lock_id(&main_lock_id),
    user_time(0), in_sub_stmt(0),
    binlog_table_maps(0), binlog_flags(0UL),
+   table_map_for_update(0),
    arg_of_last_insert_id_function(FALSE),
    first_successful_insert_id_in_prev_stmt(0),
    first_successful_insert_id_in_prev_stmt_for_binlog(0),
@@ -1156,6 +1157,8 @@ void THD::cleanup_after_query()
   free_items();
   /* Reset where. */
   where= THD::DEFAULT_WHERE;
+  /* reset table map for multi-table update */
+  table_map_for_update= 0;
 }
 
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2008-08-25 12:25:07 +0000
+++ b/sql/sql_class.h	2008-08-27 18:54:03 +0000
@@ -442,7 +442,6 @@ struct system_variables
   DATE_TIME_FORMAT *datetime_format;
   DATE_TIME_FORMAT *time_format;
   my_bool sysdate_is_now;
-
 };
 
 
@@ -1587,6 +1586,13 @@ public:
     Note: in the parser, stmt_arena == thd, even for PS/SP.
   */
   Query_arena *stmt_arena;
+
+  /*
+    map for tables that will be updated for a multi-table update query
+    statement, for other query statements, this will be zero.
+  */
+  table_map table_map_for_update;
+
   /* Tells if LAST_INSERT_ID(#) was called for the current statement */
   bool arg_of_last_insert_id_function;
   /*

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2008-06-27 16:10:42 +0000
+++ b/sql/sql_db.cc	2008-08-27 08:47:03 +0000
@@ -883,13 +883,6 @@ bool mysql_rm_db(THD *thd,char *db,bool 
 
   pthread_mutex_lock(&LOCK_mysql_create_db);
 
-  /*
-    This statement will be replicated as a statement, even when using
-    row-based replication. The flag will be reset at the end of the
-    statement.
-  */
-  thd->clear_current_stmt_binlog_row_based();
-
   length= build_table_filename(path, sizeof(path), db, "", "", 0);
   strmov(path+length, MY_DB_OPT_FILE);		// Append db option file name
   del_dbopt(path);				// Remove dboption hash entry
@@ -911,16 +904,36 @@ bool mysql_rm_db(THD *thd,char *db,bool 
   else
   {
     error= -1;
+    /*
+      We temporarily disable the binary log while dropping the objects
+      in the database. Since the DROP DATABASE statement is always
+      replicated as a statement, execution of it will drop all objects
+      in the database on the slave as well, so there is no need to
+      replicate the removal of the individual objects in the database
+      as well.
+
+      This is more of a safety precaution, since normally no objects
+      should be dropped while the database is being cleaned, but in
+      the event that a change in the code to remove other objects is
+      made, these drops should still not be logged.
+
+      Notice that the binary log have to be enabled over the call to
+      ha_drop_database(), since NDB otherwise detects the binary log
+      as disabled and will not log the drop database statement on any
+      other connected server.
+     */
     if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
                                        &dropped_tables)) >= 0)
     {
       ha_drop_database(path);
+      tmp_disable_binlog(thd);
       query_cache_invalidate1(db);
       (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */
 #ifdef HAVE_EVENT_SCHEDULER
       Events::drop_schema_events(thd, db);
 #endif
       error = 0;
+      reenable_binlog(thd);
     }
   }
   if (!silent && deleted>=0)

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-08-26 19:16:28 +0000
+++ b/sql/sql_parse.cc	2008-08-28 08:44:13 +0000
@@ -1920,6 +1920,10 @@ mysql_execute_command(THD *thd)
   TABLE_LIST *all_tables;
   /* most outer SELECT_LEX_UNIT of query */
   SELECT_LEX_UNIT *unit= &lex->unit;
+#ifdef HAVE_REPLICATION
+  /* have table map for update for multi-update statement (BUG#37051) */
+  bool have_table_map_for_update= FALSE;
+#endif
   /* Saved variable value */
   DBUG_ENTER("mysql_execute_command");
 #ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -1985,6 +1989,48 @@ mysql_execute_command(THD *thd)
       // force searching in slave.cc:tables_ok() 
       all_tables->updating= 1;
     }
+
+    /*
+      For fix of BUG#37051, the master stores the table map for update
+      in the Query_log_event, and the value is assigned to
+      thd->variables.table_map_for_update before executing the update
+      query.
+
+      If thd->variables.table_map_for_update is set, then we are
+      replicating from a new master, we can use this value to apply
+      filter rules without opening all the tables. However If
+      thd->variables.table_map_for_update is not set, then we are
+      replicating from an old master, so we just skip this and
+      continue with the old method. And of course, the bug would still
+      exist for old masters.
+    */
+    if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
+        thd->table_map_for_update)
+    {
+      have_table_map_for_update= TRUE;
+      table_map table_map_for_update= thd->table_map_for_update;
+      uint nr= 0;
+      TABLE_LIST *table;
+      for (table=all_tables; table; table=table->next_global, nr++)
+      {
+        if (table_map_for_update & ((table_map)1 << nr))
+          table->updating= TRUE;
+        else
+          table->updating= FALSE;
+      }
+
+      if (all_tables_not_ok(thd, all_tables))
+      {
+        /* we warn the slave SQL thread */
+        my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
+        if (thd->one_shot_set)
+          reset_one_shot_variables(thd);
+        DBUG_RETURN(0);
+      }
+      
+      for (table=all_tables; table; table=table->next_global)
+        table->updating= TRUE;
+    }
     
     /*
       Check if statment should be skipped because of slave filtering
@@ -2960,7 +3006,7 @@ end_with_restore_list:
 
 #ifdef HAVE_REPLICATION
     /* Check slave filtering rules */
-    if (unlikely(thd->slave_thread))
+    if (unlikely(thd->slave_thread && !have_table_map_for_update))
     {
       if (all_tables_not_ok(thd, all_tables))
       {

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-07-17 19:55:18 +0000
+++ b/sql/sql_update.cc	2008-08-26 12:29:33 +0000
@@ -1007,7 +1007,7 @@ reopen_tables:
     DBUG_RETURN(TRUE);
   }
 
-  tables_for_update= get_table_map(fields);
+  thd->table_map_for_update= tables_for_update= get_table_map(fields);
 
   /*
     Setup timestamp handling and locking mode

=== modified file 'storage/falcon/BackLog.cpp'
--- a/storage/falcon/BackLog.cpp	2008-07-17 13:52:17 +0000
+++ b/storage/falcon/BackLog.cpp	2008-08-18 20:17:15 +0000
@@ -37,7 +37,9 @@ BackLog::BackLog(Database *db, const cha
 {
 	database = db;
 	dbb = new Dbb(database->dbb, 0);
+#ifndef FALCONDB
 	dbb->createPath(fileName);
+#endif
 	dbb->create(fileName, dbb->pageSize, 0, HdrTableSpace, 0, NULL);
 	dbb->noLog = true;
 	dbb->tableSpaceId = -1;

=== modified file 'storage/falcon/CMakeLists.txt'
--- a/storage/falcon/CMakeLists.txt	2008-06-19 15:09:45 +0000
+++ b/storage/falcon/CMakeLists.txt	2008-08-27 09:49:44 +0000
@@ -23,13 +23,11 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
                     . TransformLib
                     ${CMAKE_SOURCE_DIR}/extra/yassl/include
                     ${CMAKE_SOURCE_DIR}/zlib)
-IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
-   CMAKE_GENERATOR MATCHES "Visual Studio 8")
+IF(MSVC)
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
   SET(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /EHsc")
   SET(CMAKE_CXX_FLAGS_DEBUG_INIT "${CMAKE_CXX_FLAGS_DEBUG_INIT} /EHsc")
-ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
-      CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ENDIF(MSVC)
 
 SET(FALCON_SOURCES 
 		Agent.cpp 
@@ -274,7 +272,6 @@ SET(FALCON_SOURCES 
 		StreamSegment.cpp 
 		SymbolManager.cpp 
 		Sync.cpp 
-		SyncWait.cpp 
 		Synchronize.cpp
 		SyncObject.cpp 
 		SyncTest.cpp 

=== modified file 'storage/falcon/Configuration.cpp'
--- a/storage/falcon/Configuration.cpp	2008-07-17 13:52:17 +0000
+++ b/storage/falcon/Configuration.cpp	2008-08-19 14:27:42 +0000
@@ -151,8 +151,14 @@ Configuration::Configuration(const char 
 		
 		if (!scanDir.isDirectory())
 			{
-			//throw SQLEXCEPTION (RUNTIME_ERROR, "Invalid serial log directory path \"%s\"", falcon_serial_log_dir);
-			serialLogDir = "";
+			fprintf(stderr, 
+					"Falcon: The specified serial log directory, \"%s\", "
+					"does not exist.\n"
+					"Falcon: The serial log directory must be created by "
+					"the user before initializing Falcon.\n", 
+					falcon_serial_log_dir
+				);
+			throw SQLEXCEPTION (FILE_ACCESS_ERROR, "Invalid serial log directory path \"%s\"", falcon_serial_log_dir);
 			}
 		}
 #else

=== modified file 'storage/falcon/IO.cpp'
--- a/storage/falcon/IO.cpp	2008-08-14 16:34:43 +0000
+++ b/storage/falcon/IO.cpp	2008-08-18 20:17:15 +0000
@@ -411,13 +411,17 @@ void IO::declareFatalError()
 	fatalError = true;
 }
 
+
+#ifndef ENOSYS
+#define ENOSYS EEXIST
+#endif
+
+// Make sure parent directories for file exist
 void IO::createPath(const char *fileName)
 {
-	// First, better make sure directories exists
 	JString fname = getPath(fileName);
 
 	char directory [256], *q = directory;
-
 	for (const char *p = fname.getString(); *p;)
 		{
 		char c = *p++;
@@ -427,9 +431,14 @@ void IO::createPath(const char *fileName
 			*q = 0;
 			
 			if (q > directory && q [-1] != ':')
-				if (MKDIR (directory) && errno != EEXIST)
+				{
+				if (MKDIR (directory) && errno != EEXIST && errno != ENOSYS)
+					// ENOSYS is a Solaris speficic workaround, mkdir returns it
+					// on existing automounted NFS directories, instead
+					// of EEXIST.
 					throw SQLError (IO_ERROR, 
 					"can't create directory \"%s\"\n", directory);
+				}
 			}
 		*q++ = c;
 		}

=== modified file 'storage/falcon/Index.cpp'
--- a/storage/falcon/Index.cpp	2008-07-25 18:07:24 +0000
+++ b/storage/falcon/Index.cpp	2008-08-19 03:33:01 +0000
@@ -107,7 +107,6 @@ void Index::init(Table *tbl, const char 
 	DIHashTable = NULL;
 	DIHashTableCounts =  0;
 	DIHashTableSlotsUsed =  0;
-
 	syncDIHash.setName("Index::syncDIHash");
 	syncUnique.setName("Index::syncUnique");
 	deferredIndexes.syncObject.setName("Index::deferredIndexes.syncObject");

=== modified file 'storage/falcon/Index2RootPage.cpp'
--- a/storage/falcon/Index2RootPage.cpp	2008-03-27 06:09:29 +0000
+++ b/storage/falcon/Index2RootPage.cpp	2008-08-25 22:09:13 +0000
@@ -518,9 +518,9 @@ bool Index2RootPage::splitIndexPage(Dbb 
 		
 		leftPage->parentPage = bdb->pageNumber;
 		splitPage->parentPage = bdb->pageNumber;
-		Index2Page::logIndexPage(bdb, transId);
 		Index2Page::logIndexPage(splitBdb, transId);
 		Index2Page::logIndexPage(leftBdb, transId);
+		Index2Page::logIndexPage(bdb, transId);
 
 		splitBdb->release(REL_HISTORY);
 		leftBdb->release(REL_HISTORY);

=== modified file 'storage/falcon/IndexRootPage.cpp'
--- a/storage/falcon/IndexRootPage.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/IndexRootPage.cpp	2008-08-25 22:09:13 +0000
@@ -552,12 +552,16 @@ bool IndexRootPage::splitIndexPage(Dbb *
 		page->addNode(dbb, &dummy, END_LEVEL);
 		page->addNode(dbb, &leftKey, leftBdb->pageNumber);
 		page->addNode(dbb, &splitKey, splitBdb->pageNumber);
-		
+
 		leftPage->parentPage = bdb->pageNumber;
 		splitPage->parentPage = bdb->pageNumber;
-		IndexPage::logIndexPage(bdb, transId);
+
+		// the order of adding these to the serial log is important.
+		// Recovery must write them in this order incase recovery itself crashes.
+
 		IndexPage::logIndexPage(splitBdb, transId);
 		IndexPage::logIndexPage(leftBdb, transId);
+		IndexPage::logIndexPage(bdb, transId);
 		
 		/***
 		IndexPage::printPage(bdb, false);

=== modified file 'storage/falcon/Interlock.h'
--- a/storage/falcon/Interlock.h	2008-07-10 09:27:51 +0000
+++ b/storage/falcon/Interlock.h	2008-08-21 11:23:44 +0000
@@ -396,7 +396,7 @@ inline INTERLOCK_TYPE interlockedAdd(vol
 	{
 		INTERLOCK_TYPE current= *addend;
 		INTERLOCK_TYPE ret= current + value;
-		if (COMPARE_EXCHANGE_POINTER(addend, current, ret))
+		if (COMPARE_EXCHANGE(addend, current, ret))
 			return ret;
 	}
 #endif

=== modified file 'storage/falcon/MemMgr.cpp'
--- a/storage/falcon/MemMgr.cpp	2008-08-12 22:21:35 +0000
+++ b/storage/falcon/MemMgr.cpp	2008-08-20 16:28:44 +0000
@@ -694,7 +694,7 @@ void MemMgr::corrupt(const char* text)
 #endif
 
 	MemMgrLogDump();
-	throw SQLError (BUG_CHECK, "memory is corrupt: %s", text);
+	FATAL("memory is corrupt: %s", text);
 }
 
 void* MemMgr::memoryIsExhausted(void)

=== modified file 'storage/falcon/RepositoryVolume.cpp'
--- a/storage/falcon/RepositoryVolume.cpp	2008-07-24 08:45:03 +0000
+++ b/storage/falcon/RepositoryVolume.cpp	2008-08-18 20:17:15 +0000
@@ -232,7 +232,9 @@ void RepositoryVolume::makeWritable()
 
 void RepositoryVolume::create()
 {
+#ifndef FALCONDB
 	IO::createPath (fileName);
+#endif
 	dbb->create(fileName, dbb->pageSize, 0, HdrRepositoryFile, 0, NULL);
 	Sync syncDDL(&database->syncSysDDL, "RepositoryVolume::create");
 	Transaction *transaction = database->getSystemTransaction();

=== modified file 'storage/falcon/Statement.cpp'
--- a/storage/falcon/Statement.cpp	2008-07-24 08:45:03 +0000
+++ b/storage/falcon/Statement.cpp	2008-08-18 05:45:29 +0000
@@ -144,7 +144,6 @@ Statement::Statement(Connection *pConnec
 	special = false;
 	active = false;
 	memset (&stats, 0, sizeof (stats));
-	syncObject.setName("Statement::syncObject");
 }
 
 Statement::~Statement()
@@ -2303,16 +2302,10 @@ void Statement::dropIndex(Syntax *syntax
 		throw SQLEXCEPTION (DDL_ERROR, "table %s.%s not defined", (const char*) tableName, schema);
 
 	checkAlterPriv (table);
-	Index *index = table->findIndex (name);
 
-	if (index)
-		{
 		Transaction *sysTransaction = database->getSystemTransaction();
-		table->dropIndex(index);
-		index->deleteIndex(sysTransaction); /* transaction */
-		delete index;
+	table->dropIndex(name, sysTransaction);
 		database->commitSystemTransaction();
-		}
 
 	Index::deleteIndex (database, schema, name);
 	database->commitSystemTransaction();

=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp	2008-07-24 08:45:03 +0000
+++ b/storage/falcon/StorageDatabase.cpp	2008-08-18 20:17:15 +0000
@@ -156,7 +156,9 @@ Connection* StorageDatabase::createDatab
 	try
 		{
 		masterConnection = getConnection();
+#ifndef FALCONDB
 		IO::createPath(filename);
+#endif
 		masterConnection->createDatabase(name, filename, ACCOUNT, PASSWORD, threads);
 		Statement *statement = masterConnection->createStatement();
 		
@@ -688,7 +690,7 @@ int StorageDatabase::updateRow(StorageCo
 	return 0;
 }
 
-int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql)
+int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* sql)
 {
 	Connection *connection = storageConnection->connection;
 	Statement *statement = connection->createStatement();
@@ -713,7 +715,7 @@ int StorageDatabase::createIndex(Storage
 	return 0;
 }
 
-int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql)
+int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* sql)
 {
 	Connection *connection = storageConnection->connection;
 	Statement *statement = connection->createStatement();
@@ -746,17 +748,6 @@ int StorageDatabase::renameTable(Storage
 		{
 		Database *database = connection->database;
 		Sequence *sequence = connection->findSequence(schemaName, table->name);
-		int numberIndexes = 0;
-		int firstIndex = 0;
-		Index *index;
-
-		for (index = table->indexes; index; index = index->next)
-			{
-			if (index->type == PrimaryKey)
-				firstIndex = 1;
-
-			++numberIndexes;
-			}
 
 		Sync syncDDL(&database->syncSysDDL, "StorageDatabase::renameTable(1)");
 		syncDDL.lock(Exclusive);
@@ -764,19 +755,6 @@ int StorageDatabase::renameTable(Storage
 		Sync syncTables(&database->syncTables, "StorageDatabase::renameTable(2)");
 		syncTables.lock(Exclusive);
 		
-		for (int n = firstIndex; n < numberIndexes; ++n)
-			{
-			char indexName[256];
-			sprintf(indexName, "%s$%d", (const char*) table->name, n);
-			Index *index = table->findIndex(indexName);
-
-			if (index)
-				{
-				sprintf(indexName, "%s$%d", tableName, n);
-				index->rename(indexName);
-				}
-			}
-
 		table->rename(schemaName, tableName);
 
 		if (sequence)

=== modified file 'storage/falcon/StorageDatabase.h'
--- a/storage/falcon/StorageDatabase.h	2008-07-24 08:45:03 +0000
+++ b/storage/falcon/StorageDatabase.h	2008-08-18 05:45:29 +0000
@@ -40,7 +40,7 @@ class IndexWalker;
 
 CLASS(Field);
 
-struct StorageIndexDesc;
+class StorageIndexDesc;
 struct StorageKey;
 struct StorageBlob;
 struct StorageSegment;
@@ -61,7 +61,6 @@ public:
 	int					savepointRollback(Connection* connection, int savePoint);
 	int					deleteTable(StorageConnection* storageConnection,StorageTableShare *tableShare);
 	int					truncateTable(StorageConnection* storageConnection, StorageTableShare *tableShare);
-	int					createIndex(StorageConnection *storageConnection, Table* table, StorageIndexDesc* indexDesc);
 	int					renameTable(StorageConnection* storageConnection, Table* table, const char* newName, const char *schemaName);
 	Bitmap*				indexScan(Index* index, StorageKey *lower, StorageKey *upper, int searchFlags, StorageConnection* storageConnection, Bitmap *bitmap);
 	IndexWalker*		indexPosition(Index* index, StorageKey* lower, StorageKey* upper, int searchFlags, StorageConnection* storageConnection);
@@ -74,8 +73,8 @@ public:
 	void				freeBlob(StorageBlob *blob);
 	void				close(void);
 	void				validateCache(void);
-	int					createIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql);
-	int					dropIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql);
+	int					createIndex(StorageConnection* storageConnection, Table* table, const char* sql);
+	int					dropIndex(StorageConnection* storageConnection, Table* table, const char* sql);
 	int					insert(Connection* connection, Table* table, Stream* stream);
 	
 	int					nextRow(StorageTable* storageTable, int recordNumber, bool lockForUpdate);

=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp	2008-08-11 13:22:53 +0000
+++ b/storage/falcon/StorageTable.cpp	2008-08-22 06:47:40 +0000
@@ -51,11 +51,13 @@ StorageTable::StorageTable(StorageConnec
 	upperBound = lowerBound = NULL;
 	record = NULL;
 	recordLocked = false;
-	haveTruncateLock = false;
+	indexesLocked = false;
 }
 
 StorageTable::~StorageTable(void)
 {
+	clearCurrentIndex();
+	
 	if (bitmap)
 		((Bitmap*) bitmap)->release();
 
@@ -94,12 +96,12 @@ int StorageTable::deleteTable(void)
 int StorageTable::truncateTable(void)
 {
 	clearRecord();
+	clearCurrentIndex();
+	
 	int ret = share->truncateTable(storageConnection);
 	return ret;
 }
 
-
-
 int StorageTable::insert(void)
 {
 	try
@@ -139,6 +141,16 @@ int StorageTable::updateRow(int recordNu
 	return 0;
 }
 
+int StorageTable::createIndex(StorageIndexDesc *indexDesc, const char *sql)
+{
+	return share->createIndex(storageConnection, indexDesc, sql);
+}
+
+int StorageTable::dropIndex(StorageIndexDesc *indexDesc, const char *sql)
+{
+	return share->dropIndex(storageConnection, indexDesc, sql);
+}
+
 int StorageTable::next(int recordNumber, bool lockForUpdate)
 {
 	recordLocked = false;
@@ -174,21 +186,51 @@ void StorageTable::transactionEnded(void
 {
 }
 
-int StorageTable::setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex)
+int StorageTable::setCurrentIndex(int indexId)
 {
-	if (!(currentIndex = share->getIndex(numberIndexes, indexId, storageIndex)))
+	if (!indexesLocked)
+		{
+		share->lockIndexes();
+		indexesLocked = true;
+		}
+	
+	if (!(currentIndex = share->getIndex(indexId)))
+{
+		clearCurrentIndex();
 		return StorageErrorNoIndex;
-
+		}
+		
 	upperBound = lowerBound = NULL;
 	searchFlags = 0;
+	return 0;
+}
 	
+int StorageTable::clearCurrentIndex()
+{
+	if (indexesLocked)
+		{
+		share->unlockIndexes();
+		indexesLocked = false;
+		}
+
+	currentIndex = NULL;
+	upperBound = lowerBound = NULL;
+	searchFlags = 0;
 	return 0;
 }
 
+int StorageTable::setIndex(StorageIndexDesc* indexDesc)
+{
+	return share->setIndex(indexDesc);
+}
+
 int StorageTable::indexScan(int indexOrder)
 {
 	if (!currentIndex)
+		{
+		clearCurrentIndex();
 		return StorageErrorNoIndex;
+		}
 	
 	int numberSegments = (upperBound) ?  upperBound->numberSegments : (lowerBound) ? lowerBound->numberSegments : 0;
 	
@@ -203,26 +245,16 @@ int StorageTable::indexScan(int indexOrd
 	return 0;
 }
 
-
 void StorageTable::clearBitmap(void)
 {
 	if (bitmap)
 		((Bitmap*) bitmap)->clear();
 }
 
-int StorageTable::setIndex(int indexId)
-{
-	if (!(currentIndex = share->getIndex(indexId)))
-		return StorageErrorNoIndex;
-	
-	upperBound = lowerBound = NULL;
-	searchFlags = 0;
-	
-	return 0;
-}
-
 void StorageTable::indexEnd(void)
 {
+	clearCurrentIndex();
+	
 	if (bitmap)
 		clearBitmap();
 	
@@ -236,7 +268,10 @@ void StorageTable::indexEnd(void)
 int StorageTable::setIndexBound(const unsigned char* key, int keyLength, int which)
 {
 	if (!currentIndex)
+		{
+		clearCurrentIndex();
 		return StorageErrorNoIndex;
+		}
 
 	if (which & LowerBound)
 		{

=== modified file 'storage/falcon/StorageTable.h'
--- a/storage/falcon/StorageTable.h	2008-08-11 13:22:53 +0000
+++ b/storage/falcon/StorageTable.h	2008-08-22 06:47:40 +0000
@@ -49,8 +49,7 @@ class Record;
 class SyncObject;
 class Format;
 class IndexWalker;
-
-struct StorageIndexDesc;
+class StorageIndexDesc;
 
 class StorageTable
 {
@@ -65,8 +64,6 @@ public:
 	void			clearAlter(void);
 	bool			setAlter(void);
 	
-
-	
 	virtual void	setConnection(StorageConnection* connection);
 	virtual void	clearIndexBounds(void);
 	virtual void	clearRecord(void);
@@ -78,9 +75,10 @@ public:
 	virtual int		deleteTable(void);
 	virtual int		deleteRow(int recordNumber);
 	virtual int		truncateTable(void);
-	virtual int		setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex);
 	virtual int		indexScan(int indexOrder);
-	virtual int		setIndex(int indexId);
+	virtual int		setCurrentIndex(int indexId);
+	virtual int		clearCurrentIndex();
+	virtual int		setIndex(StorageIndexDesc* indexDesc);
 	virtual void	indexEnd(void);
 	virtual int		setIndexBound(const unsigned char* key, int keyLength, int which);
 	virtual int		storeBlob(StorageBlob* blob);
@@ -96,6 +94,8 @@ public:
 	virtual int		fetch(int recordNumber, bool lockForUpdate);
 	
 	virtual int		updateRow(int recordNumber);
+	virtual int		createIndex(StorageIndexDesc *indexDesc, const char *sql);
+	virtual int		dropIndex(StorageIndexDesc *indexDesc, const char *sql);
 	virtual const unsigned char* getEncoding(int fieldIndex);
 	virtual const char*			 getName(void);
 	virtual const char*			 getSchemaName(void);
@@ -128,7 +128,7 @@ public:
 	Stream				insertStream;
 	int					searchFlags;
 	bool				recordLocked;
-	bool				haveTruncateLock;
+	bool				indexesLocked;
 };
 
 #endif

=== modified file 'storage/falcon/StorageTableShare.cpp'
--- a/storage/falcon/StorageTableShare.cpp	2008-08-04 15:53:52 +0000
+++ b/storage/falcon/StorageTableShare.cpp	2008-08-22 06:47:40 +0000
@@ -33,14 +33,11 @@
 #include "PreparedStatement.h"
 #include "ResultSet.h"
 #include "SQLException.h"
+#include "CmdGen.h"
 
 static const char *FALCON_TEMPORARY		= "/falcon_temporary";
 static const char *DB_ROOT				= ".fts";
 
-#ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
-#endif
-
 #if defined(_WIN32) && MYSQL_VERSION_ID < 0x50100
 #define IS_SLASH(c)	(c == '/' || c == '\\')
 #else
@@ -52,6 +49,43 @@ static const char *DB_ROOT				= ".fts";
 static const char THIS_FILE[]=__FILE__;
 #endif
 
+StorageIndexDesc::StorageIndexDesc()
+{
+	id = 0;
+	unique = 0;
+	primaryKey = 0;
+	numberSegments = 0;
+	index = NULL;
+	segmentRecordCounts = NULL;
+	next = NULL;
+	name[0] = '\0';
+	rawName[0] = '\0';
+};
+
+StorageIndexDesc::StorageIndexDesc(const StorageIndexDesc *indexInfo)
+{
+	if (indexInfo)
+		*this = *indexInfo;
+	else
+		{
+		id = 0;
+		unique = 0;
+		primaryKey = 0;
+		numberSegments = 0;
+		segmentRecordCounts = NULL;
+		name[0] = '\0';
+		rawName[0] = '\0';
+		}
+		
+	index = NULL;
+	next = NULL;
+	prev = NULL;
+};
+
+StorageIndexDesc::~StorageIndexDesc(void)
+{
+}
+
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
@@ -63,13 +97,15 @@ StorageTableShare::StorageTableShare(Sto
 	impure = new UCHAR[lockSize];
 	initialized = false;
 	table = NULL;
-	indexes = NULL;
 	format = NULL;
 	syncObject = new SyncObject;
 	syncObject->setName("StorageTableShare::syncObject");
+	syncIndexes = new SyncObject;
+	syncIndexes->setName("StorageTableShare::syncIndexes");
 	sequence = NULL;
 	tempTable = tempTbl;
 	setPath(path);
+	indexes = NULL;
 
 	if (tempTable)
 		tableSpace = TEMPORARY_TABLESPACE;
@@ -82,18 +118,16 @@ StorageTableShare::StorageTableShare(Sto
 StorageTableShare::~StorageTableShare(void)
 {
 	delete syncObject;
+	delete syncIndexes;
 	delete [] impure;
 	
 	if (storageDatabase)
 		storageDatabase->release();
 		
-	if (indexes)
+	for (StorageIndexDesc *indexDesc; (indexDesc = indexes);)
 		{
-		for (int n = 0; n < numberIndexes; ++n)
-			delete indexes[n];
-			
-		delete [] indexes;
-		indexes = NULL;
+		indexes = indexDesc->next;
+		delete indexDesc;
 		}
 }
 
@@ -107,6 +141,16 @@ void StorageTableShare::unlock(void)
 	syncObject->unlock();
 }
 
+void StorageTableShare::lockIndexes(bool exclusiveLock)
+{
+	syncIndexes->lock(NULL, (exclusiveLock) ? Exclusive : Shared);
+}
+
+void StorageTableShare::unlockIndexes(void)
+{
+	syncIndexes->unlock();
+}
+
 int StorageTableShare::open(void)
 {
 	if (!table)
@@ -189,7 +233,7 @@ int StorageTableShare::truncateTable(Sto
 	return res;
 }
 
-void StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength)
+const char* StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength)
 {
 	char *q = buffer;
 	char *end = buffer + bufferLength - 1;
@@ -211,6 +255,8 @@ void StorageTableShare::cleanupFieldName
 		}
 
 	*q = 0;
+	
+	return buffer;
 }
 
 const char* StorageTableShare::cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength)
@@ -239,20 +285,96 @@ const char* StorageTableShare::cleanupTa
 	return buffer;
 }
 
-int StorageTableShare::createIndex(StorageConnection *storageConnection, const char* name, const char* sql)
+char* StorageTableShare::createIndexName(const char *rawName, char *indexName)
+{
+	char nameBuffer[indexNameSize];
+	cleanupFieldName(rawName, nameBuffer, sizeof(nameBuffer));
+	sprintf(indexName, "%s$%s", name.getString(), nameBuffer);
+	return indexName;
+}
+
+int StorageTableShare::createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql)
 {
 	if (!table)
 		open();
 
-	return storageDatabase->createIndex(storageConnection, table, name, sql);
+	// Lock out other clients before locking the table
+	
+	Sync syncIndex(syncIndexes, "StorageTableShare::createIndex(1)");
+	syncIndex.lock(Exclusive);
+	
+	Sync syncObj(syncObject, "StorageTableShare::createIndex(2)");
+	syncObj.lock(Exclusive);
+	
+	int ret = storageDatabase->createIndex(storageConnection, table, sql);
+	
+	if (!ret)
+		ret = setIndex(indexDesc);
+		
+	return ret;
+}
+
+void StorageTableShare::addIndex(StorageIndexDesc *indexDesc)
+{
+	if (!getIndex(indexDesc->id))
+		{
+		if (indexes)
+			{
+			indexDesc->next = indexes;
+			indexDesc->prev = NULL;
+			indexes->prev = indexDesc;
+			}
+		
+		indexes = indexDesc;
+		}
+}
+
+void StorageTableShare::deleteIndex(int indexId)
+{
+	for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+		if (indexDesc->id == indexId)
+			{
+			if (indexDesc->prev)
+				indexDesc->prev->next = indexDesc->next;
+			else
+				indexes = indexDesc->next;
+				
+			if (indexDesc->next)
+				indexDesc->next->prev = indexDesc->prev;
+				
+			delete indexDesc;	
+			break;
+			}
 }
 
-int StorageTableShare::dropIndex(StorageConnection *storageConnection, const char* name, const char* sql)
+int StorageTableShare::dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql)
 {
 	if (!table)
 		open();
 
-	return storageDatabase->dropIndex(storageConnection, table, name, sql);
+	// Lock out other clients before locking the table
+
+	Sync syncIndex(syncIndexes, "StorageTableShare::dropIndex(1)");
+	syncIndex.lock(Exclusive);
+	
+	Sync syncObj(syncObject, "StorageTableShare::dropIndex(2)");
+	syncObj.lock(Exclusive);
+	
+	int ret = storageDatabase->dropIndex(storageConnection, table, sql);
+	
+	if (!ret)
+		deleteIndex(indexDesc->id);
+				
+	return ret;
+}
+
+void StorageTableShare::deleteIndexes()
+{
+	for (StorageIndexDesc *indexDesc; (indexDesc = indexes);)
+		{
+		indexes = indexDesc->next;
+		delete indexDesc;
+		}
 }
 
 int StorageTableShare::renameTable(StorageConnection *storageConnection, const char* newName)
@@ -274,72 +396,109 @@ int StorageTableShare::renameTable(Stora
 	return ret;
 }
 
-StorageIndexDesc* StorageTableShare::getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc)
+int StorageTableShare::setIndex(const StorageIndexDesc *indexInfo)
 {
-	// Rebuild array if indexes have been added or dropped
-	
-#ifdef ONLINE_ALTER
-
-	// TODO: This does not work. It should be done at the time of index creation
+	int ret = 0;
 
-	if (indexes && (numberIndexes != indexCount))
+	if (!getIndex(indexInfo->id))
 		{
-		Sync sync(syncObject, "StorageTableShare::getIndex");
-		sync.lock(Exclusive);
-		StorageIndexDesc **oldIndexes = indexes;
-		StorageIndexDesc **newIndexes = new StorageIndexDesc*[indexCount];
-		memset(newIndexes, 0, indexCount * sizeof(StorageIndexDesc*));
-		
-		for (int n = 0; n < numberIndexes; ++n)
-			newIndexes[n] = indexes[n];
-		
-		indexes = newIndexes;
-		numberIndexes = indexCount;
-		delete [] oldIndexes;
-		}
-#endif
-	
-	if (!indexes)
-		{
-		indexes = new StorageIndexDesc*[indexCount];
-		memset(indexes, 0, indexCount * sizeof(StorageIndexDesc*));
-		numberIndexes = indexCount;
-		}
-	
-	if (indexId >= numberIndexes)
-		return NULL;
-	
-	StorageIndexDesc *index = indexes[indexId];
-	
-	if (index)
-		return index;
+		StorageIndexDesc *indexDesc = new StorageIndexDesc(indexInfo);
+		addIndex(indexDesc);
 
-	indexes[indexId] = index = new StorageIndexDesc;
-	*index = *indexDesc;
+	// Find the corresponding Falcon index
 	
 	if (indexDesc->primaryKey)
-		index->index = table->primaryKey;
+		indexDesc->index = table->primaryKey;
 	else
 		{
-		char indexName[150];
-		sprintf(indexName, "%s$%d", (const char*) name, indexId);
-		index->index = storageDatabase->findIndex(table, indexName);
+		char indexName[indexNameSize];
+			sprintf(indexName, "%s$%s", name.getString(), indexDesc->name);
+		indexDesc->index = table->findIndex(indexName);
 		}
 
-	if (index->index)
-		index->segmentRecordCounts = index->index->recordsPerSegment;
+	if (indexDesc->index)
+		indexDesc->segmentRecordCounts = indexDesc->index->recordsPerSegment;
 	else
-		index = NULL;
+		ret = StorageErrorNoIndex;
+		}
+		
+	return ret;
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(int indexId)
+{
+	if (!indexes)
+		return NULL;
+			
+	for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+		if (indexDesc->id == indexId)
+			return indexDesc;
+		
+	return NULL;
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(int indexId, StorageIndexDesc *indexDesc)
+{
+	if (!indexes)
+		return NULL;
 	
+	Sync sync(syncIndexes, "StorageTableShare::getIndex");
+	sync.lock(Shared);
+	
+	StorageIndexDesc *index = getIndex(indexId);
+			
+	if (index)
+		*indexDesc = *index;
+		
 	return index;
 }
 
-StorageIndexDesc* StorageTableShare::getIndex(int indexId)
+StorageIndexDesc* StorageTableShare::getIndex(const char *name)
 {
-	if (!indexes || indexId >= numberIndexes)
+	if (!indexes)
 		return NULL;
 	
-	return indexes[indexId];
+	Sync sync(syncIndexes, "StorageTableShare::getIndex(name)");
+	sync.lock(Shared);
+	
+	for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+		if (indexDesc->name == name)
+			return indexDesc;
+			
+	return NULL;
+}
+
+int StorageTableShare::getIndexId(const char* schemaName, const char* indexName)
+{
+	if (!indexes)
+		return -1;
+	
+	for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+		{
+		Index *index = indexDesc->index;
+	
+		if (index)
+			if (strcmp(index->getIndexName(), indexName) == 0 &&
+				strcmp(index->getSchemaName(), schemaName) == 0)
+				return indexDesc->id;
+		}
+		
+	return -1;
+}
+
+int StorageTableShare::haveIndexes(int indexCount)
+{
+	if (!indexes)
+		return false;
+	
+	int n = 0;
+	for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next, n++)
+		{
+		if (!indexDesc->index)
+			return false;
+		}
+
+	return (n == indexCount);
 }
 
 INT64 StorageTableShare::getSequenceValue(int delta)
@@ -365,38 +524,6 @@ int StorageTableShare::setSequenceValue(
 	return 0;
 }
 
-int StorageTableShare::getIndexId(const char* schemaName, const char* indexName)
-{
-	if (indexes)
-		for (int n = 0; n < numberIndexes; ++n)
-			{
-			Index *index = indexes[n]->index;
-			
-			if (strcmp(index->getIndexName(), indexName) == 0 &&
-				strcmp(index->getSchemaName(), schemaName) == 0)
-				return n;
-			}
-		
-	return -1;
-}
-
-int StorageTableShare::haveIndexes(int indexCount)
-{
-	if (indexes == NULL)
-		return false;
-		
-#ifdef ONLINE_ALTER
-	if (indexCount != numberIndexes)
-		return false;
-#endif	
-	
-	for (int n = 0; n < numberIndexes; ++n)
-		if (indexes[n]== NULL)
-			return false;
-	
-	return true;
-}
-
 void StorageTableShare::setTablePath(const char* path, bool tmp)
 {
 	if (pathName.IsEmpty())

=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h	2008-08-04 15:53:52 +0000
+++ b/storage/falcon/StorageTableShare.h	2008-08-22 06:47:40 +0000
@@ -26,6 +26,7 @@
 typedef __int64			INT64;
 
 static const int MaxIndexSegments	= 16;
+static const int indexNameSize		= 257;
 
 class StorageDatabase;
 class StorageConnection;
@@ -47,14 +48,25 @@ struct StorageSegment {
 	void			*mysql_charset;
 	};
 
-struct StorageIndexDesc {
+// StorageIndexDesc maps a server-side index to a Falcon index
+class StorageIndexDesc
+{
+public:
+	StorageIndexDesc();
+	StorageIndexDesc(const StorageIndexDesc *indexInfo);
+	virtual ~StorageIndexDesc(void);
+	
+	int			id;
 	int			unique;
 	int			primaryKey;
 	int			numberSegments;
-	const char	*name;
+	char		name[indexNameSize];		// clean name
+	char		rawName[indexNameSize];		// original name
 	Index		*index;
 	uint64		*segmentRecordCounts;
 	StorageSegment segments[MaxIndexSegments];
+	StorageIndexDesc *next;
+	StorageIndexDesc *prev;
 	};
 
 
@@ -95,22 +107,29 @@ public:
 	StorageTableShare(StorageHandler *handler, const char * path, const char *tableSpaceName, int lockSize, bool tempTbl);
 	virtual ~StorageTableShare(void);
 	
-	virtual void		lock(bool exclusiveLock);
+	virtual void		lock(bool exclusiveLock=false);
 	virtual void		unlock(void);
-	virtual int			createIndex(StorageConnection *storageConnection, const char* name, const char* sql);
-	virtual int			dropIndex(StorageConnection *storageConnection, const char* name, const char* sql);
+	virtual void		lockIndexes(bool exclusiveLock=false);
+	virtual void		unlockIndexes(void);
+	virtual int			createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql);
+	virtual int			dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql);
+	virtual void		deleteIndexes();
 	virtual int			renameTable(StorageConnection *storageConnection, const char* newName);
 	virtual INT64		getSequenceValue(int delta);
 	virtual int			setSequenceValue(INT64 value);
 	virtual int			haveIndexes(int indexCount);
-	virtual void		cleanupFieldName(const char* name, char* buffer, int bufferLength);
+	virtual const char*	cleanupFieldName(const char* name, char* buffer, int bufferLength);
 	virtual void		setTablePath(const char* path, bool tempTable);
 	virtual void		registerCollation(const char* collationName, void* arg);
 
 	int					open(void);
-	StorageIndexDesc*	getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc);
+	void				addIndex(StorageIndexDesc *indexDesc);
+	void				deleteIndex(int indexId);
+	int					setIndex(const StorageIndexDesc* indexInfo);
+	void				clearIndex(StorageIndexDesc *indexDesc);
 	StorageIndexDesc*	getIndex(int indexId);
-
+	StorageIndexDesc*	getIndex(int indexId, StorageIndexDesc *indexDesc);
+	StorageIndexDesc*	getIndex(const char *name);
 	int					getIndexId(const char* schemaName, const char* indexName);
 	int					create(StorageConnection *storageConnection, const char* sql, int64 autoIncrementValue);
 	int					upgrade(StorageConnection *storageConnection, const char* sql, int64 autoIncrementValue);
@@ -129,6 +148,7 @@ public:
 
 	static const char*	getDefaultRoot(void);
 	static const char*	cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength);
+	char*				createIndexName(const char *rawName, char *indexName);
 	
 	JString				name;
 	JString				schemaName;
@@ -140,13 +160,13 @@ public:
 	unsigned char		*impure;
 	int					initialized;
 	SyncObject			*syncObject;
+	SyncObject			*syncIndexes;
 	StorageDatabase		*storageDatabase;
 	StorageHandler		*storageHandler;
 	Table				*table;
-	StorageIndexDesc	**indexes;
+	StorageIndexDesc	*indexes;
 	Sequence			*sequence;
 	Format				*format;						// format for insertion
-	int					numberIndexes;
 	bool				tempTable;
 	int getFieldId(const char* fieldName);
 };

=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp	2008-08-13 10:18:40 +0000
+++ b/storage/falcon/Table.cpp	2008-08-18 05:45:29 +0000
@@ -209,6 +209,34 @@ Index* Table::addIndex(const char * name
 	return index;
 }
 
+void Table::dropIndex(const char* indexName, Transaction* transaction)
+{
+	Sync sync(&syncObject, "Table::dropIndex");
+	sync.lock(Exclusive);
+	
+	Index *index = findIndex(indexName);
+		
+	if (index)
+		deleteIndex(index, transaction);
+}
+
+void Table::renameIndexes(const char *newTableName)
+{
+	for (Index *index = indexes; index; index = index->next)
+		{
+		if (index->type != PrimaryKey)
+			{
+
+			// Assume that index name is <table>$<index>
+
+			char newIndexName[256];
+			const char *p = strchr((const char*)index->name, '$');
+			sprintf(newIndexName, "%s%s", newTableName, (const char *)p);
+			index->rename(newIndexName);
+			}
+		}
+}
+
 const char* Table::getName()
 {
 	return name;
@@ -1706,6 +1734,19 @@ void Table::addIndex(Index * index)
 	*ptr = index;
 }
 
+void Table::dropIndex(Index *index)
+{
+	Sync sync(&syncObject, "Table::dropIndex");
+	sync.lock(Exclusive);
+
+	for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next)
+		if (*ptr == index)
+			{
+			*ptr = index->next;
+			break;
+			}
+}
+
 void Table::addAttachment(TableAttachment * attachment)
 {
 	attachments.appendUnique(attachment);
@@ -2226,15 +2267,6 @@ void Table::dropTrigger(Trigger *trigger
 #endif
 }
 
-void Table::dropIndex(Index *index)
-{
-	for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next)
-		if (*ptr == index)
-			{
-			*ptr = index->next;
-			break;
-			}
-}
 
 int Table::nextColumnId(int previous)
 {
@@ -3196,6 +3228,8 @@ void Table::rename(const char *newSchema
 		Index *primaryKey = getPrimaryKey();
 		database->renameTable(this, newSchema, newName);
 		
+		renameIndexes(newName);
+		
 		if (primaryKey)
 			primaryKey->rename(getPrimaryKeyName());
 		}
@@ -3491,7 +3525,7 @@ Record* Table::fetchForUpdate(Transactio
 
 				ASSERT(IS_CONSISTENT_READ(transaction->isolationLevel));
 				record->release();
-				Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s", 
+				Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s\n", 
 					transaction->transactionId, record->recordNumber, schemaName, name);
 				throw SQLError(UPDATE_CONFLICT, "update conflict in table %s.%s", schemaName, name);
 

=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h	2008-08-11 13:22:53 +0000
+++ b/storage/falcon/Table.h	2008-08-18 05:45:29 +0000
@@ -180,6 +180,8 @@ public:
 	void		create (const char *tableType, Transaction *transaction);
 	const char* getName();
 	Index*		addIndex (const char *name, int numberFields, int type);
+	void		dropIndex(const char* name, Transaction* transaction);
+	void		renameIndexes(const char *newTableName);
 	Field*		addField (const char *name, Type type, int length, int precision, int scale, int flags);
 	Field*		findField (const char *name);
 	int			getFormatVersion();

=== modified file 'storage/falcon/TableSpace.cpp'
--- a/storage/falcon/TableSpace.cpp	2008-07-17 13:52:17 +0000
+++ b/storage/falcon/TableSpace.cpp	2008-08-18 20:17:15 +0000
@@ -123,7 +123,9 @@ void TableSpace::open()
 
 void TableSpace::create()
 {
+#ifndef FALCONDB
 	dbb->createPath(filename);
+#endif
 	dbb->create(filename, dbb->pageSize, 0, HdrTableSpace, 0, NULL);
 	active = true;
 	dbb->flush();

=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp	2008-08-20 15:01:21 +0000
+++ b/storage/falcon/Transaction.cpp	2008-08-26 15:36:02 +0000
@@ -86,6 +86,7 @@ Transaction::Transaction(Connection *cnc
 	syncObject.setName("Transaction::syncObject");
 	syncActive.setName("Transaction::syncActive");
 	syncIndexes.setName("Transaction::syncIndexes");
+	syncRecords.setName("Transaction::syncRecords");
 	syncSavepoints.setName("Transaction::syncSavepoints");
 	firstRecord = NULL;
 	lastRecord = NULL;
@@ -216,20 +217,19 @@ Transaction::~Transaction()
 	delete backloggedRecords;
 	chillPoint = &firstRecord;
 
+	// We modify record list without locking.
+	// It is a destructor and if somebody accesses the list
+	// at this point, he is already lost.
 	for (RecordVersion *record; (record = firstRecord);)
 		{
-		removeRecord(record);
+		removeRecordNoLock(record);
 		}
+	firstRecord = NULL;
 	
 	releaseSavepoints();
 	
 	if (deferredIndexes)
-		{
-		Sync sync(&syncIndexes, "Transaction::~Transaction");
-		sync.lock(Exclusive);
-
 		releaseDeferredIndexes();
-		}
 }
 
 void Transaction::commit()
@@ -275,10 +275,11 @@ void Transaction::commit()
 		releaseRecordLocks();
 
 	database->serialLog->preCommit(this);
-	syncActive.unlock();
 
 	
 
+	Sync syncRec(&syncRecords,"Transaction::commit(1.5)");
+	syncRec.lock(Shared);
 	for (RecordVersion *record = firstRecord; record; record = record->nextInTrans)
 	{
 		Table * table = record->format->table;
@@ -295,15 +296,15 @@ void Transaction::commit()
 		if (record->state == recDeleted && table->cardinality > 0)
 			--table->cardinality;
 	}
-	
+	syncRec.unlock();
+
 	releaseDependencies();
 	database->flushInversion(this);
 
 	// Transfer transaction from active list to committed list, set committed state
-
-	Sync syncCommitted(&transactionManager->committedTransactions.syncObject, "Transaction::commit(2)");
 	Sync syncActiveTransactions(&transactionManager->activeTransactions.syncObject, "Transaction::commit(3)");
-
+	Sync syncCommitted(&transactionManager->committedTransactions.syncObject, "Transaction::commit(2)");
+	
 	syncActiveTransactions.lock(Exclusive);
 	syncCommitted.lock(Exclusive);
 
@@ -313,6 +314,8 @@ void Transaction::commit()
 
 	syncCommitted.unlock();
 	syncActiveTransactions.unlock();
+	
+	syncActive.unlock(); // signal waiting transactions
 
 	database->commit(this);
 
@@ -341,11 +344,7 @@ void Transaction::commitNoUpdates(void)
 	++transactionManager->committed;
 	
 	if (deferredIndexes)
-		{
-		Sync sync(&syncIndexes, "Transaction::commitNoUpdates(1)");
-		sync.lock(Exclusive);
 		releaseDeferredIndexes();
-		}
 
 	if (hasLocks)
 		releaseRecordLocks();
@@ -387,11 +386,7 @@ void Transaction::rollback()
 		throw SQLEXCEPTION (RUNTIME_ERROR, "transaction is not active");
 
 	if (deferredIndexes)
-		{
-		Sync sync(&syncIndexes, "Transaction::rollback(1)");
-		sync.lock(Exclusive);
 		releaseDeferredIndexes();
-		}
 		
 	releaseSavepoints();
 	TransactionManager *transactionManager = database->transactionManager;
@@ -403,6 +398,9 @@ void Transaction::rollback()
 	// Rollback pending record versions from newest to oldest in case
 	// there are multiple record versions on a prior record chain
 
+	Sync syncRec(&syncRecords, "Transaction::rollback(1.5)");
+	syncRec.lock(Exclusive);
+
 	while (firstRecord)
 		{
 		record = firstRecord;
@@ -428,6 +426,8 @@ void Transaction::rollback()
 		record->transaction = rollbackTransaction;
 		record->release();
 		}
+	firstRecord = NULL;
+	syncRec.unlock();
 
 	for (SavePoint *savePoint = savePoints; savePoint; savePoint = savePoint->next)
 		if (savePoint->backloggedRecords)
@@ -621,6 +621,8 @@ void Transaction::addRecord(RecordVersio
 
 	record->addRef();
 	
+	Sync syncRec(&syncRecords,"Transaction::addRecord");
+	syncRec.lock(Exclusive);
 	if ( (record->prevInTrans = lastRecord) )
 		lastRecord->nextInTrans = record;
 	else
@@ -628,6 +630,7 @@ void Transaction::addRecord(RecordVersio
 		
 	record->nextInTrans = NULL;
 	lastRecord = record;
+	syncRec.unlock();
 	
 	if (database->lowMemory && deletedRecords > MAX_LOW_MEMORY_RECORDS)
 		backlogRecords();
@@ -635,6 +638,12 @@ void Transaction::addRecord(RecordVersio
 
 void Transaction::removeRecord(RecordVersion *record)
 {
+	Sync syncRec(&syncRecords,"Transaction::removeRecord");
+	syncRec.lock(Exclusive);
+	removeRecordNoLock(record);
+}
+void Transaction::removeRecordNoLock(RecordVersion *record)
+{
 	RecordVersion **ptr;
 
 	if (record->nextInTrans)
@@ -800,6 +809,8 @@ void Transaction::releaseDependencies()
 
 void Transaction::commitRecords()
 {
+	Sync syncRec(&syncRecords,"Transaction::commitRecords");
+	syncRec.lock(Exclusive);
 	for (RecordVersion *recordList; (recordList = firstRecord);)
 		{
 		if (recordList && COMPARE_EXCHANGE_POINTER(&firstRecord, recordList, NULL))
@@ -903,13 +914,10 @@ State Transaction::getRelativeState(Tran
 
 void Transaction::dropTable(Table* table)
 {
-	Sync sync(&syncIndexes, "Transaction::dropTable");
-	sync.lock(Exclusive);
-
 	releaseDeferredIndexes(table);
 
-	// Keep exclusive lock to avoid race condition with writeComplete
-	
+	Sync syncRec(&syncRecords,"Transaction::dropTable(2)");
+	syncRec.lock(Exclusive);
 	for (RecordVersion **ptr = &firstRecord, *rec; (rec = *ptr);)
 		if (rec->format->table == table)
 			removeRecord(rec);
@@ -919,13 +927,9 @@ void Transaction::dropTable(Table* table
 
 void Transaction::truncateTable(Table* table)
 {
-	Sync sync(&syncIndexes, "Transaction::truncateTable");
-	sync.lock(Exclusive);
-
 	releaseDeferredIndexes(table);
-
-	// Keep exclusive lock to avoid race condition with writeComplete
-	
+	Sync syncRec(&syncRecords,"Transaction::truncateTable(2)");
+	syncRec.lock(Exclusive);
 	for (RecordVersion **ptr = &firstRecord, *rec; (rec = *ptr);)
 		if (rec->format->table == table)
 			removeRecord(rec);
@@ -935,9 +939,8 @@ void Transaction::truncateTable(Table* t
 
 bool Transaction::hasRecords(Table* table)
 {
-	// This lock is to avoid race with writeComplete
-	Sync sync(&syncIndexes, "Transaction::hasRecords");
-	sync.lock(Exclusive);
+	Sync syncRec(&syncRecords, "Transaction::hasRecords");
+	syncRec.lock(Shared);
 	for (RecordVersion *rec = firstRecord; rec; rec = rec->nextInTrans)
 		if (rec->format->table == table)
 			return true;
@@ -949,17 +952,12 @@ void Transaction::writeComplete(void)
 {
 	ASSERT(writePending);
 	ASSERT(state == Committed);
-	Sync sync(&syncIndexes, "Transaction::writeComplete");
-	sync.lock(Exclusive);
 	releaseDeferredIndexes();
-
-	// Keep the synIndexes lock to avoid a race condition with dropTable
 	
 	if (dependencies == 0)
 		commitRecords();
 
 	writePending = false;
-	sync.unlock();
 }
 
 bool Transaction::waitForTransaction(TransId transId)
@@ -1243,6 +1241,7 @@ void Transaction::rollbackSavepoint(int 
 
 	savePoint = savePoints;
 	
+
 	while (savePoint)
 		{
 		//validateRecords();
@@ -1251,6 +1250,8 @@ void Transaction::rollbackSavepoint(int 
 			break;
 
 		// Purge out records from this savepoint
+		Sync syncRec(&syncRecords,"Transaction::rollbackSavepoint(2)");
+		syncRec.lock(Exclusive);
 
 		RecordVersion *record = *savePoint->records;
 		RecordVersion *stack = NULL;
@@ -1290,6 +1291,7 @@ void Transaction::rollbackSavepoint(int 
 			rec->transaction = NULL;
 			rec->release();
 			}
+		syncRec.unlock();
 
 		// Handle any backlogged records
 		
@@ -1335,6 +1337,8 @@ void Transaction::releaseRecordLocks(voi
 	RecordVersion **ptr;
 	RecordVersion *record;
 
+	Sync syncRec(&syncRecords,"Transaction::releaseRecordLocks");
+	syncRec.lock(Exclusive);
 	for (ptr = &firstRecord; (record = *ptr);)
 		if (record->state == recLock)
 			{
@@ -1343,6 +1347,7 @@ void Transaction::releaseRecordLocks(voi
 			}
 		else
 			ptr = &record->nextInTrans;
+	syncRec.unlock();
 }
 
 void Transaction::print(void)
@@ -1360,6 +1365,8 @@ void Transaction::printBlocking(int leve
 	int deletes = 0;
 	RecordVersion *record;
 
+	Sync syncRec(&syncRecords,"Transaction::printBlocking");
+	syncRec.lock(Shared);
 	for (record = firstRecord; record; record = record->nextInTrans)
 		if (record->state == recLock)
 			++locks;
@@ -1407,7 +1414,7 @@ void Transaction::printBlocking(int leve
 				   record->recordNumber,
 				   what);
 		}
-
+	syncRec.unlock();
 	database->transactionManager->printBlocking(this, level);
 }
 
@@ -1445,14 +1452,7 @@ void Transaction::releaseDependency(void
 	INTERLOCKED_DECREMENT(dependencies);
 
 	if ((dependencies == 0) && !writePending && firstRecord)
-		{
-		// The Sync is to avoid a race with writeComplete().  It looks whacko, but does the trick
-		
-		Sync sync(&syncIndexes, "Transaction::releaseDependency");
-		sync.lock(Exclusive);
 		commitRecords();
-		}
-		
 	releaseCommittedTransaction();
 }
 
@@ -1497,6 +1497,8 @@ void Transaction::printBlockage(void)
 
 void Transaction::releaseDeferredIndexes(void)
 {
+	Sync sync(&syncIndexes, "Transaction::releaseDeferredIndexes");
+	sync.lock(Exclusive);
 	for (DeferredIndex *deferredIndex; (deferredIndex = deferredIndexes);)
 		{
 		ASSERT(deferredIndex->transaction == this);
@@ -1554,7 +1556,8 @@ void Transaction::backlogRecords(void)
 void Transaction::validateRecords(void)
 {
 	RecordVersion *record;
-	
+	Sync syncRec(&syncRecords,"Transaction::validateRecords");
+	syncRec.lock(Shared);
 	for (record = firstRecord; record && record->nextInTrans; record = record->nextInTrans)
 		;
 	

=== modified file 'storage/falcon/Transaction.h'
--- a/storage/falcon/Transaction.h	2008-08-11 13:22:53 +0000
+++ b/storage/falcon/Transaction.h	2008-08-25 18:24:59 +0000
@@ -87,7 +87,8 @@ public:
 
 	State		getRelativeState(Record* record, uint32 flags);
 	State		getRelativeState (Transaction *transaction, TransId transId, uint32 flags);
-	void		removeRecord (RecordVersion *record);
+	void		removeRecordNoLock (RecordVersion *record);
+	void		removeRecord(RecordVersion *record);
 	void		removeRecord (RecordVersion *record, RecordVersion **ptr);
 	void		expungeTransaction (Transaction *transaction);
 	void		commitRecords();
@@ -171,6 +172,7 @@ public:
 	SyncObject		syncObject;
 	SyncObject		syncActive;
 	SyncObject		syncIndexes;
+	SyncObject		syncRecords;
 	SyncObject		syncSavepoints;
 	uint64			totalRecordData;	// total bytes of record data for this transaction (unchilled + thawed)
 	uint32			totalRecords;		// total record count

=== modified file 'storage/falcon/TransactionManager.cpp'
--- a/storage/falcon/TransactionManager.cpp	2008-08-14 12:08:37 +0000
+++ b/storage/falcon/TransactionManager.cpp	2008-08-25 21:51:46 +0000
@@ -74,26 +74,25 @@ TransId TransactionManager::findOldestAc
 {
 	Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::findOldestActive(1)");
 	syncCommitted.lock(Shared);
-	TransId oldestActive = transactionSequence;
+	TransId oldestCommitted = transactionSequence;
 	
 	for (Transaction *trans = committedTransactions.first; trans; trans = trans->next)
-		oldestActive = MIN(trans->transactionId, oldestActive);
+		oldestCommitted = MIN(trans->transactionId, oldestCommitted);
 
 	syncCommitted.unlock();
-	Sync sync(&activeTransactions.syncObject, "TransactionManager::findOldestActive(2)");
-	sync.lock(Shared);
+
 	Transaction *oldest = findOldest();
 
 	if (oldest)
 		{
-		//Log::debug("Oldest transaction %d, oldest ancestor %d, oldest committed %d\n",  oldest->transactionId, oldest->oldestActive, oldestActive);
-					
-		return MIN(oldest->oldestActive, oldestActive);
+		//Log::debug("Oldest transaction %d, oldest ancestor %d, oldest committed %d\n",  oldest->transactionId, oldest->oldestActive, oldestCommitted);
+
+		return MIN(oldest->oldestActive, oldestCommitted);
 		}
 	
 	//Log::debug("No active, current %d, oldest committed %d\n", transactionSequence, oldestActive);
 	
-	return oldestActive;
+	return oldestCommitted;
 }
 
 Transaction* TransactionManager::findOldest(void)
@@ -247,16 +246,20 @@ void TransactionManager::rollbackByXid(i
 
 void TransactionManager::print(void)
 {
-	Sync sync (&activeTransactions.syncObject, "TransactionManager::print(1)");
-	sync.lock (Exclusive);
-	Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::print(2)");
-	committedTrans.lock (Exclusive);
+	Sync syncActive (&activeTransactions.syncObject, "TransactionManager::print(1)");
+	syncActive.lock (Exclusive);
+
+	Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::print(2)");
+	syncCommitted.lock (Exclusive);
+
 	Transaction *transaction;
 	Log::debug("Active Transaction:\n");
 	
 	for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
 		transaction->print();
-		
+
+	syncActive.unlock();
+
 	Log::debug("Committed Transaction:\n");
 	
 	for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
@@ -266,15 +269,19 @@ void TransactionManager::print(void)
 
 void TransactionManager::getTransactionInfo(InfoTable* infoTable)
 {
-	Sync sync (&activeTransactions.syncObject, "TransactionManager::getTransactionInfo(1)");
-	sync.lock (Exclusive);
-	Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::getTransactionInfo(2)");
-	committedTrans.lock (Exclusive);
+	Sync syncActive (&activeTransactions.syncObject, "TransactionManager::getTransactionInfo(2)");
+	syncActive.lock (Exclusive);
+
+	Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::getTransactionInfo(1)");
+	syncCommitted.lock (Exclusive);
+
 	Transaction *transaction;
 	
 	for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
 		transaction->getInfo(infoTable);
-	
+
+	syncActive.unlock();
+
 	for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
 		transaction->getInfo(infoTable);
 }
@@ -307,10 +314,12 @@ void TransactionManager::purgeTransactio
 
 void TransactionManager::getSummaryInfo(InfoTable* infoTable)
 {
-	Sync sync (&activeTransactions.syncObject, "TransactionManager::getSummaryInfo(1)");
-	sync.lock (Exclusive);
-	Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::getSummaryInfo(2)");
-	committedTrans.lock (Exclusive);
+	Sync syncActive (&activeTransactions.syncObject, "TransactionManager::getSummaryInfo(2)");
+	syncActive.lock (Exclusive);
+
+	Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::getSummaryInfo(1)");
+	syncCommitted.lock (Exclusive);
+
 	int numberCommitted = committed;
 	int numberRolledBack = rolledBack;
 	int numberActive = 0;
@@ -327,14 +336,14 @@ void TransactionManager::getSummaryInfo(
 		if (transaction->state == Committed)
 			++numberPendingCommit;
 		}
+	syncActive.unlock();
 
 	for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
 		if (transaction->writePending)
 			++numberPendingCompletion;
 	
-	committedTrans.unlock();
-	sync.unlock();
-	
+	syncCommitted.unlock();
+
 	int n = 0;
 	infoTable->putInt(n++, numberCommitted);
 	infoTable->putInt(n++, numberRolledBack);
@@ -402,15 +411,16 @@ void TransactionManager::expungeTransact
 
 Transaction* TransactionManager::findTransaction(TransId transactionId)
 {
-	Sync syncActiveTrans(&activeTransactions.syncObject, "TransactionManager::findTransaction(1)");
-	syncActiveTrans.lock(Shared);
+	Sync syncActive(&activeTransactions.syncObject, "TransactionManager::findTransaction(1)");
+	syncActive.lock(Shared);
 	Transaction *transaction;
 
 	for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
 		if (transaction->transactionId == transactionId)
 			return transaction;
 	
-	syncActiveTrans.unlock();
+	syncActive.unlock();
+
 	Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::findTransaction(2)");
 	syncCommitted.lock(Shared);
 
@@ -418,20 +428,21 @@ Transaction* TransactionManager::findTra
 		if (transaction->transactionId == transactionId)
 			return transaction;
 	
-	return NULL;	
+	return NULL;
 }
 
 void TransactionManager::validateDependencies(void)
 {
-	Sync sync(&committedTransactions.syncObject, "TransactionManager::validateDepedendencies(1)");
-	sync.lock(Shared);
+	Sync syncActive(&activeTransactions.syncObject, "TransactionManager::validateDepedendencies(1)");
+	syncActive.lock(Shared);
 	Transaction *transaction;
 
 	for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
 		if (transaction->isActive())
 			transaction->validateDependencies(false);
 			
-	sync.unlock();
+	syncActive.unlock();
+
 	Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::validateDepedendencies(2)");
 	syncCommitted.lock(Shared);
 

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2008-08-28 06:20:55 +0000
+++ b/storage/falcon/ha_falcon.cpp	2008-08-28 08:44:13 +0000
@@ -54,7 +54,7 @@
 #endif
 
 #ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
+#define ONLINE_ALTER
 #endif
 
 #ifdef DEBUG_BACKLOG
@@ -216,13 +216,13 @@ int StorageInterface::falcon_init(void *
 		}
 	catch(SQLException &e)
 		{
-		sql_print_error("Falcon : exception '%s'during initialization",
+		sql_print_error("Falcon: Exception '%s' during initialization",
 			e.getText());
 		error = true;
 		}
 	catch(...)
 		{
-		sql_print_error(" Falcon : general exception in initialization");
+		sql_print_error(" Falcon: General exception in initialization");
 		error = true;
 		}
 
@@ -398,6 +398,7 @@ StorageInterface::StorageInterface(handl
 	ref_length = sizeof(lastRecord);
 	stats.records = 1000;
 	stats.data_file_length = 10000;
+	stats.index_file_length = 0;
 	tableLocked = false;
 	lockForUpdate = false;
 	storageTable = NULL;
@@ -424,6 +425,9 @@ StorageInterface::StorageInterface(handl
 
 StorageInterface::~StorageInterface(void)
 {
+	if (storageTable)
+		storageTable->clearCurrentIndex();
+
 	if (activeBlobs)
 		freeActiveBlobs();
 
@@ -482,6 +486,7 @@ int StorageInterface::open(const char *n
 
 		if (!storageShare->initialized)
 			{
+//			storageShare->lockIndexes(true);
 			storageShare->lock(true);
 
 			if (!storageShare->initialized)
@@ -505,6 +510,7 @@ int StorageInterface::open(const char *n
 				}
 
 			storageShare->unlock();
+//			storageShare->unlockIndexes();
 			}
 		}
 
@@ -535,6 +541,10 @@ StorageConnection* StorageInterface::get
 int StorageInterface::close(void)
 {
 	DBUG_ENTER("StorageInterface::close");
+
+	if (storageTable)
+		storageTable->clearCurrentIndex();
+
 	unmapFields();
 
 	// Temporarily comment out DTrace probes in Falcon, see bug #36403
@@ -672,23 +682,27 @@ void StorageInterface::getDemographics(v
 
 	stats.block_size = 4096;
 
+	storageShare->lockIndexes();
+
 	for (uint n = 0; n < table->s->keys; ++n)
 		{
 		KEY *key = table->s->key_info + n;
-		StorageIndexDesc *desc = storageShare->getIndex(n);
+		StorageIndexDesc *indexDesc = storageShare->getIndex(n);
 
-		if (desc)
+		if (indexDesc)
 			{
-			ha_rows rows = 1 << desc->numberSegments;
+			ha_rows rows = 1 << indexDesc->numberSegments;
 
 			for (uint segment = 0; segment < key->key_parts; ++segment, rows >>= 1)
 				{
-				ha_rows recordsPerSegment = (ha_rows) desc->segmentRecordCounts[segment];
+				ha_rows recordsPerSegment = (ha_rows)indexDesc->segmentRecordCounts[segment];
 				key->rec_per_key[segment] = (ulong) MAX(recordsPerSegment, rows);
 				}
 			}
 		}
 
+	storageShare->unlockIndexes();
+
 	DBUG_VOID_RETURN;
 }
 
@@ -832,7 +846,7 @@ int StorageInterface::create(const char 
 
 	for (n = 0; n < form->s->keys; ++n)
 		if (n != form->s->primary_key)
-			if ((ret = createIndex(schemaName, tableName, form->key_info + n, n)))
+			if ((ret = createIndex(schemaName, tableName, form, n)))
 				{
 				storageTable->deleteTable();
 
@@ -847,32 +861,42 @@ int StorageInterface::create(const char 
 int StorageInterface::add_index(TABLE* table_arg, KEY* key_info, uint num_of_keys)
 {
 	DBUG_ENTER("StorageInterface::add_index");
-	int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), key_info, table_arg->s->keys);
+	int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), table_arg, table_arg->s->keys);
 
 	DBUG_RETURN(ret);
 }
 
-int StorageInterface::createIndex(const char *schemaName, const char *tableName,
-                                 KEY *key, int indexNumber)
+int StorageInterface::createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId)
 {
+	KEY *key = table->key_info + indexId;
+	StorageIndexDesc indexDesc;
+	getKeyDesc(table, indexId, &indexDesc);
+	
+	char indexName[indexNameSize];
+	storageShare->createIndexName(indexDesc.name, indexName);
+
 	CmdGen gen;
 	const char *unique = (key->flags & HA_NOSAME) ? "unique " : "";
-	gen.gen("create %sindex \"%s$%d\" on %s.\"%s\" ", unique, tableName,
-	        indexNumber, schemaName, tableName);
+	gen.gen("create %sindex \"%s\" on %s.\"%s\" ", unique, indexName, schemaName, tableName);
 	genKeyFields(key, &gen);
 	const char *sql = gen.getString();
 
-	return storageTable->share->createIndex(storageConnection, key->name, sql);
+	return storageTable->createIndex(&indexDesc, sql);
 }
 
-int StorageInterface::dropIndex(const char *schemaName, const char *tableName,
-                                 KEY *key, int indexNumber)
+int StorageInterface::dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId)
 {
+	StorageIndexDesc indexDesc;
+	getKeyDesc(table, indexId, &indexDesc);
+	
+	char indexName[indexNameSize];
+	storageShare->createIndexName(indexDesc.name, indexName);
+
 	CmdGen gen;
-	gen.gen("drop index %s.\"%s$%d\"", schemaName, tableName, indexNumber);
+	gen.gen("drop index %s.\"%s\"", schemaName, indexName);
 	const char *sql = gen.getString();
 
-	return storageTable->share->dropIndex(storageConnection, key->name, sql);
+	return storageTable->dropIndex(&indexDesc, sql);
 }
 
 #if 0
@@ -916,6 +940,8 @@ THR_LOCK_DATA **StorageInterface::store_
 		    && !(thd_tablespace_op(thd))
 		    &&  (sql_command != SQLCOM_ALTER_TABLE)
 		    &&  (sql_command != SQLCOM_DROP_TABLE)
+		    &&  (sql_command != SQLCOM_CREATE_INDEX)
+		    &&  (sql_command != SQLCOM_DROP_INDEX)
 		    &&  (sql_command != SQLCOM_TRUNCATE)
 		    &&  (sql_command != SQLCOM_OPTIMIZE)
 		    &&  (sql_command != SQLCOM_CREATE_TABLE)
@@ -963,6 +989,10 @@ int StorageInterface::delete_table(const
 
 	if (storageShare)
 		{
+		
+		// Lock out other clients before locking the table
+		
+		storageShare->lockIndexes(true);
 		storageShare->lock(true);
 
 		if (storageShare->initialized)
@@ -973,6 +1003,7 @@ int StorageInterface::delete_table(const
 			}
 
 		storageShare->unlock();
+		storageShare->unlockIndexes();
 		}
 
 	int res = storageTable->deleteTable();
@@ -1358,7 +1389,6 @@ int StorageInterface::index_read(uchar *
 		}
 }
 
-
 int StorageInterface::index_init(uint idx, bool sorted)
 {
 	DBUG_ENTER("StorageInterface::index_init");
@@ -1367,33 +1397,30 @@ int StorageInterface::index_init(uint id
 	haveStartKey = false;
 	haveEndKey = false;
 
-	if (!storageTable->setIndex(idx))
-		DBUG_RETURN(0);
-
-	StorageIndexDesc indexDesc;
-	getKeyDesc(table->key_info + idx, &indexDesc);
-
-	if (idx == table->s->primary_key)
-		indexDesc.primaryKey = true;
-
-	int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc);
+	int ret = storageTable->setCurrentIndex(idx);
 
 	if (ret)
+		{
+		setIndex(table, idx);
+		ret = storageTable->setCurrentIndex(idx);
+		}
+		
+	if (ret)
 		DBUG_RETURN(error(ret));
 
-	DBUG_RETURN(0);
+	DBUG_RETURN(ret);
 }
 
-
 int StorageInterface::index_end(void)
 {
 	DBUG_ENTER("StorageInterface::index_end");
+	
 	storageTable->indexEnd();
+	
 	DBUG_RETURN(0);
 }
 
-ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower,
-                                         key_range *upper)
+ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower, key_range *upper)
 {
 	DBUG_ENTER("StorageInterface::records_in_range");
 
@@ -1406,9 +1433,9 @@ ha_rows StorageInterface::records_in_ran
 	if (!lower)
 		DBUG_RETURN(MAX(cardinality, 2));
 
-	StorageIndexDesc *index = storageShare->getIndex(indexId);
+	StorageIndexDesc indexDesc;
 
-	if (!index)
+	if (!storageShare->getIndex(indexId, &indexDesc))
 		DBUG_RETURN(MAX(cardinality, 2));
 
 	int numberSegments = 0;
@@ -1416,10 +1443,10 @@ ha_rows StorageInterface::records_in_ran
 	for (int map = lower->keypart_map; map; map >>= 1)
 		++numberSegments;
 
-	if (index->unique && numberSegments == index->numberSegments)
+	if (indexDesc.unique && numberSegments == indexDesc.numberSegments)
 		DBUG_RETURN(1);
 
-	ha_rows segmentRecords = (ha_rows) index->segmentRecordCounts[numberSegments - 1];
+	ha_rows segmentRecords = (ha_rows)indexDesc.segmentRecordCounts[numberSegments - 1];
 	ha_rows guestimate = cardinality;
 
 	if (lower->flag == HA_READ_KEY_EXACT)
@@ -1436,22 +1463,34 @@ ha_rows StorageInterface::records_in_ran
 	DBUG_RETURN(MAX(guestimate, 2));
 }
 
-
-void StorageInterface::getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo)
+void StorageInterface::getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexDesc)
 {
+	KEY *keyInfo = table->key_info + indexId;
 	int numberKeys = keyInfo->key_parts;
-	indexInfo->numberSegments = numberKeys;
-	indexInfo->name = keyInfo->name;
-	indexInfo->unique = (keyInfo->flags & HA_NOSAME);
-	indexInfo->primaryKey = false;
+	char nameBuffer[indexNameSize];
+	
+	// Clean up the index name for internal use
+	
+	strncpy(indexDesc->rawName, (const char*)keyInfo->name, MIN(indexNameSize, (int)strlen(keyInfo->name)+1));
+	storageShare->cleanupFieldName(indexDesc->rawName, nameBuffer, sizeof(nameBuffer));
+	indexDesc->rawName[indexNameSize-1] = '\0';
+	
+	strncpy(indexDesc->name, (const char*)nameBuffer, MIN(indexNameSize, (int)strlen(nameBuffer)+1));
+	indexDesc->name[indexNameSize-1] = '\0';
+
+	indexDesc->id			  = indexId;
+	indexDesc->numberSegments = numberKeys;
+	indexDesc->unique		  = (keyInfo->flags & HA_NOSAME);
+	indexDesc->primaryKey	  = (table->s->primary_key == (uint)indexId);
 
 	for (int n = 0; n < numberKeys; ++n)
 		{
-		StorageSegment *segment = indexInfo->segments + n;
+		StorageSegment *segment = indexDesc->segments + n;
 		KEY_PART_INFO *part = keyInfo->key_part + n;
-		segment->offset = part->offset;
-		segment->length = part->length;
-		segment->type = part->field->key_type();
+		
+		segment->offset	= part->offset;
+		segment->length	= part->length;
+		segment->type	= part->field->key_type();
 		segment->nullBit = part->null_bit;
 		segment->isUnsigned = (part->field->flags & ENUM_FLAG) ?
 			true : ((Field_num*) part->field)->unsigned_flag;
@@ -1472,7 +1511,6 @@ void StorageInterface::getKeyDesc(KEY *k
 		}
 }
 
-
 int StorageInterface::rename_table(const char *from, const char *to)
 {
 	DBUG_ENTER("StorageInterface::rename_table");
@@ -1489,17 +1527,14 @@ int StorageInterface::rename_table(const
 		DBUG_RETURN(error(ret));
 
 	DBUG_RETURN(ret);
-
 }
 
-
 double StorageInterface::read_time(uint index, uint ranges, ha_rows rows)
 {
 	DBUG_ENTER("StorageInterface::read_time");
 	DBUG_RETURN(rows2double(rows / 3));
 }
 
-
 int StorageInterface::read_range_first(const key_range *start_key,
                                       const key_range *end_key,
                                       bool eq_range_arg, bool sorted)
@@ -1634,7 +1669,6 @@ int StorageInterface::index_next(uchar *
 		}
 }
 
-
 int StorageInterface::index_next_same(uchar *buf, const uchar *key, uint key_len)
 {
 	DBUG_ENTER("StorageInterface::index_next_same");
@@ -1654,7 +1688,6 @@ int StorageInterface::index_next_same(uc
 		}
 }
 
-
 double StorageInterface::scan_time(void)
 {
 	DBUG_ENTER("StorageInterface::scan_time");
@@ -1691,13 +1724,11 @@ bool StorageInterface::threadSwitch(THD*
 	return true;
 }
 
-
 int StorageInterface::threadSwitchError(void)
 {
 	return 1;
 }
 
-
 int StorageInterface::error(int storageError)
 {
 	DBUG_ENTER("StorageInterface::error");
@@ -1737,7 +1768,6 @@ int StorageInterface::error(int storageE
 	DBUG_RETURN(mySqlError);
 }
 
-
 int StorageInterface::getMySqlError(int storageError)
 {
 	switch (storageError)
@@ -1856,8 +1886,6 @@ int StorageInterface::reset()
 	DBUG_RETURN(0);
 }
 
- 
- 
 int StorageInterface::external_lock(THD *thd, int lock_type)
 {
 	DBUG_ENTER("StorageInterface::external_lock");
@@ -1873,7 +1901,10 @@ int StorageInterface::external_lock(THD 
 			storageConnection->releaseVerb();
 
 		if (storageTable)
+			{
 			storageTable->clearStatement();
+			storageTable->clearCurrentIndex();
+			}
 		}
 	else
 		{
@@ -1894,6 +1925,9 @@ int StorageInterface::external_lock(THD 
 
 				if (ret)
 					{
+					if (storageTable)
+						storageTable->clearCurrentIndex();
+						
 					DBUG_RETURN(error(ret));
 					}
 				}
@@ -1910,9 +1944,7 @@ int StorageInterface::external_lock(THD 
 			checkBinLog();
 			
 			if (storageConnection->startTransaction(isolation))
-				{
 				trans_register_ha(thd, true, falcon_hton);
-				}
 
 			if (storageConnection->markVerb())
 				trans_register_ha(thd, false, falcon_hton);
@@ -1922,9 +1954,7 @@ int StorageInterface::external_lock(THD 
 			checkBinLog();
 			
 			if (storageConnection->startImplicitTransaction(isolation))
-				{
 				trans_register_ha(thd, false, falcon_hton);
-				}
 			}
 
 		switch (thd_tx_isolation(mySqlThread))
@@ -1937,13 +1967,11 @@ int StorageInterface::external_lock(THD 
 				error(StorageWarningSerializable);
 				break;
 			}
-			
 		}
 
 	DBUG_RETURN(0);
 }
 
-
 void StorageInterface::get_auto_increment(ulonglong offset, ulonglong increment,
                                          ulonglong nb_desired_values,
                                          ulonglong *first_value,
@@ -1956,7 +1984,6 @@ void StorageInterface::get_auto_incremen
 	DBUG_VOID_RETURN;
 }
 
-
 const char *StorageInterface::index_type(uint key_number)
 {
   DBUG_ENTER("StorageInterface::index_type");
@@ -1971,7 +1998,6 @@ void StorageInterface::dropDatabase(hand
 	DBUG_VOID_RETURN;
 }
 
-
 void StorageInterface::freeActiveBlobs(void)
 {
 	for (StorageBlob *blob; (blob = activeBlobs); )
@@ -1983,14 +2009,12 @@ void StorageInterface::freeActiveBlobs(v
 		}
 }
 
-
 void StorageInterface::shutdown(handlerton *htons)
 {
 	if(storageHandler)
 		storageHandler->shutdownHandler();
 }
 
-
 int StorageInterface::panic(handlerton* hton, ha_panic_function flag)
 {
 	if(storageHandler)
@@ -1999,7 +2023,6 @@ int StorageInterface::panic(handlerton* 
 	return 0;
 }
 
-
 int StorageInterface::closeConnection(handlerton *hton, THD *thd)
 {
 	DBUG_ENTER("NfsStorageEngine::closeConnection");
@@ -2009,7 +2032,6 @@ int StorageInterface::closeConnection(ha
 	DBUG_RETURN(0);
 }
 
-
 int StorageInterface::alter_tablespace(handlerton* hton, THD* thd, st_alter_tablespace* ts_info)
 {
 	DBUG_ENTER("NfsStorageEngine::alter_tablespace");
@@ -2228,10 +2250,15 @@ int StorageInterface::addColumn(THD* thd
 
 int StorageInterface::addIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags)
 {
-	int ret;
+	int ret = 0;
 	const char *tableName = storageTable->getName();
 	const char *schemaName = storageTable->getSchemaName();
 
+	// Lock out other clients before locking the table
+	
+	storageShare->lockIndexes(true);
+	storageShare->lock(true);
+
 	// Find indexes to be added by comparing table and alteredTable
 
 	for (unsigned int n = 0; n < alteredTable->s->keys; n++)
@@ -2247,19 +2274,33 @@ int StorageInterface::addIndex(THD* thd,
 					break;
 					
 			if (tableKey >= tableEnd)
-				if ((ret = createIndex(schemaName, tableName, key, n)))
-					return (error(ret));
+				if ((ret = createIndex(schemaName, tableName, alteredTable, n)))
+					break;
 			}
 		}
-	return 0;
+		
+	// The server indexes may have been reordered, so remap to the Falcon indexes
+	
+	if (!ret)
+		remapIndexes(alteredTable);
+	
+	storageShare->unlock();
+	storageShare->unlockIndexes();
+	
+	return error(ret);
 }
 
 int StorageInterface::dropIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags)
 {
-	int ret;
+	int ret = 0;
 	const char *tableName = storageTable->getName();
 	const char *schemaName = storageTable->getSchemaName();
 	
+	// Lock out other clients before locking the table
+	
+	storageShare->lockIndexes(true);
+	storageShare->lock(true);
+	
 	// Find indexes to be dropped by comparing table and alteredTable
 	
 	for (unsigned int n = 0; n < table->s->keys; n++)
@@ -2275,12 +2316,20 @@ int StorageInterface::dropIndex(THD* thd
 					break;
 
 			if (alterKey >= alterEnd)
-				if ((ret = dropIndex(schemaName, tableName, key, n)))
-				return (error(ret));
+				if ((ret = dropIndex(schemaName, tableName, table, n)))
+					break;
 				}
 		}
 	
-	return 0;
+	// The server indexes have been reordered, so remap to the Falcon indexes
+	
+	if (!ret)
+		remapIndexes(alteredTable);
+	
+	storageShare->unlock();
+	storageShare->unlockIndexes();
+	
+	return error(ret);
 }
 
 uint StorageInterface::max_supported_key_length(void) const
@@ -2292,7 +2341,6 @@ uint StorageInterface::max_supported_key
 	return MAX_INDEX_KEY_LENGTH_4K;  // Default value.
 }
 
-
 uint StorageInterface::max_supported_key_part_length(void) const
 {
 	// Assume 4K page unless proven otherwise.
@@ -2302,7 +2350,6 @@ uint StorageInterface::max_supported_key
 	return MAX_INDEX_KEY_LENGTH_4K;  // Default for future sizes.
 }
 
-
 void StorageInterface::logger(int mask, const char* text, void* arg)
 {
 	if (mask & falcon_debug_mask)
@@ -2318,32 +2365,47 @@ void StorageInterface::logger(int mask, 
 		}
 }
 
+int StorageInterface::setIndex(TABLE *table, int indexId)
+{
+	StorageIndexDesc indexDesc;
+	getKeyDesc(table, indexId, &indexDesc);
+
+	return storageTable->setIndex(&indexDesc);
+}
+
 int StorageInterface::setIndexes(void)
 {
+	int ret = 0;
+	
 	if (!table || storageShare->haveIndexes(table->s->keys))
-		return 0;
+		return ret;
 
-	storageShare->lock(true);
+	storageShare->lockIndexes(true);
 
 	if (!storageShare->haveIndexes(table->s->keys))
-		{
-		StorageIndexDesc indexDesc;
-
 		for (uint n = 0; n < table->s->keys; ++n)
-			{
-			getKeyDesc(table->key_info + n, &indexDesc);
+			if ((ret = setIndex(table, n)))
+				break;
 
-			if (n == table->s->primary_key)
-				indexDesc.primaryKey = true;
+	storageShare->unlockIndexes();
 
-			int ret = storageTable->setIndex(table->s->keys, n, &indexDesc);
-			if (ret)
-				return ret;
-			}
-		}
+	return ret;
+}
 
-	storageShare->unlock();
-	return 0;
+int StorageInterface::remapIndexes(TABLE *table)
+{
+	int ret = 0;
+	
+	if (!table)
+		return ret;
+		
+	storageShare->deleteIndexes();
+
+	for (uint n = 0; n < table->s->keys; ++n)
+		if ((ret = setIndex(table, n)))
+			break;
+
+	return ret;
 }
 
 int StorageInterface::genTable(TABLE* table, CmdGen* gen)
@@ -2352,7 +2414,7 @@ int StorageInterface::genTable(TABLE* ta
 	const char *schemaName = storageTable->getSchemaName();
 	gen->gen("upgrade table \"%s\".\"%s\" (\n", schemaName, tableName);
 	const char *sep = "";
-	char nameBuffer[129];
+	char nameBuffer[256];
 
 	for (uint n = 0; n < table->s->fields; ++n)
 		{
@@ -2499,18 +2561,16 @@ int StorageInterface::genType(Field* fie
 	return 0;
 }
 
-
 void StorageInterface::genKeyFields(KEY* key, CmdGen* gen)
 {
 	const char *sep = "(";
-	char nameBuffer[129];
+	char nameBuffer[256];
 
 	for (uint n = 0; n < key->key_parts; ++n)
 		{
 		KEY_PART_INFO *part = key->key_part + n;
 		Field *field = part->field;
-		storageShare->cleanupFieldName(field->field_name, nameBuffer,
-										sizeof(nameBuffer));
+		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer));
 
 		if (part->key_part_flag & HA_PART_KEY_SEG)
 			gen->gen("%s\"%s\"(%d)", sep, nameBuffer, part->length);
@@ -2523,7 +2583,6 @@ void StorageInterface::genKeyFields(KEY*
 	gen->gen(")");
 }
 
-
 void StorageInterface::encodeRecord(uchar *buf, bool updateFlag)
 {
 	storageTable->preInsert();
@@ -3508,7 +3567,7 @@ void StorageInterface::mapFields(TABLE *
 	unmapFields();
 	fieldMap = new Field*[maxFields];
 	memset(fieldMap, 0, sizeof(fieldMap[0]) * maxFields);
-	char nameBuffer[129];
+	char nameBuffer[256];
 
 	for (uint n = 0; n < table->s->fields; ++n)
 		{

=== modified file 'storage/falcon/ha_falcon.h'
--- a/storage/falcon/ha_falcon.h	2008-07-29 10:45:39 +0000
+++ b/storage/falcon/ha_falcon.h	2008-08-22 06:47:40 +0000
@@ -29,7 +29,7 @@ static const int TRANSACTION_CONSISTENT_
 static const int TRANSACTION_SERIALIZABLE     = 16;	// Dirty reads, non-repeatable reads and phantom reads are prevented.
 
 struct st_table_share;
-struct StorageIndexDesc;
+class StorageIndexDesc;
 struct StorageBlob;
 
 class StorageInterface : public handler
@@ -113,15 +113,18 @@ public:
 	int				dropIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags);
 
 	void			getDemographics(void);
-	int				createIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber);
-	int				dropIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber);
-	void			getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo);
+//	int				createIndex(const char *schemaName, const char *tableName, KEY *key, int indexId);
+	int				createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId);
+	int				dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId);
+	void			getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexInfo);
 	void			startTransaction(void);
 	bool			threadSwitch(THD *newThread);
 	int				threadSwitchError(void);
 	int				error(int storageError);
 	void			freeActiveBlobs(void);
+	int				setIndex(TABLE *table, int indexId);
 	int				setIndexes(void);
+	int				remapIndexes(TABLE *table);
 	int				genTable(TABLE* table, CmdGen* gen);
 	int				genType(Field *field, CmdGen *gen);
 	void			genKeyFields(KEY *key, CmdGen *gen);

=== modified file 'storage/falcon/plug.in'
--- a/storage/falcon/plug.in	2008-08-12 21:50:50 +0000
+++ b/storage/falcon/plug.in	2008-08-20 13:27:29 +0000
@@ -19,6 +19,18 @@ volatile int target= 0;
 int compare= 1;
 int exchange= 2;
       ],[
+#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+  /* When compiling with Sun Studio compiler we need the Solaris atomic 
+     functions. These were first introduced in Solaris 10. */
+#if defined(HAVE_SOLARIS_ATOMIC)
+  return 0;
+#else 
+  /* Fail if the atomic functions are not available. Support for this
+     will be added when the fix for bug 37622 is completed. */
+#error Need Solaris atomic functions to use Sun Studio compiler
+#endif /* HAVE_SOLARIS_ATOMIC */
+#else
+  /* Use gcc style inline assembly when compiling with gcc */
   char ret;
   __asm__ __volatile__ (
 	  "membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore\n\t"
@@ -32,6 +44,7 @@ int exchange= 2;
 	  : "r" (&target), "0" (compare)
 	  : "memory", "cc"
 	  )
+#endif /* !__SUNPRO_C && !__SUNPRO_CC */
       ], falcon_supported_by_machine="yes", 
          falcon_supported_by_machine="no")
       ;;

=== modified file 'storage/maria/CMakeLists.txt'
--- a/storage/maria/CMakeLists.txt	2008-06-09 09:06:06 +0000
+++ b/storage/maria/CMakeLists.txt	2008-08-26 18:57:58 +0000
@@ -49,6 +49,7 @@ SET(MARIA_SOURCES ma_init.c ma_open.c ma
 IF(NOT SOURCE_SUBLIBS)
 
   ADD_LIBRARY(maria ${MARIA_SOURCES})
+  ADD_DEPENDENCIES(ha_falcon GenError)
 
 ADD_EXECUTABLE(maria_ftdump maria_ftdump.c)
 TARGET_LINK_LIBRARIES(maria_ftdump maria myisam mysys dbug strings zlib wsock32)

Thread
bzr commit into mysql-6.0 branch (kgeorge:2808) Georgi Kodinov28 Aug