List:Commits« Previous MessageNext Message »
From:Martin Skold Date:May 30 2011 9:39pm
Subject:bzr commit into mysql-5.5-cluster branch (Martin.Skold:3349)
View as plain text  
#At file:///home/marty/MySQL/mysql-5.5-cluster_WL3749/ based on revid:magnus.blaudd@stripped

 3349 Martin Skold	2011-05-30 [merge]
      WL3749: MySQL Cluster: On-line DDL, new handler interface: Code from 5.1 adapted to 5.5 changes

    modified:
      include/my_base.h
      mysql-test/include/ndb_have_online_alter.inc
      mysql-test/r/ctype_utf8mb4.result
      mysql-test/suite/innodb/r/innodb-index.result
      mysql-test/suite/innodb/r/innodb.result
      mysql-test/suite/innodb/t/innodb-index.test
      mysql-test/suite/innodb/t/innodb.test
      mysql-test/suite/ndb/r/ndb_alter_table.result
      mysql-test/suite/ndb/r/ndb_alter_table3.result
      mysql-test/suite/ndb/r/ndb_alter_table_online.result
      mysql-test/suite/ndb/r/ndb_dd_restore_compat.result
      mysql-test/suite/ndb/r/ndb_gis.result
      mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result
      mysql-test/suite/ndb/r/ndb_short_sigs.result
      mysql-test/suite/ndb/t/disabled.def
      mysql-test/suite/ndb/t/ndb_alter_table_online2.test
      mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result
      mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result
      mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result
      mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      sql/ha_ndbcluster_glue.h
      sql/handler.cc
      sql/handler.h
      sql/lex.h
      sql/log.cc
      sql/sql_admin.cc
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_bitmap.h
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_partition.cc
      sql/sql_partition.h
      sql/sql_show.cc
      sql/sql_table.cc
      sql/sql_truncate.cc
      sql/sql_yacc.yy
      sql/table.cc
      sql/table.h
      sql/unireg.cc
      storage/csv/ha_tina.cc
=== modified file 'include/my_base.h'
--- a/include/my_base.h	2011-03-14 15:13:48 +0000
+++ b/include/my_base.h	2011-05-30 21:13:02 +0000
@@ -96,6 +96,15 @@ enum ha_key_alg {
   HA_KEY_ALG_FULLTEXT=	4		/* FULLTEXT (MyISAM tables) */
 };
 
