#At file:///data0/magnus/mysql/tmp/86W2wNlNrs/5.5-cluster/ based on revid:magnus.blaudd@stripped5uqog1mfrksjcdsc
3375 magnus.blaudd@stripped 2011-06-27 [merge]
Merge
modified:
include/my_base.h
mysql-test/include/ndb_have_online_alter.inc
mysql-test/r/ctype_utf8mb4.result
mysql-test/suite/ndb/r/ndb_alter_table.result
mysql-test/suite/ndb/r/ndb_alter_table3.result
mysql-test/suite/ndb/r/ndb_alter_table_online.result
mysql-test/suite/ndb/r/ndb_dd_alter.result
mysql-test/suite/ndb/r/ndb_dd_ddl.result
mysql-test/suite/ndb/r/ndb_dd_disk2memory.result
mysql-test/suite/ndb/r/ndb_dd_restore_compat.result
mysql-test/suite/ndb/r/ndb_gis.result
mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result
mysql-test/suite/ndb/r/ndb_index_unique.result
mysql-test/suite/ndb/r/ndb_short_sigs.result
mysql-test/suite/ndb/t/disabled.def
mysql-test/suite/ndb/t/ndb_alter_table3.test
mysql-test/suite/ndb/t/ndb_alter_table_online2.test
mysql-test/suite/ndb/t/ndb_dd_ddl.test
mysql-test/suite/ndb/t/ndb_index_unique.test
mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result
mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result
mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result
mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result
mysql-test/suite/ndb_rpl/r/ndb_rpl_basic.result
mysql-test/suite/ndb_rpl/t/ndb_rpl_basic.test
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.h
sql/ha_ndbcluster_glue.h
sql/handler.cc
sql/handler.h
sql/lex.h
sql/log.cc
sql/sql_admin.cc
sql/sql_base.cc
sql/sql_base.h
sql/sql_bitmap.h
sql/sql_lex.cc
sql/sql_lex.h
sql/sql_partition.cc
sql/sql_partition.h
sql/sql_show.cc
sql/sql_table.cc
sql/sql_truncate.cc
sql/sql_yacc.yy
sql/table.cc
sql/table.h
sql/unireg.cc
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2011-06-23 06:59:40 +0000
+++ b/include/my_base.h 2011-06-27 10:16:18 +0000
@@ -96,6 +96,15 @@ enum ha_key_alg {
HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */
};
+#ifndef MCP_WL3749
+ /* Index and table build methods */
+
+enum ha_build_method {
+ HA_BUILD_DEFAULT,
+ HA_BUILD_ONLINE,
+ HA_BUILD_OFFLINE
+};
+#endif
/* Storage media types */
enum ha_storage_media {
=== modified file 'mysql-test/include/ndb_have_online_alter.inc'
--- a/mysql-test/include/ndb_have_online_alter.inc 2011-02-02 10:33:25 +0000
+++ b/mysql-test/include/ndb_have_online_alter.inc 2011-04-20 12:53:27 +0000
@@ -6,9 +6,9 @@
--disable_result_log
let $have_online_alter = 1;
CREATE TABLE check_online_alter(a int primary key);
---error 0,1064
+--error 0,ER_PARSE_ERROR, ER_NOT_SUPPORTED_YET
ALTER ONLINE TABLE check_online_alter ADD COLUMN b int;
-if($mysql_errno)
+if (`SELECT '$mysql_errno' = '1064'`)
{
let $have_online_alter= 0;
}
=== modified file 'mysql-test/r/ctype_utf8mb4.result'
--- a/mysql-test/r/ctype_utf8mb4.result 2010-09-28 15:15:58 +0000
+++ b/mysql-test/r/ctype_utf8mb4.result 2011-05-30 21:13:02 +0000
@@ -2453,6 +2453,7 @@ MODIFY p varchar(255) CHARACTER SET utf8
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
Warning 1071 Specified key was too long; max key length is 1000 bytes
+Warning 1071 Specified key was too long; max key length is 1000 bytes
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
=== modified file 'mysql-test/suite/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-06-17 10:15:34 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result 2011-06-22 11:29:27 +0000
@@ -522,10 +522,10 @@ COUNT(*)
UPDATE t1 SET c = 3.402823466E+38, d = 1.2686868689898E+308, e = 666.66, f = '2007-10-23 23:23:23', g = '1111' WHERE a = 1;
SELECT * FROM t1 WHERE a = 1 or a = 10 or a = 20 or a = 30 ORDER BY a;
a b c d e f g
-1 5 3.40282e+38 1.2686868689898e+308 666.66 2007-10-23 23:23:23 1111
-10 1 -3.40282e+38 NULL NULL NULL NULL
-20 1 -3.40282e+38 1.7976931348623e+308 345.21 NULL NULL
-30 1 -3.40282e+38 1.7976931348623e+308 345.21 1000-01-01 00:00:00 0101
+1 5 3.40282e38 1.2686868689898e308 666.66 2007-10-23 23:23:23 1111
+10 1 -3.40282e38 NULL NULL NULL NULL
+20 1 -3.40282e38 1.7976931348623e308 345.21 NULL NULL
+30 1 -3.40282e38 1.7976931348623e308 345.21 1000-01-01 00:00:00 0101
*********************************
* Backup and restore tables w/ new column
*********************************
=== modified file 'mysql-test/suite/ndb/r/ndb_dd_alter.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_alter.result 2010-11-30 10:44:15 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_alter.result 2011-06-08 12:00:29 +0000
@@ -225,7 +225,7 @@ t1 CREATE TABLE `t1` (
`a9` varchar(255) DEFAULT NULL,
`a10` blob,
PRIMARY KEY (`a1`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
+) /*!50100 TABLESPACE ts STORAGE DISK */ ENGINE=InnoDB DEFAULT CHARSET=latin1
SELECT * FROM test.t1 ORDER BY a1;
a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
1 2 2000000001 aaa1 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb1 binary data
@@ -290,7 +290,7 @@ t1 CREATE TABLE `t1` (
`a9` varchar(255) DEFAULT NULL,
`a10` blob,
PRIMARY KEY (`a1`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) /*!50100 TABLESPACE ts STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE test.t1;
CREATE TABLE test.t1 (a1 INT PRIMARY KEY) TABLESPACE ts STORAGE DISK ENGINE=NDB;
SELECT * FROM test.t1 ORDER BY a1;
@@ -317,11 +317,11 @@ a1
20
SELECT * FROM information_schema.partitions WHERE table_name= 't1' AND partition_name = 'p0';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PARTITION_NAME SUBPARTITION_NAME PARTITION_ORDINAL_POSITION SUBPARTITION_ORDINAL_POSITION PARTITION_METHOD SUBPARTITION_METHOD PARTITION_EXPRESSION SUBPARTITION_EXPRESSION PARTITION_DESCRIPTION TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE CREATE_TIME UPDATE_TIME CHECK_TIME CHECKSUM PARTITION_COMMENT NODEGROUP TABLESPACE_NAME
-NULL test t1 p0 NULL 1 NULL KEY NULL NULL NULL 0 0 0 NULL 0 0 NULL NULL NULL NULL default ts
+def test t1 p0 NULL 1 NULL KEY NULL NULL NULL 0 0 0 NULL 0 0 NULL NULL NULL NULL default ts
ALTER TABLE test.t1 ADD a2 FLOAT, ADD a3 DOUBLE;
SELECT * FROM information_schema.partitions WHERE table_name= 't1' AND partition_name = 'p0';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PARTITION_NAME SUBPARTITION_NAME PARTITION_ORDINAL_POSITION SUBPARTITION_ORDINAL_POSITION PARTITION_METHOD SUBPARTITION_METHOD PARTITION_EXPRESSION SUBPARTITION_EXPRESSION PARTITION_DESCRIPTION TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE CREATE_TIME UPDATE_TIME CHECK_TIME CHECKSUM PARTITION_COMMENT NODEGROUP TABLESPACE_NAME
-NULL test t1 p0 NULL 1 NULL KEY NULL NULL NULL 0 0 0 NULL 0 0 NULL NULL NULL NULL default ts
+def test t1 p0 NULL 1 NULL KEY NULL NULL NULL 0 0 0 NULL 0 0 NULL NULL NULL NULL default ts
SELECT * FROM test.t1 ORDER BY a1;
a1 a2 a3
1 2.2345 20000001
=== modified file 'mysql-test/suite/ndb/r/ndb_dd_ddl.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_ddl.result 2011-01-21 14:27:30 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_ddl.result 2011-06-22 12:35:08 +0000
@@ -185,11 +185,7 @@ CREATE TABLE t1
(pk1 INT NOT NULL PRIMARY KEY, b INT NOT NULL, c INT NOT NULL)
TABLESPACE ts1 STORAGE MEMORY
ENGINE NDB;
-ERROR HY000: Can't create table 'test.t1' (errno: 138)
-CREATE TABLE t1
-(pk1 INT NOT NULL PRIMARY KEY, b INT NOT NULL, c INT NOT NULL)
-TABLESPACE ts1 STORAGE DISK
-ENGINE NDB;
+ALTER TABLE t1 STORAGE DISK;
CREATE INDEX b_i on t1(b);
CREATE INDEX bc_i on t1(b, c);
DROP TABLE t1;
=== modified file 'mysql-test/suite/ndb/r/ndb_dd_disk2memory.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_disk2memory.result 2008-12-22 11:10:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_disk2memory.result 2011-06-08 12:00:29 +0000
@@ -245,7 +245,7 @@ t1 CREATE TABLE `t1` (
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,
PRIMARY KEY (`pk1`)
-) /*!50100 STORAGE MEMORY */ ENGINE=ndbcluster DEFAULT CHARSET=latin1
+) /*!50100 TABLESPACE table_space1 STORAGE MEMORY */ ENGINE=ndbcluster DEFAULT CHARSET=latin1
DROP TABLE test.t1;
DROP TABLE test.t2;
=== modified file 'mysql-test/suite/ndb/r/ndb_dd_restore_compat.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result 2011-03-04 13:14:07 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result 2011-05-30 21:13:02 +0000
@@ -45,6 +45,8 @@ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
4 5 2000000004 aaa4 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb4 binary data
5 6 2000000005 aaa5 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb5 binary data
ALTER TABLE t1 ADD COLUMN c int;
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
=== modified file 'mysql-test/suite/ndb/r/ndb_gis.result'
--- a/mysql-test/suite/ndb/r/ndb_gis.result 2011-06-23 14:24:19 +0000
+++ b/mysql-test/suite/ndb/r/ndb_gis.result 2011-06-27 10:16:18 +0000
@@ -433,6 +433,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
@@ -987,6 +989,8 @@ mpg multipolygon YES NULL
gc geometrycollection YES NULL
gm geometry YES NULL
ALTER TABLE t1 ADD fid INT;
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
SHOW FIELDS FROM t1;
Field Type Null Key Default Extra
a int(11) NO PRI NULL auto_increment
=== modified file 'mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result'
--- a/mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result 2011-03-29 12:45:25 +0000
+++ b/mysql-test/suite/ndb/r/ndb_global_schema_lock_error.result 2011-05-30 21:13:02 +0000
@@ -26,6 +26,7 @@ Warning 1296 Got error 4009 'Cluster Fai
ALTER TABLE t3 ADD COLUMN b int default NULL;
Warnings:
Warning 1296 Got error 4009 'Cluster Failure' from NDB
+Warning 1296 Got error 4009 'Cluster Failure' from NDB
INSERT INTO t2 VALUES(1);
TRUNCATE TABLE t2;
Warnings:
=== modified file 'mysql-test/suite/ndb/r/ndb_index_unique.result'
--- a/mysql-test/suite/ndb/r/ndb_index_unique.result 2011-06-23 06:59:40 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_unique.result 2011-06-27 10:16:18 +0000
@@ -181,8 +181,8 @@ a b c
5 5 NULL
8 3 NULL
9 3 NULL
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = true;
+set @old_os = @@session.optimizer_switch;
+set optimizer_switch = 'engine_condition_pushdown=on';
explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range PRIMARY,b PRIMARY 4 NULL 2 Using where with pushed condition
@@ -191,7 +191,7 @@ a b c
3 3 NULL
5 5 NULL
8 3 NULL
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t2;
CREATE TABLE t3 (
a int unsigned NOT NULL,
@@ -682,7 +682,7 @@ create table t1 (a int primary key, b va
engine=ndb charset=utf8;
insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200));
insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200));
-ERROR 23000: Duplicate entry '∫dt∫dt∫dt∫dt∫dt∫dt0: Duplicate entry '\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bdt\222Bd' for key 'b'
select a, sha1(b) from t1;
a sha1(b)
1 08f5d02c8b8bc244f275bdfc22c42c5cab0d9d7d
@@ -750,8 +750,7 @@ Warning 1121 Ndb does not support unique
insert into t1 values
(0,0),(1,1),(2,2),(3,3),(4,4),
(5,null),(6,null),(7,null),(8,null),(9,null);
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = 0;
+set optimizer_switch = 'engine_condition_pushdown=off';
select a from t1 where b is not null order by a;
a
0
@@ -766,7 +765,7 @@ a
7
8
9
-set engine_condition_pushdown = 1;
+set optimizer_switch = 'engine_condition_pushdown=on';
select a from t1 where b is not null order by a;
a
0
@@ -781,7 +780,7 @@ a
7
8
9
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t1;
create table t1 (
a int not null,
@@ -798,8 +797,7 @@ insert into t1 values
(5,null,0),(6,null,1),(7,null,1),(8,null,1),(9,null,2),
(10,0,null),(11,1,null),(12,1,null),(13,1,null),(14,2,null),
(15,null,null),(16,null,null),(17,null,null),(18,null,null),(19,null,null);
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = 0;
+set optimizer_switch = 'engine_condition_pushdown=off';
select a from t1 where b is not null and c = 1 order by a;
a
1
@@ -843,7 +841,7 @@ a
2
3
4
-set engine_condition_pushdown = 1;
+set optimizer_switch = 'engine_condition_pushdown=on';
select a from t1 where b is not null and c = 1 order by a;
a
1
@@ -887,7 +885,7 @@ a
2
3
4
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t1;
create table t1 (pk int primary key, a int) engine=ndb;
create table t2 (pk int primary key, uq int, a int,
=== 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-06-13 12:36:36 +0000
+++ b/mysql-test/suite/ndb/t/disabled.def 2011-06-22 11:29:27 +0000
@@ -18,13 +18,8 @@ ndb_disconnect_ddl : Bug#31853 fl
ndb_condition_pushdown : SEAGULL
-ndb_dd_disk2memory : SEAGULL alter
-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_multi : SEAGULL schema distribution
=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table3.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table3.test 2008-08-12 15:35:47 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table3.test 2011-06-09 13:42:10 +0000
@@ -1,4 +1,5 @@
-- source include/have_multi_ndb.inc
+-- source include/not_embedded.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table_online2.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online2.test 2011-05-18 12:56:24 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online2.test 2011-05-30 21:13:02 +0000
@@ -14,7 +14,7 @@
-- source include/not_embedded.inc
# mysqlslap seems to be not_windows. remove this when removed from mysqlslap.test
-- source include/not_windows.inc
--- source include/have_log_bin.inc
+# -- source include/have_log_bin.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
=== modified file 'mysql-test/suite/ndb/t/ndb_dd_ddl.test'
--- a/mysql-test/suite/ndb/t/ndb_dd_ddl.test 2010-10-27 11:32:32 +0000
+++ b/mysql-test/suite/ndb/t/ndb_dd_ddl.test 2011-06-22 12:35:08 +0000
@@ -270,17 +270,12 @@ ADD DATAFILE 'datafile2.dat'
INITIAL_SIZE 1M
ENGINE NDB;
---error 1005
CREATE TABLE t1
(pk1 INT NOT NULL PRIMARY KEY, b INT NOT NULL, c INT NOT NULL)
TABLESPACE ts1 STORAGE MEMORY
ENGINE NDB;
-CREATE TABLE t1
-(pk1 INT NOT NULL PRIMARY KEY, b INT NOT NULL, c INT NOT NULL)
-TABLESPACE ts1 STORAGE DISK
-ENGINE NDB;
-
+ALTER TABLE t1 STORAGE DISK;
CREATE INDEX b_i on t1(b);
CREATE INDEX bc_i on t1(b, c);
=== modified file 'mysql-test/suite/ndb/t/ndb_index_unique.test'
--- a/mysql-test/suite/ndb/t/ndb_index_unique.test 2011-06-23 06:59:40 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index_unique.test 2011-06-27 10:16:18 +0000
@@ -111,11 +111,11 @@ insert t2 values(1,1,NULL),(2,2,2),(3,3,
select * from t2 where c IS NULL order by a;
select * from t2 where b = 3 AND c IS NULL order by a;
select * from t2 where (b = 3 OR b = 5) AND c IS NULL order by a;
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = true;
+set @old_os = @@session.optimizer_switch;
+set optimizer_switch = 'engine_condition_pushdown=on';
explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t2;
@@ -449,21 +449,20 @@ insert into t1 values
(0,0),(1,1),(2,2),(3,3),(4,4),
(5,null),(6,null),(7,null),(8,null),(9,null);
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = 0;
+set optimizer_switch = 'engine_condition_pushdown=off';
# failed, empty result
select a from t1 where b is not null order by a;
# worked
select a from t1 where b is null order by a;
-set engine_condition_pushdown = 1;
+set optimizer_switch = 'engine_condition_pushdown=on';
# failed, empty result
select a from t1 where b is not null order by a;
# worked
select a from t1 where b is null order by a;
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t1;
@@ -482,9 +481,8 @@ insert into t1 values
(10,0,null),(11,1,null),(12,1,null),(13,1,null),(14,2,null),
(15,null,null),(16,null,null),(17,null,null),(18,null,null),(19,null,null);
-set @old_ecpd = @@session.engine_condition_pushdown;
-set engine_condition_pushdown = 0;
+set optimizer_switch = 'engine_condition_pushdown=off';
# worked
select a from t1 where b is not null and c = 1 order by a;
# failed, empty result
@@ -497,7 +495,7 @@ select a from t1 where b is not null and
select a from t1 where b is null and c is not null order by a;
select a from t1 where b is not null and c is not null order by a;
-set engine_condition_pushdown = 1;
+set optimizer_switch = 'engine_condition_pushdown=on';
# worked
select a from t1 where b is not null and c = 1 order by a;
# failed, empty result
@@ -510,7 +508,7 @@ select a from t1 where b is not null and
select a from t1 where b is null and c is not null order by a;
select a from t1 where b is not null and c is not null order by a;
-set engine_condition_pushdown = @old_ecpd;
+set optimizer_switch = @old_os;
drop table t1;
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result 2011-02-15 09:51:38 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_basic.result 2011-05-30 21:13:02 +0000
@@ -12,6 +12,8 @@ select @max_epoch:=max(epoch)-1 from mys
#
delete from t1;
alter table t1 add (b int);
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
insert into t1 values (3,3),(4,4);
alter table t1 rename t2;
begin;
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result 2011-02-15 09:51:38 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result 2011-05-30 21:13:02 +0000
@@ -21,6 +21,8 @@ mysqld-bin.000001 # Query 1 # use `test`
reset master;
reset master;
alter table t2 add column (b int);
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
mysqld-bin.000001 # Query 1 # use `test`; alter table t2 add column (b int)
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result 2011-03-28 14:00:51 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result 2011-05-30 21:13:02 +0000
@@ -9,6 +9,8 @@ create table t1 (a int key, b int) engin
create table t2 (a int key, b int) engine=ndb;
insert into t1 values (1,1);
alter table t1 add c int;
+Warnings:
+Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
reset master;
=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result 2011-05-13 07:40:50 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_add_column.result 2011-05-30 21:13:02 +0000
@@ -47,10 +47,10 @@ c1 c2 c d f g h
7 7 NULL NULL NULL NULL NULL
8 8 NULL NULL NULL NULL NULL
11 1 a NULL NULL NULL NULL
-12 2 b -3.40282e+38 NULL NULL NULL
-14 4 d -3.40282e+38 456.78 NULL NULL
-15 5 e -3.40282e+38 456.78 2007-10-26 12:00:00 NULL
-16 6 f -3.40282e+38 456.78 2007-10-26 12:00:00 abcd
+12 2 b -3.40282e38 NULL NULL NULL
+14 4 d -3.40282e38 456.78 NULL NULL
+15 5 e -3.40282e38 456.78 2007-10-26 12:00:00 NULL
+16 6 f -3.40282e38 456.78 2007-10-26 12:00:00 abcd
**********************
"Slave data"
**********************
@@ -63,43 +63,43 @@ c1 c2 c d f g h
7 7 NULL NULL NULL NULL NULL
8 8 NULL NULL NULL NULL NULL
11 1 a NULL NULL NULL NULL
-12 2 b -3.40282e+38 NULL NULL NULL
-14 4 d -3.40282e+38 456.78 NULL NULL
-15 5 e -3.40282e+38 456.78 2007-10-26 12:00:00 NULL
-16 6 f -3.40282e+38 456.78 2007-10-26 12:00:00 abcd
+12 2 b -3.40282e38 NULL NULL NULL
+14 4 d -3.40282e38 456.78 NULL NULL
+15 5 e -3.40282e38 456.78 2007-10-26 12:00:00 NULL
+16 6 f -3.40282e38 456.78 2007-10-26 12:00:00 abcd
UPDATE t1 SET c = "abcdef", d = 3.402823466E+38, f = 987.65, g = '2007-10-22 22:22:22', h = "aaaa";
***************************
"Master Data After Update"
***************************
SELECT * FROM t1 ORDER BY c1;
c1 c2 c d f g h
-1 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-2 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-3 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-6 6 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-7 7 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-8 8 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-11 1 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-12 2 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-14 4 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-15 5 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-16 6 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
+1 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+2 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+3 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+6 6 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+7 7 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+8 8 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+11 1 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+12 2 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+14 4 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+15 5 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+16 6 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
*************************
"Slave Data After Update"
*************************
SELECT * FROM t1 ORDER BY c1;
c1 c2 c d f g h
-1 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-2 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-3 NULL abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-6 6 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-7 7 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-8 8 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-11 1 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-12 2 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-14 4 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-15 5 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
-16 6 abcdef 3.40282e+38 987.65 2007-10-22 22:22:22 aaaa
+1 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+2 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+3 NULL abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+6 6 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+7 7 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+8 8 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+11 1 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+12 2 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+14 4 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+15 5 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
+16 6 abcdef 3.40282e38 987.65 2007-10-22 22:22:22 aaaa
DROP TABLE t1;
*************************************************
* Insert And Update New Added Columns With Commit
=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_basic.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_basic.result 2011-05-18 12:56:24 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_basic.result 2011-06-22 15:41:41 +0000
@@ -137,7 +137,6 @@ set GLOBAL slave_transaction_retries=1;
UPDATE t1 SET `nom`="DEAD" WHERE `nid`=1;
**** On Slave ****
include/wait_for_slave_sql_error.inc [errno=1205 ]
-Last_SQL_Error = 'Error 'Lock wait timeout exceeded; try restarting transaction' on query. Default database: ''. Query: 'COMMIT''
set GLOBAL slave_transaction_retries=10;
include/start_slave.inc
select * from t1 order by nid;
=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_basic.test'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_basic.test 2011-05-18 12:56:24 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_basic.test 2011-06-22 15:41:41 +0000
@@ -198,7 +198,7 @@ connection slave;
# verify with show slave status
# 1205 = ER_LOCK_WAIT_TIMEOUT
--let $slave_sql_errno= 1205
---let $show_slave_sql_error= 1
+--let $show_slave_sql_error= 0
--source include/wait_for_slave_sql_error.inc
# now set max retries high enough to succeed, and start slave again
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2011-06-23 06:59:40 +0000
+++ b/sql/ha_ndbcluster.cc 2011-06-27 10:16:18 +0000
@@ -332,6 +332,16 @@ ndbcluster_partition_flags()
HA_CAN_PARTITION_UNIQUE | HA_USE_AUTO_PARTITION);
}
+#ifndef MCP_WL3749
+static uint
+ndbcluster_alter_table_flags(uint flags)
+{
+ if (flags & ALTER_DROP_PARTITION)
+ return 0;
+ else
+ return (HA_PARTITION_FUNCTION_SUPPORTED);
+}
+#else
#ifndef NDB_WITHOUT_ONLINE_ALTER
static uint
ndbcluster_alter_partition_flags()
@@ -364,6 +374,7 @@ ndbcluster_alter_table_flags(uint flags)
return f;
}
#endif
+#endif
#define NDB_AUTO_INCREMENT_RETRIES 100
#define BATCH_FLUSH_SIZE (32768)
@@ -8903,18 +8914,6 @@ int ha_ndbcluster::create(const char *na
else
tab.setTablespaceName("DEFAULT-TS");
}
- else if (create_info->tablespace &&
- create_info->storage_media == HA_SM_MEMORY)
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- ER(ER_ILLEGAL_HA_CREATE_OPTION),
- ndbcluster_hton_name,
- "TABLESPACE currently only supported for "
- "STORAGE DISK");
- result= HA_ERR_UNSUPPORTED;
- goto abort_return;
- }
// Save the table level storage media setting
switch(create_info->storage_media)
@@ -11312,6 +11311,10 @@ static int ndbcluster_init(void *p)
h->show_status= ndbcluster_show_status; /* Show status */
h->alter_tablespace= ndbcluster_alter_tablespace; /* Show status */
h->partition_flags= ndbcluster_partition_flags; /* Partition flags */
+#ifndef MCP_WL3749
+ h->alter_table_flags=
+ ndbcluster_alter_table_flags; /* Alter table flags */
+#else
#ifndef NDB_WITHOUT_ONLINE_ALTER
h->alter_partition_flags=
ndbcluster_alter_partition_flags; /* Alter partition flags */
@@ -11319,6 +11322,7 @@ static int ndbcluster_init(void *p)
h->alter_table_flags=
ndbcluster_alter_table_flags; /* Alter table flags */
#endif
+#endif
#if MYSQL_VERSION_ID >= 50501
h->fill_is_table= ndbcluster_fill_is_table;
#else
@@ -11831,9 +11835,13 @@ ulonglong ha_ndbcluster::table_flags(voi
HA_HAS_OWN_BINLOGGING |
HA_BINLOG_ROW_CAPABLE |
HA_HAS_RECORDS |
+#ifndef MCP_WL3749
+ HA_ONLINE_ALTER |
+#else
#ifndef NDB_WITHOUT_ONLINE_ALTER
HA_ONLINE_ALTER |
#endif
+#endif
0;
/*
@@ -14952,7 +14960,7 @@ ha_ndbcluster::set_up_partition_info(par
DBUG_RETURN(0);
}
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
static
HA_ALTER_FLAGS supported_alter_operations()
{
@@ -14972,6 +14980,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)
{
@@ -14987,7 +14996,7 @@ int ha_ndbcluster::check_if_supported_al
add_column= add_column | HA_ADD_COLUMN;
adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX;
dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
- partition_info *part_info= table->part_info;
+ partition_info *part_info= altered_table->part_info;
const NDBTAB *old_tab= m_table;
if (THDVAR(thd, use_copying_alter_table))
@@ -15009,7 +15018,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);
@@ -15094,7 +15103,8 @@ int ha_ndbcluster::check_if_supported_al
}
else if (alter_flags->is_set(HA_ADD_PARTITION))
{
- new_tab.setFragmentCount(part_info->no_parts);
+ DBUG_PRINT("info", ("Adding partition (%u)", part_info->num_parts));
+ new_tab.setFragmentCount(part_info->num_parts);
}
NDB_Modifiers table_modifiers(ndb_table_modifiers);
@@ -15272,6 +15282,7 @@ int ha_ndbcluster::alter_table_phase1(TH
{
int error= 0;
uint i;
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= get_ndb(thd);
NDBDICT *dict= ndb->getDictionary();
ndb->setDatabaseName(m_dbname);
@@ -15285,9 +15296,8 @@ int ha_ndbcluster::alter_table_phase1(TH
adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX;
dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
- if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
- DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
- (thd, "ha_ndbcluster::alter_table_phase1"));
+ if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase1"))
+ DBUG_RETURN(HA_ERR_NO_CONNECTION);
if (!(alter_data= new NDB_ALTER_DATA(dict, m_table)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -15423,8 +15433,8 @@ int ha_ndbcluster::alter_table_phase1(TH
}
else if (alter_flags->is_set(HA_ADD_PARTITION))
{
- partition_info *part_info= table->part_info;
- new_tab->setFragmentCount(part_info->no_parts);
+ partition_info *part_info= altered_table->part_info;
+ new_tab->setFragmentCount(part_info->num_parts);
}
int res= dict->prepareHashMap(*old_tab, *new_tab);
@@ -15514,6 +15524,7 @@ int ha_ndbcluster::alter_table_phase2(TH
{
int error= 0;
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
NDBDICT *dict= alter_data->dictionary;
HA_ALTER_FLAGS dropping;
@@ -15521,10 +15532,9 @@ int ha_ndbcluster::alter_table_phase2(TH
DBUG_ENTER("alter_table_phase2");
dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
- if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+ if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase2"))
{
- error= ndbcluster_no_global_schema_lock_abort
- (thd, "ha_ndbcluster::alter_table_phase2");
+ error= HA_ERR_NO_CONNECTION;
goto err;
}
@@ -15589,15 +15599,15 @@ int ha_ndbcluster::alter_table_phase3(TH
HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags)
{
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
DBUG_ENTER("alter_table_phase3");
NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
- if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+ if (!thd_ndb->has_required_global_schema_lock("ha_ndbcluster::alter_table_phase3"))
{
delete alter_data;
alter_info->data= 0;
- DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
- (thd, "ha_ndbcluster::alter_table_phase3"));
+ DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
const char *db= table->s->db.str;
=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h 2011-06-23 06:59:40 +0000
+++ b/sql/ha_ndbcluster.h 2011-06-27 10:16:18 +0000
@@ -429,9 +429,10 @@ static void set_tabname(const char *path
qc_engine_callback *engine_callback,
ulonglong *engine_data);
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
int check_if_supported_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
HA_ALTER_FLAGS *alter_flags,
uint table_changes);
@@ -540,7 +541,7 @@ private:
int ndb_optimize_table(THD* thd, uint delay);
-#ifndef NDB_WITHOUT_ONLINE_ALTER
+#ifndef MCP_WL3749
int alter_frm(THD *thd, const char *file, NDB_ALTER_DATA *alter_data);
#endif
=== modified file 'sql/ha_ndbcluster_glue.h'
--- a/sql/ha_ndbcluster_glue.h 2011-06-09 12:14:22 +0000
+++ b/sql/ha_ndbcluster_glue.h 2011-06-22 11:29:27 +0000
@@ -76,12 +76,14 @@ bool close_cached_tables(THD *thd, TABLE
/* No mysql_rm_table_part2 anymore in 5.5.8 */
#define NDB_NO_MYSQL_RM_TABLE_PART2
+#ifdef MCP_WL3749
/*
The enum open_table_mode has been removed in 5.5.7 and 'open_table_from_share'
now takes "bool is_create_table" instead of the enum type. Define OTM_OPEN
to false since it's not a create table
*/
#define OTM_OPEN false
+#endif
#endif
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2011-06-27 09:06:30 +0000
+++ b/sql/handler.cc 2011-06-27 10:22:41 +0000
@@ -3404,6 +3404,249 @@ handler::ha_prepare_for_alter()
prepare_for_alter();
}
+#ifndef MCP_WL3749
+/*
+ Default implementation to support fast alter table
+ and old online add/drop index interface
+*/
+int
+handler::check_if_supported_alter(TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
+ HA_ALTER_FLAGS *alter_flags,
+ uint table_changes)
+{
+ DBUG_ENTER("check_if_supported_alter");
+ int result= HA_ALTER_NOT_SUPPORTED;
+ ulong handler_alter_flags= table->file->alter_table_flags(0);
+ HA_ALTER_FLAGS supported_alter_operations;
+ supported_alter_operations=
+ supported_alter_operations |
+ HA_ADD_INDEX |
+ HA_DROP_INDEX |
+ HA_ADD_UNIQUE_INDEX |
+ HA_DROP_UNIQUE_INDEX |
+ HA_ADD_PK_INDEX |
+ HA_DROP_PK_INDEX;
+ HA_ALTER_FLAGS not_supported= ~(supported_alter_operations);
+ DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags));
+#ifndef DBUG_OFF
+ {
+ char dbug_string[HA_MAX_ALTER_FLAGS+1];
+ alter_flags->print(dbug_string);
+ DBUG_PRINT("info", ("alter_flags: %s", dbug_string));
+ not_supported.print(dbug_string);
+ DBUG_PRINT("info", ("not_supported: %s", dbug_string));
+ }
+#endif
+ /* Check the old alter table flags */
+ if ((*alter_flags & not_supported).is_set())
+ {
+ /* Not adding/dropping index check if supported as fast alter */
+ DBUG_PRINT("info", ("alter_info->change_level %u", alter_info->change_level));
+ if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY &&
+ table->file->check_if_incompatible_data(create_info, table_changes)
+ != COMPATIBLE_DATA_NO)
+ DBUG_RETURN(HA_ALTER_SUPPORTED_WAIT_LOCK);
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ else
+ {
+ /* Add index */
+ if ((*alter_flags & HA_ADD_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ /* Drop index */
+ if ((*alter_flags & HA_DROP_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ /* Add unique index */
+ if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ /* Drop unique index */
+ if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ /* Add primary key */
+ if ((*alter_flags & HA_ADD_PK_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ /* Drop primary key */
+ if ((*alter_flags & HA_DROP_PK_INDEX).is_set())
+ {
+ if (handler_alter_flags & HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE)
+ result= HA_ALTER_SUPPORTED_WAIT_LOCK;
+ else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
+ result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
+ HA_ALTER_SUPPORTED_WAIT_LOCK
+ : HA_ALTER_SUPPORTED_NO_LOCK;
+ else
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ }
+ }
+ DBUG_RETURN(result);
+}
+
+/*
+ Default implementation to support old online add/drop index
+ */
+int
+handler::alter_table_phase1(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ DBUG_ENTER("alter_table_phase1");
+ int error= 0;
+ HA_ALTER_FLAGS adding;
+ HA_ALTER_FLAGS dropping;
+
+ adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX;
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+
+ if ((*alter_flags & adding).is_set())
+ {
+ KEY *key_info;
+ KEY *key;
+ uint *idx_p;
+ uint *idx_end_p;
+ KEY_PART_INFO *key_part;
+ KEY_PART_INFO *part_end;
+ key_info= (KEY*) thd->alloc(sizeof(KEY) * alter_info->index_add_count);
+ key= key_info;
+ for (idx_p= alter_info->index_add_buffer,
+ idx_end_p= idx_p + alter_info->index_add_count;
+ idx_p < idx_end_p;
+ idx_p++, key++)
+ {
+ /* Copy the KEY struct. */
+ *key= alter_info->key_info_buffer[*idx_p];
+ /* Fix the key parts. */
+ part_end= key->key_part + key->key_parts;
+ for (key_part= key->key_part; key_part < part_end; key_part++)
+ key_part->field= table->field[key_part->fieldnr];
+ }
+ /* Add the indexes. */
+ if ((error= add_index(table, key_info,
+ alter_info->index_add_count)))
+ {
+ /*
+ Exchange the key_info for the error message. If we exchange
+ key number by key name in the message later, we need correct info.
+ */
+ KEY *save_key_info= table->key_info;
+ table->key_info= key_info;
+ table->file->print_error(error, MYF(0));
+ table->key_info= save_key_info;
+ DBUG_RETURN(error);
+ }
+ }
+
+ if ((*alter_flags & dropping).is_set())
+ {
+ uint *key_numbers;
+ uint *keyno_p;
+ uint *idx_p;
+ uint *idx_end_p;
+ DBUG_PRINT("info", ("Renumbering indexes"));
+ /* The prepare_drop_index() method takes an array of key numbers. */
+ key_numbers= (uint*) thd->alloc(sizeof(uint) * alter_info->index_drop_count);
+ keyno_p= key_numbers;
+ /* Get the number of each key. */
+ for (idx_p= alter_info->index_drop_buffer,
+ idx_end_p= idx_p + alter_info->index_drop_count;
+ idx_p < idx_end_p;
+ idx_p++, keyno_p++)
+ *keyno_p= *idx_p;
+ if ((error= prepare_drop_index(table, key_numbers,
+ alter_info->index_drop_count)))
+ {
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+int
+handler::alter_table_phase2(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ DBUG_ENTER("alter_table_phase2");
+ int error= 0;
+ HA_ALTER_FLAGS dropping;
+
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+
+ if ((*alter_flags & dropping).is_set())
+ {
+ if ((error= final_drop_index(table)))
+ {
+ print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+int
+handler::alter_table_phase3(THD *thd, TABLE *table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ DBUG_ENTER("alter_table_phase3");
+ DBUG_RETURN(0);
+}
+#endif
/**
Rename table: public interface.
@@ -3676,7 +3919,11 @@ int ha_create_table(THD *thd, const char
init_tmp_table_share(thd, &share, db, 0, table_name, path);
if (open_table_def(thd, &share, 0) ||
open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
+#ifndef MCP_WL3749
+ OTM_CREATE))
+#else
TRUE))
+#endif
goto err;
if (update_create_info)
@@ -3745,7 +3992,11 @@ int ha_create_table_from_engine(THD* thd
{
DBUG_RETURN(3);
}
+#ifndef MCP_WL3749
+ if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
+#else
if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, FALSE))
+#endif
{
free_table_share(&share);
DBUG_RETURN(3);
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2011-06-27 09:06:30 +0000
+++ b/sql/handler.h 2011-06-27 10:22:41 +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
@@ -796,6 +859,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,
@@ -1066,6 +1132,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
{
@@ -1981,6 +2059,101 @@ public:
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
+#ifndef MCP_WL3749
+ /* On-line ALTER TABLE interface */
+
+ /**
+ Check if a storage engine supports a particular alter table on-line
+
+ @param altered_table A temporary table show what table is to
+ change to
+ @param create_info Information from the parsing phase about new
+ table properties.
+ @param alter_info Data related to detected changes
+ @param alter_flags Bitmask that shows what will be changed
+ @param table_changes Shows if table layout has changed (for
+ backwards compatibility with
+ check_if_incompatible_data
+
+ @retval HA_ALTER_ERROR Unexpected error
+ @retval HA_ALTER_SUPPORTED_WAIT_LOCK Supported, but requires DDL lock
+ @retval HA_ALTER_SUPPORTED_NO_LOCK Supported
+ @retval HA_ALTER_NOT_SUPPORTED Not supported
+
+ @note
+ The default implementation is implemented to support fast
+ alter table (storage engines that support some changes by
+ just changing the frm file) without any change in the handler
+ implementation.
+ */
+ virtual int check_if_supported_alter(TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
+ HA_ALTER_FLAGS *alter_flags,
+ uint table_changes);
+
+ /**
+ Tell storage engine to prepare for the on-line alter table (pre-alter)
+
+ @param thd The thread handle
+ @param altered_table A temporary table show what table is to
+ change to
+ @param alter_info Storage place for data used during phase1
+ and phase2 and phase3
+ @param alter_flags Bitmask that shows what will be changed
+
+ @retval 0 OK
+ @retval error error code passed from storage engine
+ */
+ virtual int alter_table_phase1(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags);
+
+ /**
+ Tell storage engine to perform the on-line alter table (alter)
+
+ @param thd The thread handle
+ @param altered_table A temporary table show what table is to
+ change to
+ @param create_info Information from the parsing phase about new
+ table properties.
+ @param alter_info Storage place for data used during phase1
+ and phase2 and phase3
+ @param alter_flags Bitmask that shows what will be changed
+
+ @retval 0 OK
+ @retval error error code passed from storage engine
+
+ @note
+ If check_if_supported_alter returns HA_ALTER_SUPPORTED_WAIT_LOCK
+ this call is to be wrapped with a DDL lock. This is currently NOT
+ supported.
+ */
+ virtual int alter_table_phase2(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags);
+
+ /**
+ Tell storage engine that changed frm file is now on disk and table
+ has been re-opened (post-alter)
+
+ @param thd The thread handle
+ @param table The altered table, re-opened
+ @param create_info Information from the parsing phase about new
+ table properties.
+ @param alter_info Storage place for data used during phase1
+ and phase2 and phase3
+ @param alter_flags Bitmask that shows what has been changed
+ */
+ virtual int alter_table_phase3(THD *thd, TABLE *table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags);
+#endif
/**
use_hidden_primary_key() is called in case of an update/delete when
=== modified file 'sql/lex.h'
--- a/sql/lex.h 2011-03-04 09:53:26 +0000
+++ b/sql/lex.h 2011-04-20 12:53:27 +0000
@@ -387,11 +387,17 @@ static SYMBOL symbols[] = {
{ "NULL", SYM(NULL_SYM)},
{ "NUMERIC", SYM(NUMERIC_SYM)},
{ "NVARCHAR", SYM(NVARCHAR_SYM)},
+#ifndef MCP_WL3749
+ { "OFFLINE", SYM(OFFLINE_SYM)},
+#endif
{ "OFFSET", SYM(OFFSET_SYM)},
{ "OLD_PASSWORD", SYM(OLD_PASSWORD)},
{ "ON", SYM(ON)},
{ "ONE", SYM(ONE_SYM)},
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
+#ifndef MCP_WL3749
+ { "ONLINE", SYM(ONLINE_SYM)},
+#endif
{ "OPEN", SYM(OPEN_SYM)},
{ "OPTIMIZE", SYM(OPTIMIZE)},
{ "OPTIONS", SYM(OPTIONS_SYM)},
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2011-05-10 09:48:14 +0000
+++ b/sql/log.cc 2011-05-30 21:13:02 +0000
@@ -4673,7 +4673,10 @@ int THD::binlog_write_table_map(TABLE *t
DBUG_PRINT("enter", ("table: 0x%lx (%s: #%lu)",
(long) table, table->s->table_name.str,
table->s->table_map_id));
-
+ DBUG_PRINT("info", ("is_current_stmt_binlog_format_row() = %s", (is_current_stmt_binlog_format_row())?"true":"false"));
+ DBUG_PRINT("info", ("mysql_bin_log.is_open() = %s", (mysql_bin_log.is_open())?"true":"false"));
+ DBUG_PRINT("info", ("current_stmt_binlog_format %u", current_stmt_binlog_format));
+
/* Pre-conditions */
DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc 2011-03-08 08:41:57 +0000
+++ b/sql/sql_admin.cc 2011-05-30 21:13:02 +0000
@@ -101,7 +101,11 @@ static int prepare_for_repair(THD *thd,
if (share == NULL)
DBUG_RETURN(0); // Can't open frm file
+#ifndef MCP_WL3749
+ if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
+#else
if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
+#endif
{
mysql_mutex_lock(&LOCK_open);
release_table_share(share);
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2011-05-12 08:43:50 +0000
+++ b/sql/sql_base.cc 2011-05-30 21:13:02 +0000
@@ -1322,6 +1322,7 @@ close_all_tables_for_name(THD *thd, TABL
const char *db= key;
const char *table_name= db + share->db.length + 1;
+ DBUG_ENTER("close_all_tables_for_name");
memcpy(key, share->table_cache_key.str, key_length);
mysql_mutex_assert_not_owner(&LOCK_open);
@@ -1332,6 +1333,9 @@ close_all_tables_for_name(THD *thd, TABL
if (table->s->table_cache_key.length == key_length &&
!memcmp(table->s->table_cache_key.str, key, key_length))
{
+#ifndef MCP_WL3749
+ if (table->pos_in_locked_tables)
+#endif
thd->locked_tables_list.unlink_from_list(thd,
table->pos_in_locked_tables,
remove_from_locked_tables);
@@ -1356,6 +1360,7 @@ close_all_tables_for_name(THD *thd, TABL
/* Remove the table share from the cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name,
FALSE);
+ DBUG_VOID_RETURN;
}
@@ -2152,7 +2157,12 @@ void close_temporary(TABLE *table, bool
free_io_cache(table);
closefrm(table, 0);
if (delete_table)
+#ifndef MCP_WL3749
+ rm_temporary_table(table_type, table->s->path.str,
+ table->s->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
+#else
rm_temporary_table(table_type, table->s->path.str);
+#endif
if (free_share)
{
free_table_share(table->s);
@@ -3030,7 +3040,11 @@ retry_share:
HA_TRY_READ_ONLY),
(READ_KEYINFO | COMPUTE_TYPES |
EXTRA_RECORD),
+#ifndef MCP_WL3749
+ thd->open_options, table, OTM_OPEN);
+#else
thd->open_options, table, FALSE);
+#endif
if (error)
{
@@ -3849,7 +3863,11 @@ static bool auto_repair_table(THD *thd,
HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
ha_open_options | HA_OPEN_FOR_REPAIR,
+#ifndef MCP_WL3749
+ entry, OTM_OPEN) || ! entry->file ||
+#else
entry, FALSE) || ! entry->file ||
+#endif
(entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
{
/* Give right error message */
@@ -5793,7 +5811,12 @@ void close_tables_for_reopen(THD *thd, T
TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
const char *table_name,
+#ifndef MCP_WL3749
+ bool add_to_temporary_tables_list,
+ open_table_mode open_mode)
+#else
bool add_to_temporary_tables_list)
+#endif
{
TABLE *tmp_table;
TABLE_SHARE *share;
@@ -5827,11 +5850,25 @@ TABLE *open_table_uncached(THD *thd, con
if (open_table_def(thd, share, 0) ||
open_table_from_share(thd, share, table_name,
+#ifndef MCP_WL3749
+ (open_mode == OTM_ALTER) ? 0 :
+ (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
+ HA_GET_INDEX),
+ (open_mode == OTM_ALTER) ?
+ (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
+ OPEN_FRM_FILE_ONLY)
+ : (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD),
+#else
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
+#endif
ha_open_options,
+#ifndef MCP_WL3749
+ tmp_table, open_mode))
+#else
tmp_table, FALSE))
+#endif
{
/* No need to lock share->mutex as this is not needed for tmp tables */
free_table_share(share);
@@ -5840,8 +5877,14 @@ TABLE *open_table_uncached(THD *thd, con
}
tmp_table->reginfo.lock_type= TL_WRITE; // Simulate locked
+#ifndef MCP_WL3749
+ share->tmp_table= (open_mode == OTM_ALTER) ? TMP_TABLE_FRM_FILE_ONLY :
+ (tmp_table->file->has_transactions() ?
+ TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
+#else
share->tmp_table= (tmp_table->file->has_transactions() ?
TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
+#endif
if (add_to_temporary_tables_list)
{
@@ -5860,20 +5903,40 @@ TABLE *open_table_uncached(THD *thd, con
DBUG_RETURN(tmp_table);
}
-
+#ifndef MCP_WL3749
+bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
+#else
bool rm_temporary_table(handlerton *base, char *path)
+#endif
{
bool error=0;
handler *file;
char *ext;
DBUG_ENTER("rm_temporary_table");
+ DBUG_PRINT("info", ("frm_only %u", frm_only));
strmov(ext= strend(path), reg_ext);
if (mysql_file_delete(key_file_frm, path, MYF(0)))
error=1; /* purecov: inspected */
*ext= 0; // remove extension
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
+#ifndef MCP_WL3749
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (frm_only && file && base == partition_hton)
+ {
+ for (const char **pext=file->bas_ext(); *pext ; pext++)
+ {
+ strmov(ext= strend(path), *pext);
+ if (mysql_file_delete(key_file_partition, path, MYF(0)))
+ error=1;
+ *ext= 0; // remove extension
+ }
+ }
+#endif
+ if (!frm_only && file && file->ha_delete_table(path))
+#else
if (file && file->ha_delete_table(path))
+#endif
{
error=1;
sql_print_warning("Could not remove temporary table: '%s', error: %d",
=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h 2011-03-07 09:08:10 +0000
+++ b/sql/sql_base.h 2011-05-30 21:13:02 +0000
@@ -146,9 +146,17 @@ bool open_new_frm(THD *thd, TABLE_SHARE
bool get_key_map_from_key_list(key_map *map, TABLE *table,
List<String> *index_list);
+#ifndef MCP_WL3749
+enum open_table_mode;
+TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
+ const char *table_name,
+ bool add_to_temporary_tables_list,
+ open_table_mode open_mode= OTM_OPEN);
+#else
TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
const char *table_name,
bool add_to_temporary_tables_list);
+#endif
TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
TABLE *find_write_locked_table(TABLE *list, const char *db,
const char *table_name);
@@ -157,7 +165,11 @@ thr_lock_type read_lock_type_for_table(T
TABLE_LIST *table_list);
my_bool mysql_rm_tmp_tables(void);
+#ifndef MCP_WL3749
+bool rm_temporary_table(handlerton *base, char *path, bool frm_only);
+#else
bool rm_temporary_table(handlerton *base, char *path);
+#endif
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp);
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
=== modified file 'sql/sql_bitmap.h'
--- a/sql/sql_bitmap.h 2010-10-27 11:32:32 +0000
+++ b/sql/sql_bitmap.h 2011-04-20 12:53:27 +0000
@@ -65,12 +65,74 @@ public:
void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); }
void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); }
my_bool is_set(uint n) const { return bitmap_is_set(&map, n); }
+#ifndef MCP_WL3749
+ my_bool is_set() const { return !bitmap_is_clear_all(&map); }
+#endif
my_bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); }
my_bool is_clear_all() const { return bitmap_is_clear_all(&map); }
my_bool is_set_all() const { return bitmap_is_set_all(&map); }
my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); }
my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
+#ifndef MCP_WL3749
+ my_bool operator!=(const Bitmap& map2) const { return !bitmap_cmp(&map, &map2.
+map); }
+ Bitmap operator&=(uint n)
+ {
+ if (bitmap_is_set(&map, n))
+ {
+ bitmap_clear_all(&map);
+ bitmap_set_bit(&map, n);
+ }
+ else
+ bitmap_clear_all(&map);
+ return *this;
+ }
+ Bitmap operator&=(const Bitmap& map2)
+ {
+ bitmap_intersect(&map, &map2.map);
+ return *this;
+ }
+ Bitmap operator&(uint n)
+ {
+ Bitmap bm(*this);
+ bm&= n;
+ return bm;
+ }
+ Bitmap operator&(const Bitmap& map2)
+ {
+ Bitmap bm(*this);
+ bm&= map2;
+ return bm;
+ }
+ Bitmap operator|=(uint n)
+ {
+ bitmap_set_bit(&map, n);
+ return *this;
+ }
+ Bitmap operator|=(const Bitmap& map2)
+ {
+ bitmap_union(&map, &map2.map);
+ }
+ Bitmap operator|(uint n)
+ {
+ Bitmap bm(*this);
+ bm|= n;
+ return bm;
+ }
+ Bitmap operator|(const Bitmap& map2)
+ {
+ Bitmap bm(*this);
+ bm|= map2;
+ return bm;
+ }
+ Bitmap operator~()
+ {
+ Bitmap bm(*this);
+ bitmap_invert(&bm.map);
+ return bm;
+ }
+#endif
char *print(char *buf) const
{
char *s=buf;
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2011-05-10 09:48:14 +0000
+++ b/sql/sql_lex.cc 2011-05-30 21:13:02 +0000
@@ -1634,6 +1634,9 @@ Alter_info::Alter_info(const Alter_info
tablespace_op(rhs.tablespace_op),
partition_names(rhs.partition_names, mem_root),
num_parts(rhs.num_parts),
+#ifndef MCP_WL3749
+ build_method(rhs.build_method),
+#endif
change_level(rhs.change_level),
datetime_field(rhs.datetime_field),
error_if_not_empty(rhs.error_if_not_empty)
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2011-05-10 09:48:14 +0000
+++ b/sql/sql_lex.h 2011-05-30 21:13:02 +0000
@@ -939,6 +939,34 @@ inline bool st_select_lex_unit::is_union
#define ALTER_ADD_COLUMN (1L << 0)
#define ALTER_DROP_COLUMN (1L << 1)
#define ALTER_CHANGE_COLUMN (1L << 2)
+#ifndef MCP_WL3627
+#define ALTER_COLUMN_STORAGE (1L << 3)
+#define ALTER_COLUMN_FORMAT (1L << 4)
+#define ALTER_COLUMN_ORDER (1L << 5)
+#define ALTER_ADD_INDEX (1L << 6)
+#define ALTER_DROP_INDEX (1L << 7)
+#define ALTER_RENAME (1L << 8)
+#define ALTER_ORDER (1L << 9)
+#define ALTER_OPTIONS (1L << 10)
+#define ALTER_COLUMN_DEFAULT (1L << 11)
+#define ALTER_KEYS_ONOFF (1L << 12)
+#define ALTER_STORAGE (1L << 13)
+#define ALTER_ROW_FORMAT (1L << 14)
+#define ALTER_CONVERT (1L << 15)
+#define ALTER_RECREATE (1L << 16)
+#define ALTER_ADD_PARTITION (1L << 17)
+#define ALTER_DROP_PARTITION (1L << 18)
+#define ALTER_COALESCE_PARTITION (1L << 19)
+#define ALTER_REORGANIZE_PARTITION (1L << 20)
+#define ALTER_PARTITION (1L << 21)
+#define ALTER_ADMIN_PARTITION (1L << 22)
+#define ALTER_TABLE_REORG (1L << 23)
+#define ALTER_REBUILD_PARTITION (1L << 24)
+#define ALTER_ALL_PARTITION (1L << 25)
+#define ALTER_REMOVE_PARTITIONING (1L << 26)
+#define ALTER_FOREIGN_KEY (1L << 27)
+#define ALTER_TRUNCATE_PARTITION (1L << 28)
+#else
#define ALTER_ADD_INDEX (1L << 3)
#define ALTER_DROP_INDEX (1L << 4)
#define ALTER_RENAME (1L << 5)
@@ -960,7 +988,8 @@ inline bool st_select_lex_unit::is_union
#define ALTER_REMOVE_PARTITIONING (1L << 21)
#define ALTER_FOREIGN_KEY (1L << 22)
#define ALTER_TRUNCATE_PARTITION (1L << 23)
-
+#endif
+/* #ifdef MCP_WL3749 */
enum enum_alter_table_change_level
{
ALTER_TABLE_METADATA_ONLY= 0,
@@ -968,7 +997,6 @@ enum enum_alter_table_change_level
ALTER_TABLE_INDEX_CHANGED= 2
};
-
/**
Temporary hack to enable a class bound forward declaration
of the enum_alter_table_change_level enumeration. To be
@@ -984,6 +1012,7 @@ public:
void operator = (enum_type v) { value = v; }
operator enum_type () { return value; }
};
+/* #endif */
/**
@@ -1005,7 +1034,12 @@ public:
enum tablespace_op_type tablespace_op;
List<char> partition_names;
uint num_parts;
+#ifndef MCP_WL3749
+ enum ha_build_method build_method;
+#endif
+/* #else */
enum_alter_table_change_level change_level;
+/* #endif */
Create_field *datetime_field;
bool error_if_not_empty;
@@ -1015,7 +1049,11 @@ public:
keys_onoff(LEAVE_AS_IS),
tablespace_op(NO_TABLESPACE_OP),
num_parts(0),
+#ifndef MCP_WL3749
+ build_method(HA_BUILD_DEFAULT),
+#else
change_level(ALTER_TABLE_METADATA_ONLY),
+#endif
datetime_field(NULL),
error_if_not_empty(FALSE)
{}
@@ -1031,7 +1069,12 @@ public:
tablespace_op= NO_TABLESPACE_OP;
num_parts= 0;
partition_names.empty();
+#ifndef MCP_WL3749
+ build_method= HA_BUILD_DEFAULT;
+#endif
+/* #else */
change_level= ALTER_TABLE_METADATA_ONLY;
+/* #endif */
datetime_field= 0;
error_if_not_empty= FALSE;
}
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2011-05-10 09:48:14 +0000
+++ b/sql/sql_partition.cc 2011-05-30 21:13:02 +0000
@@ -4578,7 +4578,12 @@ uint prep_alter_part_table(THD *thd, TAB
char *db,
const char *table_name,
const char *path,
+#ifndef MCP_WL3749
+ TABLE **repartitioned_table,
+ bool *is_fast_alter_partitioning)
+#else
TABLE **fast_alter_table)
+#endif
{
TABLE *new_table= NULL;
DBUG_ENTER("prep_alter_part_table");
@@ -4629,7 +4634,9 @@ uint prep_alter_part_table(THD *thd, TAB
new_table= open_table_uncached(thd, path, db, table_name, 0);
if (!new_table)
DBUG_RETURN(TRUE);
-
+#ifndef MCP_WL3749
+ *repartitioned_table= new_table;
+#endif
/*
This table may be used for copy rows between partitions
and also read/write columns when fixing the partition_info struct.
@@ -4641,8 +4648,18 @@ uint prep_alter_part_table(THD *thd, TAB
if (alter_info->flags & ALTER_TABLE_REORG)
{
uint new_part_no, curr_part_no;
+#ifndef MCP_WL3749
+ /* 'ALTER TABLE t REORG PARTITION' only allowed with auto partition
+ if default partitioning is used */
+ if (tab_part_info->part_type != HASH_PARTITION ||
+ (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION &&
+ !tab_part_info->use_default_num_partitions) ||
+ ((!table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) &&
+ tab_part_info->use_default_num_partitions))
+#else
if (tab_part_info->part_type != HASH_PARTITION ||
tab_part_info->use_default_num_partitions)
+#endif
{
my_error(ER_REORG_NO_PARAM_ERROR, MYF(0));
goto err;
@@ -4656,7 +4673,11 @@ uint prep_alter_part_table(THD *thd, TAB
after the change as before. Thus we can reply ok immediately
without any changes at all.
*/
+#ifndef MCP_WL3749
+ *is_fast_alter_partitioning= TRUE;
+#else
*fast_alter_table= new_table;
+#endif
thd->work_part_info= tab_part_info;
DBUG_RETURN(FALSE);
}
@@ -4681,13 +4702,22 @@ uint prep_alter_part_table(THD *thd, TAB
}
if (!(flags= new_table->file->alter_table_flags(alter_info->flags)))
{
- my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
+ my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
goto err;
}
if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0)
+#ifndef MCP_WL3749
+ *is_fast_alter_partitioning= TRUE;
+#else
*fast_alter_table= new_table;
+#endif
+#ifndef MCP_WL3749
+ DBUG_PRINT("info", ("*is_fast_alter_partitioning: %u flags: 0x%x",
+ *is_fast_alter_partitioning, flags));
+#else
DBUG_PRINT("info", ("*fast_alter_table: %p flags: 0x%x",
*fast_alter_table, flags));
+#endif
if ((alter_info->flags & ALTER_ADD_PARTITION) ||
(alter_info->flags & ALTER_REORGANIZE_PARTITION))
{
@@ -4875,7 +4905,11 @@ adding and copying partitions, the secon
and copying and finally the third line after also dropping the partitions
that are reorganised.
*/
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning &&
+#else
if (*fast_alter_table &&
+#endif
tab_part_info->part_type == HASH_PARTITION)
{
uint part_no= 0, start_part= 1, start_sec_part= 1;
@@ -4980,7 +5014,11 @@ that are reorganised.
do
{
partition_element *part_elem= alt_it++;
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning)
+#else
if (*fast_alter_table)
+#endif
part_elem->part_state= PART_TO_BE_ADDED;
if (tab_part_info->partitions.push_back(part_elem))
{
@@ -4988,6 +5026,9 @@ that are reorganised.
goto err;
}
} while (++part_count < num_new_partitions);
+ DBUG_PRINT("info", ("Setting tab_part_info->num_parts (%u) to %u",
+ tab_part_info->num_parts,
+ tab_part_info->num_parts + num_new_partitions));
tab_part_info->num_parts+= num_new_partitions;
}
/*
@@ -5069,7 +5110,11 @@ that are reorganised.
my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD");
goto err;
}
+#ifndef MCP_WL3749
+ if (!(*is_fast_alter_partitioning))
+#else
if (!(*fast_alter_table))
+#endif
{
new_table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0));
goto err;
@@ -5132,7 +5177,11 @@ state of p1.
uint part_count= 0, start_part= 1, start_sec_part= 1;
uint end_part= 0, end_sec_part= 0;
bool all_parts= TRUE;
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning &&
+#else
if (*fast_alter_table &&
+#endif
tab_part_info->linear_hash_ind)
{
uint upper_2n= tab_part_info->linear_hash_mask + 1;
@@ -5158,14 +5207,22 @@ state of p1.
do
{
partition_element *p_elem= part_it++;
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning &&
+#else
if (*fast_alter_table &&
+#endif
(all_parts ||
(part_count >= start_part && part_count <= end_part) ||
(part_count >= start_sec_part && part_count <= end_sec_part)))
p_elem->part_state= PART_CHANGED;
if (++part_count > num_parts_remain)
{
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning)
+#else
if (*fast_alter_table)
+#endif
p_elem->part_state= PART_REORGED_DROPPED;
else
part_it.remove();
@@ -5290,13 +5347,21 @@ the generated partition syntax in a corr
}
else
tab_max_range= part_elem->range_value;
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning &&
+#else
if (*fast_alter_table &&
+#endif
tab_part_info->temp_partitions.push_back(part_elem))
{
mem_alloc_error(1);
goto err;
}
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning)
+#else
if (*fast_alter_table)
+#endif
part_elem->part_state= PART_TO_BE_REORGED;
if (!found_first)
{
@@ -5316,7 +5381,11 @@ the generated partition syntax in a corr
else
alt_max_range= alt_part_elem->range_value;
+#ifndef MCP_WL3749
+ if (*is_fast_alter_partitioning)
+#else
if (*fast_alter_table)
+#endif
alt_part_elem->part_state= PART_TO_BE_ADDED;
if (alt_part_count == 0)
tab_it.replace(alt_part_elem);
@@ -5553,7 +5622,11 @@ err:
*/
close_temporary(new_table, 1, 0);
}
- *fast_alter_table= NULL;
+#ifndef MCP_WL3749
+ *repartitioned_table= NULL;
+#else
+ *fast_alter_table= NULL;
+#endif
DBUG_RETURN(TRUE);
}
=== modified file 'sql/sql_partition.h'
--- a/sql/sql_partition.h 2010-11-16 12:37:26 +0000
+++ b/sql/sql_partition.h 2011-05-30 21:13:02 +0000
@@ -263,7 +263,12 @@ uint prep_alter_part_table(THD *thd, TAB
char *db,
const char *table_name,
const char *path,
+#ifndef MCP_WL3749
+ TABLE **repartitioned_table,
+ bool *is_fast_alter_partitioning);
+#else
TABLE **fast_alter_table);
+#endif
char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc,
bool show_partition_options,
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2011-05-12 08:43:50 +0000
+++ b/sql/sql_show.cc 2011-05-30 21:13:02 +0000
@@ -3411,7 +3411,11 @@ static int fill_schema_table_from_frm(TH
if (!open_table_from_share(thd, share, table_name->str, 0,
(EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
+#ifndef MCP_WL3749
+ thd->open_options, &tbl, OTM_OPEN))
+#else
thd->open_options, &tbl, FALSE))
+#endif
{
tbl.s= share;
table_list.table= &tbl;
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2011-05-12 08:43:50 +0000
+++ b/sql/sql_table.cc 2011-06-23 10:29:27 +0000
@@ -3854,22 +3854,32 @@ static bool check_if_created_table_can_b
TABLE_SHARE share;
bool result;
+#ifdef MCP_WL3749
/*
It is impossible to open definition of partitioned table without .par file.
*/
if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
return TRUE;
+#endif
init_tmp_table_share(thd, &share, db, 0, table_name, path);
result= (open_table_def(thd, &share, 0) ||
+#ifndef MCP_WL3749
+ open_table_from_share(thd, &share, "", 0, (uint) READ_ALL,
+ 0, &table, OTM_CREATE));
+#else
open_table_from_share(thd, &share, "", 0, (uint) READ_ALL,
0, &table, TRUE));
+#endif
if (! result)
(void) closefrm(&table, 0);
free_table_share(&share);
+#ifdef MCP_WL3749
(void) file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info);
+#endif
+
return result;
}
@@ -4288,10 +4298,13 @@ bool mysql_create_table_no_lock(THD *thd
*/
TABLE *table= open_table_uncached(thd, path, db, table_name, TRUE);
-
if (!table)
{
+#ifndef MCP_WL3749
+ (void) rm_temporary_table(create_info->db_type, path, false);
+#else
(void) rm_temporary_table(create_info->db_type, path);
+#endif
goto err;
}
@@ -4319,6 +4332,18 @@ bool mysql_create_table_no_lock(THD *thd
char frm_name[FN_REFLEN];
strxmov(frm_name, path, reg_ext, NullS);
(void) mysql_file_delete(key_file_frm, frm_name, MYF(0));
+#ifndef MCP_WL3749
+ {
+ char* ext;
+ for (const char **pext=file->bas_ext(); *pext ; pext++)
+ {
+ strmov(ext= strend(path), *pext);
+ if (mysql_file_delete(key_file_partition, path, MYF(0)))
+ DBUG_PRINT("info", ("Failed to delete file %s", ext));
+ *ext= 0; // remove extension
+ }
+ }
+#endif
goto err;
}
}
@@ -4509,6 +4534,24 @@ mysql_rename_table(handlerton *base, con
to_base= lc_to;
}
+#ifndef MCP_WL3749
+ if (flags & FRM_ONLY)
+ {
+ if (rename_file_ext(from,to,reg_ext))
+ error= my_errno;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (file && (base == partition_hton))
+ {
+ for (const char **ext=file->bas_ext(); *ext ; ext++)
+ {
+ if (rename_file_ext(from,to,*ext))
+ error= my_errno;
+ }
+ }
+#endif
+ }
+ else
+#endif
if (!file || !(error=file->ha_rename_table(from_base, to_base)))
{
if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
@@ -4764,6 +4807,7 @@ err:
DBUG_RETURN(-1);
}
+#ifdef MCP_WL3749
/**
@brief Check if both DROP and CREATE are present for an index in ALTER TABLE
@@ -4802,76 +4846,118 @@ is_index_maintenance_unique (TABLE *tabl
}
return FALSE;
}
+#endif /* MCP_WL3749 */
+#ifndef MCP_WL3749
+/**
+ Copy all changes detected by parser to the HA_ALTER_FLAGS
+*/
-/*
- SYNOPSIS
- mysql_compare_tables()
- table The original table.
- alter_info Alter options, fields and keys for the new
- table.
- create_info Create options for the new table.
- order_num Number of order list elements.
- need_copy_table OUT Result of the comparison. Undefined if error.
- Otherwise is one of:
- ALTER_TABLE_METADATA_ONLY No copy needed
- ALTER_TABLE_DATA_CHANGED Data changes,
- copy needed
- ALTER_TABLE_INDEX_CHANGED Index changes,
- copy might be needed
- key_info_buffer OUT An array of KEY structs for new indexes
- index_drop_buffer OUT An array of offsets into table->key_info.
- index_drop_count OUT The number of elements in the array.
- index_add_buffer OUT An array of offsets into key_info_buffer.
- index_add_count OUT The number of elements in the array.
- candidate_key_count OUT The number of candidate keys in original table.
+void setup_ha_alter_flags(TABLE *table,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ uint flags= alter_info->flags;
- DESCRIPTION
- 'table' (first argument) contains information of the original
- table, which includes all corresponding parts that the new
- table has in arguments create_list, key_list and create_info.
+ if (ALTER_ADD_COLUMN & flags)
+ *alter_flags|= HA_ADD_COLUMN;
+ if (ALTER_DROP_COLUMN & flags)
+ *alter_flags|= HA_DROP_COLUMN;
+ if (ALTER_RENAME & flags)
+ *alter_flags|= HA_RENAME_TABLE;
+ if (ALTER_CHANGE_COLUMN & flags)
+ *alter_flags|= HA_CHANGE_COLUMN;
+ if (ALTER_COLUMN_DEFAULT & flags)
+ *alter_flags|= HA_COLUMN_DEFAULT_VALUE;
+ if (ALTER_COLUMN_STORAGE & flags)
+ *alter_flags|= HA_COLUMN_STORAGE;
+ if (ALTER_COLUMN_FORMAT & flags)
+ *alter_flags|= HA_COLUMN_FORMAT;
+ if (ALTER_COLUMN_ORDER & flags)
+ *alter_flags|= HA_ALTER_COLUMN_ORDER;
+ if (ALTER_STORAGE & flags)
+ *alter_flags|= HA_ALTER_STORAGE;
+ if (ALTER_ROW_FORMAT & flags)
+ *alter_flags|= HA_ALTER_ROW_FORMAT;
+ if (ALTER_RECREATE & flags)
+ *alter_flags|= HA_RECREATE;
+ if (ALTER_ADD_PARTITION & flags)
+ *alter_flags|= HA_ADD_PARTITION;
+ if (ALTER_DROP_PARTITION & flags)
+ *alter_flags|= HA_DROP_PARTITION;
+ if (ALTER_COALESCE_PARTITION & flags)
+ *alter_flags|= HA_COALESCE_PARTITION;
+ if (ALTER_REORGANIZE_PARTITION & flags)
+ *alter_flags|= HA_REORGANIZE_PARTITION;
+ if (ALTER_PARTITION & flags)
+ *alter_flags|= HA_ALTER_PARTITION;
+ if (ALTER_FOREIGN_KEY & flags)
+ *alter_flags|= HA_ALTER_FOREIGN_KEY;
+ if (create_info->auto_increment_value !=
+ table->file->stats.auto_increment_value)
+ *alter_flags|= HA_CHANGE_AUTOINCREMENT_VALUE;
+ if (ALTER_TABLE_REORG & flags)
+ *alter_flags|= HA_ALTER_TABLE_REORG;
+}
- By comparing the changes between the original and new table
- we can determine how much it has changed after ALTER TABLE
- and whether we need to make a copy of the table, or just change
- the .frm file.
- If there are no data changes, but index changes, 'index_drop_buffer'
- and/or 'index_add_buffer' are populated with offsets into
- table->key_info or key_info_buffer respectively for the indexes
- that need to be dropped and/or (re-)created.
+/**
+ @param thd Thread
+ @param table The original table.
+ @param alter_info Alter options, fields and keys for the new
+ table.
+ @param create_info Create options for the new table.
+ @param order_num Number of order list elements.
+ @param[out] ha_alter_flags Flags that indicate what will be changed
+ @param[out] ha_alter_info Data structures needed for on-line alter
+ @param[out] table_changes Information about particular change
+
+ First argument 'table' contains information of the original
+ table, which includes all corresponding parts that the new
+ table has in arguments create_list, key_list and create_info.
+
+ By comparing the changes between the original and new table
+ we can determine how much it has changed after ALTER TABLE
+ and whether we need to make a copy of the table, or just change
+ the .frm file.
+
+ Mark any changes detected in the ha_alter_flags.
+
+ If there are no data changes, but index changes, 'index_drop_buffer'
+ and/or 'index_add_buffer' are populated with offsets into
+ table->key_info or key_info_buffer respectively for the indexes
+ that need to be dropped and/or (re-)created.
- RETURN VALUES
- TRUE error
- FALSE success
+ @retval TRUE error
+ @retval FALSE success
*/
+static
bool
-mysql_compare_tables(TABLE *table,
- Alter_info *alter_info,
- HA_CREATE_INFO *create_info,
- uint order_num,
- enum_alter_table_change_level *need_copy_table,
- KEY **key_info_buffer,
- uint **index_drop_buffer, uint *index_drop_count,
- uint **index_add_buffer, uint *index_add_count,
- uint *candidate_key_count)
+compare_tables(THD *thd,
+ TABLE *table,
+ Alter_info *alter_info,
+ HA_CREATE_INFO *create_info,
+ uint order_num,
+ HA_ALTER_FLAGS *alter_flags,
+ HA_ALTER_INFO *ha_alter_info,
+ uint *table_changes)
{
Field **f_ptr, *field;
- uint changes= 0, tmp;
- uint key_count;
+ uint table_changes_local= 0;
List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
Create_field *new_field, *tmp_new_field;
KEY_PART_INFO *key_part;
KEY_PART_INFO *end;
- THD *thd= table->in_use;
/*
Remember if the new definition has new VARCHAR column;
create_info->varchar will be reset in mysql_prepare_create_table.
*/
bool varchar= create_info->varchar;
+ uint candidate_key_count= 0;
bool not_nullable= true;
- DBUG_ENTER("mysql_compare_tables");
+ DBUG_ENTER("compare_tables");
/*
Create a copy of alter_info.
@@ -4882,10 +4968,10 @@ mysql_compare_tables(TABLE *table,
mysql_prepare_create_table. Unfortunately,
mysql_prepare_create_table performs its transformations
"in-place", that is, modifies the argument. Since we would
- like to keep mysql_compare_tables() idempotent (not altering any
+ like to keep compare_tables() idempotent (not altering any
of the arguments) we create a copy of alter_info here and
pass it to mysql_prepare_create_table, then use the result
- to evaluate possibility of in-place ALTER TABLE, and then
+ to evaluate possibility of fast ALTER TABLE, and then
destroy the copy.
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
@@ -4896,16 +4982,33 @@ mysql_compare_tables(TABLE *table,
&tmp_alter_info,
(table->s->tmp_table != NO_TMP_TABLE),
&db_options,
- table->file, key_info_buffer,
- &key_count, 0))
- DBUG_RETURN(1);
+ table->file,
+ &ha_alter_info->key_info_buffer,
+ &ha_alter_info->key_count,
+ /* select_field_count */ 0))
+ DBUG_RETURN(TRUE);
/* Allocate result buffers. */
- if (! (*index_drop_buffer=
- (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
- ! (*index_add_buffer=
- (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
- DBUG_RETURN(1);
-
+ if (! (ha_alter_info->index_drop_buffer=
+ (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
+ ! (ha_alter_info->index_add_buffer=
+ (uint*) thd->alloc(sizeof(uint) *
+ tmp_alter_info.key_list.elements)))
+ DBUG_RETURN(TRUE);
+
+ /*
+ First we setup ha_alter_flags based on what was detected
+ by parser
+ */
+ setup_ha_alter_flags(table, create_info, alter_info, alter_flags);
+
+#ifndef DBUG_OFF
+ {
+ char dbug_string[HA_MAX_ALTER_FLAGS+1];
+ alter_flags->print(dbug_string);
+ DBUG_PRINT("info", ("alter_flags: %s", (char *) dbug_string));
+ }
+#endif
+
/*
Some very basic checks. If number of fields changes, or the
handler, we need to run full ALTER TABLE. In the future
@@ -4926,9 +5029,9 @@ mysql_compare_tables(TABLE *table,
There was a bug prior to mysql-4.0.25. Number of null fields was
calculated incorrectly. As a result frm and data files gets out of
- sync after in-place alter table. There is no way to determine by which
+ sync after fast alter table. There is no way to determine by which
mysql version (in 4.0 and 4.1 branches) table was created, thus we
- disable in-place alter table for all tables created by mysql versions
+ disable fast alter table for all tables created by mysql versions
prior to 5.0 branch.
See BUG#6236.
*/
@@ -4946,12 +5049,32 @@ mysql_compare_tables(TABLE *table,
!table->s->mysql_version ||
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
- DBUG_RETURN(0);
+ *table_changes= IS_EQUAL_NO;
+ /*
+ Check what has changed and set alter_flags
+ */
+ if (table->s->fields < alter_info->create_list.elements)
+ *alter_flags|= HA_ADD_COLUMN;
+ else if (table->s->fields > alter_info->create_list.elements)
+ *alter_flags|= HA_DROP_COLUMN;
+ if (create_info->db_type != table->s->db_type() ||
+ create_info->used_fields & HA_CREATE_USED_ENGINE)
+ *alter_flags|= HA_ALTER_STORAGE_ENGINE;
+ if (create_info->used_fields & HA_CREATE_USED_CHARSET)
+ *alter_flags|= HA_CHANGE_CHARACTER_SET;
+ if (create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)
+ *alter_flags|= HA_SET_DEFAULT_CHARACTER_SET;
+ if (alter_info->flags & ALTER_RECREATE)
+ *alter_flags|= HA_RECREATE;
+ /* TODO check for ADD/DROP FOREIGN KEY */
+ if (alter_info->flags & ALTER_FOREIGN_KEY)
+ *alter_flags|= HA_ALTER_FOREIGN_KEY;
+ if (!table->s->mysql_version ||
+ (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
+ *alter_flags|= HA_ALTER_COLUMN_TYPE;
}
-
/*
- Use transformed info to evaluate possibility of in-place ALTER TABLE
+ Use transformed info to evaluate possibility of fast ALTER TABLE
but use the preserved field to persist modifications.
*/
new_field_it.init(alter_info->create_list);
@@ -4963,7 +5086,7 @@ mysql_compare_tables(TABLE *table,
*/
for (f_ptr= table->field, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++;
- (field= *f_ptr);
+ (new_field && (field= *f_ptr));
f_ptr++, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++)
{
@@ -4971,14 +5094,6 @@ mysql_compare_tables(TABLE *table,
if (!new_field->charset)
new_field->charset= create_info->default_table_charset;
- /* Check that NULL behavior is same for old and new fields */
- if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
- (uint) (field->flags & NOT_NULL_FLAG))
- {
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
- DBUG_RETURN(0);
- }
-
/* Don't pack rows in old tables if the user has requested this. */
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
(tmp_new_field->flags & BLOB_FLAG) ||
@@ -4986,22 +5101,38 @@ mysql_compare_tables(TABLE *table,
create_info->row_type != ROW_TYPE_FIXED))
create_info->table_options|= HA_OPTION_PACK_RECORD;
- /* Check if field was renamed */
- field->flags&= ~FIELD_IS_RENAMED;
- if (my_strcasecmp(system_charset_info,
- field->field_name,
- tmp_new_field->field_name))
- field->flags|= FIELD_IS_RENAMED;
-
- /* Evaluate changes bitmap and send to check_if_incompatible_data() */
- if (!(tmp= field->is_equal(tmp_new_field)))
+ /* Check how fields have been modified */
+ if (alter_info->flags & ALTER_CHANGE_COLUMN)
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
- DBUG_RETURN(0);
+ /* Evaluate changes bitmap and send to check_if_incompatible_data() */
+ if (!(table_changes_local= field->is_equal(tmp_new_field)))
+ *alter_flags|= HA_ALTER_COLUMN_TYPE;
+
+ /* Check if field was renamed */
+ field->flags&= ~FIELD_IS_RENAMED;
+ if (my_strcasecmp(system_charset_info,
+ field->field_name,
+ tmp_new_field->field_name))
+ {
+ field->flags|= FIELD_IS_RENAMED;
+ *alter_flags|= HA_ALTER_COLUMN_NAME;
+ }
+
+ *table_changes&= table_changes_local;
+ if (table_changes_local == IS_EQUAL_PACK_LENGTH)
+ *alter_flags|= HA_ALTER_COLUMN_TYPE;
+
+ /* Check that NULL behavior is same for old and new fields */
+ if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
+ (uint) (field->flags & NOT_NULL_FLAG))
+ {
+ *table_changes= IS_EQUAL_NO;
+ *alter_flags|= HA_ALTER_COLUMN_NULLABLE;
+ }
}
- // Clear indexed marker
+
+ /* Clear indexed marker */
field->flags&= ~FIELD_IN_ADD_INDEX;
- changes|= tmp;
}
/*
@@ -5011,27 +5142,23 @@ mysql_compare_tables(TABLE *table,
KEY *table_key;
KEY *table_key_end= table->key_info + table->s->keys;
KEY *new_key;
- KEY *new_key_end= *key_info_buffer + key_count;
+ KEY *new_key_end=
+ ha_alter_info->key_info_buffer + ha_alter_info->key_count;
DBUG_PRINT("info", ("index count old: %d new: %d",
- table->s->keys, key_count));
- /*
- Step through all keys of the old table and search matching new keys.
- */
- *index_drop_count= 0;
- *index_add_count= 0;
- *candidate_key_count= 0;
+ table->s->keys, ha_alter_info->key_count));
+
+ /* Count all candidate keys. */
+
for (table_key= table->key_info; table_key < table_key_end; table_key++)
{
KEY_PART_INFO *table_part;
KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
- KEY_PART_INFO *new_part;
- /*
+ /*
Check if key is a candidate key, i.e. a unique index with no index
fields nullable, then key is either already primary key or could
be promoted to primary key if the original primary key is dropped.
- Count all candidate keys.
*/
not_nullable= true;
for (table_part= table_key->key_part;
@@ -5041,10 +5168,24 @@ mysql_compare_tables(TABLE *table,
not_nullable= not_nullable && (! table_part->field->maybe_null());
}
if ((table_key->flags & HA_NOSAME) && not_nullable)
- (*candidate_key_count)++;
+ candidate_key_count++;
+ }
+
+ /*
+ Step through all keys of the old table and search matching new keys.
+ */
+ ha_alter_info->index_drop_count= 0;
+ ha_alter_info->index_add_count= 0;
+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ {
+ KEY_PART_INFO *table_part;
+ KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
+ KEY_PART_INFO *new_part;
/* Search a new key with the same name. */
- for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+ for (new_key= ha_alter_info->key_info_buffer;
+ new_key < new_key_end;
+ new_key++)
{
if (! strcmp(table_key->name, new_key->name))
break;
@@ -5052,145 +5193,927 @@ mysql_compare_tables(TABLE *table,
if (new_key >= new_key_end)
{
/* Key not found. Add the offset of the key to the drop buffer. */
- (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+ ha_alter_info->index_drop_buffer
+ [ha_alter_info->index_drop_count++]=
+ table_key - table->key_info;
+ if (table_key->flags & HA_NOSAME)
+ {
+ /* Unique key. Check for "PRIMARY". */
+ if ((uint) (table_key - table->key_info) == table->s->primary_key)
+ {
+ *alter_flags|= HA_DROP_PK_INDEX;
+ candidate_key_count--;
+ }
+ else
+ {
+ bool is_not_null= true;
+
+ *alter_flags|= HA_DROP_UNIQUE_INDEX;
+ key_part= table_key->key_part;
+ end= key_part + table_key->key_parts;
+
+ /*
+ Check if all fields in key are declared
+ NOT NULL and adjust candidate_key_count
+ */
+ for(; key_part != end; key_part++)
+ {
+ is_not_null=
+ (is_not_null &&
+ (!table->field[key_part->fieldnr-1]->maybe_null()));
+ }
+ if (is_not_null)
+ candidate_key_count--;
+ }
+ }
+ else
+ *alter_flags|= HA_DROP_INDEX;
+ *table_changes= IS_EQUAL_NO;
DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
continue;
}
/* Check that the key types are compatible between old and new tables. */
if ((table_key->algorithm != new_key->algorithm) ||
- ((table_key->flags & HA_KEYFLAG_MASK) !=
+ ((table_key->flags & HA_KEYFLAG_MASK) !=
(new_key->flags & HA_KEYFLAG_MASK)) ||
(table_key->key_parts != new_key->key_parts))
+ {
+ if (table_key->flags & HA_NOSAME)
+ {
+ /* Unique key. Check for "PRIMARY". */
+ if ((uint) (table_key - table->key_info) == table->s->primary_key)
+ *alter_flags|= HA_ALTER_PK_INDEX;
+ else
+ *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+ }
+ else
+ *alter_flags|= HA_ALTER_INDEX;
goto index_changed;
+ }
+
+ /*
+ Check that the key parts remain compatible between the old and
+ new tables.
+ */
+ for (table_part= table_key->key_part, new_part= new_key->key_part;
+ table_part < table_part_end;
+ table_part++, new_part++)
+ {
+ /*
+ Key definition has changed if we are using a different field or
+ if the used key part length is different. We know that the fields
+ did not change. Comparing field numbers is sufficient.
+ */
+ if ((table_part->length != new_part->length) ||
+ (table_part->fieldnr - 1 != new_part->fieldnr))
+ {
+ if (table_key->flags & HA_NOSAME)
+ {
+ /* Unique key. Check for "PRIMARY" */
+ if ((uint) (table_key - table->key_info) == table->s->primary_key)
+ *alter_flags|= HA_ALTER_PK_INDEX;
+ else
+ *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+ }
+ else
+ *alter_flags|= HA_ALTER_INDEX;
+ goto index_changed;
+ }
+ }
+ continue;
+
+ index_changed:
+ /* Key modified. Add the offset of the key to both buffers. */
+ ha_alter_info->index_drop_buffer
+ [ha_alter_info->index_drop_count++]=
+ table_key - table->key_info;
+ ha_alter_info->index_add_buffer
+ [ha_alter_info->index_add_count++]=
+ new_key - ha_alter_info->key_info_buffer;
+ key_part= new_key->key_part;
+ end= key_part + new_key->key_parts;
+ for(; key_part != end; key_part++)
+ {
+ /* Mark field to be part of new key */
+ if ((field= table->field[key_part->fieldnr]))
+ field->flags|= FIELD_IN_ADD_INDEX;
+ }
+ *table_changes= IS_EQUAL_NO;
+ DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
+ }
+ /*end of for (; table_key < table_key_end;) */
+
+ /*
+ Step through all keys of the new table and find matching old keys.
+ */
+ for (new_key= ha_alter_info->key_info_buffer;
+ new_key < new_key_end;
+ new_key++)
+ {
+ /* Search an old key with the same name. */
+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ {
+ if (! strcmp(table_key->name, new_key->name))
+ break;
+ }
+ if (table_key >= table_key_end)
+ {
+ bool is_not_null= true;
+ bool no_pk= ((table->s->primary_key == MAX_KEY) ||
+ alter_flags->is_set(HA_DROP_PK_INDEX));
+
+ /* Key not found. Add the offset of the key to the add buffer. */
+ ha_alter_info->index_add_buffer
+ [ha_alter_info->index_add_count++]=
+ new_key - ha_alter_info->key_info_buffer;
+ key_part= new_key->key_part;
+ end= key_part + new_key->key_parts;
+ for(; key_part != end; key_part++)
+ {
+ /*
+ Check if all fields in key are declared
+ NOT NULL
+ */
+ if (key_part->fieldnr < table->s->fields)
+ {
+ /* Mark field to be part of new key */
+ field= table->field[key_part->fieldnr];
+ field->flags|= FIELD_IN_ADD_INDEX;
+ is_not_null= (is_not_null && (!field->maybe_null()));
+ }
+ else
+ {
+ /* Index is defined over a newly added column */
+ List_iterator_fast<Create_field>
+ new_field_it(alter_info->create_list);
+ Create_field *new_field;
+ uint fieldnr;
+
+ for (fieldnr= 0, new_field= new_field_it++;
+ fieldnr != key_part->fieldnr;
+ fieldnr++, new_field= new_field_it++);
+ is_not_null=
+ (is_not_null && (new_field->flags & NOT_NULL_FLAG));
+ }
+ }
+ if (new_key->flags & HA_NOSAME)
+ {
+ /* Unique key. Check for "PRIMARY"
+ or if adding first unique key
+ defined on non-nullable
+ */
+ DBUG_PRINT("info",("no_pk %s, candidate_key_count %u, is_not_null %s", (no_pk)?"yes":"no", candidate_key_count, (is_not_null)?"yes":"no"));
+ if ((!my_strcasecmp(system_charset_info,
+ new_key->name, primary_key_name)) ||
+ (no_pk && candidate_key_count == 0 && is_not_null))
+ *alter_flags|= HA_ADD_PK_INDEX;
+ else
+ *alter_flags|= HA_ADD_UNIQUE_INDEX;
+ }
+ else
+ *alter_flags|= HA_ADD_INDEX;
+ *table_changes= IS_EQUAL_NO;
+ DBUG_PRINT("info", ("index added: '%s'", new_key->name));
+ }
+ }
+#ifndef DBUG_OFF
+ {
+ char dbug_string[HA_MAX_ALTER_FLAGS+1];
+ alter_flags->print(dbug_string);
+ DBUG_PRINT("info", ("alter_flags: %s", (char *) dbug_string));
+ }
+#endif
+
+ DBUG_RETURN(FALSE);
+}
+#else
+/*
+ SYNOPSIS
+ mysql_compare_tables()
+ table The original table.
+ alter_info Alter options, fields and keys for the new
+ table.
+ create_info Create options for the new table.
+ order_num Number of order list elements.
+ need_copy_table OUT Result of the comparison. Undefined if error.
+ Otherwise is one of:
+ ALTER_TABLE_METADATA_ONLY No copy needed
+ ALTER_TABLE_DATA_CHANGED Data changes,
+ copy needed
+ ALTER_TABLE_INDEX_CHANGED Index changes,
+ copy might be needed
+ key_info_buffer OUT An array of KEY structs for new indexes
+ index_drop_buffer OUT An array of offsets into table->key_info.
+ index_drop_count OUT The number of elements in the array.
+ index_add_buffer OUT An array of offsets into key_info_buffer.
+ index_add_count OUT The number of elements in the array.
+ candidate_key_count OUT The number of candidate keys in original table.
+
+ DESCRIPTION
+ 'table' (first argument) contains information of the original
+ table, which includes all corresponding parts that the new
+ table has in arguments create_list, key_list and create_info.
+
+ By comparing the changes between the original and new table
+ we can determine how much it has changed after ALTER TABLE
+ and whether we need to make a copy of the table, or just change
+ the .frm file.
+
+ If there are no data changes, but index changes, 'index_drop_buffer'
+ and/or 'index_add_buffer' are populated with offsets into
+ table->key_info or key_info_buffer respectively for the indexes
+ that need to be dropped and/or (re-)created.
+
+ RETURN VALUES
+ TRUE error
+ FALSE success
+*/
+
+bool
+mysql_compare_tables(TABLE *table,
+ Alter_info *alter_info,
+ HA_CREATE_INFO *create_info,
+ uint order_num,
+ enum_alter_table_change_level *need_copy_table,
+ KEY **key_info_buffer,
+ uint **index_drop_buffer, uint *index_drop_count,
+ uint **index_add_buffer, uint *index_add_count,
+ uint *candidate_key_count)
+{
+ Field **f_ptr, *field;
+ uint changes= 0, tmp;
+ uint key_count;
+ List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
+ Create_field *new_field, *tmp_new_field;
+ KEY_PART_INFO *key_part;
+ KEY_PART_INFO *end;
+ THD *thd= table->in_use;
+ /*
+ Remember if the new definition has new VARCHAR column;
+ create_info->varchar will be reset in mysql_prepare_create_table.
+ */
+ bool varchar= create_info->varchar;
+ bool not_nullable= true;
+ DBUG_ENTER("mysql_compare_tables");
+
+ /*
+ Create a copy of alter_info.
+ To compare the new and old table definitions, we need to "prepare"
+ the new definition - transform it from parser output to a format
+ that describes the final table layout (all column defaults are
+ initialized, duplicate columns are removed). This is done by
+ mysql_prepare_create_table. Unfortunately,
+ mysql_prepare_create_table performs its transformations
+ "in-place", that is, modifies the argument. Since we would
+ like to keep mysql_compare_tables() idempotent (not altering any
+ of the arguments) we create a copy of alter_info here and
+ pass it to mysql_prepare_create_table, then use the result
+ to evaluate possibility of in-place ALTER TABLE, and then
+ destroy the copy.
+ */
+ Alter_info tmp_alter_info(*alter_info, thd->mem_root);
+ uint db_options= 0; /* not used */
+
+ /* Create the prepared information. */
+ if (mysql_prepare_create_table(thd, create_info,
+ &tmp_alter_info,
+ (table->s->tmp_table != NO_TMP_TABLE),
+ &db_options,
+ table->file, key_info_buffer,
+ &key_count, 0))
+ DBUG_RETURN(1);
+ /* Allocate result buffers. */
+ if (! (*index_drop_buffer=
+ (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
+ ! (*index_add_buffer=
+ (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
+ DBUG_RETURN(1);
+
+ /*
+ Some very basic checks. If number of fields changes, or the
+ handler, we need to run full ALTER TABLE. In the future
+ new fields can be added and old dropped without copy, but
+ not yet.
+
+ Test also that engine was not given during ALTER TABLE, or
+ we are force to run regular alter table (copy).
+ E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
+
+ For the following ones we also want to run regular alter table:
+ ALTER TABLE tbl_name ORDER BY ..
+ ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
+
+ At the moment we can't handle altering temporary tables without a copy.
+ We also test if OPTIMIZE TABLE was given and was mapped to alter table.
+ In that case we always do full copy.
+
+ There was a bug prior to mysql-4.0.25. Number of null fields was
+ calculated incorrectly. As a result frm and data files gets out of
+ sync after in-place alter table. There is no way to determine by which
+ mysql version (in 4.0 and 4.1 branches) table was created, thus we
+ disable in-place alter table for all tables created by mysql versions
+ prior to 5.0 branch.
+ See BUG#6236.
+ */
+ if (table->s->fields != alter_info->create_list.elements ||
+ table->s->db_type() != create_info->db_type ||
+ table->s->tmp_table ||
+ create_info->used_fields & HA_CREATE_USED_ENGINE ||
+ create_info->used_fields & HA_CREATE_USED_CHARSET ||
+ create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
+ (table->s->row_type != create_info->row_type) ||
+ create_info->used_fields & HA_CREATE_USED_PACK_KEYS ||
+ create_info->used_fields & HA_CREATE_USED_MAX_ROWS ||
+ (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
+ order_num ||
+ !table->s->mysql_version ||
+ (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
+ {
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_RETURN(0);
+ }
+
+ /*
+ Use transformed info to evaluate possibility of in-place ALTER TABLE
+ but use the preserved field to persist modifications.
+ */
+ new_field_it.init(alter_info->create_list);
+ tmp_new_field_it.init(tmp_alter_info.create_list);
+
+ /*
+ Go through fields and check if the original ones are compatible
+ with new table.
+ */
+ for (f_ptr= table->field, new_field= new_field_it++,
+ tmp_new_field= tmp_new_field_it++;
+ (field= *f_ptr);
+ f_ptr++, new_field= new_field_it++,
+ tmp_new_field= tmp_new_field_it++)
+ {
+ /* Make sure we have at least the default charset in use. */
+ if (!new_field->charset)
+ new_field->charset= create_info->default_table_charset;
+
+ /* Check that NULL behavior is same for old and new fields */
+ if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
+ (uint) (field->flags & NOT_NULL_FLAG))
+ {
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_RETURN(0);
+ }
+
+ /* Don't pack rows in old tables if the user has requested this. */
+ if (create_info->row_type == ROW_TYPE_DYNAMIC ||
+ (tmp_new_field->flags & BLOB_FLAG) ||
+ (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
+ create_info->row_type != ROW_TYPE_FIXED))
+ create_info->table_options|= HA_OPTION_PACK_RECORD;
+
+ /* Check if field was renamed */
+ field->flags&= ~FIELD_IS_RENAMED;
+ if (my_strcasecmp(system_charset_info,
+ field->field_name,
+ tmp_new_field->field_name))
+ field->flags|= FIELD_IS_RENAMED;
+
+ /* Evaluate changes bitmap and send to check_if_incompatible_data() */
+ if (!(tmp= field->is_equal(tmp_new_field)))
+ {
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_RETURN(0);
+ }
+ // Clear indexed marker
+ field->flags&= ~FIELD_IN_ADD_INDEX;
+ changes|= tmp;
+ }
+
+ /*
+ Go through keys and check if the original ones are compatible
+ with new table.
+ */
+ KEY *table_key;
+ KEY *table_key_end= table->key_info + table->s->keys;
+ KEY *new_key;
+ KEY *new_key_end= *key_info_buffer + key_count;
+
+ DBUG_PRINT("info", ("index count old: %d new: %d",
+ table->s->keys, key_count));
+ /*
+ Step through all keys of the old table and search matching new keys.
+ */
+ *index_drop_count= 0;
+ *index_add_count= 0;
+ *candidate_key_count= 0;
+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ {
+ KEY_PART_INFO *table_part;
+ KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
+ KEY_PART_INFO *new_part;
+
+ /*
+ Check if key is a candidate key, i.e. a unique index with no index
+ fields nullable, then key is either already primary key or could
+ be promoted to primary key if the original primary key is dropped.
+ Count all candidate keys.
+ */
+ not_nullable= true;
+ for (table_part= table_key->key_part;
+ table_part < table_part_end;
+ table_part++)
+ {
+ not_nullable= not_nullable && (! table_part->field->maybe_null());
+ }
+ if ((table_key->flags & HA_NOSAME) && not_nullable)
+ (*candidate_key_count)++;
+
+ /* Search a new key with the same name. */
+ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+ {
+ if (! strcmp(table_key->name, new_key->name))
+ break;
+ }
+ if (new_key >= new_key_end)
+ {
+ /* Key not found. Add the offset of the key to the drop buffer. */
+ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+ DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
+ continue;
+ }
+
+ /* Check that the key types are compatible between old and new tables. */
+ if ((table_key->algorithm != new_key->algorithm) ||
+ ((table_key->flags & HA_KEYFLAG_MASK) !=
+ (new_key->flags & HA_KEYFLAG_MASK)) ||
+ (table_key->key_parts != new_key->key_parts))
+ goto index_changed;
+
+ /*
+ Check that the key parts remain compatible between the old and
+ new tables.
+ */
+ for (table_part= table_key->key_part, new_part= new_key->key_part;
+ table_part < table_part_end;
+ table_part++, new_part++)
+ {
+ /*
+ Key definition has changed if we are using a different field or
+ if the used key part length is different. We know that the fields
+ did not change. Comparing field numbers is sufficient.
+ */
+ if ((table_part->length != new_part->length) ||
+ (table_part->fieldnr - 1 != new_part->fieldnr))
+ goto index_changed;
+ }
+ continue;
+
+ index_changed:
+ /* Key modified. Add the offset of the key to both buffers. */
+ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
+ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
+ key_part= new_key->key_part;
+ end= key_part + new_key->key_parts;
+ for(; key_part != end; key_part++)
+ {
+ // Mark field to be part of new key
+ field= table->field[key_part->fieldnr];
+ field->flags|= FIELD_IN_ADD_INDEX;
+ }
+ DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
+ }
+ /*end of for (; table_key < table_key_end;) */
+
+ /*
+ Step through all keys of the new table and find matching old keys.
+ */
+ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+ {
+ /* Search an old key with the same name. */
+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ {
+ if (! strcmp(table_key->name, new_key->name))
+ break;
+ }
+ if (table_key >= table_key_end)
+ {
+ /* Key not found. Add the offset of the key to the add buffer. */
+ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
+ key_part= new_key->key_part;
+ end= key_part + new_key->key_parts;
+ for(; key_part != end; key_part++)
+ {
+ // Mark field to be part of new key
+ field= table->field[key_part->fieldnr];
+ field->flags|= FIELD_IN_ADD_INDEX;
+ }
+ DBUG_PRINT("info", ("index added: '%s'", new_key->name));
+ }
+ }
+
+ /* Check if changes are compatible with current handler without a copy */
+ if (table->file->check_if_incompatible_data(create_info, changes))
+ {
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_RETURN(0);
+ }
+
+ if (*index_drop_count || *index_add_count)
+ {
+ *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
+ DBUG_RETURN(0);
+ }
+
+ *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
+ DBUG_RETURN(0);
+}
+#endif
+
+/*
+ Manages enabling/disabling of indexes for ALTER TABLE
+
+ SYNOPSIS
+ alter_table_manage_keys()
+ table Target table
+ indexes_were_disabled Whether the indexes of the from table
+ were disabled
+ keys_onoff ENABLE | DISABLE | LEAVE_AS_IS
+
+ RETURN VALUES
+ FALSE OK
+ TRUE Error
+*/
+
+static
+bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
+ enum enum_enable_or_disable keys_onoff)
+{
+ int error= 0;
+ DBUG_ENTER("alter_table_manage_keys");
+ DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
+ table, indexes_were_disabled, keys_onoff));
+
+ switch (keys_onoff) {
+ case ENABLE:
+ error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ break;
+ case LEAVE_AS_IS:
+ if (!indexes_were_disabled)
+ break;
+ /* fall-through: disabled indexes */
+ case DISABLE:
+ error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ }
+
+ if (error == HA_ERR_WRONG_COMMAND)
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
+ table->s->table_name.str);
+ error= 0;
+ } else if (error)
+ table->file->print_error(error, MYF(0));
+
+ DBUG_RETURN(error);
+}
+
+#ifndef MCP_WL3749
+int create_temporary_table(THD *thd,
+ TABLE *table,
+ char *new_db,
+ char *tmp_name,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
+ bool db_changed)
+{
+ int error;
+ char index_file[FN_REFLEN], data_file[FN_REFLEN];
+ handlerton *old_db_type, *new_db_type;
+ DBUG_ENTER("create_temporary_table");
+ old_db_type= table->s->db_type();
+ new_db_type= create_info->db_type;
+ /*
+ Handling of symlinked tables:
+ If no rename:
+ Create new data file and index file on the same disk as the
+ old data and index files.
+ Copy data.
+ Rename new data file over old data file and new index file over
+ old index file.
+ Symlinks are not changed.
+
+ If rename:
+ Create new data file and index file on the same disk as the
+ old data and index files. Create also symlinks to point at
+ the new tables.
+ Copy data.
+ At end, rename intermediate tables, and symlinks to intermediate
+ table, to final table name.
+ Remove old table and old symlinks
+
+ If rename is made to another database:
+ Create new tables in new database.
+ Copy data.
+ Remove old table and symlinks.
+ */
+ if (db_changed) // Ignore symlink if db changed
+ {
+ if (create_info->index_file_name)
+ {
+ /* Fix index_file_name to have 'tmp_name' as basename */
+ strmov(index_file, tmp_name);
+ create_info->index_file_name=fn_same(index_file,
+ create_info->index_file_name,
+ 1);
+ }
+ if (create_info->data_file_name)
+ {
+ /* Fix data_file_name to have 'tmp_name' as basename */
+ strmov(data_file, tmp_name);
+ create_info->data_file_name=fn_same(data_file,
+ create_info->data_file_name,
+ 1);
+ }
+ }
+ else
+ create_info->data_file_name=create_info->index_file_name=0;
+
+ DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
+ /*
+ Create a table with a temporary name.
+ With create_info->frm_only == 1 this creates a .frm file only.
+ We don't log the statement, it will be logged later.
+ */
+ tmp_disable_binlog(thd);
+ error= mysql_create_table_no_lock(thd, new_db, tmp_name,
+ create_info,
+ alter_info,
+ 1, 0, NULL);
+ reenable_binlog(thd);
+
+ DBUG_RETURN(error);
+}
+
+/*
+ Create a temporary table that reflects what an alter table operation
+ will accomplish.
+
+ SYNOPSIS
+ create_altered_table()
+ thd Thread handle
+ table The original table
+ create_info Information from the parsing phase about new
+ table properties.
+ alter_info Lists of fields, keys to be changed, added
+ or dropped.
+ db_change Specifies if the table is moved to another database
+ RETURN
+ A temporary table with all changes
+ NULL if error
+ NOTES
+ The temporary table is created without storing it in any storage engine
+ and is opened only to get the table struct and frm file reference.
+*/
+TABLE *create_altered_table(THD *thd,
+ TABLE *table,
+ char *new_db,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info,
+ bool db_change)
+{
+ int error;
+ HA_CREATE_INFO altered_create_info(*create_info);
+ TABLE *altered_table;
+ char tmp_name[80];
+ char path[FN_REFLEN];
+ DBUG_ENTER("create_altered_table");
+
+ my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx_%x",
+ tmp_file_prefix, current_pid,
+ thd->thread_id, thd->tmp_table++);
+ /* Safety fix for InnoDB */
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, tmp_name);
+
+ altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
+ altered_create_info.frm_only= 1;
+ if ((error= create_temporary_table(thd, table, new_db, tmp_name,
+ &altered_create_info,
+ alter_info, db_change)))
+ {
+ DBUG_PRINT("info", ("Error %u while creating temporary table", error));
+ DBUG_RETURN(NULL);
+ };
+
+ build_table_filename(path, sizeof(path), new_db, tmp_name, "",
+ FN_IS_TMP);
+ altered_table= open_table_uncached(thd, path, new_db, tmp_name, TRUE,
+ OTM_ALTER);
+ DBUG_RETURN(altered_table);
+
+ DBUG_RETURN(NULL);
+}
+
+/*
+ Perform a fast or on-line alter table
+
+ SYNOPSIS
+ mysql_fast_or_online_alter_table()
+ thd Thread handle
+ table The original table
+ altered_table A temporary table showing how we will change table
+ create_info Information from the parsing phase about new
+ table properties.
+ alter_info Storage place for data used during different phases
+ ha_alter_flags Bitmask that shows what will be changed
+ keys_onoff Specifies if keys are to be enabled/disabled
+ RETURN
+ 0 OK
+ >0 An error occured during the on-line alter table operation
+ -1 Error when re-opening table
+ NOTES
+ If mysql_alter_table does not need to copy the table, it is
+ either a fast alter table where the storage engine does not
+ need to know about the change, only the frm will change,
+ or the storage engine supports performing the alter table
+ operation directly, on-line without mysql having to copy
+ the table.
+*/
+int mysql_fast_or_online_alter_table(THD *thd,
+ TABLE *table,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *ha_alter_flags,
+ enum enum_enable_or_disable keys_onoff,
+ MDL_request *target_mdl_request)
+{
+ int error= 0;
+ bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER ||
+ table->file->alter_table_flags(0))? true:false;
+ char table_name[FN_REFLEN + 1];
+ char db[FN_REFLEN + 1];
+ char new_name[FN_REFLEN + 1];
+ char new_db[FN_REFLEN + 1];
+ TABLE *t_table;
+ Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
+ TABLE tab;
+ TABLE_LIST tbl;
+ handlerton *db_type= table->s->db_type();
+
+ DBUG_ENTER(" mysql_fast_or_online_alter_table");
+ //VOID(pthread_mutex_lock(&LOCK_open));
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+ {
+ error= my_errno;
+ goto err;
+ }
+ //VOID(pthread_mutex_unlock(&LOCK_open));
+ thd_proc_info(thd, "manage keys");
+ alter_table_manage_keys(table, table->file->indexes_are_disabled(),
+ keys_onoff);
+ error= trans_commit_stmt(thd);
+ if (trans_commit_implicit(thd))
+ error= 1;
+/*
+ error= ha_autocommit_or_rollback(thd, 0);
- /*
- Check that the key parts remain compatible between the old and
- new tables.
+ if (end_active_trans(thd))
+ error=1;
+*/
+ if (error)
+ goto err;
+ if (online)
+ {
+ /*
+ Tell the handler to prepare for the online alter
*/
- for (table_part= table_key->key_part, new_part= new_key->key_part;
- table_part < table_part_end;
- table_part++, new_part++)
+ table->file->ha_prepare_for_alter();
+ if ((error= table->file->alter_table_phase1(thd,
+ altered_table,
+ create_info,
+ alter_info,
+ ha_alter_flags)))
{
- /*
- Key definition has changed if we are using a different field or
- if the used key part length is different. We know that the fields
- did not change. Comparing field numbers is sufficient.
- */
- if ((table_part->length != new_part->length) ||
- (table_part->fieldnr - 1 != new_part->fieldnr))
- goto index_changed;
+ goto err;
}
- continue;
- index_changed:
- /* Key modified. Add the offset of the key to both buffers. */
- (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
- (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
- key_part= new_key->key_part;
- end= key_part + new_key->key_parts;
- for(; key_part != end; key_part++)
+ /*
+ Tell the storage engine to perform the online alter table
+ TODO:
+ if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
+ we need to wrap the next call with a DDL lock.
+ */
+ if ((error= table->file->alter_table_phase2(thd,
+ altered_table,
+ create_info,
+ alter_info,
+ ha_alter_flags)))
{
- // Mark field to be part of new key
- field= table->field[key_part->fieldnr];
- field->flags|= FIELD_IN_ADD_INDEX;
+ goto err;
}
- DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
}
- /*end of for (; table_key < table_key_end;) */
-
/*
- Step through all keys of the new table and find matching old keys.
+ The final .frm file is already created as a temporary file
+ and will be renamed to the original table name.
*/
- for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
- {
- /* Search an old key with the same name. */
- for (table_key= table->key_info; table_key < table_key_end; table_key++)
- {
- if (! strcmp(table_key->name, new_key->name))
- break;
- }
- if (table_key >= table_key_end)
- {
- /* Key not found. Add the offset of the key to the add buffer. */
- (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
- key_part= new_key->key_part;
- end= key_part + new_key->key_parts;
- for(; key_part != end; key_part++)
- {
- // Mark field to be part of new key
- field= table->field[key_part->fieldnr];
- field->flags|= FIELD_IN_ADD_INDEX;
- }
- DBUG_PRINT("info", ("index added: '%s'", new_key->name));
- }
- }
-
- /* Check if changes are compatible with current handler without a copy */
- if (table->file->check_if_incompatible_data(create_info, changes))
+ //VOID(pthread_mutex_lock(&LOCK_open));
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
- DBUG_RETURN(0);
+ error= my_errno;
+ goto err;
}
- if (*index_drop_count || *index_add_count)
+ strcpy(table_name, altered_table->s->table_name.str);
+ strcpy(db, altered_table->s->db.str);
+ strcpy(new_name, table->s->table_name.str);
+ strcpy(new_db, table->s->db.str);
+ close_all_tables_for_name(thd, table->s, FALSE);
+ // new_name != table_name || new_db != db);
+/*
+ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
+ close_data_files_and_morph_locks(thd,
+ table->pos_in_table_list->db,
+ table->pos_in_table_list->table_name);
+*/
+ if (mysql_rename_table(db_type,
+ altered_table->s->db.str,
+ altered_table->s->table_name.str,
+ new_db,
+ new_name, FN_FROM_IS_TMP | FRM_ONLY))
{
- *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
- DBUG_RETURN(0);
+ error= 1;
+ //VOID(pthread_mutex_unlock(&LOCK_open));
+ goto err;
}
+ //broadcast_refresh();
+ //VOID(pthread_mutex_unlock(&LOCK_open));
- *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
- DBUG_RETURN(0);
-}
-
-
+ /*
+ The ALTER TABLE is always in its own transaction.
+ Commit must not be called while LOCK_open is locked. It could call
+ wait_if_global_read_lock(), which could create a deadlock if called
+ with LOCK_open.
+ */
+ error= trans_commit_stmt(thd);
+ if (trans_commit_implicit(thd))
+ error= 1;
/*
- Manages enabling/disabling of indexes for ALTER TABLE
-
- SYNOPSIS
- alter_table_manage_keys()
- table Target table
- indexes_were_disabled Whether the indexes of the from table
- were disabled
- keys_onoff ENABLE | DISABLE | LEAVE_AS_IS
+ error= ha_autocommit_or_rollback(thd, 0);
- RETURN VALUES
- FALSE OK
- TRUE Error
+ if (end_active_trans(thd))
+ error=1;
*/
+ if (error)
+ goto err;
+ if (online)
+ {
+ tbl.table= &tab;
+ tbl.alias= new_name;
+ tbl.table_name= new_name;
+ tbl.table_name_length= strlen(new_name);
+ tbl.db= new_db;
+ tbl.db_length= strlen(new_db);
+ tbl.open_type= OT_TEMPORARY_OR_BASE;
+ tbl.i_s_requested_object= OPEN_TABLE_ONLY;
+ tbl.open_strategy= TABLE_LIST::OPEN_NORMAL;
+ tbl.mdl_request.ticket= target_mdl_request->ticket;
+ if (open_table(thd, &tbl, thd->mem_root, &ot_ctx))
+ {
+ error= -1;
+ goto err;
+ }
+ t_table= tbl.table;
-static
-bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
- enum enum_enable_or_disable keys_onoff)
-{
- int error= 0;
- DBUG_ENTER("alter_table_manage_keys");
- DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
- table, indexes_were_disabled, keys_onoff));
+ /*
+ Tell the handler that the changed frm is on disk and table
+ has been re-opened
+ */
+ if ((error= t_table->file->alter_table_phase3(thd, t_table,
+ create_info,
+ alter_info,
+ ha_alter_flags)))
+ {
+ goto err;
+ }
- switch (keys_onoff) {
- case ENABLE:
- error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
- break;
- case LEAVE_AS_IS:
- if (!indexes_were_disabled)
- break;
- /* fall-through: disabled indexes */
- case DISABLE:
- error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ /*
+ We are going to reopen table down on the road, so we have to restore
+ state of the TABLE object which we used for obtaining of handler
+ object to make it suitable for reopening.
+ */
+ //DBUG_ASSERT(t_table == table);
+ //table->open_placeholder= 1;
+ //VOID(pthread_mutex_lock(&LOCK_open));
+ //close_handle_and_leave_table_as_lock(table);
+ //VOID(pthread_mutex_unlock(&LOCK_open));
}
- if (error == HA_ERR_WRONG_COMMAND)
- {
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- table->s->table_name.str);
- error= 0;
- } else if (error)
- table->file->print_error(error, MYF(0));
-
+ err:
+ if (error)
+ DBUG_PRINT("info", ("Got error %u", error));
DBUG_RETURN(error);
}
+#endif
/**
maximum possible length for certain blob types.
@@ -5690,14 +6613,27 @@ 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;
+ alter_info->change_level= ALTER_TABLE_METADATA_ONLY;
+#else
enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
+#endif
#ifdef WITH_PARTITION_STORAGE_ENGINE
TABLE *table_for_fast_alter_partition= NULL;
+#ifndef MCP_WL3749
+ bool is_fast_alter_partitioning= FALSE;
+#endif
bool partition_changed= FALSE;
#endif
bool need_lock_for_indexes= TRUE;
+#ifdef MCP_WL3749
KEY *key_info_buffer;
uint index_drop_count= 0;
uint *index_drop_buffer= NULL;
@@ -5705,8 +6641,12 @@ bool mysql_alter_table(THD *thd,char *ne
uint *index_add_buffer= NULL;
uint candidate_key_count= 0;
bool no_pk;
+#endif
DBUG_ENTER("mysql_alter_table");
+ DBUG_PRINT("info", ("alter_info->build_method %u", alter_info->build_method));
+ DBUG_PRINT("info", ("thd->lex->alter_info.build_method %u", thd->lex->alter_info.build_method));
+
/*
Check if we attempt to alter mysql.slow_log or
mysql.general_log table and return an error if
@@ -6088,7 +7028,12 @@ bool mysql_alter_table(THD *thd,char *ne
if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
&partition_changed,
db, table_name, path,
+#ifndef MCP_WL3749
+ &table_for_fast_alter_partition,
+ &is_fast_alter_partitioning))
+#else
&table_for_fast_alter_partition))
+#endif
goto err;
#endif
/*
@@ -6103,16 +7048,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
@@ -6121,6 +7066,7 @@ bool mysql_alter_table(THD *thd,char *ne
|| partition_changed
#endif
)
+#ifdef MCP_WL3749
need_copy_table= ALTER_TABLE_DATA_CHANGED;
else
{
@@ -6323,9 +7269,14 @@ bool mysql_alter_table(THD *thd,char *ne
*/
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
create_info->frm_only= 1;
+#endif /* ifdef MCP_WL3749 */
#ifdef WITH_PARTITION_STORAGE_ENGINE
+#ifndef MCP_WL3749
+ if (is_fast_alter_partitioning)
+#else
if (table_for_fast_alter_partition)
+#endif
{
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
create_info, table_list,
@@ -6334,6 +7285,200 @@ bool mysql_alter_table(THD *thd,char *ne
}
#endif
+#ifndef MCP_WL3749
+ if (thd->variables.old_alter_table
+ || (table->s->db_type() != create_info->db_type)
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ || (partition_changed && !(create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
+#endif
+ )
+ {
+ if (alter_info->build_method == HA_BUILD_ONLINE)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
+ goto err;
+ }
+ alter_info->build_method= HA_BUILD_OFFLINE;
+ }
+
+ if (alter_info->build_method != HA_BUILD_OFFLINE)
+ {
+ TABLE *altered_table= 0;
+ HA_ALTER_INFO ha_alter_info;
+ HA_ALTER_FLAGS ha_alter_flags;
+ uint table_changes= IS_EQUAL_YES;
+ /* Check how much the tables differ. */
+ if (compare_tables(thd, table, alter_info,
+ create_info, order_num,
+ &ha_alter_flags,
+ &ha_alter_info,
+ &table_changes))
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ Check if storage engine supports altering the table
+ on-line.
+ */
+
+#ifndef DBUG_OFF
+ {
+ char dbug_string[HA_MAX_ALTER_FLAGS+1];
+ ha_alter_flags.print(dbug_string);
+ DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags: %s",
+ need_copy_table, table_changes,
+ (char *) dbug_string));
+ }
+#endif
+
+ /*
+ If table is not renamed, changed database and
+ some change was detected then check if engine
+ can do the change on-line
+ */
+ if (new_name == table_name && new_db == db &&
+ ha_alter_flags.is_set())
+ {
+ Alter_info tmp_alter_info(*alter_info, thd->mem_root);
+
+ /*
+ If no table rename,
+ check if table can be altered on-line
+ */
+ if (!(altered_table= create_altered_table(thd,
+ table,
+ new_db,
+ create_info,
+ &tmp_alter_info,
+ !strcmp(db, new_db))))
+ goto err;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ /* Copy over new partitioning information */
+ if (partition_changed && table_for_fast_alter_partition)
+ altered_table->part_info= table_for_fast_alter_partition->part_info;
+ else
+ altered_table->part_info= table->part_info;
+#endif
+ switch (table->file->check_if_supported_alter(altered_table,
+ create_info,
+ alter_info,
+ &ha_alter_flags,
+ table_changes)) {
+ case HA_ALTER_SUPPORTED_WAIT_LOCK:
+ case HA_ALTER_SUPPORTED_NO_LOCK:
+ /*
+ @todo: Currently we always acquire an exclusive name
+ lock on the table metadata when performing fast or online
+ ALTER TABLE. In future we may consider this unnecessary,
+ and narrow the scope of the exclusive name lock to only
+ cover manipulation with .frms. Storage engine API
+ call check_if_supported_alter has provision for this
+ already now.
+ */
+ need_copy_table= FALSE;
+ if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY)
+ need_lock_for_indexes= FALSE;
+ break;
+ case HA_ALTER_NOT_SUPPORTED:
+ if (alter_info->build_method == HA_BUILD_ONLINE)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ altered_table->part_info= NULL;;
+#endif
+ close_temporary_table(thd, altered_table, 1, 1);
+ goto err;
+ }
+ need_copy_table= TRUE;
+ break;
+ case HA_ALTER_ERROR:
+ default:
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ altered_table->part_info= NULL;;
+#endif
+ close_temporary_table(thd, altered_table, 1, 1);
+ goto err;
+ }
+#ifndef DBUG_OFF
+ {
+ char dbug_string[HA_MAX_ALTER_FLAGS+1];
+ ha_alter_flags.print(dbug_string);
+ DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags: %s",
+ need_copy_table, table_changes,
+ (char *) dbug_string));
+ }
+#endif
+
+ }
+ /* TODO need to check if changes can be handled as fast ALTER TABLE */
+ if (!altered_table)
+ need_copy_table= TRUE;
+
+ if (!need_copy_table)
+ {
+ error= mysql_fast_or_online_alter_table(thd,
+ table,
+ altered_table,
+ create_info,
+ &ha_alter_info,
+ &ha_alter_flags,
+ alter_info->keys_onoff,
+ &target_mdl_request);
+ if (thd->lock)
+ {
+ if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
+ thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
+ {
+ mysql_unlock_tables(thd, thd->lock);
+ thd->lock=0;
+ }
+ }
+ else
+ {
+ /*
+ If LOCK TABLES list is not empty and contains this table,
+ unlock the table and remove the table from this list.
+ */
+ mysql_lock_remove(thd, thd->lock, table);
+ }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ altered_table->part_info= NULL;;
+#endif
+ close_temporary_table(thd, altered_table, 1, 1);
+ if (!error && thd->stmt_da->is_error())
+ error= thd->stmt_da->sql_errno();
+ if (error)
+ {
+ switch (error) {
+ case(-1):
+ //pthread_mutex_lock(&LOCK_open);
+ goto err_with_mdl;
+ default:
+ goto err;
+ }
+ }
+ else
+ {
+ //pthread_mutex_lock(&LOCK_open);
+ goto end_online;
+ }
+ }
+
+ if (altered_table)
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ altered_table->part_info= NULL;;
+#endif
+ close_temporary_table(thd, altered_table, 1, 1);
+ }
+
+ }
+ if (need_copy_table)
+ {
+#endif /* ifndef MCP_WL3749 */
+
+ /* Open the table so we need to copy the data to it. */
my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
current_pid, thd->thread_id);
/* Safety fix for innodb */
@@ -6405,7 +7550,11 @@ bool mysql_alter_table(THD *thd,char *ne
/* Open the table if we need to copy the data. */
DBUG_PRINT("info", ("need_copy_table: %u", need_copy_table));
+#ifndef MCP_WL3749
+ if (need_copy_table)
+#else
if (need_copy_table != ALTER_TABLE_METADATA_ONLY)
+#endif
{
if (table->s->tmp_table)
{
@@ -6435,7 +7584,6 @@ bool mysql_alter_table(THD *thd,char *ne
copy data for MERGE tables. Only the children have data.
*/
}
-
/* Copy the data if necessary. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
@@ -6482,6 +7630,7 @@ bool mysql_alter_table(THD *thd,char *ne
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+#ifdef MCP_WL3749
/* If we did not need to copy, we might still need to add/drop indexes. */
if (! new_table)
{
@@ -6569,7 +7718,7 @@ bool mysql_alter_table(THD *thd,char *ne
goto err_new_table_cleanup;
}
/*end of if (! new_table) for add/drop index*/
-
+#endif /* ifdef MCP_WL3749 */
if (error)
goto err_new_table_cleanup;
@@ -6664,12 +7813,14 @@ bool mysql_alter_table(THD *thd,char *ne
table is renamed and the SE is also changed, then an intermediate table
is created and the additional call will not take place.
*/
+#ifdef MCP_WL3749
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
DBUG_ASSERT(new_db_type == old_db_type);
/* This type cannot happen in regular ALTER. */
new_db_type= old_db_type= NULL;
}
+#endif /* MCP_WL3749 */
if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
FN_TO_IS_TMP))
{
@@ -6679,9 +7830,11 @@ bool mysql_alter_table(THD *thd,char *ne
else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
new_alias, FN_FROM_IS_TMP) ||
((new_name != table_name || new_db != db) && // we also do rename
+#ifdef MCP_WL3749
(need_copy_table != ALTER_TABLE_METADATA_ONLY ||
mysql_rename_table(save_old_db_type, db, table_name, new_db,
new_alias, NO_FRM_RENAME)) &&
+#endif /* MCP_WL3749 */
Table_triggers_list::change_table_name(thd, db, alias, table_name,
new_db, new_alias)))
{
@@ -6701,7 +7854,7 @@ bool mysql_alter_table(THD *thd,char *ne
/* This shouldn't happen. But let us play it safe. */
goto err_with_mdl;
}
-
+#ifdef MCP_WL3749
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
/*
@@ -6746,6 +7899,13 @@ bool mysql_alter_table(THD *thd,char *ne
if (error)
goto err_with_mdl;
}
+#endif /* MCP_WL3749 */
+
+#ifndef MCP_WL3749
+ } /* else */
+end_online:
+#endif
+
if (thd->locked_tables_list.reopen_tables(thd))
goto err_with_mdl;
=== modified file 'sql/sql_truncate.cc'
--- a/sql/sql_truncate.cc 2011-05-10 09:48:14 +0000
+++ b/sql/sql_truncate.cc 2011-05-30 21:13:02 +0000
@@ -255,6 +255,10 @@ static bool recreate_temporary_table(THD
TABLE_SHARE *share= table->s;
HA_CREATE_INFO create_info;
handlerton *table_type= table->s->db_type();
+#ifndef MCP_WL3749
+ bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
+#endif
+
DBUG_ENTER("recreate_temporary_table");
memset(&create_info, 0, sizeof(create_info));
@@ -279,7 +283,11 @@ static bool recreate_temporary_table(THD
thd->thread_specific_used= TRUE;
}
else
+#ifndef MCP_WL3749
+ rm_temporary_table(table_type, share->path.str, frm_only);
+#else
rm_temporary_table(table_type, share->path.str);
+#endif
free_table_share(share);
my_free(table);
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2011-05-10 09:48:14 +0000
+++ b/sql/sql_yacc.yy 2011-05-30 21:13:02 +0000
@@ -695,7 +695,11 @@ bool setup_select_in_parentheses(LEX *le
return FALSE;
}
+#ifndef MCP_WL3749
+static bool add_create_index_prepare (LEX *lex, Table_ident *table, enum ha_build_method method)
+#else
static bool add_create_index_prepare (LEX *lex, Table_ident *table)
+#endif
{
lex->sql_command= SQLCOM_CREATE_INDEX;
if (!lex->current_select->add_table_to_list(lex->thd, table, NULL,
@@ -705,6 +709,9 @@ static bool add_create_index_prepare (LE
return TRUE;
lex->alter_info.reset();
lex->alter_info.flags= ALTER_ADD_INDEX;
+#ifndef MCP_WL3749
+ lex->alter_info.build_method= method;
+#endif
lex->col_list.empty();
lex->change= NullS;
return FALSE;
@@ -768,6 +775,9 @@ static bool add_create_index (LEX *lex,
sp_head *sphead;
struct p_elem_val *p_elem_value;
enum index_hint_type index_hint;
+#ifndef MCP_WL3749
+ enum ha_build_method build_method;
+#endif
enum enum_filetype filetype;
enum Foreign_key::fk_option m_fk_option;
enum enum_yes_no_unknown m_yes_no_unk;
@@ -1146,11 +1156,17 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token NUM
%token NUMERIC_SYM /* SQL-2003-R */
%token NVARCHAR_SYM
+/* #ifndef MCP_WL3749 */
+%token OFFLINE_SYM
+/* #endif */
%token OFFSET_SYM
%token OLD_PASSWORD
%token ON /* SQL-2003-R */
%token ONE_SHOT_SYM
%token ONE_SYM
+/* #ifndef MCP_WL3749 */
+%token ONLINE_SYM
+/* #endif */
%token OPEN_SYM /* SQL-2003-R */
%token OPTIMIZE
%token OPTIONS_SYM
@@ -1548,6 +1564,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
%type <boolfunc2creator> comp_op
+/* #ifndef MCP_WL3749 */
+%type <build_method> build_method
+/* #endif */
+
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
@@ -2068,36 +2088,80 @@ create:
}
create_table_set_open_action_and_adjust_tables(lex);
}
+/* #ifndef MCP_WL3749 */
+ | CREATE build_method opt_unique INDEX_SYM ident key_alg ON table_ident
+/* #else
| CREATE opt_unique INDEX_SYM ident key_alg ON table_ident
+ #endif
+*/
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index_prepare(Lex, $8, $2))
+/* #else
if (add_create_index_prepare(Lex, $7))
+ #endif
+*/
MYSQL_YYABORT;
}
'(' key_list ')' normal_key_options
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index(Lex, $3, $5))
+/* #else
if (add_create_index(Lex, $2, $4))
- MYSQL_YYABORT;
+ #endif
+*/ MYSQL_YYABORT;
}
+/* #ifndef MCP_WL3749 */
+ | CREATE build_method fulltext INDEX_SYM ident init_key_options ON
+/* #else
| CREATE fulltext INDEX_SYM ident init_key_options ON
+ #endif
+*/
table_ident
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index_prepare(Lex, $8, $2))
+/* #else
if (add_create_index_prepare(Lex, $7))
+ #endif
+*/
MYSQL_YYABORT;
}
'(' key_list ')' fulltext_key_options
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index(Lex, $3, $5))
+/* #else
if (add_create_index(Lex, $2, $4))
+ #endif
+*/
MYSQL_YYABORT;
}
+/* #ifndef MCP_WL3749 */
+ | CREATE build_method spatial INDEX_SYM ident init_key_options ON
+/* #else
| CREATE spatial INDEX_SYM ident init_key_options ON
+ #endif
+*/
table_ident
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index_prepare(Lex, $8, $2))
+/* #else
if (add_create_index_prepare(Lex, $7))
+ #endif
+*/
MYSQL_YYABORT;
}
'(' key_list ')' spatial_key_options
{
+/* #ifndef MCP_WL3749 */
+ if (add_create_index(Lex, $3, $5))
+/* #else
if (add_create_index(Lex, $2, $4))
+ #endif
+*/
MYSQL_YYABORT;
}
| CREATE DATABASE opt_if_not_exists ident
@@ -5115,6 +5179,9 @@ create_table_option:
{
Lex->create_info.row_type= $3;
Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
+#ifndef MCP_WL3749
+ Lex->alter_info.flags|= ALTER_ROW_FORMAT;
+#endif
}
| UNION_SYM opt_equal
{
@@ -5672,7 +5739,13 @@ opt_attribute_list:
attribute:
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
- | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
+ | DEFAULT now_or_signed_literal
+ {
+ Lex->default_value=$2;
+/* #ifndef MCP_WL3749 */
+ Lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #endif */
+ }
| ON UPDATE_SYM NOW_SYM optional_braces
{
Item *item= new (YYTHD->mem_root) Item_func_now_local();
@@ -6192,7 +6265,12 @@ string_list:
*/
alter:
+/* #ifndef MCP_WL3749 */
+ ALTER build_method opt_ignore TABLE_SYM table_ident
+/* #else
ALTER opt_ignore TABLE_SYM table_ident
+ #endif
+*/
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
@@ -6200,7 +6278,12 @@ alter:
lex->name.length= 0;
lex->sql_command= SQLCOM_ALTER_TABLE;
lex->duplicates= DUP_ERROR;
+/* #ifndef MCP_WL3749 */
+ if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
+/* #else
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
+ #endif
+*/
TL_OPTION_UPDATING,
TL_READ_NO_INSERT,
MDL_SHARED_NO_WRITE))
@@ -6215,6 +6298,9 @@ alter:
lex->alter_info.reset();
lex->no_write_to_binlog= 0;
lex->create_info.storage_media= HA_SM_DEFAULT;
+/* #ifndef MCP_WL3749 */
+ lex->alter_info.build_method= $2;
+/* #endif */
lex->create_last_non_select_table= lex->last_table();
DBUG_ASSERT(!lex->m_stmt);
}
@@ -6519,6 +6605,23 @@ alter_commands:
| reorg_partition_rule
;
+/* #ifndef MCP_WL3749 */
+build_method:
+ /* empty */
+ {
+ $$= HA_BUILD_DEFAULT;
+ }
+ | ONLINE_SYM
+ {
+ $$= HA_BUILD_ONLINE;
+ }
+ | OFFLINE_SYM
+ {
+ $$= HA_BUILD_OFFLINE;
+ }
+ ;
+/* #else */
+
remove_partitioning:
REMOVE_SYM PARTITIONING_SYM
{
@@ -6728,7 +6831,12 @@ alter_list_item:
if (ac == NULL)
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac);
+/* #ifndef MCP_WL3749 */
+ lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #else
lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
+ #endif
+*/
}
| ALTER opt_column field_ident DROP DEFAULT
{
@@ -6737,7 +6845,12 @@ alter_list_item:
if (ac == NULL)
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac);
+/* #ifndef MCP_WL3749 */
+ lex->alter_info.flags|= ALTER_COLUMN_DEFAULT;
+/* #else
lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
+ #endif
+*/
}
| RENAME opt_to table_ident
{
@@ -6813,8 +6926,22 @@ opt_restrict:
opt_place:
/* empty */ {}
+/* #ifndef MCP_WL3749 */
+ | AFTER_SYM ident
+ {
+ store_position_for_column($2.str);
+ Lex->alter_info.flags|= ALTER_COLUMN_ORDER;
+ }
+ | FIRST_SYM
+ {
+ store_position_for_column(first_keyword);
+ Lex->alter_info.flags|= ALTER_COLUMN_ORDER;
+ }
+/* #else
| AFTER_SYM ident { store_position_for_column($2.str); }
| FIRST_SYM { store_position_for_column(first_keyword); }
+ #endif
+*/
;
opt_to:
@@ -10257,17 +10384,35 @@ drop:
}
table_list opt_restrict
{}
+/* #ifndef MCP_WL3749 */
+ | DROP build_method INDEX_SYM ident ON table_ident {}
+/* #else
| DROP INDEX_SYM ident ON table_ident {}
+ #endif
+*/
{
LEX *lex=Lex;
+/* #ifndef MCP_WL3749 */
+ Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str);
+/* #else
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
+ #endif
+*/
if (ad == NULL)
MYSQL_YYABORT;
lex->sql_command= SQLCOM_DROP_INDEX;
lex->alter_info.reset();
lex->alter_info.flags= ALTER_DROP_INDEX;
+/* #ifndef MCP_WL3749 */
+ lex->alter_info.build_method= $2;
+/* #endif */
lex->alter_info.drop_list.push_back(ad);
+/* #ifndef MCP_WL3749 */
+ if (!lex->current_select->add_table_to_list(lex->thd, $6, NULL,
+/* #else
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
+ #endif
+*/
TL_OPTION_UPDATING,
TL_READ_NO_INSERT,
MDL_SHARED_NO_WRITE))
@@ -12604,9 +12749,15 @@ keyword_sp:
| NONE_SYM {}
| NVARCHAR_SYM {}
| OFFSET_SYM {}
+/* #ifndef MCP_WL3749 */
+ | OFFLINE_SYM {}
+/* #endif */
| OLD_PASSWORD {}
| ONE_SHOT_SYM {}
| ONE_SYM {}
+/* #ifndef MCP_WL3749 */
+ | ONLINE_SYM {}
+/* #endif */
| PACK_KEYS_SYM {}
| PAGE_SYM {}
| PARTIAL {}
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2011-05-12 08:43:50 +0000
+++ b/sql/table.cc 2011-05-30 21:13:02 +0000
@@ -1824,7 +1824,11 @@ static int open_binary_frm(THD *thd, TAB
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint db_stat, uint prgflag, uint ha_open_flags,
+#ifndef MCP_WL3749
+ TABLE *outparam, open_table_mode open_mode)
+#else
TABLE *outparam, bool is_create_table)
+#endif
{
int error;
uint records, i, bitmap_size;
@@ -1832,8 +1836,17 @@ int open_table_from_share(THD *thd, TABL
uchar *record, *bitmaps;
Field **field_ptr;
DBUG_ENTER("open_table_from_share");
+#ifndef MCP_WL3749
+ DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx, open mode:%s",
+ share->db.str,
+ share->table_name.str,
+ (long) outparam,
+ (open_mode == OTM_OPEN)?"open":
+ ((open_mode == OTM_CREATE)?"create":"alter")));
+#else
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
share->table_name.str, (long) outparam));
+#endif
error= 1;
bzero((char*) outparam, sizeof(*outparam));
@@ -2005,7 +2018,11 @@ int open_table_from_share(THD *thd, TABL
tmp= mysql_unpack_partition(thd, share->partition_info_str,
share->partition_info_str_len,
+#ifndef MCP_WL3749
+ outparam, (open_mode != OTM_OPEN),
+#else
outparam, is_create_table,
+#endif
share->default_part_db_type,
&work_part_info_used);
if (tmp)
@@ -2020,19 +2037,32 @@ int open_table_from_share(THD *thd, TABL
caller's arena depending on work_part_info_used value
*/
if (!work_part_info_used)
+#ifndef MCP_WL3749
+ tmp= fix_partition_func(thd, outparam, (open_mode != OTM_OPEN));
+#else
tmp= fix_partition_func(thd, outparam, is_create_table);
+#endif
thd->stmt_arena= backup_stmt_arena_ptr;
thd->restore_active_arena(&part_func_arena, &backup_arena);
if (!tmp)
{
if (work_part_info_used)
+#ifndef MCP_WL3749
+ tmp= fix_partition_func(thd, outparam, (open_mode != OTM_OPEN));
+#else
tmp= fix_partition_func(thd, outparam, is_create_table);
+#endif
+ outparam->part_info->item_free_list= part_func_arena.free_list;
}
outparam->part_info->item_free_list= part_func_arena.free_list;
partititon_err:
if (tmp)
{
+#ifndef MCP_WL3749
+ if (open_mode == OTM_CREATE)
+#else
if (is_create_table)
+#endif
{
/*
During CREATE/ALTER TABLE it is ok to receive errors here.
@@ -2061,7 +2091,11 @@ partititon_err:
/* The table struct is now initialized; Open the table */
error= 2;
+#ifndef MCP_WL3749
+ if (db_stat && open_mode != OTM_ALTER)
+#else
if (db_stat)
+#endif
{
int ha_err;
if ((ha_err= (outparam->file->
=== modified file 'sql/table.h'
--- a/sql/table.h 2011-06-23 06:59:40 +0000
+++ b/sql/table.h 2011-06-27 10:16:18 +0000
@@ -290,7 +290,11 @@ typedef struct st_grant_info
enum tmp_table_type
{
NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE,
+#ifndef MCP_WL3749
+ INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE, TMP_TABLE_FRM_FILE_ONLY
+#else
INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE
+#endif
};
enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
@@ -2044,9 +2048,24 @@ size_t max_row_length(TABLE *table, cons
void init_mdl_requests(TABLE_LIST *table_list);
+#ifndef MCP_WL3749
+/**
+ Opening modes for open_temporary_table and open_table_from_share
+*/
+enum open_table_mode
+{
+ OTM_OPEN= 0,
+ OTM_CREATE= 1,
+ OTM_ALTER= 2
+};
+#endif
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint db_stat, uint prgflag, uint ha_open_flags,
+#ifndef MCP_WL3749
+ TABLE *outparam, open_table_mode open_mode= OTM_OPEN);
+#else
TABLE *outparam, bool is_create_table);
+#endif
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
uint key_length);
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2011-05-12 08:43:50 +0000
+++ b/sql/unireg.cc 2011-05-30 21:13:02 +0000
@@ -529,11 +529,20 @@ int rea_create_table(THD *thd, const cha
DBUG_ASSERT(*fn_rext(frm_name));
if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES;
+#ifndef MCP_WL3749
+ if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG,
+ create_info))
+ goto err_handler;
+ if (!create_info->frm_only &&
+ ha_create_table(thd, path, db, table_name, create_info, 0))
+ goto err_handler;
+#else
if (!create_info->frm_only &&
(file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG,
create_info) ||
ha_create_table(thd, path, db, table_name, create_info, 0)))
goto err_handler;
+#endif
DBUG_RETURN(0);
err_handler:
No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).| Thread |
|---|
| • bzr commit into mysql-5.5-cluster branch (magnus.blaudd:3375) | magnus.blaudd | 27 Jun |