#At file:///opt/local/work/trunk-runtime/ based on revid:kostja@stripped
3019 Konstantin Osipov 2010-05-20 [merge]
Bug#42643, with review comments.
added:
sql/datadict.cc
sql/datadict.h
sql/sql_truncate.cc
sql/sql_truncate.h
modified:
.bzrignore
libmysqld/CMakeLists.txt
libmysqld/Makefile.am
mysql-test/extra/binlog_tests/binlog_truncate.test
mysql-test/include/mix1.inc
mysql-test/r/innodb_bug38231.result
mysql-test/r/innodb_mysql.result
mysql-test/r/mdl_sync.result
mysql-test/r/partition_innodb_semi_consistent.result
mysql-test/r/truncate.result
mysql-test/suite/binlog/r/binlog_truncate_innodb.result
mysql-test/suite/binlog/r/binlog_truncate_myisam.result
mysql-test/suite/binlog/t/binlog_truncate_innodb.test
mysql-test/suite/binlog/t/binlog_truncate_myisam.test
mysql-test/suite/binlog/t/disabled.def
mysql-test/t/innodb_bug38231.test
mysql-test/t/mdl_sync.test
mysql-test/t/partition_innodb_semi_consistent.test
mysql-test/t/truncate.test
sql/CMakeLists.txt
sql/Makefile.am
sql/sql_base.cc
sql/sql_bitmap.h
sql/sql_delete.cc
sql/sql_delete.h
sql/sql_parse.cc
sql/sql_rename.cc
sql/sql_show.cc
sql/sql_table.cc
sql/sql_view.cc
sql/sql_view.h
sql/table.h
=== modified file '.bzrignore'
--- a/.bzrignore 2010-04-21 19:59:19 +0000
+++ b/.bzrignore 2010-05-20 12:07:41 +0000
@@ -996,6 +996,8 @@ libmysqld/.deps/sql_crypt.Po
libmysqld/.deps/sql_cursor.Po
libmysqld/.deps/sql_db.Po
libmysqld/.deps/sql_delete.Po
+libmysqld/.deps/sql_truncate.Po
+libmysqld/.deps/datadict.Po
libmysqld/.deps/sql_derived.Po
libmysqld/.deps/sql_do.Po
libmysqld/.deps/sql_error.Po
@@ -1172,6 +1174,8 @@ libmysqld/sql_cursor.cc
libmysqld/sql_cursor.h
libmysqld/sql_db.cc
libmysqld/sql_delete.cc
+libmysqld/sql_truncate.cc
+libmysqld/datadict.cc
libmysqld/sql_derived.cc
libmysqld/sql_do.cc
libmysqld/sql_error.cc
@@ -2062,6 +2066,8 @@ sql/.deps/sql_crypt.Po
sql/.deps/sql_cursor.Po
sql/.deps/sql_db.Po
sql/.deps/sql_delete.Po
+sql/.deps/sql_truncate.Po
+sql/.deps/datadict.Po
sql/.deps/sql_derived.Po
sql/.deps/sql_do.Po
sql/.deps/sql_error.Po
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-04-13 15:04:45 +0000
+++ b/libmysqld/CMakeLists.txt 2010-05-20 12:07:41 +0000
@@ -63,7 +63,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc l
../sql/sql_class.cc ../sql/sql_crypt.cc ../sql/sql_cursor.cc
../sql/sql_db.cc ../sql/sql_delete.cc ../sql/sql_derived.cc
../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc
- ../sql/sql_help.cc ../sql/sql_insert.cc
+ ../sql/sql_help.cc ../sql/sql_insert.cc ../sql/datadict.cc
+ ../sql/sql_truncate.cc
../sql/sql_lex.cc ../sql/keycaches.cc
../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc
../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2010-04-13 15:04:45 +0000
+++ b/libmysqld/Makefile.am 2010-05-20 12:07:41 +0000
@@ -63,9 +63,10 @@ sqlsources = derror.cc field.cc field_co
protocol.cc net_serv.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
sql_load.cc discover.cc sql_locale.cc \
- sql_profile.cc \
+ sql_profile.cc sql_truncate.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
+ datadict.cc \
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
scheduler.cc sql_connect.cc sql_parse.cc \
sql_prepare.cc sql_derived.cc sql_rename.cc \
=== modified file 'mysql-test/extra/binlog_tests/binlog_truncate.test'
--- a/mysql-test/extra/binlog_tests/binlog_truncate.test 2009-02-06 16:06:41 +0000
+++ b/mysql-test/extra/binlog_tests/binlog_truncate.test 2010-03-17 20:06:37 +0000
@@ -25,3 +25,44 @@ TRUNCATE TABLE t2;
source include/show_binlog_events.inc;
DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+--echo #
+
+eval CREATE TABLE t1 (a INT) ENGINE=$engine;
+eval CREATE TABLE t2 (a INT) ENGINE=$engine;
+INSERT INTO t1 VALUES (1),(2);
+
+let $binlog_start = query_get_value("SHOW MASTER STATUS", Position, 1);
+if (`select length('$before_truncate') > 0`) {
+ eval $before_truncate;
+}
+
+--echo # Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+
+connect (truncate,localhost,root,,);
+--echo # Connection: truncate
+send TRUNCATE TABLE t1;
+
+connection default;
+--echo # Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COMMIT;
+
+connection truncate;
+--echo # Connection: truncate
+--echo # Reaping TRUNCATE TABLE
+--reap
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t2;
+
+connection default;
+--echo # Connection: default
+
+source include/show_binlog_events.inc;
+disconnect truncate;
+DROP TABLE t1,t2;
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc 2009-12-08 07:39:49 +0000
+++ b/mysql-test/include/mix1.inc 2010-03-17 20:06:37 +0000
@@ -1351,6 +1351,13 @@ connection con1;
SELECT * FROM t1;
ROLLBACK;
+--echo # Switch to connection con2
+connection con2;
+ROLLBACK;
+
+--echo # Switch to connection con1
+connection con1;
+
--echo # 2. test for serialized update:
CREATE TABLE t2 (a INT);
@@ -1435,6 +1442,7 @@ connection con2;
--reap
SELECT * FROM t1;
+--enable_abort_on_error
connection default;
disconnect con1;
disconnect con2;
@@ -1556,3 +1564,32 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
DROP TABLE t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+--echo #
+
+eval CREATE TABLE t1 (a INT) ENGINE=$engine_type;
+INSERT INTO t1 VALUES (1),(2),(3);
+BEGIN;
+SELECT * FROM t1 ORDER BY a;
+--echo # Connection con1
+connect (con1, localhost, root,,);
+--send TRUNCATE TABLE t1;
+--echo # Connection default
+connection default;
+let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='TRUNCATE TABLE t1';
+--source include/wait_condition.inc
+SELECT * FROM t1 ORDER BY a;
+ROLLBACK;
+--echo # Connection con1
+connection con1;
+--echo # Reaping TRUNCATE TABLE
+--reap
+SELECT * FROM t1;
+--echo # Disconnect con1
+disconnect con1;
+--echo # Connection default
+connection default;
+DROP TABLE t1;
=== modified file 'mysql-test/r/innodb_bug38231.result'
--- a/mysql-test/r/innodb_bug38231.result 2008-12-14 21:26:31 +0000
+++ b/mysql-test/r/innodb_bug38231.result 2010-03-17 20:06:37 +0000
@@ -1,11 +1,2 @@
SET storage_engine=InnoDB;
-INSERT INTO bug38231 VALUES (1), (10), (300);
-SET autocommit=0;
-SELECT * FROM bug38231 FOR UPDATE;
-a
-1
-10
-300
-TRUNCATE TABLE bug38231;
-COMMIT;
DROP TABLE bug38231;
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2010-03-24 15:03:44 +0000
+++ b/mysql-test/r/innodb_mysql.result 2010-05-20 12:07:41 +0000
@@ -1590,6 +1590,9 @@ SELECT * FROM t1;
a b
1 12
ROLLBACK;
+# Switch to connection con2
+ROLLBACK;
+# Switch to connection con1
# 2. test for serialized update:
CREATE TABLE t2 (a INT);
TRUNCATE t1;
@@ -1764,6 +1767,33 @@ id select_type table type possible_keys
2 DERIVED t1 index c3,c2 c2 14 NULL 5
DROP TABLE t1;
End of 5.1 tests
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2),(3);
+BEGIN;
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+# Connection con1
+TRUNCATE TABLE t1;;
+# Connection default
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+ROLLBACK;
+# Connection con1
+# Reaping TRUNCATE TABLE
+SELECT * FROM t1;
+a
+# Disconnect con1
+# Connection default
+DROP TABLE t1;
drop table if exists t1, t2, t3;
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
=== modified file 'mysql-test/r/mdl_sync.result'
--- a/mysql-test/r/mdl_sync.result 2010-03-13 10:58:27 +0000
+++ b/mysql-test/r/mdl_sync.result 2010-03-17 20:06:37 +0000
@@ -2381,3 +2381,41 @@ commit;
# Reap ALTER TABLE.
set debug_sync= 'RESET';
drop table t1;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2),(3);
+# Connection: con1
+SET debug_sync='truncate_by_delete SIGNAL parked_truncate WAIT_FOR go_truncate';
+TRUNCATE TABLE t1;
+# Connection: default
+SET debug_sync= 'now WAIT_FOR parked_truncate';
+# Connection: con2
+SET debug_sync='after_open_table_ignore_flush SIGNAL parked_show WAIT_FOR go_show';
+SHOW FIELDS FROM t1;
+# Connection: default
+SET debug_sync= 'now WAIT_FOR parked_show';
+# Connection: con3
+SET debug_sync= 'after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush';
+FLUSH TABLES t1;
+# Connection: default
+SET debug_sync= 'now WAIT_FOR parked_flush';
+SET debug_sync= 'now SIGNAL go_truncate';
+# Connection: con1
+# Reaping...
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Connection: default
+SET debug_sync= 'now SIGNAL go_show';
+# Connection: con2 (SHOW FIELDS FROM t1)
+# Reaping...
+Field Type Null Key Default Extra
+a int(11) YES NULL
+# Connection: default
+SET debug_sync= 'now SIGNAL go_flush';
+# Connection: con3 (FLUSH TABLES t1)
+# Reaping...
+# Connection: default
+SET debug_sync= 'RESET';
+DROP TABLE t1;
=== modified file 'mysql-test/r/partition_innodb_semi_consistent.result'
--- a/mysql-test/r/partition_innodb_semi_consistent.result 2009-12-04 23:02:48 +0000
+++ b/mysql-test/r/partition_innodb_semi_consistent.result 2010-03-17 20:06:37 +0000
@@ -64,6 +64,7 @@ a b
# Switch to connection con2
UPDATE t1 SET b = 21 WHERE a = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ROLLBACK;
# Switch to connection con1
SELECT * FROM t1;
a b
@@ -99,6 +100,7 @@ a b
SELECT * FROM t1;
a b
1 init+con1+con2
+COMMIT;
# Switch to connection con1
# 3. test for updated key column:
TRUNCATE t1;
=== modified file 'mysql-test/r/truncate.result'
--- a/mysql-test/r/truncate.result 2009-12-11 12:24:23 +0000
+++ b/mysql-test/r/truncate.result 2010-03-17 20:06:37 +0000
@@ -99,7 +99,7 @@ LOCK TABLE t1 WRITE;
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
TRUNCATE v1;
-ERROR 42S02: Table 'test.v1' doesn't exist
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
@@ -107,7 +107,7 @@ LOCK TABLE t1 WRITE, t2 WRITE;
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
TRUNCATE v1;
-ERROR 42S02: Table 'test.v1' doesn't exist
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
@@ -117,7 +117,7 @@ c1
1
3
TRUNCATE v1;
-ERROR 42S02: Table 'test.v1' doesn't exist
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
SELECT * FROM v1;
c1
1
@@ -129,7 +129,7 @@ c1
1
3
TRUNCATE v1;
-ERROR 42S02: Table 'test.v1' doesn't exist
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
SELECT * FROM v1;
c1
1
=== modified file 'mysql-test/suite/binlog/r/binlog_truncate_innodb.result'
--- a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result 2009-02-06 16:06:41 +0000
+++ b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result 2010-03-17 20:06:37 +0000
@@ -1,3 +1,6 @@
+SET @old_binlog_format=@@binlog_format;
+SET BINLOG_FORMAT=ROW;
+RESET MASTER;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
@@ -9,6 +12,45 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+# Even though the isolation level might be permissive, truncate
+# table follows a stricter isolation as its locking is based on
+# (exclusive) metadata locks.
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
@@ -22,6 +64,43 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
@@ -35,6 +114,193 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1),(2),(3);
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+**** Truncate of empty table shall be logged
+TRUNCATE TABLE t1;
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+TRUNCATE TABLE t2;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
+DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1),(2),(3);
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+**** Truncate of empty table shall be logged
+TRUNCATE TABLE t1;
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+TRUNCATE TABLE t2;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
+DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+SET BINLOG_FORMAT=STATEMENT;
+RESET MASTER;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1),(2),(3);
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+**** Truncate of empty table shall be logged
+TRUNCATE TABLE t1;
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+TRUNCATE TABLE t2;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
+DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
@@ -48,6 +314,41 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
@@ -61,3 +362,39 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+SET BINLOG_FORMAT=@old_binlog_format;
=== modified file 'mysql-test/suite/binlog/r/binlog_truncate_myisam.result'
--- a/mysql-test/suite/binlog/r/binlog_truncate_myisam.result 2009-02-10 21:26:37 +0000
+++ b/mysql-test/suite/binlog/r/binlog_truncate_myisam.result 2010-03-17 20:06:37 +0000
@@ -1,3 +1,5 @@
+SET @old_binlog_format=@@binlog_format;
+SET BINLOG_FORMAT=ROW;
RESET MASTER;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
@@ -10,3 +12,91 @@ Log_name Pos Event_type Server_id End_lo
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+SET BINLOG_FORMAT=STATEMENT;
+RESET MASTER;
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2),(3);
+**** Truncate of empty table shall be logged
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
+DROP TABLE t1,t2;
+#
+# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+# Connection: default
+BEGIN;
+INSERT INTO t2 SELECT * FROM t1;
+# Connection: truncate
+TRUNCATE TABLE t1;
+# Connection: default
+INSERT INTO t2 SELECT * FROM t1;
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+COMMIT;
+# Connection: truncate
+# Reaping TRUNCATE TABLE
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4
+# Connection: default
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
+DROP TABLE t1,t2;
+SET BINLOG_FORMAT=@old_binlog_format;
=== modified file 'mysql-test/suite/binlog/t/binlog_truncate_innodb.test'
--- a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test 2009-02-10 21:26:37 +0000
+++ b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test 2010-03-17 20:06:37 +0000
@@ -1,20 +1,18 @@
source include/have_log_bin.inc;
source include/have_innodb.inc;
-# It is necessary to reset the master since otherwise the binlog test
-# might show the wrong binary log. The default for SHOW BINLOG EVENTS
-# is to show the first binary log, not the current one (which is
-# actually a better idea).
+let $engine = InnoDB;
+
+SET @old_binlog_format=@@binlog_format;
+SET BINLOG_FORMAT=ROW;
RESET MASTER;
-let $engine = InnoDB;
source extra/binlog_tests/binlog_truncate.test;
-# Under transaction isolation level READ UNCOMMITTED and READ
-# COMMITTED, InnoDB does not permit statement-based replication of
-# row-deleting statement. In these cases, TRUNCATE TABLE should still
-# be replicated as a statement.
+--echo # Even though the isolation level might be permissive, truncate
+--echo # table follows a stricter isolation as its locking is based on
+--echo # (exclusive) metadata locks.
let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
source extra/binlog_tests/binlog_truncate.test;
@@ -27,3 +25,16 @@ source extra/binlog_tests/binlog_truncat
let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
source extra/binlog_tests/binlog_truncate.test;
+
+SET BINLOG_FORMAT=STATEMENT;
+RESET MASTER;
+
+source extra/binlog_tests/binlog_truncate.test;
+
+let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+source extra/binlog_tests/binlog_truncate.test;
+
+let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+source extra/binlog_tests/binlog_truncate.test;
+
+SET BINLOG_FORMAT=@old_binlog_format;
=== modified file 'mysql-test/suite/binlog/t/binlog_truncate_myisam.test'
--- a/mysql-test/suite/binlog/t/binlog_truncate_myisam.test 2009-02-10 21:26:37 +0000
+++ b/mysql-test/suite/binlog/t/binlog_truncate_myisam.test 2010-03-17 20:06:37 +0000
@@ -1,11 +1,17 @@
source include/have_log_bin.inc;
-# It is necessary to reset the master since otherwise the binlog test
-# might show the wrong binary log. The default for SHOW BINLOG EVENTS
-# is to show the first binary log, not the current one (which is
-# actually a better idea).
+SET @old_binlog_format=@@binlog_format;
+let $engine = MyISAM;
+
+SET BINLOG_FORMAT=ROW;
+RESET MASTER;
+
+source extra/binlog_tests/binlog_truncate.test;
+
+SET BINLOG_FORMAT=STATEMENT;
RESET MASTER;
-let $engine = MyISAM;
source extra/binlog_tests/binlog_truncate.test;
+
+SET BINLOG_FORMAT=@old_binlog_format;
=== modified file 'mysql-test/suite/binlog/t/disabled.def'
--- a/mysql-test/suite/binlog/t/disabled.def 2010-01-13 23:27:22 +0000
+++ b/mysql-test/suite/binlog/t/disabled.def 2010-03-17 20:06:37 +0000
@@ -9,6 +9,5 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763
binlog_unsafe : BUG#50312 2010-01-13 lsoares Warnings for unsafe sub-statement not returned to client
=== modified file 'mysql-test/t/innodb_bug38231.test'
--- a/mysql-test/t/innodb_bug38231.test 2009-01-08 12:31:34 +0000
+++ b/mysql-test/t/innodb_bug38231.test 2010-03-17 20:06:37 +0000
@@ -49,27 +49,9 @@ UNLOCK TABLES;
-- disconnect con1
-- disconnect con2
-# test that TRUNCATE works with with row-level locks
-
-- enable_query_log
-- enable_result_log
-INSERT INTO bug38231 VALUES (1), (10), (300);
-
--- connect (con4,localhost,root,,)
-
--- connection con4
-SET autocommit=0;
-SELECT * FROM bug38231 FOR UPDATE;
-
-- connection default
-TRUNCATE TABLE bug38231;
-
--- connection con4
-COMMIT;
-
--- connection default
-
--- disconnect con4
DROP TABLE bug38231;
=== modified file 'mysql-test/t/mdl_sync.test'
--- a/mysql-test/t/mdl_sync.test 2010-03-13 10:58:27 +0000
+++ b/mysql-test/t/mdl_sync.test 2010-03-17 20:06:37 +0000
@@ -3468,6 +3468,83 @@ connection default;
set debug_sync= 'RESET';
drop table t1;
+--echo #
+--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
+--echo #
+
+connect (con1,localhost,root,,test,,);
+connect (con2,localhost,root,,test,,);
+connect (con3,localhost,root,,test,,);
+
+connection default;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2),(3);
+
+--echo # Connection: con1
+connection con1;
+SET debug_sync='truncate_by_delete SIGNAL parked_truncate WAIT_FOR go_truncate';
+send TRUNCATE TABLE t1;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'now WAIT_FOR parked_truncate';
+
+connection con2;
+--echo # Connection: con2
+SET debug_sync='after_open_table_ignore_flush SIGNAL parked_show WAIT_FOR go_show';
+send SHOW FIELDS FROM t1;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'now WAIT_FOR parked_show';
+
+connection con3;
+--echo # Connection: con3
+SET debug_sync= 'after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush';
+send FLUSH TABLES t1;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'now WAIT_FOR parked_flush';
+SET debug_sync= 'now SIGNAL go_truncate';
+
+connection con1;
+--echo # Connection: con1
+--echo # Reaping...
+--error ER_LOCK_DEADLOCK
+reap;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'now SIGNAL go_show';
+
+connection con2;
+--echo # Connection: con2 (SHOW FIELDS FROM t1)
+--echo # Reaping...
+reap;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'now SIGNAL go_flush';
+
+connection con3;
+--echo # Connection: con3 (FLUSH TABLES t1)
+--echo # Reaping...
+reap;
+
+disconnect con1;
+disconnect con2;
+disconnect con3;
+
+connection default;
+--echo # Connection: default
+SET debug_sync= 'RESET';
+DROP TABLE t1;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
=== modified file 'mysql-test/t/partition_innodb_semi_consistent.test'
--- a/mysql-test/t/partition_innodb_semi_consistent.test 2010-02-16 17:23:21 +0000
+++ b/mysql-test/t/partition_innodb_semi_consistent.test 2010-03-17 20:06:37 +0000
@@ -101,6 +101,7 @@ connection con2;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t1 SET b = 21 WHERE a = 1;
--disable_info
+ROLLBACK;
--echo # Switch to connection con1
connection con1;
@@ -150,6 +151,7 @@ SELECT * FROM t1;
connection con2;
--reap
SELECT * FROM t1;
+COMMIT;
--echo # Switch to connection con1
connection con1;
=== modified file 'mysql-test/t/truncate.test'
--- a/mysql-test/t/truncate.test 2009-12-11 12:24:23 +0000
+++ b/mysql-test/t/truncate.test 2010-03-17 20:06:37 +0000
@@ -102,7 +102,7 @@ SELECT * FROM v1;
LOCK TABLE t1 WRITE;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
---error ER_NO_SUCH_TABLE
+--error ER_TABLE_NOT_LOCKED
TRUNCATE v1;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
@@ -111,7 +111,7 @@ UNLOCK TABLES;
LOCK TABLE t1 WRITE, t2 WRITE;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
---error ER_NO_SUCH_TABLE
+--error ER_TABLE_NOT_LOCKED
TRUNCATE v1;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
@@ -119,14 +119,14 @@ UNLOCK TABLES;
#
LOCK TABLE v1 WRITE;
SELECT * FROM v1;
---error ER_NO_SUCH_TABLE
+--error ER_TABLE_NOT_LOCKED
TRUNCATE v1;
SELECT * FROM v1;
UNLOCK TABLES;
#
LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
SELECT * FROM v1;
---error ER_NO_SUCH_TABLE
+--error ER_TABLE_NOT_LOCKED
TRUNCATE v1;
SELECT * FROM v1;
UNLOCK TABLES;
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-04-27 09:37:46 +0000
+++ b/sql/CMakeLists.txt 2010-05-20 12:07:41 +0000
@@ -75,7 +75,7 @@ SET (SQL_SOURCE
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc
sql_signal.cc rpl_handler.cc mdl.cc
- transaction.cc sys_vars.cc
+ transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE})
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-04-13 15:04:45 +0000
+++ b/sql/Makefile.am 2010-05-20 12:07:41 +0000
@@ -39,7 +39,9 @@ DTRACEFILES = filesort.o \
sql_connect.o \
sql_cursor.o \
sql_delete.o \
+ sql_truncate.o \
sql_insert.o \
+ datadict.o \
sql_parse.o \
sql_prepare.o \
sql_select.o \
@@ -56,7 +58,9 @@ DTRACEFILES_DEPEND = filesort.o \
sql_connect.o \
sql_cursor.o \
sql_delete.o \
+ sql_truncate.o \
sql_insert.o \
+ datadict.o \
sql_parse.o \
sql_prepare.o \
sql_select.o \
@@ -121,7 +125,8 @@ noinst_HEADERS = item.h item_func.h item
sql_audit.h \
contributors.h sql_servers.h sql_signal.h records.h \
sql_prepare.h rpl_handler.h replication.h mdl.h \
- sql_plist.h transaction.h sys_vars.h
+ sql_plist.h transaction.h sys_vars.h sql_truncate.h \
+ datadict.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -136,10 +141,10 @@ mysqld_SOURCES = sql_lex.cc sql_handler.
sql_connect.cc scheduler.cc sql_parse.cc \
keycaches.cc set_var.cc sql_yacc.yy sys_vars.cc \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
- sql_profile.cc \
+ datadict.cc sql_profile.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
- procedure.cc sql_test.cc \
+ procedure.cc sql_test.cc sql_truncate.cc \
log.cc init.cc derror.cc sql_acl.cc \
unireg.cc des_key_file.cc \
log_event.cc rpl_record.cc \
=== added file 'sql/datadict.cc'
--- a/sql/datadict.cc 1970-01-01 00:00:00 +0000
+++ b/sql/datadict.cc 2010-05-20 12:07:41 +0000
@@ -0,0 +1,147 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "datadict.h"
+#include "sql_priv.h"
+#include "sql_class.h"
+#include "sql_table.h"
+
+
+/**
+ Check type of .frm if we are not going to parse it.
+
+ @param path path to file
+
+ @retval FRMTYPE_ERROR error
+ @retval FRMTYPE_TABLE table
+ @retval FRMTYPE_VIEW view
+*/
+
+frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
+{
+ File file;
+ uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
+ size_t error;
+ DBUG_ENTER("dd_frm_type");
+
+ *dbt= DB_TYPE_UNKNOWN;
+
+ if ((file= mysql_file_open(key_file_frm,
+ path, O_RDONLY | O_SHARE, MYF(0))) < 0)
+ DBUG_RETURN(FRMTYPE_ERROR);
+ error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
+ mysql_file_close(file, MYF(MY_WME));
+
+ if (error)
+ DBUG_RETURN(FRMTYPE_ERROR);
+ if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header)))
+ DBUG_RETURN(FRMTYPE_VIEW);
+
+ /*
+ This is just a check for DB_TYPE. We'll return default unknown type
+ if the following test is true (arg #3). This should not have effect
+ on return value from this function (default FRMTYPE_TABLE)
+ */
+ if (header[0] != (uchar) 254 || header[1] != 1 ||
+ (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
+ (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
+ DBUG_RETURN(FRMTYPE_TABLE);
+
+ *dbt= (enum legacy_db_type) (uint) *(header + 3);
+ DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
+}
+
+
+/**
+ Given a table name, check if the storage engine for the
+ table referred by this name supports an option 'flag'.
+ Return an error if the table does not exist or is not a
+ base table.
+
+ @pre Any metadata lock on the table.
+
+ @param[in] thd The current session.
+ @param[in] db Table schema.
+ @param[in] table_name Table database.
+ @param[in] flag The option to check.
+ @param[out] yes_no The result. Undefined if error.
+*/
+
+bool dd_check_storage_engine_flag(THD *thd,
+ const char *db, const char *table_name,
+ uint32 flag,
+ bool *yes_no)
+{
+ char path[FN_REFLEN + 1];
+ enum legacy_db_type db_type;
+ handlerton *table_type;
+
+ /* There should be at least some lock on the table. */
+ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
+ MDL_SHARED));
+
+ (void) build_table_filename(path, sizeof(path) - 1, db,
+ table_name, reg_ext, 0);
+
+ dd_frm_type(thd, path, &db_type);
+
+ /* Type is unknown if the object is not found or is not a table. */
+ if (db_type == DB_TYPE_UNKNOWN)
+ {
+ my_error(ER_NO_SUCH_TABLE, MYF(0), db, table_name);
+ return TRUE;
+ }
+ table_type= ha_resolve_by_legacy_type(thd, db_type);
+
+ *yes_no= ha_check_storage_engine_flag(table_type, flag);
+ return FALSE;
+}
+
+
+/*
+ Regenerate a metadata locked table.
+
+ @param thd Thread context.
+ @param db Name of the database to which the table belongs to.
+ @param name Table name.
+
+ @retval FALSE Success.
+ @retval TRUE Error.
+*/
+
+bool dd_recreate_table(THD *thd, const char *db, const char *table_name)
+{
+ bool error= TRUE;
+ HA_CREATE_INFO create_info;
+ char path[FN_REFLEN + 1];
+ DBUG_ENTER("dd_recreate_table");
+
+ /* There should be a exclusive metadata lock on the table. */
+ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
+ MDL_EXCLUSIVE));
+
+ memset(&create_info, 0, sizeof(create_info));
+
+ /* Create a path to the table, but without a extension. */
+ build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0);
+
+ /* Attempt to reconstruct the table. */
+ mysql_mutex_lock(&LOCK_open);
+ error= ha_create_table(thd, path, db, table_name, &create_info, TRUE);
+ mysql_mutex_unlock(&LOCK_open);
+
+ DBUG_RETURN(error);
+}
+
=== added file 'sql/datadict.h'
--- a/sql/datadict.h 1970-01-01 00:00:00 +0000
+++ b/sql/datadict.h 2010-05-20 12:07:41 +0000
@@ -0,0 +1,39 @@
+#ifndef DATADICT_INCLUDED
+#define DATADICT_INCLUDED
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "handler.h"
+/*
+ Data dictionary API.
+*/
+
+enum frm_type_enum
+{
+ FRMTYPE_ERROR= 0,
+ FRMTYPE_TABLE,
+ FRMTYPE_VIEW
+};
+
+
+frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt);
+
+bool dd_check_storage_engine_flag(THD *thd,
+ const char *db, const char *table_name,
+ uint32 flag,
+ bool *yes_no);
+bool dd_recreate_table(THD *thd, const char *db, const char *table_name);
+
+#endif // DATADICT_INCLUDED
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-05-05 22:02:08 +0000
+++ b/sql/sql_base.cc 2010-05-20 12:07:41 +0000
@@ -27,7 +27,7 @@
#include "sql_show.h" // append_identifier
#include "strfunc.h" // find_type
#include "parse_file.h" // sql_parse_prepare, File_parser
-#include "sql_view.h" // mysql_frm_type, mysql_make_view, VIEW_ANY_ACL
+#include "sql_view.h" // mysql_make_view, VIEW_ANY_ACL
#include "sql_parse.h" // check_table_access
#include "sql_insert.h" // kill_delayed_threads
#include "sql_acl.h" // *_ACL, check_grant_all_columns,
@@ -52,6 +52,7 @@
#include <hash.h>
#include "rpl_filter.h"
#include "sql_table.h" // build_table_filename
+#include "datadict.h" // dd_frm_type()
#ifdef __WIN__
#include <io.h>
#endif
@@ -2672,7 +2673,7 @@ bool open_table(THD *thd, TABLE_LIST *ta
during prelocking process (in this case in theory we still
should hold shared metadata lock on it).
*/
- if (mysql_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW)
+ if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW)
{
if (!tdc_open_view(thd, table_list, alias, key, key_length,
mem_root, 0))
=== modified file 'sql/sql_bitmap.h'
--- a/sql/sql_bitmap.h 2010-03-31 14:05:33 +0000
+++ b/sql/sql_bitmap.h 2010-05-20 12:07:41 +0000
@@ -22,6 +22,7 @@
#ifndef SQL_BITMAP_INCLUDED
#define SQL_BITMAP_INCLUDED
+#include <my_sys.h>
#include <my_bitmap.h>
template <uint default_width> class Bitmap
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2010-03-31 14:05:33 +0000
+++ b/sql/sql_delete.cc 2010-05-20 12:07:41 +0000
@@ -14,7 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
- Delete of records and truncate of tables.
+ Delete of records tables.
Multi-table deletes were introduced by Monty and Sinisa
*/
@@ -48,8 +48,7 @@
*/
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- SQL_LIST *order, ha_rows limit, ulonglong options,
- bool reset_auto_increment)
+ SQL_LIST *order, ha_rows limit, ulonglong options)
{
bool will_batch;
int error, loc_error;
@@ -60,18 +59,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *
bool transactional_table, safe_update, const_cond;
bool const_cond_result;
ha_rows deleted= 0;
- bool triggers_applicable;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
THD::killed_state killed_status= THD::NOT_KILLED;
+ THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
DBUG_ENTER("mysql_delete");
bool save_binlog_row_based;
- THD::enum_binlog_query_type query_type=
- thd->lex->sql_command == SQLCOM_TRUNCATE ?
- THD::STMT_QUERY_TYPE :
- THD::ROW_QUERY_TYPE;
-
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
if (!(table= table_list->table))
@@ -130,25 +124,20 @@ bool mysql_delete(THD *thd, TABLE_LIST *
any side-effects (because of triggers), so we can use optimized
handler::delete_all_rows() method.
- We implement fast TRUNCATE for InnoDB even if triggers are
- present. TRUNCATE ignores triggers.
-
We can use delete_all_rows() if and only if:
- We allow new functions (not using option --skip-new), and are
not in safe mode (not using option --safe-mode)
- There is no limit clause
- The condition is constant
- If there is a condition, then it it produces a non-zero value
- - If the current command is DELETE FROM with no where clause
- (i.e., not TRUNCATE) then:
- - We should not be binlogging this statement row-based, and
+ - If the current command is DELETE FROM with no where clause, then:
+ - We should not be binlogging this statement in row-based, and
- there should be no delete triggers associated with the table.
*/
if (!using_limit && const_cond_result &&
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
- (thd->lex->sql_command == SQLCOM_TRUNCATE ||
(!thd->is_current_stmt_binlog_format_row() &&
- !(table->triggers && table->triggers->has_delete_triggers()))))
+ !(table->triggers && table->triggers->has_delete_triggers())))
{
/* Update the table->file->stats.records number */
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@@ -161,7 +150,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
query in row format, so we have to log it in statement format.
*/
query_type= THD::STMT_QUERY_TYPE;
- error= -1; // ok
+ error= -1;
deleted= maybe_deleted;
save_binlog_row_based= thd->is_current_stmt_binlog_format_row();
goto cleanup;
@@ -214,11 +203,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *
if (thd->is_error())
DBUG_RETURN(TRUE);
my_ok(thd, (ha_rows) thd->row_count_func);
- /*
- We don't need to call reset_auto_increment in this case, because
- mysql_truncate always gives a NULL conds argument, hence we never
- get here.
- */
DBUG_RETURN(0); // Nothing to delete
}
@@ -288,12 +272,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
init_ftfuncs(thd, select_lex, 1);
thd_proc_info(thd, "updating");
- /* NOTE: TRUNCATE must not invoke triggers. */
-
- triggers_applicable= table->triggers &&
- thd->lex->sql_command != SQLCOM_TRUNCATE;
-
- if (triggers_applicable &&
+ if (table->triggers &&
table->triggers->has_triggers(TRG_EVENT_DELETE,
TRG_ACTION_AFTER))
{
@@ -323,7 +302,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
if (!(select && select->skip_record())&& ! thd->is_error() )
{
- if (triggers_applicable &&
+ if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
{
@@ -334,7 +313,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
if (!(error= table->file->ha_delete_row(table->record[0])))
{
deleted++;
- if (triggers_applicable &&
+ if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{
@@ -379,21 +358,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_NORMAL);
- if (reset_auto_increment && (error < 0))
- {
- /*
- We're really doing a truncate and need to reset the table's
- auto-increment counter.
- */
- int error2= table->file->ha_reset_auto_increment(0);
-
- if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
- {
- table->file->print_error(error2, MYF(0));
- error= 1;
- }
- }
-
cleanup:
/*
Invalidate the table in the query cache if something changed. This must
@@ -419,29 +383,22 @@ cleanup:
thd->is_current_stmt_binlog_format_row() &&
find_temporary_table(thd, table_list)))
{
- bool const is_trans=
- thd->lex->sql_command == SQLCOM_TRUNCATE ?
- FALSE :
- transactional_table;
-
int errcode= 0;
if (error < 0)
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-
+
/*
[binlog]: If 'handler::delete_all_rows()' was called and the
storage engine does not inject the rows itself, we replicate
statement-based; otherwise, 'ha_delete_row()' was used to
delete specific rows which we might log row-based.
-
- Note that TRUNCATE TABLE is not transactional and should
- therefore be treated as a DDL.
*/
int log_result= thd->binlog_query(query_type,
thd->query(), thd->query_length(),
- is_trans, FALSE, FALSE, errcode);
+ transactional_table, FALSE, FALSE,
+ errcode);
if (log_result)
{
@@ -456,11 +413,7 @@ cleanup:
if (error < 0 ||
(thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
{
- /*
- If a TRUNCATE TABLE was issued, the number of rows should be reported as
- zero since the exact number is unknown.
- */
- thd->row_count_func= reset_auto_increment ? 0 : deleted;
+ thd->row_count_func= deleted;
my_ok(thd, (ha_rows) thd->row_count_func);
DBUG_PRINT("info",("%ld records deleted",(long) deleted));
}
@@ -1064,227 +1017,3 @@ bool multi_delete::send_eof()
return 0;
}
-
-/***************************************************************************
- TRUNCATE TABLE
-****************************************************************************/
-
-/*
- Row-by-row truncation if the engine does not support table recreation.
- Probably a InnoDB table.
-*/
-
-static bool mysql_truncate_by_delete(THD *thd, TABLE_LIST *table_list)
-{
- bool error;
- DBUG_ENTER("mysql_truncate_by_delete");
- table_list->lock_type= TL_WRITE;
- table_list->mdl_request.set_type(MDL_SHARED_WRITE);
- mysql_init_select(thd->lex);
- /* Delete all rows from table */
- error= mysql_delete(thd, table_list, NULL, NULL, HA_POS_ERROR, LL(0), TRUE);
- /*
- All effects of a TRUNCATE TABLE operation are rolled back if a row by row
- deletion fails. Otherwise, operation is automatically committed at the end.
- */
- if (error)
- {
- DBUG_ASSERT(thd->stmt_da->is_error());
- trans_rollback_stmt(thd);
- trans_rollback(thd);
- }
- DBUG_RETURN(error);
-}
-
-
-/*
- Optimize delete of all rows by doing a full generate of the table
- This will work even if the .ISM and .ISD tables are destroyed
-
- dont_send_ok should be set if:
- - We should always wants to generate the table (even if the table type
- normally can't safely do this.
- - We don't want an ok to be sent to the end user.
- - We don't want to log the truncate command
- - If we want to keep exclusive metadata lock on the table (obtained by
- caller) on exit without errors.
-*/
-
-bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
-{
- HA_CREATE_INFO create_info;
- char path[FN_REFLEN + 1];
- TABLE *table;
- bool error= TRUE;
- uint path_length;
- /*
- Is set if we're under LOCK TABLES, and used
- to downgrade the exclusive lock after the
- table was truncated.
- */
- MDL_ticket *mdl_ticket= NULL;
- bool has_mdl_lock= FALSE;
- bool is_temporary_table= false;
- DBUG_ENTER("mysql_truncate");
-
- bzero((char*) &create_info,sizeof(create_info));
-
- /* Remove tables from the HANDLER's hash. */
- mysql_ha_rm_tables(thd, table_list);
-
- /* If it is a temporary table, close and regenerate it */
- if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
- {
- is_temporary_table= true;
- handlerton *table_type= table->s->db_type();
- TABLE_SHARE *share= table->s;
- /* Note that a temporary table cannot be partitioned */
- if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
- goto trunc_by_del;
-
- table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
-
- close_temporary_table(thd, table, 0, 0); // Don't free share
- ha_create_table(thd, share->normalized_path.str,
- share->db.str, share->table_name.str, &create_info, 1);
- // We don't need to call invalidate() because this table is not in cache
- if ((error= (int) !(open_temporary_table(thd, share->path.str,
- share->db.str,
- share->table_name.str, 1))))
- (void) rm_temporary_table(table_type, path);
- else
- thd->thread_specific_used= TRUE;
-
- free_table_share(share);
- my_free((char*) table,MYF(0));
- /*
- If we return here we will not have logged the truncation to the bin log
- and we will not my_ok() to the client.
- */
- goto end;
- }
-
- path_length= build_table_filename(path, sizeof(path) - 1, table_list->db,
- table_list->table_name, reg_ext, 0);
-
- if (!dont_send_ok)
- {
- enum legacy_db_type table_type;
- /*
- FIXME: Code of TRUNCATE breaks the meta-data
- locking protocol since it tries to find out the table storage
- engine and therefore accesses table in some way without holding
- any kind of meta-data lock.
- */
- mysql_frm_type(thd, path, &table_type);
- if (table_type == DB_TYPE_UNKNOWN)
- {
- my_error(ER_NO_SUCH_TABLE, MYF(0),
- table_list->db, table_list->table_name);
- DBUG_RETURN(TRUE);
- }
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- /*
- TODO: Add support for TRUNCATE PARTITION for NDB and other engines
- supporting native partitioning
- */
- if (table_type != DB_TYPE_PARTITION_DB &&
- thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
- {
- my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
- DBUG_RETURN(TRUE);
- }
-#endif
- if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd,
- table_type),
- HTON_CAN_RECREATE) ||
- thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
- goto trunc_by_del;
-
-
- if (thd->locked_tables_mode)
- {
- if (!(table= find_table_for_mdl_upgrade(thd->open_tables, table_list->db,
- table_list->table_name, FALSE)))
- DBUG_RETURN(TRUE);
- mdl_ticket= table->mdl_ticket;
- if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
- goto end;
- close_all_tables_for_name(thd, table->s, FALSE);
- }
- else
- {
- MDL_request mdl_global_request, mdl_request;
- MDL_request_list mdl_requests;
- /*
- Even though we could use the previous execution branch
- here just as well, we must not try to open the table:
- MySQL manual documents that TRUNCATE can be used to
- repair a damaged table, i.e. a table that can not be
- fully "opened". In particular MySQL manual says:
-
- As long as the table format file tbl_name.frm is valid,
- the table can be re-created as an empty table with TRUNCATE
- TABLE, even if the data or index files have become corrupted.
- */
-
- mdl_global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE);
- mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name,
- MDL_EXCLUSIVE);
- mdl_requests.push_front(&mdl_request);
- mdl_requests.push_front(&mdl_global_request);
-
- if (thd->mdl_context.acquire_locks(&mdl_requests,
- thd->variables.lock_wait_timeout))
- DBUG_RETURN(TRUE);
-
- has_mdl_lock= TRUE;
- mysql_mutex_lock(&LOCK_open);
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
- table_list->table_name);
- mysql_mutex_unlock(&LOCK_open);
- }
- }
-
- /*
- Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
- crashes, replacement works. *(path + path_length - reg_ext_length)=
- '\0';
- */
- path[path_length - reg_ext_length] = 0;
- mysql_mutex_lock(&LOCK_open);
- error= ha_create_table(thd, path, table_list->db, table_list->table_name,
- &create_info, 1);
- mysql_mutex_unlock(&LOCK_open);
- query_cache_invalidate3(thd, table_list, 0);
-
-end:
- if (!dont_send_ok)
- {
- if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
- thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
- /*
- Even if we failed to reopen some tables,
- the operation itself succeeded, write the binlog.
- */
- if (!error)
- {
- /* In RBR, the statement is not binlogged if the table is temporary. */
- if (!is_temporary_table || !thd->is_current_stmt_binlog_format_row())
- error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- if (!error)
- my_ok(thd); // This should return record count
- }
- if (has_mdl_lock)
- thd->mdl_context.release_transactional_locks();
- if (mdl_ticket)
- mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
- }
-
- DBUG_PRINT("exit", ("error: %d", error));
- DBUG_RETURN(error);
-
-trunc_by_del:
- error= mysql_truncate_by_delete(thd, table_list);
- DBUG_RETURN(error);
-}
=== modified file 'sql/sql_delete.h'
--- a/sql/sql_delete.h 2010-04-12 13:17:37 +0000
+++ b/sql/sql_delete.h 2010-05-20 12:07:41 +0000
@@ -27,8 +27,6 @@ typedef struct st_sql_list SQL_LIST;
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- SQL_LIST *order, ha_rows rows, ulonglong options,
- bool reset_auto_increment);
-bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok);
+ SQL_LIST *order, ha_rows rows, ulonglong options);
#endif /* SQL_DELETE_INCLUDED */
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-05-05 22:02:08 +0000
+++ b/sql/sql_parse.cc 2010-05-20 12:07:41 +0000
@@ -49,6 +49,7 @@
// mysql_recreate_table,
// mysql_backup_table,
// mysql_restore_table
+#include "sql_truncate.h" // mysql_truncate_table
#include "sql_connect.h" // check_user,
// decrease_user_connections,
// thd_init_client_charset, check_mqh,
@@ -3281,7 +3282,8 @@ end_with_restore_list:
}
if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE))
goto error;
- res= mysql_truncate(thd, first_table, 0);
+ if (! (res= mysql_truncate_table(thd, first_table)))
+ my_ok(thd);
break;
case SQLCOM_DELETE:
{
@@ -3294,8 +3296,7 @@ end_with_restore_list:
MYSQL_DELETE_START(thd->query());
res = mysql_delete(thd, all_tables, select_lex->where,
&select_lex->order_list,
- unit->select_limit_cnt, select_lex->options,
- FALSE);
+ unit->select_limit_cnt, select_lex->options);
MYSQL_DELETE_DONE(res, (ulong) thd->row_count_func);
break;
}
=== modified file 'sql/sql_rename.cc'
--- a/sql/sql_rename.cc 2010-05-05 22:02:08 +0000
+++ b/sql/sql_rename.cc 2010-05-20 12:07:41 +0000
@@ -29,6 +29,7 @@
// start_waiting_global_read_lock
#include "sql_base.h" // tdc_remove_table
#include "sql_handler.h" // mysql_ha_rm_tables
+#include "datadict.h"
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool skip_error);
@@ -283,7 +284,7 @@ do_rename(THD *thd, TABLE_LIST *ren_tabl
build_table_filename(name, sizeof(name) - 1,
ren_table->db, old_alias, reg_ext, 0);
- frm_type= mysql_frm_type(thd, name, &table_type);
+ frm_type= dd_frm_type(thd, name, &table_type);
switch (frm_type)
{
case FRMTYPE_TABLE:
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-28 10:04:11 +0000
+++ b/sql/sql_show.cc 2010-05-20 12:07:41 +0000
@@ -27,7 +27,6 @@
// primary_key_name,
// build_table_filename
#include "repl_failsafe.h"
-#include "sql_view.h" // mysql_frm_type
#include "sql_parse.h" // check_access, check_table_access
#include "sql_partition.h" // partition_element
#include "sql_db.h" // check_db_dir_existence, load_db_opt_by_name
@@ -50,6 +49,8 @@
#endif
#include <my_dir.h>
#include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH
+#include "debug_sync.h"
+#include "datadict.h" // dd_frm_type()
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
@@ -2959,6 +2960,9 @@ fill_schema_show_cols_or_idxs(THD *thd,
(can_deadlock ?
MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)));
lex->sql_command= save_sql_command;
+
+ DEBUG_SYNC(thd, "after_open_table_ignore_flush");
+
/*
get_all_tables() returns 1 on failure and 0 on success thus
return only these and not the result code of ::process_table()
@@ -3018,7 +3022,7 @@ static int fill_schema_table_names(THD *
char path[FN_REFLEN + 1];
(void) build_table_filename(path, sizeof(path) - 1, db_name->str,
table_name->str, reg_ext, 0);
- switch (mysql_frm_type(thd, path, ¬_used)) {
+ switch (dd_frm_type(thd, path, ¬_used)) {
case FRMTYPE_ERROR:
table->field[3]->store(STRING_WITH_LEN("ERROR"),
system_charset_info);
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-05-13 09:24:59 +0000
+++ b/sql/sql_table.cc 2010-05-20 12:07:41 +0000
@@ -27,8 +27,8 @@
// start_waiting_global_read_lock,
// unlock_table_names, mysql_unlock_tables
#include "strfunc.h" // find_type2, find_set
-#include "sql_view.h" // mysql_frm_type, view_checksum, mysql_frm_type
-#include "sql_delete.h" // mysql_truncate
+#include "sql_view.h" // view_checksum
+#include "sql_truncate.h" // regenerate_locked_table
#include "sql_partition.h" // mem_alloc_error,
// generate_partition_syntax,
// partition_info
@@ -52,6 +52,7 @@
#include "sql_show.h"
#include "transaction.h"
#include "keycaches.h"
+#include "datadict.h" // dd_frm_type()
#ifdef __WIN__
#include <io.h>
@@ -2096,7 +2097,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
((access(path, F_OK) &&
ha_create_table_from_engine(thd, db, alias)) ||
(!drop_view &&
- mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
+ dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
{
// Table was not found on disk and table can't be created from engine
if (if_exists)
@@ -2116,7 +2117,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
*/
if (frm_db_type == DB_TYPE_UNKNOWN)
{
- mysql_frm_type(thd, path, &frm_db_type);
+ dd_frm_type(thd, path, &frm_db_type);
DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path));
}
table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
@@ -4557,12 +4558,18 @@ static int prepare_for_repair(THD *thd,
"Failed renaming data file");
goto end;
}
- if (mysql_truncate(thd, table_list, 1))
+ if (dd_recreate_table(thd, table_list->db, table_list->table_name))
{
error= send_check_errmsg(thd, table_list, "repair",
"Failed generating table from .frm file");
goto end;
}
+ /*
+ 'FALSE' for 'using_transactions' means don't postpone
+ invalidation till the end of a transaction, but do it
+ immediately.
+ */
+ query_cache_invalidate3(thd, table_list, FALSE);
if (mysql_file_rename(key_file_misc, tmp, from, MYF(MY_WME)))
{
error= send_check_errmsg(thd, table_list, "repair",
@@ -6535,7 +6542,7 @@ bool mysql_alter_table(THD *thd,char *ne
into the main table list, like open_tables does).
This code is wrong and will be removed, please do not copy.
*/
- frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
+ frm_type= dd_frm_type(thd, new_name_buff, &table_type);
/* Rename a view */
/* Sic: there is a race here */
if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME))
=== added file 'sql/sql_truncate.cc'
--- a/sql/sql_truncate.cc 1970-01-01 00:00:00 +0000
+++ b/sql/sql_truncate.cc 2010-05-20 12:07:41 +0000
@@ -0,0 +1,403 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "sql_truncate.h"
+#include "sql_priv.h"
+#include "transaction.h"
+#include "debug_sync.h"
+#include "records.h" // READ_RECORD
+#include "table.h" // TABLE
+#include "sql_class.h" // THD
+#include "sql_base.h" // open_and_lock_tables
+#include "sql_table.h" // write_bin_log
+#include "sql_handler.h" // mysql_ha_rm_tables
+#include "datadict.h" // dd_recreate_table()
+#include "lock.h" // MYSQL_OPEN_TEMPORARY_ONLY
+
+
+/*
+ Delete all rows of a locked table.
+
+ @param thd Thread context.
+ @param table_list Table list element for the table.
+ @param rows_deleted Whether rows might have been deleted.
+
+ @retval FALSE Success.
+ @retval TRUE Error.
+*/
+
+static bool
+delete_all_rows(THD *thd, TABLE *table)
+{
+ int error;
+ READ_RECORD info;
+ bool is_bulk_delete;
+ bool some_rows_deleted= FALSE;
+ bool save_binlog_row_based= thd->is_current_stmt_binlog_format_row();
+ DBUG_ENTER("delete_all_rows");
+
+ /* Replication of truncate table must be statement based. */
+ thd->clear_current_stmt_binlog_format_row();
+ /*
+ Attempt to delete all rows in the table.
+ If it is unsupported, switch to row by row deletion.
+ */
+ if (! (error= table->file->ha_delete_all_rows()))
+ goto end;
+ if (error != HA_ERR_WRONG_COMMAND)
+ {
+ /*
+ If a transactional engine fails in the middle of
+ deletion, we expect it to be able to roll it back.
+ Some reasons for the engine to fail would be media
+ failure or corrupted data dictionary (i.e. in case of
+ a partitioned table). We have sufficiently strong
+ metadata locks to rule out any potential deadlocks.
+
+ If a non-transactional engine fails here (that would
+ not be MyISAM, since MyISAM does TRUNCATE by
+ recreate), and binlog is on, replication breaks,
+ since nothing gets written to the binary log.
+ (XXX: is this a bug?)
+ */
+ table->file->print_error(error, MYF(0));
+ goto end;
+ }
+ /*
+ A workaround for Bug#53696 "Performance schema engine violates the
+ PSEA API by calling my_error()".
+ */
+ if (thd->is_error())
+ goto end;
+
+ /* Handler didn't support fast delete. Delete rows one by one. */
+
+ init_read_record(&info, thd, table, NULL, TRUE, TRUE, FALSE);
+
+ /*
+ Start bulk delete. If the engine does not support it,
+ go on, it's not an error.
+ */
+ is_bulk_delete= ! table->file->start_bulk_delete();
+
+ table->mark_columns_needed_for_delete();
+
+ for (error= info.read_record(&info); !error && !thd->killed;
+ error= info.read_record(&info))
+ {
+ if ((error= table->file->ha_delete_row(table->record[0])))
+ {
+ table->file->print_error(error, MYF(0));
+ break;
+ }
+ some_rows_deleted= TRUE;
+ }
+
+ if (error == -1) /* HA_ERR_END_OF_FILE */
+ error= 0;
+
+ /* Close down the bulk delete. */
+ if (is_bulk_delete)
+ {
+ int bulk_delete_error= table->file->end_bulk_delete();
+ if (bulk_delete_error && !error)
+ {
+ table->file->print_error(bulk_delete_error, MYF(0));
+ error= bulk_delete_error;
+ }
+ }
+ end_read_record(&info);
+
+ /*
+ Regardless of the error status, the query must be written to the
+ binary log if rows of the table is non-transactional.
+ */
+ if (some_rows_deleted && !table->file->has_transactions())
+ {
+ thd->transaction.stmt.modified_non_trans_table= TRUE;
+ thd->transaction.all.modified_non_trans_table= TRUE;
+ }
+
+ if (error || thd->killed)
+ goto end;
+
+ /* Truncate resets the auto-increment counter. */
+ error= table->file->ha_reset_auto_increment(0);
+ if (error)
+ {
+ if (error != HA_ERR_WRONG_COMMAND)
+ table->file->print_error(error, MYF(0));
+ else
+ error= 0;
+ }
+
+end:
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
+
+ DBUG_RETURN(test(error));
+}
+
+
+/*
+ Close and recreate a temporary table. In case of success,
+ write truncate statement into the binary log if in statement
+ mode.
+
+ @param thd Thread context.
+ @param table The temporary table.
+
+ @retval FALSE Success.
+ @retval TRUE Error.
+*/
+
+static bool recreate_temporary_table(THD *thd, TABLE *table)
+{
+ bool error= TRUE;
+ TABLE_SHARE *share= table->s;
+ HA_CREATE_INFO create_info;
+ handlerton *table_type= table->s->db_type();
+ DBUG_ENTER("recreate_temporary_table");
+
+ memset(&create_info, 0, sizeof(create_info));
+
+ table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
+
+ /* Don't free share. */
+ close_temporary_table(thd, table, FALSE, FALSE);
+
+ /*
+ We must use share->normalized_path.str since for temporary tables it
+ differs from what dd_recreate_table() would generate based
+ on table and schema names.
+ */
+ ha_create_table(thd, share->normalized_path.str, share->db.str,
+ share->table_name.str, &create_info, 1);
+
+ if (open_temporary_table(thd, share->path.str, share->db.str,
+ share->table_name.str, 1))
+ {
+ error= FALSE;
+ thd->thread_specific_used= TRUE;
+ }
+ else
+ rm_temporary_table(table_type, share->path.str);
+
+ free_table_share(share);
+ my_free(table, MYF(0));
+
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Optimized delete of all rows by doing a full generate of the table.
+
+ @remark Will work even if the .MYI and .MYD files are destroyed.
+ In other words, it works as long as the .FRM is intact and
+ the engine supports re-create.
+
+ @param thd Thread context.
+ @param table_ref Table list element for the table to be truncated.
+
+ @retval FALSE Success.
+ @retval TRUE Error.
+*/
+
+bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref)
+{
+ TABLE *table;
+ bool error= TRUE;
+ MDL_ticket *mdl_ticket= NULL;
+ DBUG_ENTER("mysql_truncate_table");
+
+ /* Remove tables from the HANDLER's hash. */
+ mysql_ha_rm_tables(thd, table_ref);
+
+ /* If it is a temporary table, no need to take locks. */
+ if ((table= find_temporary_table(thd, table_ref)))
+ {
+ /* Note that a temporary table cannot be partitioned */
+ if (ha_check_storage_engine_flag(table->s->db_type(), HTON_CAN_RECREATE))
+ {
+ error= recreate_temporary_table(thd, table);
+ DBUG_ASSERT(! thd->transaction.stmt.modified_non_trans_table);
+ }
+ else
+ {
+ /*
+ The engine does not support truncate-by-recreate.
+ Open the table and delete all rows.
+ Sic: this can in fact open several tables
+ if it's a temporary MyISAMMRG table.
+ */
+ if (open_and_lock_tables(thd, table_ref, TL_WRITE,
+ MYSQL_OPEN_TEMPORARY_ONLY))
+ DBUG_RETURN(TRUE);
+
+ error= delete_all_rows(thd, table_ref->table);
+ }
+ /*
+ No need to invalidate the query cache, queries with temporary
+ tables are not in the cache.
+ */
+ }
+ else /* It's not a temporary table. */
+ {
+ bool hton_can_recreate;
+ /*
+ Before doing anything else,
+ acquire a metadata lock on the table, or ensure we have one.
+ We don't use open_and_lock_tables() right away because
+ we want to be able to truncate (and recreate) corrupted tables,
+ those that we can't fully open.
+ MySQL manual documents that TRUNCATE can be used to repair a
+ damaged table, i.e. a table that can not be fully "opened".
+ In particular MySQL manual says:
+
+ As long as the table format file tbl_name.frm is valid, the table
+ can be re-created as an empty table with TRUNCATE TABLE, even if
+ the data or index files have become corrupted.
+ */
+ if (thd->locked_tables_mode)
+ {
+ if (!(table= find_table_for_mdl_upgrade(thd->open_tables, table_ref->db,
+ table_ref->table_name, FALSE)))
+ DBUG_RETURN(TRUE);
+ mdl_ticket= table->mdl_ticket;
+ hton_can_recreate= ha_check_storage_engine_flag(table->s->db_type(),
+ HTON_CAN_RECREATE);
+ }
+ else
+ {
+ /*
+ Even though we could use the previous execution branch here just as
+ well, we must not try to open the table:
+ */
+ MDL_request mdl_global_request, mdl_request;
+ MDL_request_list mdl_requests;
+
+ mdl_global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE);
+ mdl_request.init(MDL_key::TABLE, table_ref->db, table_ref->table_name,
+ MDL_SHARED_NO_READ_WRITE);
+ mdl_requests.push_front(&mdl_request);
+ mdl_requests.push_front(&mdl_global_request);
+
+ if (thd->mdl_context.acquire_locks(&mdl_requests,
+ thd->variables.lock_wait_timeout))
+ DBUG_RETURN(TRUE);
+
+ mdl_ticket= mdl_request.ticket;
+
+ if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name,
+ HTON_CAN_RECREATE, &hton_can_recreate))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ }
+ if (hton_can_recreate)
+ {
+ /*
+ Acquire an exclusive lock. The storage engine can recreate the
+ table only if there are no references to it from anywhere,
+ i.e. no cached TABLE in the table cache. To remove
+ the table from cache we need an exclusive lock.
+ */
+ if (thd->locked_tables_mode)
+ {
+ mdl_ticket= table->mdl_ticket;
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+ DBUG_RETURN(TRUE);
+ close_all_tables_for_name(thd, table->s, FALSE);
+ }
+ else
+ {
+ ulong timeout= thd->variables.lock_wait_timeout;
+ if (thd->mdl_context.upgrade_shared_lock_to_exclusive(mdl_ticket, timeout))
+ DBUG_RETURN(TRUE);
+ mysql_mutex_lock(&LOCK_open);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
+ table_ref->db, table_ref->table_name);
+ mysql_mutex_unlock(&LOCK_open);
+ }
+ /*
+ The storage engine can truncate the table by creating
+ an empty table with the same structure.
+ */
+ error= dd_recreate_table(thd, table_ref->db, table_ref->table_name);
+
+ if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
+ thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
+ }
+ else
+ {
+ /*
+ Delete all rows in the table. Our metadata lock
+ guarantees that no transaction is reading or writing into the
+ table. Yet to open a write cursor we need a thr_lock lock.
+ Use open_and_lock_tables() to do the necessary job.
+ */
+
+ /* Allow to open base tables only. */
+ table_ref->required_type= FRMTYPE_TABLE;
+ table_ref->lock_type= TL_WRITE;
+ /* We don't need to load triggers. */
+ DBUG_ASSERT(table_ref->trg_event_map == 0);
+
+ /*
+ Open the table as it will handle some required preparations.
+ Ignore pending FLUSH TABLES since we don't want to release
+ the MDL lock taken above and otherwise there is no way
+ to wait for FLUSH TABLES in deadlock-free fashion.
+ */
+ if (open_and_lock_tables(thd, table_ref, TL_WRITE,
+ MYSQL_OPEN_IGNORE_FLUSH |
+ MYSQL_OPEN_SKIP_TEMPORARY))
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ error= delete_all_rows(thd, table_ref->table);
+ }
+ query_cache_invalidate3(thd, table_ref, FALSE);
+ }
+
+ /*
+ DDL is logged in statement format, regardless of binlog format.
+ In RBR, the statement is not binlogged if the table is temporary.
+ No need to binlog failed truncate-by-recreate.
+ */
+ if ((!error || thd->transaction.stmt.modified_non_trans_table) &&
+ !thd->is_current_stmt_binlog_format_row())
+ error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
+ /*
+ All effects of a TRUNCATE TABLE operation are rolled back if a row
+ by row deletion fails. Otherwise, it is automatically committed at
+ the end.
+ */
+ if (error)
+ {
+ trans_rollback_stmt(thd);
+ trans_rollback(thd);
+ }
+
+ if (thd->locked_tables_mode && mdl_ticket)
+ mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
+
+ DBUG_PRINT("exit", ("error: %d", error));
+ DBUG_RETURN(test(error));
+}
+
+
=== added file 'sql/sql_truncate.h'
--- a/sql/sql_truncate.h 1970-01-01 00:00:00 +0000
+++ b/sql/sql_truncate.h 2010-05-20 12:07:41 +0000
@@ -0,0 +1,23 @@
+#ifndef SQL_TRUNCATE_INCLUDED
+#define SQL_TRUNCATE_INCLUDED
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+class THD;
+class TABLE_LIST;
+
+bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref);
+
+#endif
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-04-07 11:58:40 +0000
+++ b/sql/sql_view.cc 2010-05-20 12:07:41 +0000
@@ -32,6 +32,7 @@
#include "sp.h"
#include "sp_head.h"
#include "sp_cache.h"
+#include "datadict.h" // dd_frm_type()
#define MD5_BUFF_LENGTH 33
@@ -1663,7 +1664,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
view->db, view->table_name, reg_ext, 0);
if (access(path, F_OK) ||
- FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used)))
+ FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used)))
{
char name[FN_REFLEN];
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
@@ -1742,54 +1743,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
/*
- Check type of .frm if we are not going to parse it
-
- SYNOPSIS
- mysql_frm_type()
- path path to file
-
- RETURN
- FRMTYPE_ERROR error
- FRMTYPE_TABLE table
- FRMTYPE_VIEW view
-*/
-
-frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
-{
- File file;
- uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
- size_t error;
- DBUG_ENTER("mysql_frm_type");
-
- *dbt= DB_TYPE_UNKNOWN;
-
- if ((file= mysql_file_open(key_file_frm,
- path, O_RDONLY | O_SHARE, MYF(0))) < 0)
- DBUG_RETURN(FRMTYPE_ERROR);
- error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
- mysql_file_close(file, MYF(MY_WME));
-
- if (error)
- DBUG_RETURN(FRMTYPE_ERROR);
- if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header)))
- DBUG_RETURN(FRMTYPE_VIEW);
-
- /*
- This is just a check for DB_TYPE. We'll return default unknown type
- if the following test is true (arg #3). This should not have effect
- on return value from this function (default FRMTYPE_TABLE)
- */
- if (header[0] != (uchar) 254 || header[1] != 1 ||
- (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
- (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
- DBUG_RETURN(FRMTYPE_TABLE);
-
- *dbt= (enum legacy_db_type) (uint) *(header + 3);
- DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
-}
-
-
-/*
check of key (primary or unique) presence in updatable view
SYNOPSIS
=== modified file 'sql/sql_view.h'
--- a/sql/sql_view.h 2010-03-31 14:05:33 +0000
+++ b/sql/sql_view.h 2010-05-20 12:07:41 +0000
@@ -43,8 +43,6 @@ bool check_key_in_view(THD *thd, TABLE_L
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view);
-frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt);
-
int view_checksum(THD *thd, TABLE_LIST *view);
extern TYPELIB updatable_views_with_limit_typelib;
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-04-12 13:17:37 +0000
+++ b/sql/table.h 2010-05-20 12:07:41 +0000
@@ -20,6 +20,7 @@
#include "sql_plist.h"
#include "sql_list.h" /* Sql_alloc */
#include "mdl.h"
+#include "datadict.h"
#ifndef MYSQL_CLIENT
@@ -305,14 +306,6 @@ enum tmp_table_type
NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE,
INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE
};
-
-enum frm_type_enum
-{
- FRMTYPE_ERROR= 0,
- FRMTYPE_TABLE,
- FRMTYPE_VIEW
-};
-
enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
typedef struct st_filesort_info
Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100520120741-i253if43sooteyy7.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-runtime branch (kostja:3019) Bug#42643 | Konstantin Osipov | 20 May |