List:Commits« Previous MessageNext Message »
From:Martin Skold Date:April 20 2011 12:53pm
Subject:bzr commit into mysql-5.5-telco-7.0 branch (Martin.Skold:3227) WL#3749
View as plain text  
#At file:///home/marty/MySQL/mysql-5.5-telco-7.0/ based on revid:magnus.blaudd@stripped

 3227 Martin Skold	2011-04-20
      WL#3749 MySQL Cluster: On-line DDL, new handler interface: Major changes to merge with mysql-5.5

    modified:
      include/my_base.h
      mysql-test/include/ndb_have_online_alter.inc
      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_gis.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
      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_show.cc
      sql/sql_table.cc
      sql/sql_truncate.cc
      sql/sql_yacc.yy
      sql/table.cc
      sql/table.h
      storage/csv/ha_tina.cc
=== modified file 'include/my_base.h'
--- a/include/my_base.h	2010-11-09 14:08:03 +0000
+++ b/include/my_base.h	2011-04-20 12:53:27 +0000
@@ -98,6 +98,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/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-01-21 10:29:46 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2011-04-20 12:53:27 +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_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_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-03-04 14:13:43 +0000
+++ b/mysql-test/suite/ndb/t/disabled.def	2011-04-20 12:53:27 +0000
@@ -32,7 +32,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-02-02 10:33:25 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online2.test	2011-04-20 12:53:27 +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 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-03-04 13:14:07 +0000
+++ b/sql/ha_ndbcluster.cc	2011-04-20 12:53:27 +0000
@@ -13738,6 +13738,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)
 {
@@ -13775,7 +13776,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);
@@ -13860,7 +13861,7 @@ int ha_ndbcluster::check_if_supported_al
      }
      else if (alter_flags->is_set(HA_ADD_PARTITION))
      {
-       new_tab.setFragmentCount(part_info->no_parts);
+       new_tab.setFragmentCount(part_info->num_parts);
      }
 
      NDB_Modifiers table_modifiers(ndb_table_modifiers);
@@ -14190,7 +14191,7 @@ 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);
+      new_tab->setFragmentCount(part_info->num_parts);
     }
 
     int res= dict->prepareHashMap(*old_tab, *new_tab);

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-02-21 12:09:15 +0000
+++ b/sql/ha_ndbcluster.h	2011-04-20 12:53:27 +0000
@@ -564,6 +564,7 @@ static void set_tabname(const char *path
 #ifndef NDB_WITHOUT_ONLINE_ALTER
   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);
 

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2011-03-04 10:35:37 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-04-20 12:53:27 +0000
@@ -2302,7 +2302,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-04 10:43:50 +0000
+++ b/sql/ha_ndbcluster_glue.h	2011-04-20 12:53:27 +0000
@@ -64,8 +64,10 @@ bool close_cached_tables(THD *thd, TABLE
   return close_cached_tables(thd, tables, wait_for_refresh, LONG_TIMEOUT);
 }
 
+#ifdef MCP_WL3749
 /* Online alter table not supported */
 #define NDB_WITHOUT_ONLINE_ALTER
+#endif
 
 /* Read before write removal not supported */
 #define NDB_WITHOUT_READ_BEFORE_WRITE_REMOVAL
