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
3226 Magnus Blåudd 2011-03-04
ndb
- remove disabled.def listing and fix result file for ndb_dd_basic, ndb_dd_dump and ndb_dd_sql_features
modified:
mysql-test/suite/ndb/r/ndb_dd_basic.result
mysql-test/suite/ndb/t/disabled.def
=== 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=
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-5.5-telco-7.0 branch (Martin.Skold:3226 to 3227) WL#3749 | Martin Skold | 20 Apr |