+#ifndef MCP_WL3749
+        /* Index and table build methods */
+
+enum ha_build_method {
+  HA_BUILD_DEFAULT,
+  HA_BUILD_ONLINE,
+  HA_BUILD_OFFLINE
+};
+#endif
         /* Storage media types */ 
 
 enum ha_storage_media {

=== modified file 'mysql-test/include/ndb_have_online_alter.inc'
--- a/mysql-test/include/ndb_have_online_alter.inc	2011-02-02 10:33:25 +0000
+++ b/mysql-test/include/ndb_have_online_alter.inc	2011-04-20 12:53:27 +0000
@@ -6,9 +6,9 @@
 --disable_result_log
 let $have_online_alter = 1;
 CREATE TABLE check_online_alter(a int primary key);
---error 0,1064
+--error 0,ER_PARSE_ERROR, ER_NOT_SUPPORTED_YET
 ALTER ONLINE TABLE check_online_alter ADD COLUMN b int;
-if($mysql_errno)
+if (`SELECT '$mysql_errno' = '1064'`)
 {
   let $have_online_alter= 0;
 }

=== modified file 'mysql-test/r/ctype_utf8mb4.result'
--- a/mysql-test/r/ctype_utf8mb4.result	2010-09-28 15:15:58 +0000
+++ b/mysql-test/r/ctype_utf8mb4.result	2011-05-30 21:13:02 +0000
@@ -2453,6 +2453,7 @@ MODIFY p varchar(255) CHARACTER SET utf8
 Warnings:
 Warning	1071	Specified key was too long; max key length is 1000 bytes
 Warning	1071	Specified key was too long; max key length is 1000 bytes
+Warning	1071	Specified key was too long; max key length is 1000 bytes
 SHOW CREATE TABLE t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (

=== modified file 'mysql-test/suite/innodb/r/innodb-index.result'
--- a/mysql-test/suite/innodb/r/innodb-index.result	2010-11-16 12:37:26 +0000
+++ b/mysql-test/suite/innodb/r/innodb-index.result	2011-05-30 21:13:02 +0000
@@ -434,7 +434,6 @@ t3	CREATE TABLE `t3` (
   KEY `c` (`c`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 alter table t2 drop index b, add index (b);
-ERROR 42000: Incorrect index name 'b'
 show create table t2;
 Table	Create Table
 t2	CREATE TABLE `t2` (
@@ -445,8 +444,8 @@ t2	CREATE TABLE `t2` (
   `e` int(11) DEFAULT NULL,
   PRIMARY KEY (`a`),
   UNIQUE KEY `dc` (`d`,`c`),
-  KEY `b` (`b`),
   KEY `c` (`c`),
+  KEY `b` (`b`),
   CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`b`) ON DELETE CASCADE,
   CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t3` (`c`),
   CONSTRAINT `t2_ibfk_3` FOREIGN KEY (`d`) REFERENCES `t4` (`d`)
@@ -834,7 +833,7 @@ Table	Op	Msg_type	Msg_text
 test.t1	check	status	OK
 explain select * from t1 where b like 'adfd%';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ALL	b	NULL	NULL	NULL	15	Using where
+1	SIMPLE	t1	range	b	b	769	NULL	11	Using where
 drop table t1;
 set global innodb_file_per_table=on;
 set global innodb_file_format='Barracuda';

=== modified file 'mysql-test/suite/innodb/r/innodb.result'
--- a/mysql-test/suite/innodb/r/innodb.result	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/innodb/r/innodb.result	2011-05-30 21:13:02 +0000
@@ -704,7 +704,6 @@ select count(*) from t1 where cat_code='
 count(*)
 0
 alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
-ERROR 42000: Incorrect index name 'sca_pic'
 alter table t1 drop index sca_pic;
 alter table t1 add index (sca_pic, cat_code);
 select count(*) from t1 where sca_code='PD' and sca_pic is null;
@@ -1673,7 +1672,7 @@ variable_value - @innodb_rows_deleted_or
 71
 SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
 variable_value - @innodb_rows_inserted_orig
-1066
+1069
 SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
 variable_value - @innodb_rows_updated_orig
 866

=== modified file 'mysql-test/suite/innodb/t/innodb-index.test'
--- a/mysql-test/suite/innodb/t/innodb-index.test	2010-10-27 11:32:32 +0000
+++ b/mysql-test/suite/innodb/t/innodb-index.test	2011-05-30 21:13:02 +0000
@@ -132,7 +132,8 @@ show create table t4;
 alter table t3 add constraint dc foreign key (a) references t1(a);
 show create table t3;
 # this should be fixed by MySQL (see Bug #51451)
---error ER_WRONG_NAME_FOR_INDEX
+# --error ER_WRONG_NAME_FOR_INDEX
+# With WL#3749 this case now becomes an offline alter
 alter table t2 drop index b, add index (b);
 show create table t2;
 --error ER_ROW_IS_REFERENCED_2

=== modified file 'mysql-test/suite/innodb/t/innodb.test'
--- a/mysql-test/suite/innodb/t/innodb.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/innodb/t/innodb.test	2011-05-30 21:13:02 +0000
@@ -453,7 +453,8 @@ select count(*) from t1 where sca_code='
 select count(*) from t1 where cat_code='E';
 
 # this should be fixed by MySQL (see Bug #51451)
---error ER_WRONG_NAME_FOR_INDEX
+#--error ER_WRONG_NAME_FOR_INDEX
+# With WL#3749 this case now becomes an offline alter
 alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
 alter table t1 drop index sca_pic;
 alter table t1 add index (sca_pic, cat_code);

=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table.result	2011-02-16 08:18:12 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table.result	2011-04-20 12:53:27 +0000
@@ -297,6 +297,8 @@ select * from t2 where a = 6;
 a	b
 6	203
 alter table t2 add c int;
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 insert into t2 (b) values (301),(302),(303);
 select * from t2 where a = 9;
 a	b	c

=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table3.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table3.result	2011-01-26 09:54:24 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table3.result	2011-04-20 12:53:27 +0000
@@ -4,18 +4,18 @@ engine=ndb;
 insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three');
 create index c on t1(c);
 show indexes from t1;
-Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
-t1	0	PRIMARY	1	a	A	3	NULL	NULL		BTREE	
-t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE	
-t1	1	c	1	c	A	NULL	NULL	NULL	YES	BTREE	
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	a	A	3	NULL	NULL		BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	c	1	c	A	NULL	NULL	NULL	YES	BTREE		
 select * from t1 where c = 'two';
 a	b	c
 2	two	two
 alter table t1 drop index c;
 show indexes from t1;
-Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
-t1	0	PRIMARY	1	a	A	3	NULL	NULL		BTREE	
-t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE	
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	a	A	3	NULL	NULL		BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
 select * from t1 where c = 'two';
 a	b	c
 2	two	two

=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table_online.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2011-04-11 13:36:12 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2011-05-30 21:13:02 +0000
@@ -583,10 +583,10 @@ COUNT(*)
 UPDATE t1 SET c = 3.402823466E+38, d = 1.2686868689898E+308, e = 666.66, f = '2007-10-23 23:23:23', g = '1111' WHERE a = 1;
 SELECT * FROM t1 WHERE a = 1 or a = 10 or a = 20 or a = 30 ORDER BY a;
 a	b	c	d	e	f	g
-1	5	3.40282e+38	1.2686868689898e+308	666.66	2007-10-23 23:23:23	1111
-10	1	-3.40282e+38	NULL	NULL	NULL	NULL
-20	1	-3.40282e+38	1.7976931348623e+308	345.21	NULL	NULL
-30	1	-3.40282e+38	1.7976931348623e+308	345.21	1000-01-01 00:00:00	0101
+1	5	3.40282e38	1.2686868689898e308	666.66	2007-10-23 23:23:23	1111
+10	1	-3.40282e38	NULL	NULL	NULL	NULL
+20	1	-3.40282e38	1.7976931348623e308	345.21	NULL	NULL
+30	1	-3.40282e38	1.7976931348623e308	345.21	1000-01-01 00:00:00	0101
 *********************************
 * Backup and restore tables w/ new column
 *********************************

=== modified file 'mysql-test/suite/ndb/r/ndb_dd_restore_compat.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result	2011-03-04 13:14:07 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result	2011-05-30 21:13:02 +0000
@@ -45,6 +45,8 @@ a1	a2	a3	a4	a5	a6	a7	a8	a9	a10
 4	5	2000000004	aaa4	34.2	04:03:02	2006-01-01	1971-05-28 16:55:03	bbbbbbbbbbbbb4	binary data
 5	6	2000000005	aaa5	34.2	04:03:02	2006-01-01	1971-05-28 16:55:03	bbbbbbbbbbbbb5	binary data
 ALTER TABLE t1 ADD COLUMN c int;
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 SHOW CREATE TABLE t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (

=== modified file 'mysql-test/suite/ndb/r/ndb_gis.result'
--- a/mysql-test/suite/ndb/r/ndb_gis.result	2011-02-16 08:52:31 +0000
+++ b/mysql-test/suite/ndb/r/ndb_gis.result	2011-04-20 12:53:27 +0000
@@ -431,6 +431,8 @@ mpg	multipolygon	YES		NULL	
 gc	geometrycollection	YES		NULL	
 gm	geometry	YES		NULL	
 ALTER TABLE t1 ADD fid INT;
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 SHOW FIELDS FROM t1;
 Field	Type	Null	Key	Default	Extra
 a	int(11)	NO	PRI	NULL	auto_increment
@@ -983,6 +985,8 @@ mpg	multipolygon	YES		NULL	
 gc	geometrycollection	YES		NULL	
 gm	geometry	YES		NULL	
 ALTER TABLE t1 ADD fid INT;
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 SHOW FIELDS FROM t1;
 Field	Type	Null	Key	Default	Extra
 a	int(11)	NO	PRI	NULL	auto_increment

=== modified file 'mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result'
--- a/mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result	2011-03-29 12:45:25 +0000
+++ b/mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result	2011-05-30 21:13:02 +0000
@@ -26,6 +26,7 @@ Warning	1296	Got error 4009 'Cluster Fai
 ALTER TABLE t3 ADD COLUMN b int default NULL;
 Warnings:
 Warning	1296	Got error 4009 'Cluster Failure' from NDB
+Warning	1296	Got error 4009 'Cluster Failure' from NDB
 INSERT INTO t2 VALUES(1);
 TRUNCATE TABLE t2;
 Warnings:

=== modified file 'mysql-test/suite/ndb/r/ndb_short_sigs.result'
--- a/mysql-test/suite/ndb/r/ndb_short_sigs.result	2011-02-21 13:44:45 +0000
+++ b/mysql-test/suite/ndb/r/ndb_short_sigs.result	2011-04-20 12:53:27 +0000
@@ -63,6 +63,8 @@ th	un	de	length(rb)	length(al)
 4	9	4	991	60009
 5	10	5	990	60010
 alter table t1 add column extra varchar(2000);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 update t1 set extra = repeat(rb, 2);
 select th, un, de, length(rb), length(al), length(extra)
 from t1 

=== modified file 'mysql-test/suite/ndb/t/disabled.def'
--- a/mysql-test/suite/ndb/t/disabled.def	2011-05-09 08:49:19 +0000
+++ b/mysql-test/suite/ndb/t/disabled.def	2011-05-30 21:13:02 +0000
@@ -27,7 +27,6 @@ ndb_dd_alter		 : SEAGULL alter
 ndb_index_ordered	 : SEAGULL alter in second connection deadlocks
 
 ndb_index_unique	 : SEAGULL different error with copying alter
-ndb_alter_table3	 : SEAGULL different error with copying alter
 
 ndb_read_multi_range      : SEAGULL "total length of the partitioning fields is too large"
 

=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table_online2.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online2.test	2011-05-18 12:56:24 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online2.test	2011-05-30 21:13:02 +0000
@@ -14,7 +14,7 @@
 -- source include/not_embedded.inc
 # mysqlslap seems to be not_windows. remove this when removed from mysqlslap.test
 -- source include/not_windows.inc
--- source include/have_log_bin.inc
+# -- source include/have_log_bin.inc
 
 --disable_warnings
 DROP TABLE IF EXISTS t1;

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result	2011-02-15 09:51:38 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result	2011-05-30 21:13:02 +0000
@@ -12,6 +12,8 @@ select @max_epoch:=max(epoch)-1 from mys
 #
 delete from t1;
 alter table t1 add (b int);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 insert into t1 values (3,3),(4,4);
 alter table t1 rename t2;
 begin;

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result	2011-02-15 09:51:38 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result	2011-05-30 21:13:02 +0000
@@ -21,6 +21,8 @@ mysqld-bin.000001	#	Query	1	#	use `test`
 reset master;
 reset master;
 alter table t2 add column (b int);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 mysqld-bin.000001	#	Query	1	#	use `test`; alter table t2 add column (b int)

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2011-03-28 14:00:51 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2011-05-30 21:13:02 +0000
@@ -9,6 +9,8 @@ create table t1 (a int key, b int) engin
 create table t2 (a int key, b int) engine=ndb;
 insert into t1 values (1,1);
 alter table t1 add c int;
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 reset master;

=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result	2011-05-13 07:40:50 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result	2011-05-30 21:13:02 +0000
@@ -47,10 +47,10 @@ c1	c2	c	d	f	g	h
 7	7	NULL	NULL	NULL	NULL	NULL
 8	8	NULL	NULL	NULL	NULL	NULL
 11	1	a	NULL	NULL	NULL	NULL
-12	2	b	-3.40282e+38	NULL	NULL	NULL
-14	4	d	-3.40282e+38	456.78	NULL	NULL
-15	5	e	-3.40282e+38	456.78	2007-10-26 12:00:00	NULL
-16	6	f	-3.40282e+38	456.78	2007-10-26 12:00:00	abcd
+12	2	b	-3.40282e38	NULL	NULL	NULL
+14	4	d	-3.40282e38	456.78	NULL	NULL
+15	5	e	-3.40282e38	456.78	2007-10-26 12:00:00	NULL
+16	6	f	-3.40282e38	456.78	2007-10-26 12:00:00	abcd
 **********************
 "Slave data"
 **********************
@@ -63,43 +63,43 @@ c1	c2	c	d	f	g	h
 7	7	NULL	NULL	NULL	NULL	NULL
 8	8	NULL	NULL	NULL	NULL	NULL
 11	1	a	NULL	NULL	NULL	NULL
-12	2	b	-3.40282e+38	NULL	NULL	NULL
-14	4	d	-3.40282e+38	456.78	NULL	NULL
-15	5	e	-3.40282e+38	456.78	2007-10-26 12:00:00	NULL
-16	6	f	-3.40282e+38	456.78	2007-10-26 12:00:00	abcd
+12	2	b	-3.40282e38	NULL	NULL	NULL
+14	4	d	-3.40282e38	456.78	NULL	NULL
+15	5	e	-3.40282e38	456.78	2007-10-26 12:00:00	NULL
+16	6	f	-3.40282e38	456.78	2007-10-26 12:00:00	abcd
 UPDATE t1 SET c = "abcdef", d = 3.402823466E+38, f = 987.65, g = '2007-10-22 22:22:22', h = "aaaa";
 ***************************
 "Master Data After Update"
 ***************************
 SELECT * FROM t1 ORDER BY c1;
 c1	c2	c	d	f	g	h
-1	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-2	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-3	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-6	6	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-7	7	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-8	8	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-11	1	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-12	2	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-14	4	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-15	5	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-16	6	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
+1	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+2	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+3	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+6	6	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+7	7	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+8	8	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+11	1	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+12	2	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+14	4	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+15	5	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+16	6	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
 *************************
 "Slave Data After Update"
 *************************
 SELECT * FROM t1 ORDER BY c1;
 c1	c2	c	d	f	g	h
-1	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-2	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-3	NULL	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-6	6	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-7	7	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-8	8	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-11	1	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-12	2	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-14	4	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-15	5	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
-16	6	abcdef	3.40282e+38	987.65	2007-10-22 22:22:22	aaaa
+1	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+2	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+3	NULL	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+6	6	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+7	7	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+8	8	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+11	1	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+12	2	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+14	4	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+15	5	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
+16	6	abcdef	3.40282e38	987.65	2007-10-22 22:22:22	aaaa
 DROP TABLE t1;
 *************************************************
 * Insert And Update New Added Columns With Commit

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-05-06 13:40:03 +0000
+++ b/sql/ha_ndbcluster.cc	2011-05-30 21:13:02 +0000
@@ -300,6 +300,16 @@ ndbcluster_partition_flags()
           HA_CAN_PARTITION_UNIQUE | HA_USE_AUTO_PARTITION);
 }
 
+#ifndef MCP_WL3749
+static uint
+ndbcluster_alter_table_flags(uint flags)
+{
+  if (flags & ALTER_DROP_PARTITION)
+    return 0;
+  else
+    return (HA_PARTITION_FUNCTION_SUPPORTED);
+}
+#else
 #ifndef NDB_WITHOUT_ONLINE_ALTER
 static uint
 ndbcluster_alter_partition_flags()
@@ -332,6 +342,7 @@ ndbcluster_alter_table_flags(uint flags)
   return f;
 }
 #endif
+#endif
 
 #define NDB_AUTO_INCREMENT_RETRIES 100
 #define BATCH_FLUSH_SIZE (32768)
@@ -10695,6 +10706,10 @@ static int ndbcluster_init(void *p)
     h->show_status=      ndbcluster_show_status;    /* Show status */
     h->alter_tablespace= ndbcluster_alter_tablespace;    /* Show status */
     h->partition_flags=  ndbcluster_partition_flags; /* Partition flags */
+#ifndef MCP_WL3749
+    h->alter_table_flags=
+      ndbcluster_alter_table_flags;                 /* Alter table flags */
+#else
 #ifndef NDB_WITHOUT_ONLINE_ALTER
     h->alter_partition_flags=
       ndbcluster_alter_partition_flags;             /* Alter partition flags */
@@ -10702,6 +10717,7 @@ static int ndbcluster_init(void *p)
     h->alter_table_flags=
       ndbcluster_alter_table_flags;                 /* Alter table flags */
 #endif
+#endif
 #if MYSQL_VERSION_ID >= 50501
     h->fill_is_table=    ndbcluster_fill_is_table;
 #else
@@ -11166,9 +11182,13 @@ ulonglong ha_ndbcluster::table_flags(voi
     HA_HAS_OWN_BINLOGGING |
     HA_BINLOG_ROW_CAPABLE |
     HA_HAS_RECORDS |
+#ifndef MCP_WL3749
+    HA_ONLINE_ALTER |
+#else
 #ifndef NDB_WITHOUT_ONLINE_ALTER
     HA_ONLINE_ALTER |
 #endif
+#endif
     0;
 
   /*
@@ -13751,7 +13771,7 @@ ha_ndbcluster::set_up_partition_info(par
   DBUG_RETURN(0);
 }
 
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
 static
 HA_ALTER_FLAGS supported_alter_operations()
 {
@@ -13771,6 +13791,7 @@ HA_ALTER_FLAGS supported_alter_operation
 
 int ha_ndbcluster::check_if_supported_alter(TABLE *altered_table,
                                             HA_CREATE_INFO *create_info,
+                                            Alter_info *alter_info,
                                             HA_ALTER_FLAGS *alter_flags,
                                             uint table_changes)
 {
@@ -13786,7 +13807,7 @@ int ha_ndbcluster::check_if_supported_al
   add_column= add_column | HA_ADD_COLUMN;
   adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX;
   dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
-  partition_info *part_info= table->part_info;
+  partition_info *part_info= altered_table->part_info;
   const NDBTAB *old_tab= m_table;
 
   if (THDVAR(thd, use_copying_alter_table))
@@ -13808,7 +13829,7 @@ int ha_ndbcluster::check_if_supported_al
       sql_partition.cc tries to compute what is going on
       and sets flags...that we clear
     */
-    if (part_info->use_default_no_partitions)
+    if (part_info->use_default_num_partitions)
     {
       alter_flags->clear_bit(HA_COALESCE_PARTITION);
       alter_flags->clear_bit(HA_ADD_PARTITION);
@@ -13893,7 +13914,8 @@ int ha_ndbcluster::check_if_supported_al
      }
      else if (alter_flags->is_set(HA_ADD_PARTITION))
      {
-       new_tab.setFragmentCount(part_info->no_parts);
+       DBUG_PRINT("info", ("Adding partition (%u)", part_info->num_parts));
+       new_tab.setFragmentCount(part_info->num_parts);
      }
 
      NDB_Modifiers table_modifiers(ndb_table_modifiers);
@@ -14071,6 +14093,7 @@ int ha_ndbcluster::alter_table_phase1(TH
 {
   int error= 0;
   uint i;
+  Thd_ndb *thd_ndb= get_thd_ndb(thd);
   Ndb *ndb= get_ndb(thd);
   NDBDICT *dict= ndb->getDictionary();
   ndb->setDatabaseName(m_dbname);
@@ -14084,9 +14107,8 @@ int ha_ndbcluster::alter_table_phase1(TH
   adding=  adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX;
   dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
 
-  if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
-    DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
-                (thd, "ha_ndbcluster::alter_table_phase1"));
+  if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase1"))
+    DBUG_RETURN(HA_ERR_NO_CONNECTION);
 
   if (!(alter_data= new NDB_ALTER_DATA(dict, m_table)))
     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -14222,8 +14244,8 @@ int ha_ndbcluster::alter_table_phase1(TH
     }
     else if (alter_flags->is_set(HA_ADD_PARTITION))
     {
-      partition_info *part_info= table->part_info;
-      new_tab->setFragmentCount(part_info->no_parts);
+      partition_info *part_info= altered_table->part_info;
+      new_tab->setFragmentCount(part_info->num_parts);
     }
 
     int res= dict->prepareHashMap(*old_tab, *new_tab);
@@ -14313,6 +14335,7 @@ int ha_ndbcluster::alter_table_phase2(TH
 
 {
   int error= 0;
+  Thd_ndb *thd_ndb= get_thd_ndb(thd);
   NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
   NDBDICT *dict= alter_data->dictionary;
   HA_ALTER_FLAGS dropping;
@@ -14320,10 +14343,9 @@ int ha_ndbcluster::alter_table_phase2(TH
   DBUG_ENTER("alter_table_phase2");
   dropping= dropping  | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
 
-  if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+  if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase2"))
   {
-    error= ndbcluster_no_global_schema_lock_abort
-      (thd, "ha_ndbcluster::alter_table_phase2");
+    error= HA_ERR_NO_CONNECTION;
     goto err;
   }
 
@@ -14388,15 +14410,15 @@ int ha_ndbcluster::alter_table_phase3(TH
                                       HA_ALTER_INFO *alter_info,
                                       HA_ALTER_FLAGS *alter_flags)
 {
+  Thd_ndb *thd_ndb= get_thd_ndb(thd);
   DBUG_ENTER("alter_table_phase3");
 
   NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
-  if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+  if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase3"))
   {
     delete alter_data;
     alter_info->data= 0;
-    DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
-                (thd, "ha_ndbcluster::alter_table_phase3"));
+    DBUG_RETURN(HA_ERR_NO_CONNECTION);
   }
 
   const char *db= table->s->db.str;

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-05-06 13:40:03 +0000
+++ b/sql/ha_ndbcluster.h	2011-05-30 21:13:02 +0000
@@ -369,9 +369,10 @@ static void set_tabname(const char *path
                                      qc_engine_callback *engine_callback,
                                      ulonglong *engine_data);
 
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
   int check_if_supported_alter(TABLE *altered_table,
                                HA_CREATE_INFO *create_info,
+                               Alter_info *alter_info,
                                HA_ALTER_FLAGS *alter_flags,
                                uint table_changes);
 
@@ -482,7 +483,7 @@ private:
 
   int ndb_optimize_table(THD* thd, uint delay);
 
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
   int alter_frm(THD *thd, const char *file, NDB_ALTER_DATA *alter_data);
 #endif
 

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2011-04-06 13:51:46 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-05-30 21:13:02 +0000
@@ -2056,7 +2056,7 @@ end:
         {
           sql_print_error("NDB %s: distributing %s timed out. Ignoring...",
                           type_str, ndb_schema_object->key);
-          DBUG_ASSERT(false);
+          // DBUG_ASSERT(false);
           break;
         }
         if (opt_ndb_extra_logging)

=== modified file 'sql/ha_ndbcluster_glue.h'
--- a/sql/ha_ndbcluster_glue.h	2011-03-08 15:17:16 +0000
+++ b/sql/ha_ndbcluster_glue.h	2011-05-30 21:13:02 +0000
@@ -79,12 +79,14 @@ bool close_cached_tables(THD *thd, TABLE
 /* No mysql_rm_table_part2 anymore in 5.5.8 */
 #define NDB_NO_MYSQL_RM_TABLE_PART2
 
+#ifdef MCP_WL3749
 /*
   The enum open_table_mode has been removed in 5.5.7 and 'open_table_from_share'
   now takes "bool is_create_table" instead of the enum type. Define OTM_OPEN
   to false since it's not a create table
 */
 #define OTM_OPEN false
+#endif
 
 #endif
 

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-05-12 08:43:50 +0000
+++ b/sql/handler.cc	2011-05-30 21:13:02 +0000
@@ -3404,6 +3404,249 @@ handler::ha_prepare_for_alter()
   prepare_for_alter();
 }
 
+#ifndef MCP_WL3749
+/*
+   Default implementation to support fast alter table
+   and old online add/drop index interface
+*/
+int
+handler::check_if_supported_alter(TABLE *altered_table,
+                                  HA_CREATE_INFO *create_info,
+                                  Alter_info *alter_info,
+                                  HA_ALTER_FLAGS *alter_flags,
+                                  uint table_changes)
+{
+  DBUG_ENTER("check_if_supported_alter");
+  int result= HA_ALTER_NOT_SUPPORTED;
+  ulong handler_alter_flags= table->file->alter_table_flags(0);
+  HA_ALTER_FLAGS supported_alter_operations;
+  supported_alter_operations=
+    supported_alter_operations |
+    HA_ADD_INDEX |
+    HA_DROP_INDEX |
+    HA_ADD_UNIQUE_INDEX |
+    HA_DROP_UNIQUE_INDEX |
+    HA_ADD_PK_INDEX |
+    HA_DROP_PK_INDEX;
+  HA_ALTER_FLAGS not_supported= ~(supported_alter_operations);
+  DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags));
+#ifndef DBUG_OFF
+  {
+    char dbug_string[HA_MAX_ALTER_FLAGS+1];
+    alter_flags->print(dbug_string);
+    DBUG_PRINT("info", ("alter_flags: %s", dbug_string));
+    not_supported.print(dbug_string);
+    DBUG_PRINT("info", ("not_supported: %s", dbug_string));
+  }
+#endif
+  /* Check the old alter table flags */
+  if ((*alter_flags & not_supported).is_set())
+  {
+    /* Not adding/dropping index check if supported as fast alter */
+    DBUG_PRINT("info", ("alter_info->change_level %u", alter_info->change_level));
+    if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY &&
+        table->file->check_if_incompatible_data(create_info, table_changes)
+        != COMPATIBLE_DATA_NO) 
+      DBUG_RETURN(HA_ALTER_SUPPORTED_WAIT_LOCK);
+    else
+      DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+  }
+  else
+  {
+    /* Add index */
+    if ((*alter_flags & HA_ADD_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+    /* Drop index */
+    if ((*alter_flags & HA_DROP_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+    /* Add unique index */
+    if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+    /* Drop unique index */
+    if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+    /* Add primary key */
+    if ((*alter_flags & HA_ADD_PK_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+    /* Drop primary key */
+    if ((*alter_flags & HA_DROP_PK_INDEX).is_set())
+    {
+      if (handler_alter_flags & HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
+        result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+          HA_ALTER_SUPPORTED_WAIT_LOCK
+          : HA_ALTER_SUPPORTED_NO_LOCK;
+      else
+        DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+    }
+  }
+  DBUG_RETURN(result);
+}
+
+/*
+  Default implementation to support old online add/drop index
+ */
+int
+handler::alter_table_phase1(THD *thd,
+                            TABLE *altered_table,
+                            HA_CREATE_INFO *create_info,
+                            HA_ALTER_INFO *alter_info,
+                            HA_ALTER_FLAGS *alter_flags)
+{
+  DBUG_ENTER("alter_table_phase1");
+  int error= 0;
+  HA_ALTER_FLAGS adding;
+  HA_ALTER_FLAGS dropping;
+
+  adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX;
+  dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+
+  if ((*alter_flags & adding).is_set())
+  {
+    KEY           *key_info;
+    KEY           *key;
+    uint          *idx_p;
+    uint          *idx_end_p;
+    KEY_PART_INFO *key_part;
+    KEY_PART_INFO *part_end;
+    key_info= (KEY*) thd->alloc(sizeof(KEY) * alter_info->index_add_count);
+    key= key_info;
+    for (idx_p=  alter_info->index_add_buffer,
+         idx_end_p= idx_p + alter_info->index_add_count;
+         idx_p < idx_end_p;
+         idx_p++, key++)
+     {
+      /* Copy the KEY struct. */
+       *key= alter_info->key_info_buffer[*idx_p];
+      /* Fix the key parts. */
+      part_end= key->key_part + key->key_parts;
+      for (key_part= key->key_part; key_part < part_end; key_part++)
+        key_part->field= table->field[key_part->fieldnr];
+     }
+    /* Add the indexes. */
+    if ((error= add_index(table, key_info,
+                          alter_info->index_add_count)))
+    {
+      /*
+        Exchange the key_info for the error message. If we exchange
+        key number by key name in the message later, we need correct info.
+      */
+      KEY *save_key_info= table->key_info;
+      table->key_info= key_info;
+      table->file->print_error(error, MYF(0));
+      table->key_info= save_key_info;
+      DBUG_RETURN(error);
+    }
+  }
+
+  if ((*alter_flags & dropping).is_set())
+  {
+    uint          *key_numbers;
+    uint          *keyno_p;
+    uint          *idx_p;
+    uint          *idx_end_p;
+    DBUG_PRINT("info", ("Renumbering indexes"));
+    /* The prepare_drop_index() method takes an array of key numbers. */
+    key_numbers= (uint*) thd->alloc(sizeof(uint) * alter_info->index_drop_count);
+    keyno_p= key_numbers;
+    /* Get the number of each key. */
+    for (idx_p= alter_info->index_drop_buffer,
+         idx_end_p= idx_p + alter_info->index_drop_count;
+         idx_p < idx_end_p;
+         idx_p++, keyno_p++)
+      *keyno_p= *idx_p;
+    if ((error= prepare_drop_index(table, key_numbers,
+                                   alter_info->index_drop_count)))
+    {
+      table->file->print_error(error, MYF(0));
+      DBUG_RETURN(error);
+    }
+  }
+
+  DBUG_RETURN(0);
+}
+
+int
+handler::alter_table_phase2(THD *thd,
+                                TABLE *altered_table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags)
+{
+  DBUG_ENTER("alter_table_phase2");
+  int error= 0;
+  HA_ALTER_FLAGS dropping;
+
+  dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+
+  if ((*alter_flags & dropping).is_set())
+  {
+    if ((error= final_drop_index(table)))
+    {
+      print_error(error, MYF(0));
+      DBUG_RETURN(error);
+    }
+  }
+
+  DBUG_RETURN(0);
+}
+
+int
+handler::alter_table_phase3(THD *thd, TABLE *table,
+                            HA_CREATE_INFO *create_info,
+                            HA_ALTER_INFO *alter_info,
+                            HA_ALTER_FLAGS *alter_flags)
+{
+  DBUG_ENTER("alter_table_phase3");
+  DBUG_RETURN(0);
+}
+#endif
 
 /**
   Rename table: public interface.
@@ -3676,7 +3919,11 @@ int ha_create_table(THD *thd, const char
   init_tmp_table_share(thd, &share, db, 0, table_name, path);
   if (open_table_def(thd, &share, 0) ||
       open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
+#ifndef MCP_WL3749
+                            OTM_CREATE))
+#else
                             TRUE))
+#endif
     goto err;
 
   if (update_create_info)
@@ -3745,7 +3992,11 @@ int ha_create_table_from_engine(THD* thd
   {
     DBUG_RETURN(3);
   }
+#ifndef MCP_WL3749
+  if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
+#else
   if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, FALSE))
+#endif
   {
     free_table_share(&share);
     DBUG_RETURN(3);

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2011-05-12 08:43:50 +0000
+++ b/sql/handler.h	2011-05-30 21:13:02 +0000
@@ -50,6 +50,64 @@
 #define HA_ADMIN_NEEDS_ALTER    -11
 #define HA_ADMIN_NEEDS_CHECK    -12
 
+#ifndef MCP_WL3749
+class Alter_info;
+/* Bits to show what an alter table will do */
+#include <sql_bitmap.h>
+
+#define HA_MAX_ALTER_FLAGS 40
+typedef Bitmap<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
+
+#define HA_ADD_INDEX                  (0)
+#define HA_DROP_INDEX                 (1)
+#define HA_ALTER_INDEX                (2)
+#define HA_RENAME_INDEX               (3)
+#define HA_ADD_UNIQUE_INDEX           (4)
+#define HA_DROP_UNIQUE_INDEX          (5)
+#define HA_ALTER_UNIQUE_INDEX         (6)
+#define HA_RENAME_UNIQUE_INDEX        (7)
+#define HA_ADD_PK_INDEX               (8)
+#define HA_DROP_PK_INDEX              (9)
+#define HA_ALTER_PK_INDEX             (10)
+#define HA_ADD_COLUMN                 (11)
+#define HA_DROP_COLUMN                (12)
+#define HA_CHANGE_COLUMN              (13)
+#define HA_ALTER_COLUMN_NAME          (14)
+#define HA_ALTER_COLUMN_TYPE          (15)
+#define HA_ALTER_COLUMN_ORDER         (16)
+#define HA_ALTER_COLUMN_NULLABLE      (17)
+#define HA_COLUMN_DEFAULT_VALUE       (18)
+#define HA_COLUMN_STORAGE             (19)
+#define HA_COLUMN_FORMAT              (20)
+#define HA_ADD_FOREIGN_KEY            (21)
+#define HA_DROP_FOREIGN_KEY           (22)
+#define HA_ALTER_FOREIGN_KEY          (23)
+#define HA_ADD_CONSTRAINT             (24)
+#define HA_ADD_PARTITION              (25)
+#define HA_DROP_PARTITION             (26)
+#define HA_ALTER_PARTITION            (27)
+#define HA_COALESCE_PARTITION         (28)
+#define HA_REORGANIZE_PARTITION       (29)
+#define HA_CHANGE_CHARACTER_SET       (30)
+#define HA_SET_DEFAULT_CHARACTER_SET  (31)
+#define HA_CHANGE_AUTOINCREMENT_VALUE (32)
+#define HA_ALTER_STORAGE              (33)
+#define HA_ALTER_TABLESPACE           (34)
+#define HA_ALTER_ROW_FORMAT           (35)
+#define HA_RENAME_TABLE               (36)
+#define HA_ALTER_STORAGE_ENGINE       (37)
+#define HA_RECREATE                   (38)
+#define HA_ALTER_TABLE_REORG          (39)
+/* Remember to increase HA_MAX_ALTER_FLAGS when adding more flags! */
+
+/* Return values for check_if_supported_alter */
+
+#define HA_ALTER_ERROR               -1
+#define HA_ALTER_SUPPORTED_WAIT_LOCK  0
+#define HA_ALTER_SUPPORTED_NO_LOCK    1
+#define HA_ALTER_NOT_SUPPORTED        2
+#endif
+
 /* Bits in table_flags() to show what database can do */
 
 #define HA_NO_TRANSACTIONS     (1 << 0) /* Doesn't support transactions */
@@ -130,6 +188,11 @@
 */
 #define HA_BINLOG_ROW_CAPABLE  (LL(1) << 34)
 #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
+#ifndef MCP_WL3749
+#define HA_ONLINE_ALTER        (LL(1) << 36)
+#endif
+
+
 /*
     When a multiple key conflict happens in a REPLACE command mysql
     expects the conflicts to be reported in the ascending order of
@@ -762,6 +825,9 @@ struct handlerton
    bool (*flush_logs)(handlerton *hton);
    bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
    uint (*partition_flags)();
+#ifndef MCP_WL3749
+   uint (*alter_partition_flags)();
+#endif
    uint (*alter_table_flags)(uint flags);
    int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
    int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables, 
@@ -1026,6 +1092,18 @@ typedef struct st_ha_create_information
   enum enum_ha_unused unused2;
 } HA_CREATE_INFO;
 
+#ifndef MCP_WL3749
+typedef struct st_ha_alter_information
+{
+  KEY  *key_info_buffer;
+  uint key_count;
+  uint index_drop_count;
+  uint *index_drop_buffer;
+  uint index_add_count;
+  uint *index_add_buffer;
+  void *data;
+} HA_ALTER_INFO;
+#endif
 
 typedef struct st_key_create_information
 {
@@ -1881,6 +1959,101 @@ public:
  virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
 					 uint table_changes)
  { return COMPATIBLE_DATA_NO; }
+#ifndef MCP_WL3749
+ /* On-line ALTER TABLE interface */
+
+ /**
+    Check if a storage engine supports a particular alter table on-line
+
+    @param    altered_table     A temporary table show what table is to
+                                change to
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
+    @param    alter_info        Data related to detected changes
+    @param    alter_flags       Bitmask that shows what will be changed
+    @param    table_changes     Shows if table layout has changed (for
+                                backwards compatibility with
+                                check_if_incompatible_data
+
+    @retval   HA_ALTER_ERROR                Unexpected error
+    @retval   HA_ALTER_SUPPORTED_WAIT_LOCK  Supported, but requires DDL lock
+    @retval   HA_ALTER_SUPPORTED_NO_LOCK    Supported
+    @retval   HA_ALTER_NOT_SUPPORTED        Not supported
+
+    @note
+      The default implementation is implemented to support fast
+      alter table (storage engines that support some changes by
+      just changing the frm file) without any change in the handler
+      implementation.
+ */
+ virtual int check_if_supported_alter(TABLE *altered_table,
+                                      HA_CREATE_INFO *create_info,
+                                      Alter_info *alter_info,
+                                      HA_ALTER_FLAGS *alter_flags,
+                                      uint table_changes);
+
+ /**
+   Tell storage engine to prepare for the on-line alter table (pre-alter)
+
+   @param     thd               The thread handle
+   @param     altered_table     A temporary table show what table is to
+                                change to
+   @param     alter_info        Storage place for data used during phase1
+                                and phase2 and phase3
+   @param     alter_flags       Bitmask that shows what will be changed
+
+   @retval   0      OK
+   @retval   error  error code passed from storage engine
+ */
+ virtual int alter_table_phase1(THD *thd,
+                                TABLE *altered_table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags);
+
+  /**
+    Tell storage engine to perform the on-line alter table (alter)
+
+    @param    thd               The thread handle
+    @param    altered_table     A temporary table show what table is to
+                                change to
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
+    @param    alter_info        Storage place for data used during phase1
+                                and phase2 and phase3
+    @param    alter_flags       Bitmask that shows what will be changed
+
+    @retval  0      OK
+    @retval  error  error code passed from storage engine
+
+    @note
+      If check_if_supported_alter returns HA_ALTER_SUPPORTED_WAIT_LOCK
+      this call is to be wrapped with a DDL lock. This is currently NOT
+      supported.
+ */
+ virtual int alter_table_phase2(THD *thd,
+                                TABLE *altered_table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags);
+
+ /**
+    Tell storage engine that changed frm file is now on disk and table
+    has been re-opened (post-alter)
+
+    @param    thd               The thread handle
+    @param    table             The altered table, re-opened
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
+    @param    alter_info        Storage place for data used during phase1
+                                and phase2 and phase3
+    @param    alter_flags       Bitmask that shows what has been changed
+ */
+ virtual int alter_table_phase3(THD *thd, TABLE *table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags);
+#endif
 
   /**
     use_hidden_primary_key() is called in case of an update/delete when

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2011-03-04 09:53:26 +0000
+++ b/sql/lex.h	2011-04-20 12:53:27 +0000
@@ -387,11 +387,17 @@ static SYMBOL symbols[] = {
   { "NULL",		SYM(NULL_SYM)},
   { "NUMERIC",		SYM(NUMERIC_SYM)},
   { "NVARCHAR",		SYM(NVARCHAR_SYM)},
+#ifndef MCP_WL3749
+  { "OFFLINE",          SYM(OFFLINE_SYM)},
+#endif
   { "OFFSET",		SYM(OFFSET_SYM)},
   { "OLD_PASSWORD",	SYM(OLD_PASSWORD)},
   { "ON",		SYM(ON)},
   { "ONE",              SYM(ONE_SYM)},
   { "ONE_SHOT",		SYM(ONE_SHOT_SYM)},
+#ifndef MCP_WL3749
+  { "ONLINE",           SYM(ONLINE_SYM)},
+#endif
   { "OPEN",		SYM(OPEN_SYM)},
   { "OPTIMIZE",		SYM(OPTIMIZE)},
   { "OPTIONS",		SYM(OPTIONS_SYM)},

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2011-05-10 09:48:14 +0000
+++ b/sql/log.cc	2011-05-30 21:13:02 +0000
@@ -4673,7 +4673,10 @@ int THD::binlog_write_table_map(TABLE *t
   DBUG_PRINT("enter", ("table: 0x%lx  (%s: #%lu)",
                        (long) table, table->s->table_name.str,
                        table->s->table_map_id));
-
+  DBUG_PRINT("info", ("is_current_stmt_binlog_format_row() = %s", (is_current_stmt_binlog_format_row())?"true":"false"));
+  DBUG_PRINT("info", ("mysql_bin_log.is_open() = %s", (mysql_bin_log.is_open())?"true":"false"));
+  DBUG_PRINT("info", ("current_stmt_binlog_format %u", current_stmt_binlog_format));
+  
   /* Pre-conditions */
   DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
   DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2011-03-08 08:41:57 +0000
+++ b/sql/sql_admin.cc	2011-05-30 21:13:02 +0000
@@ -101,7 +101,11 @@ static int prepare_for_repair(THD *thd, 
     if (share == NULL)
       DBUG_RETURN(0);				// Can't open frm file
 
+#ifndef MCP_WL3749
+    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
+#else
     if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
+#endif
     {
       mysql_mutex_lock(&LOCK_open);
       release_table_share(share);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-05-12 08:43:50 +0000
+++ b/sql/sql_base.cc	2011-05-30 21:13:02 +0000
@@ -1322,6 +1322,7 @@ close_all_tables_for_name(THD *thd, TABL
   const char *db= key;
   const char *table_name= db + share->db.length + 1;
 
+  DBUG_ENTER("close_all_tables_for_name");
   memcpy(key, share->table_cache_key.str, key_length);
 
   mysql_mutex_assert_not_owner(&LOCK_open);
@@ -1332,6 +1333,9 @@ close_all_tables_for_name(THD *thd, TABL
     if (table->s->table_cache_key.length == key_length &&
         !memcmp(table->s->table_cache_key.str, key, key_length))
     {
+#ifndef MCP_WL3749
+      if (table->pos_in_locked_tables)
+#endif
       thd->locked_tables_list.unlink_from_list(thd,
                                                table->pos_in_locked_tables,
                                                remove_from_locked_tables);
@@ -1356,6 +1360,7 @@ close_all_tables_for_name(THD *thd, TABL
   /* Remove the table share from the cache. */
   tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name,
                    FALSE);
+  DBUG_VOID_RETURN;
 }
 
 
@@ -2152,7 +2157,12 @@ void close_temporary(TABLE *table, bool 
   free_io_cache(table);
   closefrm(table, 0);
   if (delete_table)
+#ifndef MCP_WL3749
+    rm_temporary_table(table_type, table->s->path.str,
+                       table->s->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
+#else
     rm_temporary_table(table_type, table->s->path.str);
+#endif
   if (free_share)
   {
     free_table_share(table->s);
@@ -3030,7 +3040,11 @@ retry_share:
                                          HA_TRY_READ_ONLY),
                                  (READ_KEYINFO | COMPUTE_TYPES |
                                   EXTRA_RECORD),
+#ifndef MCP_WL3749
+                                 thd->open_options, table, OTM_OPEN);
+#else
                                  thd->open_options, table, FALSE);
+#endif
 
     if (error)
     {
@@ -3849,7 +3863,11 @@ static bool auto_repair_table(THD *thd, 
                                     HA_TRY_READ_ONLY),
                             READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
                             ha_open_options | HA_OPEN_FOR_REPAIR,
+#ifndef MCP_WL3749
+                            entry, OTM_OPEN) || ! entry->file ||
+#else
                             entry, FALSE) || ! entry->file ||
+#endif
       (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
   {
     /* Give right error message */
@@ -5793,7 +5811,12 @@ void close_tables_for_reopen(THD *thd, T
 
 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
                            const char *table_name,
+#ifndef MCP_WL3749
+                           bool add_to_temporary_tables_list,
+                           open_table_mode open_mode)
+#else
                            bool add_to_temporary_tables_list)
+#endif
 {
   TABLE *tmp_table;
   TABLE_SHARE *share;
@@ -5827,11 +5850,25 @@ TABLE *open_table_uncached(THD *thd, con
 
   if (open_table_def(thd, share, 0) ||
       open_table_from_share(thd, share, table_name,
+#ifndef MCP_WL3749
+                            (open_mode == OTM_ALTER) ? 0 :
+                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
+                                    HA_GET_INDEX),
+                            (open_mode == OTM_ALTER) ?
+                              (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
+                               OPEN_FRM_FILE_ONLY)
+                            : (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD),
+#else
                             (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
                                     HA_GET_INDEX),
                             READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
+#endif
                             ha_open_options,
+#ifndef MCP_WL3749
+                            tmp_table, open_mode))
+#else
                             tmp_table, FALSE))
+#endif
   {
     /* No need to lock share->mutex as this is not needed for tmp tables */
     free_table_share(share);
@@ -5840,8 +5877,14 @@ TABLE *open_table_uncached(THD *thd, con
   }
 
   tmp_table->reginfo.lock_type= TL_WRITE;	 // Simulate locked
+#ifndef MCP_WL3749
+  share->tmp_table= (open_mode == OTM_ALTER) ? TMP_TABLE_FRM_FILE_ONLY :
+                    (tmp_table->file->has_transactions() ?
+                     TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
+#else
   share->tmp_table= (tmp_table->file->has_transactions() ? 
                      TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
+#endif
 
   if (add_to_temporary_tables_list)
   {
@@ -5860,20 +5903,40 @@ TABLE *open_table_uncached(THD *thd, con
   DBUG_RETURN(tmp_table);
 }
 
-
+#ifndef MCP_WL3749
+bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
+#else
 bool rm_temporary_table(handlerton *base, char *path)
+#endif
 {
   bool error=0;
   handler *file;
   char *ext;
   DBUG_ENTER("rm_temporary_table");
 
+  DBUG_PRINT("info", ("frm_only %u", frm_only));
   strmov(ext= strend(path), reg_ext);
   if (mysql_file_delete(key_file_frm, path, MYF(0)))
     error=1; /* purecov: inspected */
   *ext= 0;				// remove extension
   file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
+#ifndef MCP_WL3749
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  if (frm_only && file && base == partition_hton)
+  {
+    for (const char **pext=file->bas_ext(); *pext ; pext++)
+    {
+      strmov(ext= strend(path), *pext);
+      if (mysql_file_delete(key_file_partition, path, MYF(0)))
+        error=1;
+      *ext= 0;                         // remove extension
+    }
+  }
+#endif
+  if (!frm_only && file && file->ha_delete_table(path))
+#else
   if (file && file->ha_delete_table(path))
+#endif
   {
     error=1;
     sql_print_warning("Could not remove temporary table: '%s', error: %d",

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2011-03-07 09:08:10 +0000
+++ b/sql/sql_base.h	2011-05-30 21:13:02 +0000
@@ -146,9 +146,17 @@ bool open_new_frm(THD *thd, TABLE_SHARE 
 
 bool get_key_map_from_key_list(key_map *map, TABLE *table,
                                List<String> *index_list);
+#ifndef MCP_WL3749
+enum open_table_mode;
+TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
+			   const char *table_name,
+                           bool add_to_temporary_tables_list,
+                           open_table_mode open_mode= OTM_OPEN);
+#else
 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
 			   const char *table_name,
                            bool add_to_temporary_tables_list);
+#endif
 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
 TABLE *find_write_locked_table(TABLE *list, const char *db,
                                const char *table_name);
@@ -157,7 +165,11 @@ thr_lock_type read_lock_type_for_table(T
                                        TABLE_LIST *table_list);
 
 my_bool mysql_rm_tmp_tables(void);
+#ifndef MCP_WL3749
+bool rm_temporary_table(handlerton *base, char *path, bool frm_only);
+#else
 bool rm_temporary_table(handlerton *base, char *path);
+#endif
 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
                              const MDL_savepoint &start_of_statement_svp);
 TABLE_LIST *find_table_in_list(TABLE_LIST *table,

=== modified file 'sql/sql_bitmap.h'
--- a/sql/sql_bitmap.h	2010-10-27 11:32:32 +0000
+++ b/sql/sql_bitmap.h	2011-04-20 12:53:27 +0000
@@ -65,12 +65,74 @@ public:
   void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); }
   void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); }
   my_bool is_set(uint n) const { return bitmap_is_set(&map, n); }
+#ifndef MCP_WL3749
+  my_bool is_set() const { return !bitmap_is_clear_all(&map); }
+#endif
   my_bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); }
   my_bool is_clear_all() const { return bitmap_is_clear_all(&map); }
   my_bool is_set_all() const { return bitmap_is_set_all(&map); }
   my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
   my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); }
   my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
+#ifndef MCP_WL3749
+    my_bool operator!=(const Bitmap& map2) const { return !bitmap_cmp(&map, &map2.
+map); }
+  Bitmap operator&=(uint n)
+  {
+    if (bitmap_is_set(&map, n))
+    {
+      bitmap_clear_all(&map);
+      bitmap_set_bit(&map, n);
+    }
+    else
+      bitmap_clear_all(&map);
+    return *this;
+  }
+  Bitmap operator&=(const Bitmap& map2)
+  {
+    bitmap_intersect(&map, &map2.map);
+    return *this;
+  }
+  Bitmap operator&(uint n)
+  {
+    Bitmap bm(*this);
+    bm&= n;
+    return bm;
+  }
+  Bitmap operator&(const Bitmap& map2)
+  {
+    Bitmap bm(*this);
+    bm&= map2;
+    return bm;
+  }
+  Bitmap operator|=(uint n)
+  {
+    bitmap_set_bit(&map, n);
+    return *this;
+  }
+  Bitmap operator|=(const Bitmap& map2)
+  {
+    bitmap_union(&map, &map2.map);
+  }
+  Bitmap operator|(uint n)
+  {
+    Bitmap bm(*this);
+    bm|= n;
+    return bm;
+  }
+  Bitmap operator|(const Bitmap& map2)
+  {
+    Bitmap bm(*this);
+    bm|= map2;
+    return bm;
+  }
+  Bitmap operator~()
+  {
+    Bitmap bm(*this);
+    bitmap_invert(&bm.map);
+    return bm;
+  }
+#endif
   char *print(char *buf) const
   {
     char *s=buf;

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2011-05-10 09:48:14 +0000
+++ b/sql/sql_lex.cc	2011-05-30 21:13:02 +0000
@@ -1634,6 +1634,9 @@ Alter_info::Alter_info(const Alter_info 
   tablespace_op(rhs.tablespace_op),
   partition_names(rhs.partition_names, mem_root),
   num_parts(rhs.num_parts),
+#ifndef MCP_WL3749 
+  build_method(rhs.build_method),
+#endif
   change_level(rhs.change_level),
   datetime_field(rhs.datetime_field),
   error_if_not_empty(rhs.error_if_not_empty)

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-05-10 09:48:14 +0000
+++ b/sql/sql_lex.h	2011-05-30 21:13:02 +0000
@@ -939,6 +939,34 @@ inline bool st_select_lex_unit::is_union
 #define ALTER_ADD_COLUMN	(1L << 0)
 #define ALTER_DROP_COLUMN	(1L << 1)
 #define ALTER_CHANGE_COLUMN	(1L << 2)
+#ifndef MCP_WL3627
+#define ALTER_COLUMN_STORAGE    (1L << 3)
+#define ALTER_COLUMN_FORMAT     (1L << 4)
+#define ALTER_COLUMN_ORDER      (1L << 5)
+#define ALTER_ADD_INDEX         (1L << 6)
+#define ALTER_DROP_INDEX        (1L << 7)
+#define ALTER_RENAME            (1L << 8)
+#define ALTER_ORDER             (1L << 9)
+#define ALTER_OPTIONS           (1L << 10)
+#define ALTER_COLUMN_DEFAULT    (1L << 11)
+#define ALTER_KEYS_ONOFF        (1L << 12)
+#define ALTER_STORAGE           (1L << 13)
+#define ALTER_ROW_FORMAT        (1L << 14)
+#define ALTER_CONVERT           (1L << 15)
+#define ALTER_RECREATE          (1L << 16)
+#define ALTER_ADD_PARTITION     (1L << 17)
+#define ALTER_DROP_PARTITION    (1L << 18)
+#define ALTER_COALESCE_PARTITION (1L << 19)
+#define ALTER_REORGANIZE_PARTITION (1L << 20)
+#define ALTER_PARTITION         (1L << 21)
+#define ALTER_ADMIN_PARTITION   (1L << 22)
+#define ALTER_TABLE_REORG       (1L << 23)
+#define ALTER_REBUILD_PARTITION (1L << 24)
+#define ALTER_ALL_PARTITION     (1L << 25)
+#define ALTER_REMOVE_PARTITIONING (1L << 26)
+#define ALTER_FOREIGN_KEY       (1L << 27)
+#define ALTER_TRUNCATE_PARTITION (1L << 28)
+#else
 #define ALTER_ADD_INDEX		(1L << 3)
 #define ALTER_DROP_INDEX	(1L << 4)
 #define ALTER_RENAME		(1L << 5)
@@ -960,7 +988,8 @@ inline bool st_select_lex_unit::is_union
 #define ALTER_REMOVE_PARTITIONING (1L << 21)
 #define ALTER_FOREIGN_KEY        (1L << 22)
 #define ALTER_TRUNCATE_PARTITION (1L << 23)
-
+#endif
+/* #ifdef MCP_WL3749 */
 enum enum_alter_table_change_level
 {
   ALTER_TABLE_METADATA_ONLY= 0,
@@ -968,7 +997,6 @@ enum enum_alter_table_change_level
   ALTER_TABLE_INDEX_CHANGED= 2
 };
 
-
 /**
   Temporary hack to enable a class bound forward declaration
   of the enum_alter_table_change_level enumeration. To be
@@ -984,6 +1012,7 @@ public:
   void operator = (enum_type v) { value = v; }
   operator enum_type () { return value; }
 };
+/* #endif */
 
 
 /**
@@ -1005,7 +1034,12 @@ public:
   enum tablespace_op_type       tablespace_op;
   List<char>                    partition_names;
   uint                          num_parts;
+#ifndef MCP_WL3749
+  enum ha_build_method          build_method;
+#endif
+/* #else */
   enum_alter_table_change_level change_level;
+/* #endif */
   Create_field                 *datetime_field;
   bool                          error_if_not_empty;
 
@@ -1015,7 +1049,11 @@ public:
     keys_onoff(LEAVE_AS_IS),
     tablespace_op(NO_TABLESPACE_OP),
     num_parts(0),
+#ifndef MCP_WL3749
+    build_method(HA_BUILD_DEFAULT),
+#else
     change_level(ALTER_TABLE_METADATA_ONLY),
+#endif
     datetime_field(NULL),
     error_if_not_empty(FALSE)
   {}
@@ -1031,7 +1069,12 @@ public:
     tablespace_op= NO_TABLESPACE_OP;
     num_parts= 0;
     partition_names.empty();
+#ifndef MCP_WL3749
+    build_method= HA_BUILD_DEFAULT;
+#endif
+/* #else */
     change_level= ALTER_TABLE_METADATA_ONLY;
+/* #endif */
     datetime_field= 0;
     error_if_not_empty= FALSE;
   }

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2011-05-10 09:48:14 +0000
+++ b/sql/sql_partition.cc	2011-05-30 21:13:02 +0000
@@ -4578,7 +4578,12 @@ uint prep_alter_part_table(THD *thd, TAB
                            char *db,
                            const char *table_name,
                            const char *path,
+#ifndef MCP_WL3749
+                           TABLE **repartitioned_table,
+                           bool *is_fast_alter_partitioning)
+#else
                            TABLE **fast_alter_table)
+#endif
 {
   TABLE *new_table= NULL;
   DBUG_ENTER("prep_alter_part_table");
@@ -4629,7 +4634,9 @@ uint prep_alter_part_table(THD *thd, TAB
     new_table= open_table_uncached(thd, path, db, table_name, 0);
     if (!new_table)
       DBUG_RETURN(TRUE);
-
+#ifndef MCP_WL3749
+    *repartitioned_table= new_table;
+#endif
     /*
       This table may be used for copy rows between partitions
       and also read/write columns when fixing the partition_info struct.
@@ -4641,8 +4648,18 @@ uint prep_alter_part_table(THD *thd, TAB
     if (alter_info->flags & ALTER_TABLE_REORG)
     {
       uint new_part_no, curr_part_no;
+#ifndef MCP_WL3749
+      /* 'ALTER TABLE t REORG PARTITION' only allowed with auto partition 
+          if default partitioning is used */
+      if (tab_part_info->part_type != HASH_PARTITION ||
+          (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION &&
+           !tab_part_info->use_default_num_partitions) ||
+          ((!table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) &&
+           tab_part_info->use_default_num_partitions))
+#else
       if (tab_part_info->part_type != HASH_PARTITION ||
           tab_part_info->use_default_num_partitions)
+#endif
       {
         my_error(ER_REORG_NO_PARAM_ERROR, MYF(0));
         goto err;
@@ -4656,7 +4673,11 @@ uint prep_alter_part_table(THD *thd, TAB
           after the change as before. Thus we can reply ok immediately
           without any changes at all.
         */
+#ifndef MCP_WL3749
+        *is_fast_alter_partitioning= TRUE;
+#else
         *fast_alter_table= new_table;
+#endif
         thd->work_part_info= tab_part_info;
         DBUG_RETURN(FALSE);
       }
@@ -4681,13 +4702,22 @@ uint prep_alter_part_table(THD *thd, TAB
     }
     if (!(flags= new_table->file->alter_table_flags(alter_info->flags)))
     {
-      my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
+       my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
       goto err;
     }
     if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0)
+#ifndef MCP_WL3749
+      *is_fast_alter_partitioning= TRUE;
+#else
       *fast_alter_table= new_table;
+#endif
+#ifndef MCP_WL3749
+    DBUG_PRINT("info", ("*is_fast_alter_partitioning: %u  flags: 0x%x",
+                        *is_fast_alter_partitioning, flags));
+#else
     DBUG_PRINT("info", ("*fast_alter_table: %p  flags: 0x%x",
                         *fast_alter_table, flags));
+#endif
     if ((alter_info->flags & ALTER_ADD_PARTITION) ||
          (alter_info->flags & ALTER_REORGANIZE_PARTITION))
     {
@@ -4875,7 +4905,11 @@ adding and copying partitions, the secon
 and copying and finally the third line after also dropping the partitions
 that are reorganised.
 */
+#ifndef MCP_WL3749
+      if (*is_fast_alter_partitioning &&
+#else
       if (*fast_alter_table &&
+#endif
           tab_part_info->part_type == HASH_PARTITION)
       {
         uint part_no= 0, start_part= 1, start_sec_part= 1;
@@ -4980,7 +5014,11 @@ that are reorganised.
         do
         {
           partition_element *part_elem= alt_it++;
+#ifndef MCP_WL3749
+          if (*is_fast_alter_partitioning)
+#else
           if (*fast_alter_table)
+#endif
             part_elem->part_state= PART_TO_BE_ADDED;
           if (tab_part_info->partitions.push_back(part_elem))
           {
@@ -4988,6 +5026,9 @@ that are reorganised.
             goto err;
           }
         } while (++part_count < num_new_partitions);
+        DBUG_PRINT("info", ("Setting  tab_part_info->num_parts (%u) to %u",
+                            tab_part_info->num_parts,
+                            tab_part_info->num_parts + num_new_partitions));
         tab_part_info->num_parts+= num_new_partitions;
       }
       /*
@@ -5069,7 +5110,11 @@ that are reorganised.
         my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD");
         goto err;
       }
+#ifndef MCP_WL3749
+      if (!(*is_fast_alter_partitioning))
+#else
       if (!(*fast_alter_table))
+#endif
       {
         new_table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0));
         goto err;
@@ -5132,7 +5177,11 @@ state of p1.
         uint part_count= 0, start_part= 1, start_sec_part= 1;
         uint end_part= 0, end_sec_part= 0;
         bool all_parts= TRUE;
+#ifndef MCP_WL3749
+        if (*is_fast_alter_partitioning &&
+#else
         if (*fast_alter_table &&
+#endif
             tab_part_info->linear_hash_ind)
         {
           uint upper_2n= tab_part_info->linear_hash_mask + 1;
@@ -5158,14 +5207,22 @@ state of p1.
         do
         {
           partition_element *p_elem= part_it++;
+#ifndef MCP_WL3749
+          if (*is_fast_alter_partitioning &&
+#else
           if (*fast_alter_table &&
+#endif
               (all_parts ||
               (part_count >= start_part && part_count <= end_part) ||
               (part_count >= start_sec_part && part_count <= end_sec_part)))
             p_elem->part_state= PART_CHANGED;
           if (++part_count > num_parts_remain)
           {
+#ifndef MCP_WL3749
+            if (*is_fast_alter_partitioning)
+#else
             if (*fast_alter_table)
+#endif
               p_elem->part_state= PART_REORGED_DROPPED;
             else
               part_it.remove();
@@ -5290,13 +5347,21 @@ the generated partition syntax in a corr
             }
             else
               tab_max_range= part_elem->range_value;
+#ifndef MCP_WL3749
+            if (*is_fast_alter_partitioning &&
+#else
             if (*fast_alter_table &&
+#endif
                 tab_part_info->temp_partitions.push_back(part_elem))
             {
               mem_alloc_error(1);
               goto err;
             }
+#ifndef MCP_WL3749
+            if (*is_fast_alter_partitioning)
+#else
             if (*fast_alter_table)
+#endif
               part_elem->part_state= PART_TO_BE_REORGED;
             if (!found_first)
             {
@@ -5316,7 +5381,11 @@ the generated partition syntax in a corr
                 else
                   alt_max_range= alt_part_elem->range_value;
 
+#ifndef MCP_WL3749
+                if (*is_fast_alter_partitioning)
+#else
                 if (*fast_alter_table)
+#endif
                   alt_part_elem->part_state= PART_TO_BE_ADDED;
                 if (alt_part_count == 0)
                   tab_it.replace(alt_part_elem);
@@ -5553,7 +5622,11 @@ err:
     */
     close_temporary(new_table, 1, 0);
   }
-  *fast_alter_table= NULL;
+#ifndef MCP_WL3749
+    *repartitioned_table= NULL;
+#else
+    *fast_alter_table= NULL;
+#endif
   DBUG_RETURN(TRUE);
 }
 

=== modified file 'sql/sql_partition.h'
--- a/sql/sql_partition.h	2010-11-16 12:37:26 +0000
+++ b/sql/sql_partition.h	2011-05-30 21:13:02 +0000
@@ -263,7 +263,12 @@ uint prep_alter_part_table(THD *thd, TAB
                            char *db,
                            const char *table_name,
                            const char *path,
+#ifndef MCP_WL3749
+                           TABLE **repartitioned_table,
+                           bool *is_fast_alter_partitioning);
+#else
                            TABLE **fast_alter_table);
+#endif
 char *generate_partition_syntax(partition_info *part_info,
                                 uint *buf_length, bool use_sql_alloc,
                                 bool show_partition_options,

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2011-05-12 08:43:50 +0000
+++ b/sql/sql_show.cc	2011-05-30 21:13:02 +0000
@@ -3411,7 +3411,11 @@ static int fill_schema_table_from_frm(TH
 
   if (!open_table_from_share(thd, share, table_name->str, 0,
                              (EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
+#ifndef MCP_WL3749
+                             thd->open_options, &tbl, OTM_OPEN))
+#else
                              thd->open_options, &tbl, FALSE))
+#endif
   {
     tbl.s= share;
     table_list.table= &tbl;

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-05-12 08:43:50 +0000
+++ b/sql/sql_table.cc	2011-05-30 21:13:02 +0000
@@ -3854,22 +3854,32 @@ static bool check_if_created_table_can_b
   TABLE_SHARE share;
   bool result;
 
+#ifdef MCP_WL3749
   /*
     It is impossible to open definition of partitioned table without .par file.
   */
   if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
     return TRUE;
+#endif
 
   init_tmp_table_share(thd, &share, db, 0, table_name, path);
 
   result= (open_table_def(thd, &share, 0) ||
+#ifndef MCP_WL3749
+           open_table_from_share(thd, &share, "", 0, (uint) READ_ALL,
+                                 0, &table, OTM_CREATE));
+#else
            open_table_from_share(thd, &share, "", 0, (uint) READ_ALL,
                                  0, &table, TRUE));
+#endif
   if (! result)
     (void) closefrm(&table, 0);
 
   free_table_share(&share);
+#ifdef MCP_WL3749
   (void) file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info);
+#endif
+
   return result;
 }
 
@@ -4288,10 +4298,13 @@ bool mysql_create_table_no_lock(THD *thd
     */
 
     TABLE *table= open_table_uncached(thd, path, db, table_name, TRUE);
-
     if (!table)
     {
+#ifndef MCP_WL3749
+      (void) rm_temporary_table(create_info->db_type, path, false);
+#else
       (void) rm_temporary_table(create_info->db_type, path);
+#endif
       goto err;
     }
 
@@ -4319,6 +4332,18 @@ bool mysql_create_table_no_lock(THD *thd
       char frm_name[FN_REFLEN];
       strxmov(frm_name, path, reg_ext, NullS);
       (void) mysql_file_delete(key_file_frm, frm_name, MYF(0));
+#ifndef MCP_WL3749
+  {
+    char* ext;
+    for (const char **pext=file->bas_ext(); *pext ; pext++)
+    {
+      strmov(ext= strend(path), *pext);
+      if (mysql_file_delete(key_file_partition, path, MYF(0)))
+        DBUG_PRINT("info", ("Failed to delete file %s", ext));
+      *ext= 0;                         // remove extension
+    }
+  }
+#endif
       goto err;
     }
   }
@@ -4509,6 +4534,24 @@ mysql_rename_table(handlerton *base, con
     to_base= lc_to;
   }
 
+#ifndef MCP_WL3749
+  if (flags & FRM_ONLY)
+  {
+    if (rename_file_ext(from,to,reg_ext))
+      error= my_errno;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+    if (file && (base == partition_hton))
+    {
+      for (const char **ext=file->bas_ext(); *ext ; ext++)
+      {
+        if (rename_file_ext(from,to,*ext))
+          error= my_errno;
+      }
+    }
+#endif
+  }
+  else
+#endif
   if (!file || !(error=file->ha_rename_table(from_base, to_base)))
   {
     if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
@@ -4764,6 +4807,7 @@ err:
   DBUG_RETURN(-1);
 }
 
+#ifdef MCP_WL3749
 /**
   @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
  
@@ -4802,76 +4846,118 @@ is_index_maintenance_unique (TABLE *tabl
   }
   return FALSE;
 }
+#endif /* MCP_WL3749 */
 
+#ifndef MCP_WL3749
+/**
+  Copy all changes detected by parser to the HA_ALTER_FLAGS
+*/
 
-/*
-  SYNOPSIS
-    mysql_compare_tables()
-      table                     The original table.
-      alter_info                Alter options, fields and keys for the new
-                                table.
-      create_info               Create options for the new table.
-      order_num                 Number of order list elements.
-      need_copy_table     OUT   Result of the comparison. Undefined if error.
-                                Otherwise is one of:
-                                ALTER_TABLE_METADATA_ONLY  No copy needed
-                                ALTER_TABLE_DATA_CHANGED   Data changes,
-                                                           copy needed
-                                ALTER_TABLE_INDEX_CHANGED  Index changes,
-                                                           copy might be needed
-      key_info_buffer     OUT   An array of KEY structs for new indexes
-      index_drop_buffer   OUT   An array of offsets into table->key_info.
-      index_drop_count    OUT   The number of elements in the array.
-      index_add_buffer    OUT   An array of offsets into key_info_buffer.
-      index_add_count     OUT   The number of elements in the array.
-      candidate_key_count OUT   The number of candidate keys in original table.
+void setup_ha_alter_flags(TABLE *table,
+                          HA_CREATE_INFO *create_info,
+                          Alter_info *alter_info,
+                          HA_ALTER_FLAGS *alter_flags)
+{
+  uint flags= alter_info->flags;
 
-  DESCRIPTION
-    'table' (first argument) contains information of the original
-    table, which includes all corresponding parts that the new
-    table has in arguments create_list, key_list and create_info.
+  if (ALTER_ADD_COLUMN & flags)
+    *alter_flags|= HA_ADD_COLUMN;
+  if (ALTER_DROP_COLUMN & flags)
+    *alter_flags|= HA_DROP_COLUMN;
+  if (ALTER_RENAME & flags)
+    *alter_flags|= HA_RENAME_TABLE;
+  if (ALTER_CHANGE_COLUMN & flags)
+    *alter_flags|= HA_CHANGE_COLUMN;
+  if (ALTER_COLUMN_DEFAULT & flags)
+    *alter_flags|= HA_COLUMN_DEFAULT_VALUE;
+  if (ALTER_COLUMN_STORAGE & flags)
+    *alter_flags|= HA_COLUMN_STORAGE;
+  if (ALTER_COLUMN_FORMAT & flags)
+    *alter_flags|= HA_COLUMN_FORMAT;
+  if (ALTER_COLUMN_ORDER & flags)
+    *alter_flags|= HA_ALTER_COLUMN_ORDER;
+  if (ALTER_STORAGE & flags)
+    *alter_flags|= HA_ALTER_STORAGE;
+  if (ALTER_ROW_FORMAT & flags)
+    *alter_flags|= HA_ALTER_ROW_FORMAT;
+  if (ALTER_RECREATE & flags)
+    *alter_flags|= HA_RECREATE;
+  if (ALTER_ADD_PARTITION & flags)
+    *alter_flags|= HA_ADD_PARTITION;
+  if (ALTER_DROP_PARTITION & flags)
+    *alter_flags|= HA_DROP_PARTITION;
+  if (ALTER_COALESCE_PARTITION & flags)
+    *alter_flags|= HA_COALESCE_PARTITION;
+  if (ALTER_REORGANIZE_PARTITION & flags)
+    *alter_flags|= HA_REORGANIZE_PARTITION;
+  if (ALTER_PARTITION & flags)
+    *alter_flags|= HA_ALTER_PARTITION;
+  if (ALTER_FOREIGN_KEY & flags)
+    *alter_flags|= HA_ALTER_FOREIGN_KEY;
+  if (create_info->auto_increment_value !=
+      table->file->stats.auto_increment_value)
+    *alter_flags|= HA_CHANGE_AUTOINCREMENT_VALUE;
+  if (ALTER_TABLE_REORG & flags)
+    *alter_flags|= HA_ALTER_TABLE_REORG;
+}
 
-    By comparing the changes between the original and new table
-    we can determine how much it has changed after ALTER TABLE
-    and whether we need to make a copy of the table, or just change
-    the .frm file.
 
-    If there are no data changes, but index changes, 'index_drop_buffer'
-    and/or 'index_add_buffer' are populated with offsets into
-    table->key_info or key_info_buffer respectively for the indexes
-    that need to be dropped and/or (re-)created.
+/**
+   @param       thd                Thread
+   @param       table              The original table.
+   @param       alter_info         Alter options, fields and keys for the new
+                                   table.
+   @param       create_info        Create options for the new table.
+   @param       order_num          Number of order list elements.
+   @param[out]  ha_alter_flags  Flags that indicate what will be changed
+   @param[out]  ha_alter_info      Data structures needed for on-line alter
+   @param[out]  table_changes      Information about particular change
+
+   First argument 'table' contains information of the original
+   table, which includes all corresponding parts that the new
+   table has in arguments create_list, key_list and create_info.
+
+   By comparing the changes between the original and new table
+   we can determine how much it has changed after ALTER TABLE
+   and whether we need to make a copy of the table, or just change
+   the .frm file.
+
+   Mark any changes detected in the ha_alter_flags.
+
+   If there are no data changes, but index changes, 'index_drop_buffer'
+   and/or 'index_add_buffer' are populated with offsets into
+   table->key_info or key_info_buffer respectively for the indexes
+   that need to be dropped and/or (re-)created.
 
-  RETURN VALUES
-    TRUE   error
-    FALSE  success
+   @retval TRUE  error
+   @retval FALSE success
 */
 
+static
 bool
-mysql_compare_tables(TABLE *table,
-                     Alter_info *alter_info,
-                     HA_CREATE_INFO *create_info,
-                     uint order_num,
-                     enum_alter_table_change_level *need_copy_table,
-                     KEY **key_info_buffer,
-                     uint **index_drop_buffer, uint *index_drop_count,
-                     uint **index_add_buffer, uint *index_add_count,
-                     uint *candidate_key_count)
+compare_tables(THD *thd,
+               TABLE *table,
+               Alter_info *alter_info,
+               HA_CREATE_INFO *create_info,
+               uint order_num,
+               HA_ALTER_FLAGS *alter_flags,
+               HA_ALTER_INFO *ha_alter_info,
+               uint *table_changes)
 {
   Field **f_ptr, *field;
-  uint changes= 0, tmp;
-  uint key_count;
+  uint table_changes_local= 0;
   List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
   Create_field *new_field, *tmp_new_field;
   KEY_PART_INFO *key_part;
   KEY_PART_INFO *end;
-  THD *thd= table->in_use;
   /*
     Remember if the new definition has new VARCHAR column;
     create_info->varchar will be reset in mysql_prepare_create_table.
   */
   bool varchar= create_info->varchar;
+  uint candidate_key_count= 0;
   bool not_nullable= true;
-  DBUG_ENTER("mysql_compare_tables");
+  DBUG_ENTER("compare_tables");
 
   /*
     Create a copy of alter_info.
@@ -4882,10 +4968,10 @@ mysql_compare_tables(TABLE *table,
     mysql_prepare_create_table.  Unfortunately,
     mysql_prepare_create_table performs its transformations
     "in-place", that is, modifies the argument.  Since we would
-    like to keep mysql_compare_tables() idempotent (not altering any
+    like to keep compare_tables() idempotent (not altering any
     of the arguments) we create a copy of alter_info here and
     pass it to mysql_prepare_create_table, then use the result
-    to evaluate possibility of in-place ALTER TABLE, and then
+    to evaluate possibility of fast ALTER TABLE, and then
     destroy the copy.
   */
   Alter_info tmp_alter_info(*alter_info, thd->mem_root);
@@ -4896,16 +4982,33 @@ mysql_compare_tables(TABLE *table,
                                  &tmp_alter_info,
                                  (table->s->tmp_table != NO_TMP_TABLE),
                                  &db_options,
-                                 table->file, key_info_buffer,
-                                 &key_count, 0))
-    DBUG_RETURN(1);
+                                 table->file,
+                                 &ha_alter_info->key_info_buffer,
+                                 &ha_alter_info->key_count,
+                                 /* select_field_count */ 0))
+    DBUG_RETURN(TRUE);
   /* Allocate result buffers. */
-  if (! (*index_drop_buffer=
-         (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
-      ! (*index_add_buffer=
-         (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
-    DBUG_RETURN(1);
-  
+  if (! (ha_alter_info->index_drop_buffer=
+          (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
+      ! (ha_alter_info->index_add_buffer=
+          (uint*) thd->alloc(sizeof(uint) *
+                            tmp_alter_info.key_list.elements)))
+    DBUG_RETURN(TRUE);
+
+  /*
+    First we setup ha_alter_flags based on what was detected
+    by parser
+  */
+  setup_ha_alter_flags(table, create_info, alter_info, alter_flags);
+
+#ifndef DBUG_OFF
+  {
+    char dbug_string[HA_MAX_ALTER_FLAGS+1];
+    alter_flags->print(dbug_string);
+    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
+  }
+#endif
+
   /*
     Some very basic checks. If number of fields changes, or the
     handler, we need to run full ALTER TABLE. In the future
@@ -4926,9 +5029,9 @@ mysql_compare_tables(TABLE *table,
 
     There was a bug prior to mysql-4.0.25. Number of null fields was
     calculated incorrectly. As a result frm and data files gets out of
-    sync after in-place alter table. There is no way to determine by which
+    sync after fast alter table. There is no way to determine by which
     mysql version (in 4.0 and 4.1 branches) table was created, thus we
-    disable in-place alter table for all tables created by mysql versions
+    disable fast alter table for all tables created by mysql versions
     prior to 5.0 branch.
     See BUG#6236.
   */
@@ -4946,12 +5049,32 @@ mysql_compare_tables(TABLE *table,
       !table->s->mysql_version ||
       (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
   {
-    *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-    DBUG_RETURN(0);
+    *table_changes= IS_EQUAL_NO;
+    /*
+      Check what has changed and set alter_flags
+    */
+    if (table->s->fields < alter_info->create_list.elements)
+      *alter_flags|= HA_ADD_COLUMN;
+    else if (table->s->fields > alter_info->create_list.elements)
+      *alter_flags|= HA_DROP_COLUMN;
+    if (create_info->db_type != table->s->db_type() ||
+        create_info->used_fields & HA_CREATE_USED_ENGINE)
+      *alter_flags|= HA_ALTER_STORAGE_ENGINE;
+    if (create_info->used_fields & HA_CREATE_USED_CHARSET)
+      *alter_flags|= HA_CHANGE_CHARACTER_SET;
+    if (create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)
+      *alter_flags|= HA_SET_DEFAULT_CHARACTER_SET;
+    if (alter_info->flags & ALTER_RECREATE)
+      *alter_flags|= HA_RECREATE;
+    /* TODO check for ADD/DROP FOREIGN KEY */
+    if (alter_info->flags & ALTER_FOREIGN_KEY)
+      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
+    if (!table->s->mysql_version ||
+        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
+      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
   }
-
   /*
-    Use transformed info to evaluate possibility of in-place ALTER TABLE
+    Use transformed info to evaluate possibility of fast ALTER TABLE
     but use the preserved field to persist modifications.
   */
   new_field_it.init(alter_info->create_list);
@@ -4963,7 +5086,7 @@ mysql_compare_tables(TABLE *table,
   */
   for (f_ptr= table->field, new_field= new_field_it++,
        tmp_new_field= tmp_new_field_it++;
-       (field= *f_ptr);
+       (new_field && (field= *f_ptr));
        f_ptr++, new_field= new_field_it++,
        tmp_new_field= tmp_new_field_it++)
   {
@@ -4971,14 +5094,6 @@ mysql_compare_tables(TABLE *table,
     if (!new_field->charset)
       new_field->charset= create_info->default_table_charset;
 
-    /* Check that NULL behavior is same for old and new fields */
-    if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
-	(uint) (field->flags & NOT_NULL_FLAG))
-    {
-      *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-      DBUG_RETURN(0);
-    }
-
     /* Don't pack rows in old tables if the user has requested this. */
     if (create_info->row_type == ROW_TYPE_DYNAMIC ||
 	(tmp_new_field->flags & BLOB_FLAG) ||
@@ -4986,22 +5101,38 @@ mysql_compare_tables(TABLE *table,
 	create_info->row_type != ROW_TYPE_FIXED))
       create_info->table_options|= HA_OPTION_PACK_RECORD;
 
-    /* Check if field was renamed */
-    field->flags&= ~FIELD_IS_RENAMED;
-    if (my_strcasecmp(system_charset_info,
-		      field->field_name,
-		      tmp_new_field->field_name))
-      field->flags|= FIELD_IS_RENAMED;      
-
-    /* Evaluate changes bitmap and send to check_if_incompatible_data() */
-    if (!(tmp= field->is_equal(tmp_new_field)))
+    /* Check how fields have been modified */
+    if (alter_info->flags & ALTER_CHANGE_COLUMN)
     {
-      *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-      DBUG_RETURN(0);
+      /* Evaluate changes bitmap and send to check_if_incompatible_data() */
+      if (!(table_changes_local= field->is_equal(tmp_new_field)))
+        *alter_flags|= HA_ALTER_COLUMN_TYPE;
+
+      /* Check if field was renamed */
+      field->flags&= ~FIELD_IS_RENAMED;
+      if (my_strcasecmp(system_charset_info,
+                        field->field_name,
+                        tmp_new_field->field_name))
+      {
+        field->flags|= FIELD_IS_RENAMED;
+        *alter_flags|= HA_ALTER_COLUMN_NAME;
+      }
+
+      *table_changes&= table_changes_local;
+      if (table_changes_local == IS_EQUAL_PACK_LENGTH)
+        *alter_flags|= HA_ALTER_COLUMN_TYPE;
+
+      /* Check that NULL behavior is same for old and new fields */
+      if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
+          (uint) (field->flags & NOT_NULL_FLAG))
+      {
+        *table_changes= IS_EQUAL_NO;
+        *alter_flags|= HA_ALTER_COLUMN_NULLABLE;
+      }
     }
-    // Clear indexed marker
+
+    /* Clear indexed marker */
     field->flags&= ~FIELD_IN_ADD_INDEX;
-    changes|= tmp;
   }
 
   /*
@@ -5011,27 +5142,23 @@ mysql_compare_tables(TABLE *table,
   KEY *table_key;
   KEY *table_key_end= table->key_info + table->s->keys;
   KEY *new_key;
-  KEY *new_key_end= *key_info_buffer + key_count;
+  KEY *new_key_end=
+       ha_alter_info->key_info_buffer + ha_alter_info->key_count;
 
   DBUG_PRINT("info", ("index count old: %d  new: %d",
-                      table->s->keys, key_count));
-  /*
-    Step through all keys of the old table and search matching new keys.
-  */
-  *index_drop_count= 0;
-  *index_add_count= 0;
-  *candidate_key_count= 0;
+                      table->s->keys, ha_alter_info->key_count));
+
+  /* Count all candidate keys. */
+
   for (table_key= table->key_info; table_key < table_key_end; table_key++)
   {
     KEY_PART_INFO *table_part;
     KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
-    KEY_PART_INFO *new_part;
 
-   /*
+    /*
       Check if key is a candidate key, i.e. a unique index with no index
       fields nullable, then key is either already primary key or could
       be promoted to primary key if the original primary key is dropped.
-      Count all candidate keys.
     */
     not_nullable= true;
     for (table_part= table_key->key_part;
@@ -5041,10 +5168,24 @@ mysql_compare_tables(TABLE *table,
       not_nullable= not_nullable && (! table_part->field->maybe_null());
     }
     if ((table_key->flags & HA_NOSAME) && not_nullable)
-      (*candidate_key_count)++;
+      candidate_key_count++;
+  }
+
+  /*
+    Step through all keys of the old table and search matching new keys.
+  */
+  ha_alter_info->index_drop_count= 0;
+  ha_alter_info->index_add_count= 0;
+  for (table_key= table->key_info; table_key < table_key_end; table_key++)
+  {
+    KEY_PART_INFO *table_part;
+    KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
+    KEY_PART_INFO *new_part;
 
     /* Search a new key with the same name. */
-    for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+    for (new_key= ha_alter_info->key_info_buffer;
+         new_key < new_key_end;
+         new_key++)
     {
       if (! strcmp(table_key->name, new_key->name))
         break;
@@ -5052,145 +5193,927 @@ mysql_compare_tables(TABLE *table,
     if (new_key >= new_key_end)
     {
       /* Key not found. Add the offset of the key to the drop buffer. */
-      (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+      ha_alter_info->index_drop_buffer
+           [ha_alter_info->index_drop_count++]=
+           table_key - table->key_info;
+      if (table_key->flags & HA_NOSAME)
+      {
+        /* Unique key. Check for "PRIMARY". */
+        if ((uint) (table_key - table->key_info) == table->s->primary_key)
+        {
+          *alter_flags|= HA_DROP_PK_INDEX;
+          candidate_key_count--;
+        }
+        else
+        {
+          bool is_not_null= true;
+
+          *alter_flags|= HA_DROP_UNIQUE_INDEX;
+          key_part= table_key->key_part;
+          end= key_part + table_key->key_parts;
+
+         /*
+            Check if all fields in key are declared
+            NOT NULL and adjust candidate_key_count
+          */
+          for(; key_part != end; key_part++)
+          {
+            is_not_null=
+              (is_not_null &&
+               (!table->field[key_part->fieldnr-1]->maybe_null()));
+          }
+          if (is_not_null)
+            candidate_key_count--;
+        }
+      }
+      else
+        *alter_flags|= HA_DROP_INDEX;
+      *table_changes= IS_EQUAL_NO;
       DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
       continue;
     }
 
     /* Check that the key types are compatible between old and new tables. */
     if ((table_key->algorithm != new_key->algorithm) ||
-	((table_key->flags & HA_KEYFLAG_MASK) !=
+        ((table_key->flags & HA_KEYFLAG_MASK) !=
          (new_key->flags & HA_KEYFLAG_MASK)) ||
         (table_key->key_parts != new_key->key_parts))
+    {
+      if (table_key->flags & HA_NOSAME)
+      {
+        /* Unique key. Check for "PRIMARY". */
+        if ((uint) (table_key - table->key_info) == table->s->primary_key)
+          *alter_flags|= HA_ALTER_PK_INDEX;
+        else
+          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+      }
+      else
+        *alter_flags|= HA_ALTER_INDEX;
       goto index_changed;
+    }
+
+    /*
+      Check that the key parts remain compatible between the old and
+      new tables.
+    */
+    for (table_part= table_key->key_part, new_part= new_key->key_part;
+         table_part < table_part_end;
+         table_part++, new_part++)
+    {
+      /*
+        Key definition has changed if we are using a different field or
+	if the used key part length is different. We know that the fields
+        did not change. Comparing field numbers is sufficient.
+      */
+      if ((table_part->length != new_part->length) ||
+          (table_part->fieldnr - 1 != new_part->fieldnr))
+      {
+        if (table_key->flags & HA_NOSAME)
+        {
+          /* Unique key. Check for "PRIMARY" */
+          if ((uint) (table_key - table->key_info) ==  table->s->primary_key)
+            *alter_flags|= HA_ALTER_PK_INDEX;
+          else
+            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+        }
+        else
+          *alter_flags|= HA_ALTER_INDEX;
+        goto index_changed;
+      }
+    }
+    continue;
+
+  index_changed:
+    /* Key modified. Add the offset of the key to both buffers. */
+    ha_alter_info->index_drop_buffer
+         [ha_alter_info->index_drop_count++]=
+         table_key - table->key_info;
+    ha_alter_info->index_add_buffer
+         [ha_alter_info->index_add_count++]=
+         new_key - ha_alter_info->key_info_buffer;
+    key_part= new_key->key_part;
+    end= key_part + new_key->key_parts;
+    for(; key_part != end; key_part++)
+    {
+      /* Mark field to be part of new key */
+      if ((field= table->field[key_part->fieldnr]))
+        field->flags|= FIELD_IN_ADD_INDEX;
+    }
+    *table_changes= IS_EQUAL_NO;
+    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
+  }
+  /*end of for (; table_key < table_key_end;) */
+
+  /*
+    Step through all keys of the new table and find matching old keys.
+  */
+  for (new_key= ha_alter_info->key_info_buffer;
+       new_key < new_key_end;
+       new_key++)
+  {
+    /* Search an old key with the same name. */
+    for (table_key= table->key_info; table_key < table_key_end; table_key++)
+    {
+      if (! strcmp(table_key->name, new_key->name))
+        break;
+    }
+    if (table_key >= table_key_end)
+    {
+      bool is_not_null= true;
+      bool no_pk= ((table->s->primary_key == MAX_KEY) ||
+                   alter_flags->is_set(HA_DROP_PK_INDEX));
+
+      /* Key not found. Add the offset of the key to the add buffer. */
+      ha_alter_info->index_add_buffer
+           [ha_alter_info->index_add_count++]=
+           new_key - ha_alter_info->key_info_buffer;
+      key_part= new_key->key_part;
+      end= key_part + new_key->key_parts;
+      for(; key_part != end; key_part++)
+      {
+        /*
+          Check if all fields in key are declared
+          NOT NULL
+         */
+        if (key_part->fieldnr < table->s->fields)
+        {
+          /* Mark field to be part of new key */
+          field= table->field[key_part->fieldnr];
+          field->flags|= FIELD_IN_ADD_INDEX;
+          is_not_null= (is_not_null && (!field->maybe_null()));
+        }
+        else
+        {
+          /* Index is defined over a newly added column */
+          List_iterator_fast<Create_field>
+            new_field_it(alter_info->create_list);
+          Create_field *new_field;
+          uint fieldnr;
+
+          for (fieldnr= 0, new_field= new_field_it++;
+               fieldnr != key_part->fieldnr;
+               fieldnr++, new_field= new_field_it++);
+          is_not_null=
+            (is_not_null && (new_field->flags & NOT_NULL_FLAG));
+        }
+      }
+      if (new_key->flags & HA_NOSAME)
+      {
+        /* Unique key. Check for "PRIMARY"
+           or if adding first unique key
+           defined on non-nullable
+        */
+        DBUG_PRINT("info",("no_pk %s, candidate_key_count %u, is_not_null %s", (no_pk)?"yes":"no", candidate_key_count, (is_not_null)?"yes":"no"));
+        if ((!my_strcasecmp(system_charset_info,
+                            new_key->name, primary_key_name)) ||
+            (no_pk && candidate_key_count == 0 && is_not_null))
+          *alter_flags|= HA_ADD_PK_INDEX;
+        else
+        *alter_flags|= HA_ADD_UNIQUE_INDEX;
+      }
+      else
+        *alter_flags|= HA_ADD_INDEX;
+      *table_changes= IS_EQUAL_NO;
+      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
+    }
+  }
+#ifndef DBUG_OFF
+  {
+    char dbug_string[HA_MAX_ALTER_FLAGS+1];
+    alter_flags->print(dbug_string);
+    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
+  }
+#endif
+
+  DBUG_RETURN(FALSE);
+}
+#else
+/*
+  SYNOPSIS
+    mysql_compare_tables()
+      table                     The original table.
+      alter_info                Alter options, fields and keys for the new
+                                table.
+      create_info               Create options for the new table.
+      order_num                 Number of order list elements.
+      need_copy_table     OUT   Result of the comparison. Undefined if error.
+                                Otherwise is one of:
+                                ALTER_TABLE_METADATA_ONLY  No copy needed
+                                ALTER_TABLE_DATA_CHANGED   Data changes,
+                                                           copy needed
+                                ALTER_TABLE_INDEX_CHANGED  Index changes,
+                                                           copy might be needed
+      key_info_buffer     OUT   An array of KEY structs for new indexes
+      index_drop_buffer   OUT   An array of offsets into table->key_info.
+      index_drop_count    OUT   The number of elements in the array.
+      index_add_buffer    OUT   An array of offsets into key_info_buffer.
+      index_add_count     OUT   The number of elements in the array.
+      candidate_key_count OUT   The number of candidate keys in original table.
+
+  DESCRIPTION
+    'table' (first argument) contains information of the original
+    table, which includes all corresponding parts that the new
+    table has in arguments create_list, key_list and create_info.
+
+    By comparing the changes between the original and new table
+    we can determine how much it has changed after ALTER TABLE
+    and whether we need to make a copy of the table, or just change
+    the .frm file.
+
+    If there are no data changes, but index changes, 'index_drop_buffer'
+    and/or 'index_add_buffer' are populated with offsets into
+    table->key_info or key_info_buffer respectively for the indexes
+    that need to be dropped and/or (re-)created.
+
+  RETURN VALUES
+    TRUE   error
+    FALSE  success
+*/
+
+bool
+mysql_compare_tables(TABLE *table,
+                     Alter_info *alter_info,
+                     HA_CREATE_INFO *create_info,
+                     uint order_num,
+                     enum_alter_table_change_level *need_copy_table,
+                     KEY **key_info_buffer,
+                     uint **index_drop_buffer, uint *index_drop_count,
+                     uint **index_add_buffer, uint *index_add_count,
+                     uint *candidate_key_count)
+{
+  Field **f_ptr, *field;
+  uint changes= 0, tmp;
+  uint key_count;
+  List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
+  Create_field *new_field, *tmp_new_field;
+  KEY_PART_INFO *key_part;
+  KEY_PART_INFO *end;
+  THD *thd= table->in_use;
+  /*
+    Remember if the new definition has new VARCHAR column;
+    create_info->varchar will be reset in mysql_prepare_create_table.
+  */
+  bool varchar= create_info->varchar;
+  bool not_nullable= true;
+  DBUG_ENTER("mysql_compare_tables");
+
+  /*
+    Create a copy of alter_info.
+    To compare the new and old table definitions, we need to "prepare"
+    the new definition - transform it from parser output to a format
+    that describes the final table layout (all column defaults are
+    initialized, duplicate columns are removed). This is done by
+    mysql_prepare_create_table.  Unfortunately,
+    mysql_prepare_create_table performs its transformations
+    "in-place", that is, modifies the argument.  Since we would
+    like to keep mysql_compare_tables() idempotent (not altering any
+    of the arguments) we create a copy of alter_info here and
+    pass it to mysql_prepare_create_table, then use the result
+    to evaluate possibility of in-place ALTER TABLE, and then
+    destroy the copy.
+  */
+  Alter_info tmp_alter_info(*alter_info, thd->mem_root);
+  uint db_options= 0; /* not used */
+
+  /* Create the prepared information. */
+  if (mysql_prepare_create_table(thd, create_info,
+                                 &tmp_alter_info,
+                                 (table->s->tmp_table != NO_TMP_TABLE),
+                                 &db_options,
+                                 table->file, key_info_buffer,
+                                 &key_count, 0))
+    DBUG_RETURN(1);
+  /* Allocate result buffers. */
+  if (! (*index_drop_buffer=
+         (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
+      ! (*index_add_buffer=
+         (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
+    DBUG_RETURN(1);
+  
+  /*
+    Some very basic checks. If number of fields changes, or the
+    handler, we need to run full ALTER TABLE. In the future
+    new fields can be added and old dropped without copy, but
+    not yet.
+
+    Test also that engine was not given during ALTER TABLE, or
+    we are force to run regular alter table (copy).
+    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
+
+    For the following ones we also want to run regular alter table:
+    ALTER TABLE tbl_name ORDER BY ..
+    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
+
+    At the moment we can't handle altering temporary tables without a copy.
+    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
+    In that case we always do full copy.
+
+    There was a bug prior to mysql-4.0.25. Number of null fields was
+    calculated incorrectly. As a result frm and data files gets out of
+    sync after in-place alter table. There is no way to determine by which
+    mysql version (in 4.0 and 4.1 branches) table was created, thus we
+    disable in-place alter table for all tables created by mysql versions
+    prior to 5.0 branch.
+    See BUG#6236.
+  */
+  if (table->s->fields != alter_info->create_list.elements ||
+      table->s->db_type() != create_info->db_type ||
+      table->s->tmp_table ||
+      create_info->used_fields & HA_CREATE_USED_ENGINE ||
+      create_info->used_fields & HA_CREATE_USED_CHARSET ||
+      create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
+      (table->s->row_type != create_info->row_type) ||
+      create_info->used_fields & HA_CREATE_USED_PACK_KEYS ||
+      create_info->used_fields & HA_CREATE_USED_MAX_ROWS ||
+      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
+      order_num ||
+      !table->s->mysql_version ||
+      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
+  {
+    *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+    DBUG_RETURN(0);
+  }
+
+  /*
+    Use transformed info to evaluate possibility of in-place ALTER TABLE
+    but use the preserved field to persist modifications.
+  */
+  new_field_it.init(alter_info->create_list);
+  tmp_new_field_it.init(tmp_alter_info.create_list);
+
+  /*
+    Go through fields and check if the original ones are compatible
+    with new table.
+  */
+  for (f_ptr= table->field, new_field= new_field_it++,
+       tmp_new_field= tmp_new_field_it++;
+       (field= *f_ptr);
+       f_ptr++, new_field= new_field_it++,
+       tmp_new_field= tmp_new_field_it++)
+  {
+    /* Make sure we have at least the default charset in use. */
+    if (!new_field->charset)
+      new_field->charset= create_info->default_table_charset;
+
+    /* Check that NULL behavior is same for old and new fields */
+    if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
+	(uint) (field->flags & NOT_NULL_FLAG))
+    {
+      *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+      DBUG_RETURN(0);
+    }
+
+    /* Don't pack rows in old tables if the user has requested this. */
+    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
+	(tmp_new_field->flags & BLOB_FLAG) ||
+	(tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
+	create_info->row_type != ROW_TYPE_FIXED))
+      create_info->table_options|= HA_OPTION_PACK_RECORD;
+
+    /* Check if field was renamed */
+    field->flags&= ~FIELD_IS_RENAMED;
+    if (my_strcasecmp(system_charset_info,
+		      field->field_name,
+		      tmp_new_field->field_name))
+      field->flags|= FIELD_IS_RENAMED;      
+
+    /* Evaluate changes bitmap and send to check_if_incompatible_data() */
+    if (!(tmp= field->is_equal(tmp_new_field)))
+    {
+      *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+      DBUG_RETURN(0);
+    }
+    // Clear indexed marker
+    field->flags&= ~FIELD_IN_ADD_INDEX;
+    changes|= tmp;
+  }
+
+  /*
+    Go through keys and check if the original ones are compatible
+    with new table.
+  */
+  KEY *table_key;
+  KEY *table_key_end= table->key_info + table->s->keys;
+  KEY *new_key;
+  KEY *new_key_end= *key_info_buffer + key_count;
+
+  DBUG_PRINT("info", ("index count old: %d  new: %d",
+                      table->s->keys, key_count));
+  /*
+    Step through all keys of the old table and search matching new keys.
+  */
+  *index_drop_count= 0;
+  *index_add_count= 0;
+  *candidate_key_count= 0;
+  for (table_key= table->key_info; table_key < table_key_end; table_key++)
+  {
+    KEY_PART_INFO *table_part;
+    KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
+    KEY_PART_INFO *new_part;
+
+   /*
+      Check if key is a candidate key, i.e. a unique index with no index
+      fields nullable, then key is either already primary key or could
+      be promoted to primary key if the original primary key is dropped.
+      Count all candidate keys.
+    */
+    not_nullable= true;
+    for (table_part= table_key->key_part;
+         table_part < table_part_end;
+         table_part++)
+    {
+      not_nullable= not_nullable && (! table_part->field->maybe_null());
+    }
+    if ((table_key->flags & HA_NOSAME) && not_nullable)
+      (*candidate_key_count)++;
+
+    /* Search a new key with the same name. */
+    for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+    {
+      if (! strcmp(table_key->name, new_key->name))
+        break;
+    }
+    if (new_key >= new_key_end)
+    {
+      /* Key not found. Add the offset of the key to the drop buffer. */
+      (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+      DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
+      continue;
+    }
+
+    /* Check that the key types are compatible between old and new tables. */
+    if ((table_key->algorithm != new_key->algorithm) ||
+	((table_key->flags & HA_KEYFLAG_MASK) !=
+         (new_key->flags & HA_KEYFLAG_MASK)) ||
+        (table_key->key_parts != new_key->key_parts))
+      goto index_changed;
+
+    /*
+      Check that the key parts remain compatible between the old and
+      new tables.
+    */
+    for (table_part= table_key->key_part, new_part= new_key->key_part;
+         table_part < table_part_end;
+         table_part++, new_part++)
+    {
+      /*
+	Key definition has changed if we are using a different field or
+	if the used key part length is different. We know that the fields
+        did not change. Comparing field numbers is sufficient.
+      */
+      if ((table_part->length != new_part->length) ||
+          (table_part->fieldnr - 1 != new_part->fieldnr))
+	goto index_changed;
+    }
+    continue;
+
+  index_changed:
+    /* Key modified. Add the offset of the key to both buffers. */
+    (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+    (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
+    key_part= new_key->key_part;
+    end= key_part + new_key->key_parts;
+    for(; key_part != end; key_part++)
+    {
+      // Mark field to be part of new key 
+      field= table->field[key_part->fieldnr];
+      field->flags|= FIELD_IN_ADD_INDEX;
+    }
+    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
+  }
+  /*end of for (; table_key < table_key_end;) */
+
+  /*
+    Step through all keys of the new table and find matching old keys.
+  */
+  for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+  {
+    /* Search an old key with the same name. */
+    for (table_key= table->key_info; table_key < table_key_end; table_key++)
+    {
+      if (! strcmp(table_key->name, new_key->name))
+        break;
+    }
+    if (table_key >= table_key_end)
+    {
+      /* Key not found. Add the offset of the key to the add buffer. */
+      (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
+      key_part= new_key->key_part;
+      end= key_part + new_key->key_parts;
+      for(; key_part != end; key_part++)
+      {
+        // Mark field to be part of new key 
+        field= table->field[key_part->fieldnr];
+        field->flags|= FIELD_IN_ADD_INDEX;
+      }
+      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
+    }
+  }
+
+  /* Check if changes are compatible with current handler without a copy */
+  if (table->file->check_if_incompatible_data(create_info, changes))
+  {
+    *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+    DBUG_RETURN(0);
+  }
+
+  if (*index_drop_count || *index_add_count)
+  {
+    *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
+    DBUG_RETURN(0);
+  }
+
+  *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
+  DBUG_RETURN(0);
+}
+#endif
+
+/*
+  Manages enabling/disabling of indexes for ALTER TABLE
+
+  SYNOPSIS
+    alter_table_manage_keys()
+      table                  Target table
+      indexes_were_disabled  Whether the indexes of the from table
+                             were disabled
+      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
+
+  RETURN VALUES
+    FALSE  OK
+    TRUE   Error
+*/
+
+static
+bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
+                             enum enum_enable_or_disable keys_onoff)
+{
+  int error= 0;
+  DBUG_ENTER("alter_table_manage_keys");
+  DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
+             table, indexes_were_disabled, keys_onoff));
+
+  switch (keys_onoff) {
+  case ENABLE:
+    error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+    break;
+  case LEAVE_AS_IS:
+    if (!indexes_were_disabled)
+      break;
+    /* fall-through: disabled indexes */
+  case DISABLE:
+    error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+  }
+
+  if (error == HA_ERR_WRONG_COMMAND)
+  {
+    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
+                        table->s->table_name.str);
+    error= 0;
+  } else if (error)
+    table->file->print_error(error, MYF(0));
+
+  DBUG_RETURN(error);
+}
+
+#ifndef MCP_WL3749
+int create_temporary_table(THD *thd,
+                           TABLE *table,
+                           char *new_db,
+                           char *tmp_name,
+                           HA_CREATE_INFO *create_info,
+                           Alter_info *alter_info,
+                           bool db_changed)
+{
+  int error;
+  char index_file[FN_REFLEN], data_file[FN_REFLEN];
+  handlerton *old_db_type, *new_db_type;
+  DBUG_ENTER("create_temporary_table");
+  old_db_type= table->s->db_type();
+  new_db_type= create_info->db_type;
+  /*
+    Handling of symlinked tables:
+    If no rename:
+      Create new data file and index file on the same disk as the
+      old data and index files.
+      Copy data.
+      Rename new data file over old data file and new index file over
+      old index file.
+      Symlinks are not changed.
+
+   If rename:
+      Create new data file and index file on the same disk as the
+      old data and index files.  Create also symlinks to point at
+      the new tables.
+      Copy data.
+      At end, rename intermediate tables, and symlinks to intermediate
+      table, to final table name.
+      Remove old table and old symlinks
+
+    If rename is made to another database:
+      Create new tables in new database.
+      Copy data.
+      Remove old table and symlinks.
+  */
+  if (db_changed)               // Ignore symlink if db changed
+  {
+    if (create_info->index_file_name)
+    {
+      /* Fix index_file_name to have 'tmp_name' as basename */
+      strmov(index_file, tmp_name);
+      create_info->index_file_name=fn_same(index_file,
+                                           create_info->index_file_name,
+                                           1);
+    }
+    if (create_info->data_file_name)
+    {
+      /* Fix data_file_name to have 'tmp_name' as basename */
+      strmov(data_file, tmp_name);
+      create_info->data_file_name=fn_same(data_file,
+                                          create_info->data_file_name,
+                                          1);
+    }
+  }
+  else
+    create_info->data_file_name=create_info->index_file_name=0;
+
+  DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
+  /*
+    Create a table with a temporary name.
+    With create_info->frm_only == 1 this creates a .frm file only.
+    We don't log the statement, it will be logged later.
+  */
+  tmp_disable_binlog(thd);
+  error= mysql_create_table_no_lock(thd, new_db, tmp_name,
+                                    create_info,
+                                    alter_info,
+                                    1, 0, NULL);
+  reenable_binlog(thd);
+
+  DBUG_RETURN(error);
+}
+
+/*
+  Create a temporary table that reflects what an alter table operation
+  will accomplish.
+
+  SYNOPSIS
+    create_altered_table()
+      thd              Thread handle
+      table            The original table
+      create_info      Information from the parsing phase about new
+                       table properties.
+      alter_info       Lists of fields, keys to be changed, added
+                       or dropped.
+      db_change        Specifies if the table is moved to another database
+  RETURN
+    A temporary table with all changes
+    NULL if error
+  NOTES
+    The temporary table is created without storing it in any storage engine
+    and is opened only to get the table struct and frm file reference.
+*/
+TABLE *create_altered_table(THD *thd,
+                            TABLE *table,
+                            char *new_db,
+                            HA_CREATE_INFO *create_info,
+                            Alter_info *alter_info,
+                            bool db_change)
+{
+  int error;
+  HA_CREATE_INFO altered_create_info(*create_info);
+  TABLE *altered_table;
+  char tmp_name[80];
+  char path[FN_REFLEN];
+  DBUG_ENTER("create_altered_table");
+
+  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx_%x",
+              tmp_file_prefix, current_pid,
+              thd->thread_id, thd->tmp_table++);
+  /* Safety fix for InnoDB */
+  if (lower_case_table_names)
+    my_casedn_str(files_charset_info, tmp_name);
+  
+  altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
+  altered_create_info.frm_only= 1;
+  if ((error= create_temporary_table(thd, table, new_db, tmp_name,
+                                     &altered_create_info,
+                                     alter_info, db_change)))
+  {
+    DBUG_PRINT("info", ("Error %u while creating temporary table", error));
+    DBUG_RETURN(NULL);
+  };
+
+  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
+                       FN_IS_TMP);
+  altered_table= open_table_uncached(thd, path, new_db, tmp_name, TRUE,
+                                     OTM_ALTER);
+  DBUG_RETURN(altered_table);
+
+  DBUG_RETURN(NULL);
+}
+
+/*
+  Perform a fast or on-line alter table
+
+  SYNOPSIS
+    mysql_fast_or_online_alter_table()
+      thd              Thread handle
+      table            The original table
+      altered_table    A temporary table showing how we will change table
+      create_info      Information from the parsing phase about new
+                       table properties.
+      alter_info       Storage place for data used during different phases
+      ha_alter_flags   Bitmask that shows what will be changed
+      keys_onoff       Specifies if keys are to be enabled/disabled
+  RETURN
+     0  OK
+    >0  An error occured during the on-line alter table operation
+    -1  Error when re-opening table
+  NOTES
+    If mysql_alter_table does not need to copy the table, it is
+    either a fast alter table where the storage engine does not
+    need to know about the change, only the frm will change,
+    or the storage engine supports performing the alter table
+    operation directly, on-line without mysql having to copy
+    the table.
+*/
+int mysql_fast_or_online_alter_table(THD *thd,
+                                     TABLE *table,
+                                     TABLE *altered_table,
+                                     HA_CREATE_INFO *create_info,
+                                     HA_ALTER_INFO *alter_info,
+                                     HA_ALTER_FLAGS *ha_alter_flags,
+                                     enum enum_enable_or_disable keys_onoff,
+                                     MDL_request *target_mdl_request)
+{
+  int error= 0;
+  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER ||
+                table->file->alter_table_flags(0))? true:false;
+  char table_name[FN_REFLEN + 1];
+  char db[FN_REFLEN + 1];
+  char new_name[FN_REFLEN + 1];
+  char new_db[FN_REFLEN + 1];
+  TABLE *t_table;
+  Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
+  TABLE tab;
+  TABLE_LIST tbl;
+  handlerton *db_type= table->s->db_type();
+
+  DBUG_ENTER(" mysql_fast_or_online_alter_table");
+  //VOID(pthread_mutex_lock(&LOCK_open));
+  if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+  {
+    error= my_errno;
+    goto err;
+  }
+  //VOID(pthread_mutex_unlock(&LOCK_open));
+  thd_proc_info(thd, "manage keys");
+  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
+                          keys_onoff);
+  error= trans_commit_stmt(thd);
+  if (trans_commit_implicit(thd))
+    error= 1;
+/*
+  error= ha_autocommit_or_rollback(thd, 0);
 
-    /*
-      Check that the key parts remain compatible between the old and
-      new tables.
+  if (end_active_trans(thd))
+    error=1;
+*/
+  if (error)
+    goto err;
+  if (online)
+  {
+   /*
+      Tell the handler to prepare for the online alter
     */
-    for (table_part= table_key->key_part, new_part= new_key->key_part;
-         table_part < table_part_end;
-         table_part++, new_part++)
+    table->file->ha_prepare_for_alter();
+    if ((error= table->file->alter_table_phase1(thd,
+                                                altered_table,
+                                                create_info,
+                                                alter_info,
+                                                ha_alter_flags)))
     {
-      /*
-	Key definition has changed if we are using a different field or
-	if the used key part length is different. We know that the fields
-        did not change. Comparing field numbers is sufficient.
-      */
-      if ((table_part->length != new_part->length) ||
-          (table_part->fieldnr - 1 != new_part->fieldnr))
-	goto index_changed;
+      goto err;
     }
-    continue;
 
-  index_changed:
-    /* Key modified. Add the offset of the key to both buffers. */
-    (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
-    (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
-    key_part= new_key->key_part;
-    end= key_part + new_key->key_parts;
-    for(; key_part != end; key_part++)
+    /*
+       Tell the storage engine to perform the online alter table
+       TODO:
+       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
+       we need to wrap the next call with a DDL lock.
+     */
+    if ((error= table->file->alter_table_phase2(thd,
+                                                altered_table,
+                                                create_info,
+                                                alter_info,
+                                                ha_alter_flags)))
     {
-      // Mark field to be part of new key 
-      field= table->field[key_part->fieldnr];
-      field->flags|= FIELD_IN_ADD_INDEX;
+      goto err;
     }
-    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
   }
-  /*end of for (; table_key < table_key_end;) */
-
   /*
-    Step through all keys of the new table and find matching old keys.
+    The final .frm file is already created as a temporary file
+    and will be renamed to the original table name.
   */
-  for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
-  {
-    /* Search an old key with the same name. */
-    for (table_key= table->key_info; table_key < table_key_end; table_key++)
-    {
-      if (! strcmp(table_key->name, new_key->name))
-        break;
-    }
-    if (table_key >= table_key_end)
-    {
-      /* Key not found. Add the offset of the key to the add buffer. */
-      (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
-      key_part= new_key->key_part;
-      end= key_part + new_key->key_parts;
-      for(; key_part != end; key_part++)
-      {
-        // Mark field to be part of new key 
-        field= table->field[key_part->fieldnr];
-        field->flags|= FIELD_IN_ADD_INDEX;
-      }
-      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
-    }
-  }
-
-  /* Check if changes are compatible with current handler without a copy */
-  if (table->file->check_if_incompatible_data(create_info, changes))
+  //VOID(pthread_mutex_lock(&LOCK_open));
+  if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
   {
-    *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-    DBUG_RETURN(0);
+    error= my_errno;
+    goto err;
   }
 
-  if (*index_drop_count || *index_add_count)
+  strcpy(table_name, altered_table->s->table_name.str);
+  strcpy(db, altered_table->s->db.str);
+  strcpy(new_name, table->s->table_name.str);
+  strcpy(new_db, table->s->db.str);
+  close_all_tables_for_name(thd, table->s, FALSE);
+                            // new_name != table_name || new_db != db);
+/*
+  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
+  close_data_files_and_morph_locks(thd,
+                                   table->pos_in_table_list->db,
+                                   table->pos_in_table_list->table_name);
+*/
+  if (mysql_rename_table(db_type,
+                         altered_table->s->db.str,
+                         altered_table->s->table_name.str,
+                         new_db,
+                         new_name, FN_FROM_IS_TMP | FRM_ONLY))
   {
-    *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
-    DBUG_RETURN(0);
+    error= 1;
+    //VOID(pthread_mutex_unlock(&LOCK_open));
+    goto err;
   }
+  //broadcast_refresh();
+  //VOID(pthread_mutex_unlock(&LOCK_open));
 
-  *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
-  DBUG_RETURN(0);
-}
-
-
+  /*
+    The ALTER TABLE is always in its own transaction.
+    Commit must not be called while LOCK_open is locked. It could call
+    wait_if_global_read_lock(), which could create a deadlock if called
+    with LOCK_open.
+  */
+  error= trans_commit_stmt(thd);
+  if (trans_commit_implicit(thd))
+    error= 1;
 /*
-  Manages enabling/disabling of indexes for ALTER TABLE
+  error= ha_autocommit_or_rollback(thd, 0);
 
-  SYNOPSIS
-    alter_table_manage_keys()
-      table                  Target table
-      indexes_were_disabled  Whether the indexes of the from table
-                             were disabled
-      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
-
-  RETURN VALUES
-    FALSE  OK
-    TRUE   Error
+  if (end_active_trans(thd))
+    error=1;
 */
+  if (error)
+    goto err;
+  if (online)
+  {
+    tbl.table= &tab;
+    tbl.alias= new_name;
+    tbl.table_name= new_name;
+    tbl.table_name_length= strlen(new_name);
+    tbl.db= new_db;
+    tbl.db_length= strlen(new_db);
+    tbl.open_type= OT_TEMPORARY_OR_BASE;
+    tbl.i_s_requested_object= OPEN_TABLE_ONLY;
+    tbl.open_strategy= TABLE_LIST::OPEN_NORMAL;
+    tbl.mdl_request.ticket= target_mdl_request->ticket;
+    if (open_table(thd, &tbl, thd->mem_root, &ot_ctx))
+    {
+      error= -1;
+      goto err;
+    }
+    t_table= tbl.table;
 
-static
-bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
-                             enum enum_enable_or_disable keys_onoff)
-{
-  int error= 0;
-  DBUG_ENTER("alter_table_manage_keys");
-  DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
-             table, indexes_were_disabled, keys_onoff));
+   /*
+      Tell the handler that the changed frm is on disk and table
+      has been re-opened
+   */
+    if ((error= t_table->file->alter_table_phase3(thd, t_table,
+                                                  create_info,
+                                                  alter_info,
+                                                  ha_alter_flags)))
+    {
+      goto err;
+    }
 
-  switch (keys_onoff) {
-  case ENABLE:
-    error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
-    break;
-  case LEAVE_AS_IS:
-    if (!indexes_were_disabled)
-      break;
-    /* fall-through: disabled indexes */
-  case DISABLE:
-    error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+    /*
+      We are going to reopen table down on the road, so we have to restore
+      state of the TABLE object which we used for obtaining of handler
+      object to make it suitable for reopening.
+    */
+    //DBUG_ASSERT(t_table == table);
+    //table->open_placeholder= 1;
+    //VOID(pthread_mutex_lock(&LOCK_open));
+    //close_handle_and_leave_table_as_lock(table);
+    //VOID(pthread_mutex_unlock(&LOCK_open));
   }
 
-  if (error == HA_ERR_WRONG_COMMAND)
-  {
-    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
-                        table->s->table_name.str);
-    error= 0;
-  } else if (error)
-    table->file->print_error(error, MYF(0));
-
+ err:
+  if (error)
+    DBUG_PRINT("info", ("Got error %u", error));
   DBUG_RETURN(error);
 }
+#endif
 
 /**
   maximum possible length for certain blob types.
@@ -5690,14 +6613,26 @@ bool mysql_alter_table(THD *thd,char *ne
   char index_file[FN_REFLEN], data_file[FN_REFLEN];
   char path[FN_REFLEN + 1];
   char reg_path[FN_REFLEN+1];
+#ifndef MCP_WL3749
+  ha_rows copied=0,deleted=0;
+#else
   ha_rows copied,deleted;
+#endif
   handlerton *old_db_type, *new_db_type, *save_old_db_type;
+#ifndef MCP_WL3749
+  bool need_copy_table= TRUE;
+#else
   enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
+#endif
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   TABLE *table_for_fast_alter_partition= NULL;
+#ifndef MCP_WL3749
+  bool is_fast_alter_partitioning= FALSE;
+#endif
   bool partition_changed= FALSE;
 #endif
   bool need_lock_for_indexes= TRUE;
+#ifdef MCP_WL3749
   KEY  *key_info_buffer;
   uint index_drop_count= 0;
   uint *index_drop_buffer= NULL;
@@ -5705,8 +6640,12 @@ bool mysql_alter_table(THD *thd,char *ne
   uint *index_add_buffer= NULL;
   uint candidate_key_count= 0;
   bool no_pk;
+#endif
   DBUG_ENTER("mysql_alter_table");
 
+  DBUG_PRINT("info", ("alter_info->build_method %u", alter_info->build_method));
+  DBUG_PRINT("info", ("thd->lex->alter_info.build_method %u", thd->lex->alter_info.build_method));
+
   /*
     Check if we attempt to alter mysql.slow_log or
     mysql.general_log table and return an error if
@@ -6088,7 +7027,12 @@ bool mysql_alter_table(THD *thd,char *ne
   if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
                             &partition_changed,
                             db, table_name, path,
+#ifndef MCP_WL3749
+                            &table_for_fast_alter_partition,
+                            &is_fast_alter_partitioning))
+#else
                             &table_for_fast_alter_partition))
+#endif
     goto err;
 #endif
   /*
@@ -6103,16 +7047,16 @@ bool mysql_alter_table(THD *thd,char *ne
     temporary table to the result table files.
   */
   new_db_type= create_info->db_type;
-
+#ifdef MCP_WL3749
   if (is_index_maintenance_unique (table, alter_info))
     need_copy_table= ALTER_TABLE_DATA_CHANGED;
-
+#endif
   if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
     goto err;
-  
+#ifdef MCP_WL3749
   if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-    need_copy_table= alter_info->change_level;
-
+    need_copy_table= alter_info->change_levels;
+#endif
   set_table_default_charset(thd, create_info, db);
 
   if (thd->variables.old_alter_table
@@ -6121,6 +7065,7 @@ bool mysql_alter_table(THD *thd,char *ne
       || partition_changed
 #endif
      )
+#ifdef MCP_WL3749
     need_copy_table= ALTER_TABLE_DATA_CHANGED;
   else
   {
@@ -6323,9 +7268,14 @@ bool mysql_alter_table(THD *thd,char *ne
   */
   if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
     create_info->frm_only= 1;
+#endif /* ifdef MCP_WL3749 */
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
+#ifndef MCP_WL3749
+  if (is_fast_alter_partitioning)
+#else
   if (table_for_fast_alter_partition)
+#endif
   {
     DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
                                            create_info, table_list,
@@ -6334,6 +7284,199 @@ bool mysql_alter_table(THD *thd,char *ne
   }
 #endif
 
+#ifndef MCP_WL3749
+  if (thd->variables.old_alter_table
+      || (table->s->db_type() != create_info->db_type)
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+      || (partition_changed && !(create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
+#endif
+     )
+  {
+    if (alter_info->build_method == HA_BUILD_ONLINE)
+    {
+      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
+      goto err;
+    }
+    alter_info->build_method= HA_BUILD_OFFLINE;
+  }
+
+  if (alter_info->build_method != HA_BUILD_OFFLINE)
+  {
+    TABLE *altered_table= 0;
+    HA_ALTER_INFO ha_alter_info;
+    HA_ALTER_FLAGS ha_alter_flags;
+    uint table_changes= IS_EQUAL_YES;
+    /* Check how much the tables differ. */
+    if (compare_tables(thd, table, alter_info,
+                       create_info, order_num,
+                       &ha_alter_flags,
+                       &ha_alter_info,
+                       &table_changes))
+    {
+      DBUG_RETURN(TRUE);
+    }
+
+    /*
+      Check if storage engine supports altering the table
+      on-line.
+    */
+
+#ifndef DBUG_OFF
+    {
+      char dbug_string[HA_MAX_ALTER_FLAGS+1];
+      ha_alter_flags.print(dbug_string);
+      DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
+                          need_copy_table, table_changes,
+                          (char *) dbug_string));
+    }
+#endif
+
+    /*
+      If table is not renamed, changed database and
+      some change was detected then check if engine
+      can do the change on-line
+    */
+    if (new_name == table_name && new_db == db &&
+        ha_alter_flags.is_set())
+    {
+      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
+
+      /*
+        If no table rename,
+        check if table can be altered on-line
+      */
+      if (!(altered_table= create_altered_table(thd,
+                                                table,
+                                                new_db,
+                                                create_info,
+                                                &tmp_alter_info,
+                                                !strcmp(db, new_db))))
+        goto err;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+      /* Copy over new partitioning information */
+      if (partition_changed && table_for_fast_alter_partition)
+        altered_table->part_info= table_for_fast_alter_partition->part_info;
+      else
+        altered_table->part_info= table->part_info;
+#endif
+      switch (table->file->check_if_supported_alter(altered_table,
+                                                    create_info,
+                                                    alter_info,
+                                                    &ha_alter_flags,
+                                                    table_changes)) {
+      case HA_ALTER_SUPPORTED_WAIT_LOCK:
+      case HA_ALTER_SUPPORTED_NO_LOCK:
+        /*
+          @todo: Currently we always acquire an exclusive name
+          lock on the table metadata when performing fast or online
+          ALTER TABLE. In future we may consider this unnecessary,
+          and narrow the scope of the exclusive name lock to only
+          cover manipulation with .frms. Storage engine API
+          call check_if_supported_alter has provision for this
+          already now.
+        */
+        need_copy_table= FALSE;
+        if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY)
+          need_lock_for_indexes= FALSE;
+        break;
+      case HA_ALTER_NOT_SUPPORTED:
+        if (alter_info->build_method == HA_BUILD_ONLINE)
+        {
+          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+          altered_table->part_info= NULL;;
+#endif
+          close_temporary_table(thd, altered_table, 1, 1);
+          goto err;
+        }
+        need_copy_table= TRUE;
+        break;
+      case HA_ALTER_ERROR:
+      default:
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+        altered_table->part_info= NULL;;
+#endif
+        close_temporary_table(thd, altered_table, 1, 1);
+        goto err;
+      }
+#ifndef DBUG_OFF
+      {
+        char dbug_string[HA_MAX_ALTER_FLAGS+1];
+        ha_alter_flags.print(dbug_string);
+        DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
+                            need_copy_table, table_changes,
+                            (char *) dbug_string));
+      }
+#endif
+
+    }
+    /* TODO need to check if changes can be handled as fast ALTER TABLE */
+    if (!altered_table)
+      need_copy_table= TRUE;
+
+    if (!need_copy_table)
+    {
+      error= mysql_fast_or_online_alter_table(thd,
+                                              table,
+                                              altered_table,
+                                              create_info,
+                                              &ha_alter_info,
+                                              &ha_alter_flags,
+                                              alter_info->keys_onoff,
+                                              &target_mdl_request);
+      if (thd->lock)
+      {
+        if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
+            thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
+        {
+          mysql_unlock_tables(thd, thd->lock);
+          thd->lock=0;
+        }
+      }
+      else
+      {
+        /*
+          If LOCK TABLES list is not empty and contains this table,
+          unlock the table and remove the table from this list.
+        */
+        mysql_lock_remove(thd, thd->lock, table);
+      }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+      altered_table->part_info= NULL;;
+#endif
+      close_temporary_table(thd, altered_table, 1, 1);
+
+      if (error)
+      {
+        switch (error) {
+        case(-1):
+          //pthread_mutex_lock(&LOCK_open);
+          goto err_with_mdl;
+        default:
+          goto err;
+        }
+      }
+      else
+      {
+        //pthread_mutex_lock(&LOCK_open);
+        goto end_online;
+      }
+    }
+
+    if (altered_table)
+    {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+      altered_table->part_info= NULL;;
+#endif
+      close_temporary_table(thd, altered_table, 1, 1);
+    }
+
+  }
+  if (need_copy_table)
+  {
+#endif /* ifndef MCP_WL3749 */
+
+  /* Open the table so we need to copy the data to it. */
   my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
 	      current_pid, thd->thread_id);
   /* Safety fix for innodb */
@@ -6405,7 +7548,11 @@ bool mysql_alter_table(THD *thd,char *ne
 
   /* Open the table if we need to copy the data. */
   DBUG_PRINT("info", ("need_copy_table: %u", need_copy_table));
+#ifndef MCP_WL3749
+  if (need_copy_table)
+#else
   if (need_copy_table != ALTER_TABLE_METADATA_ONLY)
+#endif
   {
     if (table->s->tmp_table)
     {
@@ -6435,7 +7582,6 @@ bool mysql_alter_table(THD *thd,char *ne
       copy data for MERGE tables. Only the children have data.
     */
   }
-
   /* Copy the data if necessary. */
   thd->count_cuted_fields= CHECK_FIELD_WARN;	// calc cuted fields
   thd->cuted_fields=0L;
@@ -6482,6 +7628,7 @@ bool mysql_alter_table(THD *thd,char *ne
   }
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
+#ifdef MCP_WL3749
   /* If we did not need to copy, we might still need to add/drop indexes. */
   if (! new_table)
   {
@@ -6569,7 +7716,7 @@ bool mysql_alter_table(THD *thd,char *ne
       goto err_new_table_cleanup;
   }
   /*end of if (! new_table) for add/drop index*/
-
+#endif /* ifdef MCP_WL3749 */
   if (error)
     goto err_new_table_cleanup;
 
@@ -6664,12 +7811,14 @@ bool mysql_alter_table(THD *thd,char *ne
     table is renamed and the SE is also changed, then an intermediate table
     is created and the additional call will not take place.
   */
+#ifdef MCP_WL3749
   if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
   {
     DBUG_ASSERT(new_db_type == old_db_type);
     /* This type cannot happen in regular ALTER. */
     new_db_type= old_db_type= NULL;
   }
+#endif /* MCP_WL3749 */
   if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
                          FN_TO_IS_TMP))
   {
@@ -6679,9 +7828,11 @@ bool mysql_alter_table(THD *thd,char *ne
   else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
                               new_alias, FN_FROM_IS_TMP) ||
            ((new_name != table_name || new_db != db) && // we also do rename
+#ifdef MCP_WL3749
            (need_copy_table != ALTER_TABLE_METADATA_ONLY ||
             mysql_rename_table(save_old_db_type, db, table_name, new_db,
                                new_alias, NO_FRM_RENAME)) &&
+#endif /* MCP_WL3749 */
            Table_triggers_list::change_table_name(thd, db, alias, table_name,
                                                   new_db, new_alias)))
   {
@@ -6701,7 +7852,7 @@ bool mysql_alter_table(THD *thd,char *ne
     /* This shouldn't happen. But let us play it safe. */
     goto err_with_mdl;
   }
-
+#ifdef MCP_WL3749
   if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
   {
     /*
@@ -6746,6 +7897,13 @@ bool mysql_alter_table(THD *thd,char *ne
     if (error)
       goto err_with_mdl;
   }
+#endif /* MCP_WL3749 */
+
+#ifndef MCP_WL3749
+  } /* else */
+end_online:
+#endif
+
   if (thd->locked_tables_list.reopen_tables(thd))
     goto err_with_mdl;
 

=== modified file 'sql/sql_truncate.cc'
--- a/sql/sql_truncate.cc	2011-05-10 09:48:14 +0000
+++ b/sql/sql_truncate.cc	2011-05-30 21:13:02 +0000
@@ -255,6 +255,10 @@ static bool recreate_temporary_table(THD
   TABLE_SHARE *share= table->s;
   HA_CREATE_INFO create_info;
   handlerton *table_type= table->s->db_type();
+#ifndef MCP_WL3749
+  bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
+#endif
+
   DBUG_ENTER("recreate_temporary_table");
 
   memset(&create_info, 0, sizeof(create_info));
@@ -279,7 +283,11 @@ static bool recreate_temporary_table(THD
     thd->thread_specific_used= TRUE;
   }
   else
+#ifndef MCP_WL3749
+    rm_temporary_table(table_type, share->path.str, frm_only);
+#else
     rm_temporary_table(table_type, share->path.str);
+#endif
 
   free_table_share(share);
   my_free(table);

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-05-10 09:48:14 +0000
+++ b/sql/sql_yacc.yy	2011-05-30 21:13:02 +0000
@@ -695,7 +695,11 @@ bool setup_select_in_parentheses(LEX *le
   return FALSE;
 }
 
+#ifndef MCP_WL3749
+static bool add_create_index_prepare (LEX *lex, Table_ident *table, enum ha_build_method method)
+#else
 static bool add_create_index_prepare (LEX *lex, Table_ident *table)
+#endif
 {
   lex->sql_command= SQLCOM_CREATE_INDEX;
   if (!lex->current_select->add_table_to_list(lex->thd, table, NULL,
@@ -705,6 +709,9 @@ static bool add_create_index_prepare (LE
     return TRUE;
   lex->alter_info.reset();
   lex->alter_info.flags= ALTER_ADD_INDEX;
+#ifndef MCP_WL3749
+  lex->alter_info.build_method= method;
+#endif
   lex->col_list.empty();
   lex->change= NullS;
   return FALSE;
@@ -768,6 +775,9 @@ static bool add_create_index (LEX *lex, 
   sp_head *sphead;
   struct p_elem_val *p_elem_value;
   enum index_hint_type index_hint;
+#ifndef MCP_WL3749
+  enum ha_build_method build_method;
+#endif
   enum enum_filetype filetype;
   enum Foreign_key::fk_option m_fk_option;
   enum enum_yes_no_unknown m_yes_no_unk;
@@ -1146,11 +1156,17 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  NUM
 %token  NUMERIC_SYM                   /* SQL-2003-R */
 %token  NVARCHAR_SYM
+/* #ifndef MCP_WL3749  */
+%token  OFFLINE_SYM
+/* #endif */
 %token  OFFSET_SYM
 %token  OLD_PASSWORD
 %token  ON                            /* SQL-2003-R */
 %token  ONE_SHOT_SYM
 %token  ONE_SYM
+/* #ifndef MCP_WL3749  */
+%token  ONLINE_SYM
+/* #endif */
 %token  OPEN_SYM                      /* SQL-2003-R */
 %token  OPTIMIZE
 %token  OPTIONS_SYM
@@ -1548,6 +1564,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %type <boolfunc2creator> comp_op
 
+/* #ifndef MCP_WL3749 */
+%type <build_method> build_method
+/* #endif */
+
 %type <NONE>
         query verb_clause create change select do drop insert replace insert2
         insert_values update delete truncate rename
@@ -2068,36 +2088,80 @@ create:
             }
             create_table_set_open_action_and_adjust_tables(lex);
           }
+/* #ifndef MCP_WL3749 */
+        | CREATE build_method opt_unique INDEX_SYM ident key_alg ON table_ident
+/* #else
         | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident
+   #endif
+*/
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index_prepare(Lex, $8, $2))
+/* #else
             if (add_create_index_prepare(Lex, $7))
+   #endif
+*/
               MYSQL_YYABORT;
           }
           '(' key_list ')' normal_key_options
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index(Lex, $3, $5))
+/* #else
             if (add_create_index(Lex, $2, $4))
-              MYSQL_YYABORT;
+   #endif
+*/              MYSQL_YYABORT;
           }
+/* #ifndef MCP_WL3749 */
+        | CREATE build_method fulltext INDEX_SYM ident init_key_options ON
+/* #else
         | CREATE fulltext INDEX_SYM ident init_key_options ON
+   #endif
+*/
           table_ident
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index_prepare(Lex, $8, $2))
+/* #else
             if (add_create_index_prepare(Lex, $7))
+   #endif
+*/
               MYSQL_YYABORT;
           }
           '(' key_list ')' fulltext_key_options
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index(Lex, $3, $5))
+/* #else
             if (add_create_index(Lex, $2, $4))
+   #endif
+*/
               MYSQL_YYABORT;
           }
+/* #ifndef MCP_WL3749 */
+        | CREATE build_method spatial INDEX_SYM ident init_key_options ON
+/* #else
         | CREATE spatial INDEX_SYM ident init_key_options ON
+   #endif
+*/
           table_ident
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index_prepare(Lex, $8, $2))
+/* #else
             if (add_create_index_prepare(Lex, $7))
+   #endif
+*/
               MYSQL_YYABORT;
           }
           '(' key_list ')' spatial_key_options
           {
+/* #ifndef MCP_WL3749 */
+            if (add_create_index(Lex, $3, $5))
+/* #else
             if (add_create_index(Lex, $2, $4))
+   #endif
+*/
               MYSQL_YYABORT;
           }
         | CREATE DATABASE opt_if_not_exists ident
@@ -5115,6 +5179,9 @@ create_table_option:
           {
             Lex->create_info.row_type= $3;
             Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
+#ifndef MCP_WL3749
+            Lex->alter_info.flags|= ALTER_ROW_FORMAT;
+#endif
           }
         | UNION_SYM opt_equal
           {
@@ -5672,7 +5739,13 @@ opt_attribute_list:
 attribute:
           NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
         | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
-        | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
+        | DEFAULT now_or_signed_literal
+          {       
+            Lex->default_value=$2;
+/* #ifndef MCP_WL3749 */
+            Lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #endif */
+          }
         | ON UPDATE_SYM NOW_SYM optional_braces
           {
             Item *item= new (YYTHD->mem_root) Item_func_now_local();
@@ -6192,7 +6265,12 @@ string_list:
 */
 
 alter:
+/* #ifndef MCP_WL3749 */
+          ALTER build_method opt_ignore TABLE_SYM table_ident
+/* #else
           ALTER opt_ignore TABLE_SYM table_ident
+   #endif
+*/
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
@@ -6200,7 +6278,12 @@ alter:
             lex->name.length= 0;
             lex->sql_command= SQLCOM_ALTER_TABLE;
             lex->duplicates= DUP_ERROR; 
+/* #ifndef MCP_WL3749 */
+            if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
+/* #else
             if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
+   #endif
+*/
                                                    TL_OPTION_UPDATING,
                                                    TL_READ_NO_INSERT,
                                                    MDL_SHARED_NO_WRITE))
@@ -6215,6 +6298,9 @@ alter:
             lex->alter_info.reset();
             lex->no_write_to_binlog= 0;
             lex->create_info.storage_media= HA_SM_DEFAULT;
+/* #ifndef MCP_WL3749 */
+            lex->alter_info.build_method= $2;
+/* #endif */
             lex->create_last_non_select_table= lex->last_table();
             DBUG_ASSERT(!lex->m_stmt);
           }
@@ -6519,6 +6605,23 @@ alter_commands:
         | reorg_partition_rule
         ;
 
+/* #ifndef MCP_WL3749 */
+build_method:
+        /* empty */
+          {
+            $$= HA_BUILD_DEFAULT;
+          }
+        | ONLINE_SYM
+          {
+            $$= HA_BUILD_ONLINE;
+          }
+        | OFFLINE_SYM
+          {
+            $$= HA_BUILD_OFFLINE;
+          }
+        ;
+/* #else */
+
 remove_partitioning:
           REMOVE_SYM PARTITIONING_SYM
           {
@@ -6728,7 +6831,12 @@ alter_list_item:
             if (ac == NULL)
               MYSQL_YYABORT;
             lex->alter_info.alter_list.push_back(ac);
+/* #ifndef MCP_WL3749 */
+            lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #else
             lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
+   #endif
+*/
           }
         | ALTER opt_column field_ident DROP DEFAULT
           {
@@ -6737,7 +6845,12 @@ alter_list_item:
             if (ac == NULL)
               MYSQL_YYABORT;
             lex->alter_info.alter_list.push_back(ac);
+/* #ifndef MCP_WL3749 */
+            lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #else
             lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
+   #endif
+*/
           }
         | RENAME opt_to table_ident
           {
@@ -6813,8 +6926,22 @@ opt_restrict:
 
 opt_place:
           /* empty */ {}
+/* #ifndef MCP_WL3749 */
+        | AFTER_SYM ident
+          {
+            store_position_for_column($2.str);
+            Lex->alter_info.flags|= ALTER_COLUMN_ORDER;
+          }
+        | FIRST_SYM
+          {
+            store_position_for_column(first_keyword);
+            Lex->alter_info.flags|= ALTER_COLUMN_ORDER;
+          }
+/* #else
         | AFTER_SYM ident { store_position_for_column($2.str); }
         | FIRST_SYM  { store_position_for_column(first_keyword); }
+   #endif
+*/
         ;
 
 opt_to:
@@ -10257,17 +10384,35 @@ drop:
           }
           table_list opt_restrict
           {}
+/* #ifndef MCP_WL3749 */
+        | DROP build_method INDEX_SYM ident ON table_ident {}
+/* #else
         | DROP INDEX_SYM ident ON table_ident {}
+   #endif
+*/
           {
             LEX *lex=Lex;
+/* #ifndef MCP_WL3749 */
+            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str);
+/* #else
             Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
+   #endif
+*/
             if (ad == NULL)
               MYSQL_YYABORT;
             lex->sql_command= SQLCOM_DROP_INDEX;
             lex->alter_info.reset();
             lex->alter_info.flags= ALTER_DROP_INDEX;
+/* #ifndef MCP_WL3749 */
+            lex->alter_info.build_method= $2;
+/* #endif */
             lex->alter_info.drop_list.push_back(ad);
+/* #ifndef MCP_WL3749 */
+            if (!lex->current_select->add_table_to_list(lex->thd, $6, NULL,
+/* #else
             if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
+   #endif
+*/
                                                         TL_OPTION_UPDATING,
                                                         TL_READ_NO_INSERT,
                                                         MDL_SHARED_NO_WRITE))
@@ -12604,9 +12749,15 @@ keyword_sp:
         | NONE_SYM                 {}
         | NVARCHAR_SYM             {}
         | OFFSET_SYM               {}
+/* #ifndef MCP_WL3749 */
+        | OFFLINE_SYM              {}
+/* #endif */
         | OLD_PASSWORD             {}
         | ONE_SHOT_SYM             {}
         | ONE_SYM                  {}
+/* #ifndef MCP_WL3749 */
+        | ONLINE_SYM               {}
+/* #endif */
         | PACK_KEYS_SYM            {}
         | PAGE_SYM                 {}
         | PARTIAL                  {}

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-05-12 08:43:50 +0000
+++ b/sql/table.cc	2011-05-30 21:13:02 +0000
@@ -1824,7 +1824,11 @@ static int open_binary_frm(THD *thd, TAB
 
 int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
                           uint db_stat, uint prgflag, uint ha_open_flags,
+#ifndef MCP_WL3749
+                          TABLE *outparam, open_table_mode open_mode)
+#else
                           TABLE *outparam, bool is_create_table)
+#endif
 {
   int error;
   uint records, i, bitmap_size;
@@ -1832,8 +1836,17 @@ int open_table_from_share(THD *thd, TABL
   uchar *record, *bitmaps;
   Field **field_ptr;
   DBUG_ENTER("open_table_from_share");
+#ifndef MCP_WL3749
+  DBUG_PRINT("enter",("name: '%s.%s'  form: 0x%lx, open mode:%s",
+                      share->db.str,
+                      share->table_name.str,
+                      (long) outparam,
+                      (open_mode == OTM_OPEN)?"open":
+                      ((open_mode == OTM_CREATE)?"create":"alter")));
+#else
   DBUG_PRINT("enter",("name: '%s.%s'  form: 0x%lx", share->db.str,
                       share->table_name.str, (long) outparam));
+#endif
 
   error= 1;
   bzero((char*) outparam, sizeof(*outparam));
@@ -2005,7 +2018,11 @@ int open_table_from_share(THD *thd, TABL
 
     tmp= mysql_unpack_partition(thd, share->partition_info_str,
                                 share->partition_info_str_len,
+#ifndef MCP_WL3749
+                                outparam, (open_mode != OTM_OPEN),
+#else
                                 outparam, is_create_table,
+#endif
                                 share->default_part_db_type,
                                 &work_part_info_used);
     if (tmp)
@@ -2020,19 +2037,32 @@ int open_table_from_share(THD *thd, TABL
        caller's arena depending on work_part_info_used value
     */
     if (!work_part_info_used)
+#ifndef MCP_WL3749
+      tmp= fix_partition_func(thd, outparam, (open_mode != OTM_OPEN));
+#else
       tmp= fix_partition_func(thd, outparam, is_create_table);
+#endif
     thd->stmt_arena= backup_stmt_arena_ptr;
     thd->restore_active_arena(&part_func_arena, &backup_arena);
     if (!tmp)
     {
       if (work_part_info_used)
+#ifndef MCP_WL3749
+        tmp= fix_partition_func(thd, outparam, (open_mode != OTM_OPEN));
+#else
         tmp= fix_partition_func(thd, outparam, is_create_table);
+#endif
+      outparam->part_info->item_free_list= part_func_arena.free_list;
     }
     outparam->part_info->item_free_list= part_func_arena.free_list;
 partititon_err:
     if (tmp)
     {
+#ifndef MCP_WL3749
+      if (open_mode == OTM_CREATE)
+#else
       if (is_create_table)
+#endif
       {
         /*
           During CREATE/ALTER TABLE it is ok to receive errors here.
@@ -2061,7 +2091,11 @@ partititon_err:
 
   /* The table struct is now initialized;  Open the table */
   error= 2;
+#ifndef MCP_WL3749
+  if (db_stat && open_mode != OTM_ALTER)
+#else
   if (db_stat)
+#endif
   {
     int ha_err;
     if ((ha_err= (outparam->file->

=== modified file 'sql/table.h'
--- a/sql/table.h	2011-05-12 08:43:50 +0000
+++ b/sql/table.h	2011-05-30 21:13:02 +0000
@@ -290,7 +290,11 @@ typedef struct st_grant_info
 enum tmp_table_type
 {
   NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE,
+#ifndef MCP_WL3749
+  INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE, TMP_TABLE_FRM_FILE_ONLY
+#else
   INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE
+#endif
 };
 enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
 
@@ -2044,9 +2048,24 @@ size_t max_row_length(TABLE *table, cons
 
 void init_mdl_requests(TABLE_LIST *table_list);
 
+#ifndef MCP_WL3749
+/**
+  Opening modes for open_temporary_table and open_table_from_share
+*/
+enum open_table_mode
+{
+  OTM_OPEN= 0,
+  OTM_CREATE= 1,
+  OTM_ALTER= 2
+};
+#endif
 int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
                           uint db_stat, uint prgflag, uint ha_open_flags,
+#ifndef MCP_WL3749
+                          TABLE *outparam, open_table_mode open_mode= OTM_OPEN);
+#else
                           TABLE *outparam, bool is_create_table);
+#endif
 TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
                                uint key_length);
 void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,

=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc	2011-05-12 08:43:50 +0000
+++ b/sql/unireg.cc	2011-05-30 21:13:02 +0000
@@ -529,11 +529,20 @@ int rea_create_table(THD *thd, const cha
   DBUG_ASSERT(*fn_rext(frm_name));
   if (thd->variables.keep_files_on_create)
     create_info->options|= HA_CREATE_KEEP_FILES;
+#ifndef MCP_WL3749
+  if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG,
+                                     create_info))
+    goto err_handler;
+  if (!create_info->frm_only &&
+      ha_create_table(thd, path, db, table_name, create_info, 0))
+    goto err_handler;
+#else
   if (!create_info->frm_only &&
       (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG,
                                      create_info) ||
        ha_create_table(thd, path, db, table_name, create_info, 0)))
     goto err_handler;
+#endif
   DBUG_RETURN(0);
 
 err_handler:

=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc	2010-10-27 11:32:32 +0000
+++ b/storage/csv/ha_tina.cc	2011-04-20 12:53:27 +0000
@@ -1747,7 +1747,10 @@ int ha_tina::check(THD* thd, HA_CHECK_OP
 bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info,
 					   uint table_changes)
 {
-  return COMPATIBLE_DATA_YES;
+  if (table_changes == IS_EQUAL_NO)
+    return COMPATIBLE_DATA_NO;
+  else
+    return COMPATIBLE_DATA_YES;
 }
 
 struct st_mysql_storage_engine csv_storage_engine=

No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
Thread
bzr commit into mysql-5.5-cluster branch (Martin.Skold:3349) Martin Skold31 May