@@ -79,12 +81,14 @@ bool close_cached_tables(THD *thd, TABLE
 /* Global schema lock not available */
 #define NDB_NO_GLOBAL_SCHEMA_LOCK
 
+#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-03-04 08:52:27 +0000
+++ b/sql/handler.cc	2011-04-20 12:53:27 +0000
@@ -3357,6 +3357,225 @@ 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_ONLINE_ADD_INDEX_NO_WRITES)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_ONLINE_ADD_INDEX)
+        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_ONLINE_DROP_INDEX_NO_WRITES)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_ONLINE_DROP_INDEX)
+        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_ONLINE_ADD_PK_INDEX_NO_WRITES)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_ONLINE_ADD_PK_INDEX)
+        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_ONLINE_DROP_PK_INDEX_NO_WRITES)
+        result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+      else if (handler_alter_flags & HA_ONLINE_DROP_PK_INDEX)
+        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.
@@ -3629,7 +3848,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)
@@ -3698,7 +3921,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-03-04 09:53:26 +0000
+++ b/sql/handler.h	2011-04-20 12:53:27 +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
@@ -751,6 +814,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, 
@@ -1015,6 +1081,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
 {
@@ -1870,6 +1948,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	2010-11-16 12:37:26 +0000
+++ b/sql/log.cc	2011-04-20 12:53:27 +0000
@@ -4465,7 +4465,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	2010-09-22 08:15:41 +0000
+++ b/sql/sql_admin.cc	2011-04-20 12:53:27 +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	2010-11-16 12:37:26 +0000
+++ b/sql/sql_base.cc	2011-04-20 12:53:27 +0000
@@ -1330,6 +1330,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);
@@ -1369,6 +1370,7 @@ close_all_tables_for_name(THD *thd, TABL
     on the table to go away. Wake it up.
   */
   broadcast_refresh();
+  DBUG_VOID_RETURN;
 }
 
 
@@ -2165,7 +2167,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);
@@ -3007,7 +3014,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)
     {
@@ -3808,7 +3819,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 */
@@ -5725,7 +5740,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;
@@ -5759,11 +5779,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);
@@ -5772,8 +5806,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)
   {
@@ -5792,20 +5832,28 @@ 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
+  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	2010-09-30 13:29:12 +0000
+++ b/sql/sql_base.h	2011-04-20 12:53:27 +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,
                              MDL_ticket *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	2010-11-16 12:37:26 +0000
+++ b/sql/sql_lex.cc	2011-04-20 12:53:27 +0000
@@ -1635,6 +1635,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	2010-11-29 14:38:44 +0000
+++ b/sql/sql_lex.h	2011-04-20 12:53:27 +0000
@@ -940,6 +940,35 @@ 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_FORCE             (1L << 16)
+#define ALTER_RECREATE          (1L << 17)
+#define ALTER_ADD_PARTITION     (1L << 18)
+#define ALTER_DROP_PARTITION    (1L << 19)
+#define ALTER_COALESCE_PARTITION (1L << 20)
+#define ALTER_REORGANIZE_PARTITION (1L << 21)
+#define ALTER_PARTITION         (1L << 22)
+#define ALTER_ADMIN_PARTITION   (1L << 23)
+#define ALTER_TABLE_REORG       (1L << 24)
+#define ALTER_REBUILD_PARTITION (1L << 25)
+#define ALTER_ALL_PARTITION     (1L << 26)
+#define ALTER_REMOVE_PARTITIONING (1L << 27)
+#define ALTER_FOREIGN_KEY       (1L << 28)
+#define ALTER_TRUNCATE_PARTITION (1L << 29)
+#else
 #define ALTER_ADD_INDEX		(1L << 3)
 #define ALTER_DROP_INDEX	(1L << 4)
 #define ALTER_RENAME		(1L << 5)
@@ -954,15 +983,17 @@ inline bool st_select_lex_unit::is_union
 #define ALTER_DROP_PARTITION    (1L << 14)
 #define ALTER_COALESCE_PARTITION (1L << 15)
 #define ALTER_REORGANIZE_PARTITION (1L << 16) 
-#define ALTER_PARTITION          (1L << 17)
-#define ALTER_ADMIN_PARTITION    (1L << 18)
-#define ALTER_TABLE_REORG        (1L << 19)
-#define ALTER_REBUILD_PARTITION  (1L << 20)
-#define ALTER_ALL_PARTITION      (1L << 21)
+#define ALTER_PARTITION         (1L << 17)
+#define ALTER_ADMIN_PARTITION   (1L << 18)
+#define ALTER_TABLE_REORG       (1L << 19)
+#define ALTER_REBUILD_PARTITION (1L << 20)
+#define ALTER_ALL_PARTITION     (1L << 21)
 #define ALTER_REMOVE_PARTITIONING (1L << 22)
-#define ALTER_FOREIGN_KEY        (1L << 23)
+#define ALTER_FOREIGN_KEY       (1L << 23)
 #define ALTER_TRUNCATE_PARTITION (1L << 24)
+#endif
 
+/* #ifdef MCP_WL3749 */
 enum enum_alter_table_change_level
 {
   ALTER_TABLE_METADATA_ONLY= 0,
@@ -970,7 +1001,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
@@ -986,6 +1016,7 @@ public:
   void operator = (enum_type v) { value = v; }
   operator enum_type () { return value; }
 };
+/* #endif */
 
 
 /**
@@ -1007,7 +1038,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;
 
@@ -1017,7 +1053,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)
   {}
@@ -1033,7 +1073,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_show.cc'
--- a/sql/sql_show.cc	2011-03-04 09:53:26 +0000
+++ b/sql/sql_show.cc	2011-04-20 12:53:27 +0000
@@ -3402,7 +3402,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-03-04 08:52:27 +0000
+++ b/sql/sql_table.cc	2011-04-20 12:53:27 +0000
@@ -4229,10 +4229,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;
     }
 
@@ -4667,6 +4670,7 @@ err:
   DBUG_RETURN(-1);
 }
 
+#ifdef MCP_WL3749
 /**
   @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
  
@@ -4703,10 +4707,550 @@ is_index_maintenance_unique (TABLE *tabl
       }
     }
   }
-  return FALSE;
-}
-
+  return FALSE;
+}
+#endif /* MCP_WL3749 */
+
+#ifndef MCP_WL3749
+/**
+  Copy all changes detected by parser to the HA_ALTER_FLAGS
+*/
+
+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;
+
+  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;
+}
+
+
+/**
+   @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.
+
+   @retval TRUE  error
+   @retval FALSE success
+*/
+
+static
+bool
+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 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;
+  /*
+    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("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 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 fast 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,
+                                 &ha_alter_info->key_info_buffer,
+                                 &ha_alter_info->key_count,
+                                 /* select_field_count */ 0))
+    DBUG_RETURN(TRUE);
+  /* Allocate result buffers. */
+  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
+    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 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 fast 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))
+  {
+    *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 fast 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++;
+       (new_field && (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;
+
+    /* 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 how fields have been modified */
+    if (alter_info->flags & ALTER_CHANGE_COLUMN)
+    {
+      /* 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 */
+    field->flags&= ~FIELD_IN_ADD_INDEX;
+  }
+
+  /*
+    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=
+       ha_alter_info->key_info_buffer + ha_alter_info->key_count;
+
+  DBUG_PRINT("info", ("index count old: %d  new: %d",
+                      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;
+
+    /*
+      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.
+    */
+    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++;
+  }
+
+  /*
+    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= ha_alter_info->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. */
+      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) !=
+         (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()
@@ -5045,7 +5589,7 @@ mysql_compare_tables(TABLE *table,
   *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
   DBUG_RETURN(0);
 }
-
+#endif
 
 /*
   Manages enabling/disabling of indexes for ALTER TABLE
@@ -5095,6 +5639,330 @@ bool alter_table_manage_keys(TABLE *tabl
   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",
+              tmp_file_prefix, current_pid, thd->thread_id);
+  /* 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= NULL;
+  char *db= NULL;
+  char *new_name= NULL;
+  char *new_db= NULL;
+  TABLE *t_table;
+
+  DBUG_ENTER(" mysql_fast_or_online_alter_table");
+  //VOID(pthread_mutex_lock(&LOCK_open));
+  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+  //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);
+
+  if (end_active_trans(thd))
+    error=1;
+*/
+  if (error)
+    goto err;
+  if (online)
+  {
+   /*
+      Tell the handler to prepare for the online alter
+    */
+    if ((error= table->file->alter_table_phase1(thd,
+                                                altered_table,
+                                                create_info,
+                                                alter_info,
+                                                ha_alter_flags)))
+    {
+      goto err;
+    }
+
+    /*
+       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)))
+    {
+      goto err;
+    }
+  }
+  /*
+    The final .frm file is already created as a temporary file
+    and will be renamed to the original table name.
+  */
+  //VOID(pthread_mutex_lock(&LOCK_open));
+  if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
+    goto err;
+
+  table_name= altered_table->s->table_name.str;
+  db= altered_table->s->db.str;
+  new_name= table->s->table_name.str;
+  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(NULL,
+                         altered_table->s->db.str,
+                         altered_table->s->table_name.str,
+                         new_db,
+                         new_name, FN_FROM_IS_TMP))
+  {
+    error= 1;
+    //VOID(pthread_mutex_unlock(&LOCK_open));
+    goto err;
+  }
+  broadcast_refresh();
+  //VOID(pthread_mutex_unlock(&LOCK_open));
+
+  /*
+    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;
+/*
+  error= ha_autocommit_or_rollback(thd, 0);
+
+  if (end_active_trans(thd))
+    error=1;
+*/
+  if (error)
+    goto err;
+  if (online)
+  {
+    Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
+    TABLE_LIST tbl;
+
+    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.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;
+
+   /*
+      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;
+    }
+
+    /*
+      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));
+  }
+
+ err:
+  if (error)
+    DBUG_PRINT("info", ("Got error %u", error));
+  DBUG_RETURN(error);
+}
+#endif
+
 /**
   maximum possible length for certain blob types.
 
@@ -5594,13 +6462,22 @@ 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;
   bool partition_changed= FALSE;
 #endif
+#ifdef MCP_WL3749
   bool need_lock_for_indexes= TRUE;
   KEY  *key_info_buffer;
   uint index_drop_count= 0;
@@ -5609,8 +6486,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
@@ -5985,16 +6866,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;
-
+#endif
   set_table_default_charset(thd, create_info, db);
 
   if (thd->variables.old_alter_table
@@ -6003,6 +6884,7 @@ bool mysql_alter_table(THD *thd,char *ne
       || partition_changed
 #endif
      )
+#ifdef MCP_WL3749
     need_copy_table= ALTER_TABLE_DATA_CHANGED;
   else
   {
@@ -6201,6 +7083,7 @@ 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
   if (table_for_fast_alter_partition)
@@ -6212,6 +7095,179 @@ 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;
+
+      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;
+        break;
+      case HA_ALTER_NOT_SUPPORTED:
+        if (alter_info->build_method == HA_BUILD_ONLINE)
+        {
+          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
+          close_temporary_table(thd, altered_table, 1, 1);
+          goto err;
+        }
+        need_copy_table= TRUE;
+        break;
+      case HA_ALTER_ERROR:
+      default:
+        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)
+      {
+        DBUG_PRINT("info", ("Line %u", __LINE__));
+        if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
+            thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
+        {
+          DBUG_PRINT("info", ("Line %u", __LINE__));
+          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.
+        */
+        DBUG_PRINT("info", ("Line %u", __LINE__));
+        mysql_lock_remove(thd, thd->lock, table);
+      }
+      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)
+      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 */
@@ -6283,7 +7339,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)
     {
@@ -6313,7 +7373,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;
@@ -6352,6 +7411,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)
   {
@@ -6439,7 +7499,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;
 
@@ -6451,6 +7511,7 @@ bool mysql_alter_table(THD *thd,char *ne
       if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
           thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
       {
+        DBUG_PRINT("info", ("Line %u", __LINE__));
         mysql_unlock_tables(thd, thd->lock);
         thd->lock=0;
       }
@@ -6534,12 +7595,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))
   {
@@ -6549,9 +7612,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)))
   {
@@ -6571,7 +7636,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)
   {
     /*
@@ -6616,6 +7681,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	2010-10-06 14:34:28 +0000
+++ b/sql/sql_truncate.cc	2011-04-20 12:53:27 +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-03-04 09:53:26 +0000
+++ b/sql/sql_yacc.yy	2011-04-20 12:53:27 +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:
@@ -10258,17 +10385,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))
@@ -12609,9 +12754,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-03-04 09:53:26 +0000
+++ b/sql/table.cc	2011-04-20 12:53:27 +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,31 @@ 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;
     }
 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 +2090,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-03-04 08:52:27 +0000
+++ b/sql/table.h	2011-04-20 12:53:27 +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 };
 
@@ -2035,9 +2039,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 '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=


Attachment: [text/bzr-bundle] bzr/martin.skold@mysql.com-20110420125327-wl7476x2ijise701.bundle
Thread
bzr commit into mysql-5.5-telco-7.0 branch (Martin.Skold:3227) WL#3749Martin Skold20 Apr