summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2021-11-30 01:46:27 +0300
committerAleksey Midenkov <midenok@gmail.com>2021-12-10 13:41:49 +0300
commit111f58c9233c183f3a5cf2caac5dc26ad4e0cbc7 (patch)
tree04abd7d34fae9f0c56ace319429022c139f40f94
parent80834a8f5d0bbaefd98baac6399321bb2e06e97c (diff)
downloadmariadb-git-bb-10.7-midenok-MDEV-25292.tar.gz
MDEV-25292 Atomic CREATE OR REPLACE TABLEbb-10.7-midenok-MDEV-25292
Atomic replace algorithm Two DDL chains are used for CREATE OR REPLACE: ddl_log_state_create (C) and ddl_log_state_rm (D). 1. (C) Write DDL_LOG_CREATE_TABLE_ACTION of TMP table (drops TMP table); 2. Create new table as TMP; 3. Do everything with TMP (like insert data); 4. (D) Write DDL_LOG_RENAME_TABLE_ACTION from ORIG to TMP (replays TMP -> ORIG); 5. (D) Write DDL_LOG_DROP_ACTION of ORIG; 6. (C) close chain; 7. (D) replay chain Temporary table for CREATE OR REPLACE Before dropping "old" table, CREATE OR REPLACE creates "tmp" table. ddl_log_state_create holds the drop of the "tmp" table. When everything is OK (data is inserted, "tmp" is ready) ddl_log_state_rm is written to replace "old" with "tmp". Until ddl_log_state_create is closed ddl_log_state_rm is not executed. After the binlogging is done ddl_log_state_create is closed. At that point ddl_log_state_rm is executed and "tmp" is replaced with "old". That is: final rename is done by the DDL log. With that important role of DDL log for CREATE OR REPLACE operation replay of ddl_log_state_rm must fail at the first hit error and print the error message if possible. F.ex. foreign key error is discovered at this phase: InnoDB rejects to drop the "old" table and returns corresponding foreign key error code. Additional notes - CREATE TABLE without REPLACE is not affected by this commit. - Engines having HTON_EXPENSIVE_RENAME flag set are not affected by this commit. - CREATE TABLE .. SELECT XID usage is fixed and now there is no need to log DROP TABLE via DDL_CREATE_TABLE_PHASE_LOG (see comments in do_postlock()). XID is now correctly updated so it disables DDL_LOG_DROP_TABLE_ACTION. Note that binary log is flushed at the final stage when the table is ready. So if we have XID in the binary log we don't need to drop the table. - Three variations of CREATE OR REPLACE handled: 1. CREATE OR REPLACE TABLE t1 (..); 2. CREATE OR REPLACE TABLE t1 LIKE t2; 3. CREATE OR REPLACE TABLE t1 SELECT ..; - Test case uses 5 combinations for engines (aria, aria_notrans, myisam, ib, expensive_rename) and 2 combinations for binlog types (row, stmt). Combinations help to check differences between the results. Error failures are tested for the above three variations. - Triggers mechanism is unaffected by this change. This is tested in create_replace.test. - LOCK TABLES is affected. Lock restoration must be done after "rm" chain is replayed. Rename and drop via DDL log We replay ddl_log_state_rm to drop the old table and rename the temporary table. In that case we must throw the correct error message if ddl_log_revert() fails (f.ex. on FK error). If table is deleted earlier and not via DDL log and the crash happened, your create chain is not closed. Linked drop chain is not executed and the new table is not installed. But the old table is already deleted. ddl_log.cc changes Now we can place action before DDL_LOG_DROP_INIT_ACTION and it will be replayed after DDL_LOG_DROP_TABLE_ACTION. report_error parameter for ddl_log_revert() allows to fail at first error and print the error message if possible. ddl_log_execute_action() now can print error message. Since we now can handle errors from ddl_log_execute_action() (in case of non-recovery execution) unconditional setting "error= TRUE" is wrong (it was wrong anyway because it was overwritten at the end of the function). On XID usage Like with all other atomic DDL operations XID is used to avoid inconsistency between master and slave in the case of a crash after binary log is written and before ddl_log_state_create is closed. On recovery XIDs are taken from binary log and corresponding DDL log events get disabled. That is done by ddl_log_close_binlogged_events(). On linking two chains together Chains are executed in the ascending order of entry_pos of execute entries. But entry_pos assignment order is undefined: it may assign bigger number for the first chain and then smaller number for the second chain. So the execution order in that case will be reverse: second chain will be executed first. To avoid that we link one chain to another. While the master chain is active the slave chain is not executed. That is: only one chain can be executed in two linked chains. The interface ddl_log_link_chains() was done in "MDEV-22166 ddl_log_write_execute_entry() extension". Refactoring: moved select_field_count into Alter_info. As atomic CREATER OR REPLACE .. SELECT now uses temporary table there is a need to have both C_ALTER_TABLE and select_field_count in one call. Semantically creation mode and field count are two different things. Making creation mode negative constants and field count positive variable into one parameter seems to be a lazy hack for not making the second parameter. select_field_count does not make sense without alter_info->create_list, so the natural way is to hold it in Alter_info too. More on CREATE OR REPLACE .. SELECT We use create_and_open_tmp_table() like in ALTER TABLE to create temporary TABLE object (tmp_table is (NON_)TRANSACTIONAL_TMP_TABLE). After we created such TABLE object we use create_info->tmp_table() instead of table->s->tmp_table when we need to check for parser-requested tmp-table. External locking is required for temporary table created by create_and_open_tmp_table(). F.ex. that disables logging for Aria transactional tables and wihout that (when no mysql_lock_tables() is done) it cannot work correctly. For external locking we require Aria table to work in non-transactional mode. That is usually done by ha_enable_transaction(false). But we cannot disable transaction completely because: 1. binlog rollback removes pending row events (binlog_remove_pending_rows_event()). The row events are added during CREATE .. SELECT data insertion phase. 2. replication slave highly depends on transaction and cannot work without it. So we put temporary Aria table into non-transactional mode with "thd->transaction->on hack". See comment for on_save variable. Note that Aria table has internal_table mode. But we cannot use it because: if (!internal_table) { mysql_mutex_lock(&THR_LOCK_myisam); old_info= test_if_reopen(name_buff); } For internal_table test_if_reopen() is not called and we get a new MARIA_SHARE for each file handler. In that case duplicate errors are missed because insert and lookup in CREATE .. SELECT is done via two different handlers (see create_lookup_handler()). For temporary table before dropping TABLE_SHARE by drop_temporary_table() we must do ha_reset(). ha_reset() releases storage share. Without that the share is kept and the second CREATE OR REPLACE .. SELECT fails with: HA_ERR_TABLE_EXIST (156): MyISAM table '#sql-create-b5377-4-t2' is in use (most likely by a MERGE table). Try FLUSH TABLES. HA_EXTRA_PREPARE_FOR_DROP also removes MYISAM_SHARE, but that is not needed as ha_reset() does the job. ha_reset() is usually done by mark_tmp_table_as_free_for_reuse(). But we don't need that mechanism for our temporary table. Atomic_info in HA_CREATE_INFO Many functions in CREATE TABLE pass the same parameters. These parameters are part of table creation info and should be in HA_CREATE_INFO (or whatever). Passing parameters via single structure is much easier for adding new data and refactoring.
-rw-r--r--mysql-test/include/log_bin.combinations8
-rw-r--r--mysql-test/include/log_bin.inc1
-rw-r--r--mysql-test/main/backup_log.inc26
-rw-r--r--mysql-test/main/backup_log.result190
-rw-r--r--mysql-test/main/backup_log.test2
-rw-r--r--mysql-test/main/backup_log_print.inc7
-rw-r--r--mysql-test/main/create_or_replace.result244
-rw-r--r--mysql-test/main/create_or_replace.test105
-rw-r--r--mysql-test/main/create_or_replace2.result7
-rw-r--r--mysql-test/main/create_or_replace2.test1
-rw-r--r--mysql-test/main/default.result14
-rw-r--r--mysql-test/main/default.test15
-rw-r--r--mysql-test/main/long_unique_bugs.result3
-rw-r--r--mysql-test/main/long_unique_bugs.test1
-rw-r--r--mysql-test/suite/atomic/create_replace,expensive_rename,row.rdiff333
-rw-r--r--mysql-test/suite/atomic/create_replace,expensive_rename.rdiff289
-rw-r--r--mysql-test/suite/atomic/create_replace,ib,row.rdiff410
-rw-r--r--mysql-test/suite/atomic/create_replace,ib.rdiff384
-rw-r--r--mysql-test/suite/atomic/create_replace,myisam,row.rdiff395
-rw-r--r--mysql-test/suite/atomic/create_replace,myisam.rdiff365
-rw-r--r--mysql-test/suite/atomic/create_replace,row.rdiff60
-rw-r--r--mysql-test/suite/atomic/create_replace.combinations5
-rw-r--r--mysql-test/suite/atomic/create_replace.result400
-rw-r--r--mysql-test/suite/atomic/create_replace.test193
-rw-r--r--mysql-test/suite/atomic/create_table.result209
-rw-r--r--mysql-test/suite/atomic/create_table.test8
-rw-r--r--mysql-test/suite/parts/r/backup_log.result215
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace2,stmt.rdiff17
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace2.result11
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_mix.result31
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_row.result35
-rw-r--r--mysql-test/suite/rpl/r/create_or_replace_statement.result31
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_strict.result3
-rw-r--r--mysql-test/suite/rpl/t/create_or_replace.inc11
-rw-r--r--mysql-test/suite/rpl/t/create_or_replace2.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_strict.test5
-rw-r--r--mysql-test/suite/sql_sequence/create.result2
-rw-r--r--mysql-test/suite/sql_sequence/create.test6
-rw-r--r--sql/ddl_log.cc210
-rw-r--r--sql/ddl_log.h7
-rw-r--r--sql/handler.cc18
-rw-r--r--sql/handler.h55
-rw-r--r--sql/log.cc7
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/sql_alter.cc1
-rw-r--r--sql/sql_alter.h8
-rw-r--r--sql/sql_class.h11
-rw-r--r--sql/sql_db.cc5
-rw-r--r--sql/sql_insert.cc309
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_table.cc737
-rw-r--r--sql/sql_table.h56
-rw-r--r--sql/sql_trigger.cc19
-rw-r--r--sql/sql_trigger.h5
-rw-r--r--sql/table.cc2
-rw-r--r--storage/innobase/dict/dict0dict.cc12
-rw-r--r--storage/innobase/handler/ha_innodb.cc6
-rw-r--r--storage/innobase/handler/handler0alter.cc2
-rw-r--r--storage/innobase/include/dict0dict.h3
-rw-r--r--storage/innobase/row/row0mysql.cc1
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ha_s3.cc3
64 files changed, 4591 insertions, 943 deletions
diff --git a/mysql-test/include/log_bin.combinations b/mysql-test/include/log_bin.combinations
new file mode 100644
index 00000000000..07042c2cbec
--- /dev/null
+++ b/mysql-test/include/log_bin.combinations
@@ -0,0 +1,8 @@
+[row]
+binlog-format=row
+
+[stmt]
+binlog-format=statement
+
+[mix]
+binlog-format=mixed
diff --git a/mysql-test/include/log_bin.inc b/mysql-test/include/log_bin.inc
new file mode 100644
index 00000000000..aadec436c18
--- /dev/null
+++ b/mysql-test/include/log_bin.inc
@@ -0,0 +1 @@
+--source include/have_log_bin.inc
diff --git a/mysql-test/main/backup_log.inc b/mysql-test/main/backup_log.inc
index f553a3b9527..4ad6b9122cd 100644
--- a/mysql-test/main/backup_log.inc
+++ b/mysql-test/main/backup_log.inc
@@ -7,7 +7,7 @@
# non-partitioned testing
--echo #
---echo # Testing with normal tables
+--echo # Testing normal tables
--echo #
eval create table t1 (a int) engine=myisam $part_int;
@@ -20,6 +20,8 @@ repair table t1;
optimize table t1;
drop table t1;
+--source backup_log_print.inc
+
eval create table t1_innodb (a int) engine=innodb $part_int;
insert into t1_innodb values (1),(2);
alter table t1_innodb add column b int;
@@ -30,6 +32,8 @@ repair table t1_innodb;
optimize table t1_innodb;
drop table t1_innodb;
+--source backup_log_print.inc
+
--echo #
--echo # Testing with temporary tables (should not be logged)
--echo #
@@ -41,6 +45,8 @@ rename table tmp_t11 to tmp_t10;
truncate table tmp_t10;
drop table tmp_t10;
+--source backup_log_print.inc
+
--echo #
--echo # Testing with mix of normal and temporary tables
--echo #
@@ -54,6 +60,8 @@ eval create table t21 (a int) $part_int;
drop temporary table if exists tmp_t21,t21;
drop table if exists tmp_t21,t21;
+--source backup_log_print.inc
+
--echo #
--echo # Testing create select
--echo #
@@ -68,6 +76,8 @@ eval create or replace table t31 (a int primary key) $part_int select * from t30
eval create table t32 (a int) $part_int;
drop table if exists t30,t31,t32,tmp_t30;
+--source backup_log_print.inc
+
--echo #
--echo # Testing create LIKE
--echo #
@@ -81,6 +91,8 @@ create or replace table t42 like t41;
show create table t42;
drop table t40, t41, t42;
+--source backup_log_print.inc
+
--echo #
--echo # Testing rename
--echo #
@@ -91,6 +103,8 @@ rename table t50 to t52, t51 to t53;
rename table t52 to tmp, t53 to t52, tmp to t53;
drop table t52,t53;
+--source backup_log_print.inc
+
--echo #
--echo # Testing enable/disable keys
--echo #
@@ -107,6 +121,8 @@ INSERT INTO t61 VALUES(1),(2),(3);
ALTER TABLE t61 DISABLE KEYS;
DROP TABLE t61;
+--source backup_log_print.inc
+
--echo #
--echo # Testing load data
--echo #
@@ -128,6 +144,8 @@ insert into t71 select * from t70;
unlock tables;
drop table t70,t71;
+--source backup_log_print.inc
+
--echo #
--echo # Testing strange table names
--echo #
@@ -135,6 +153,8 @@ drop table t70,t71;
eval create table `t 1` (a int) $part_int;
drop table `t 1`;
+--source backup_log_print.inc
+
--echo #
--echo # Testing views and triggers
--echo #
@@ -146,6 +166,8 @@ drop trigger trg;
drop view v1;
drop table t80;
+--source backup_log_print.inc
+
--echo #
--echo # Testing alter to a new storage engine
--echo #
@@ -153,3 +175,5 @@ drop table t80;
eval create table t85 (a int primary key, b int) engine=myisam $part_int;
alter table t85 engine=innodb;
drop table t85;
+
+--source backup_log_print.inc
diff --git a/mysql-test/main/backup_log.result b/mysql-test/main/backup_log.result
index 94590a220d4..cac4d1cc382 100644
--- a/mysql-test/main/backup_log.result
+++ b/mysql-test/main/backup_log.result
@@ -4,7 +4,7 @@ connect con1,localhost,root,,;
BACKUP STAGE START;
connection default;
#
-# Testing with normal tables
+# Testing normal tables
#
create table t1 (a int) engine=myisam ;
insert into t1 values (1),(2);
@@ -19,6 +19,16 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
drop table t1;
+#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t1,id: 1,,0,,,
+ALTER,MyISAM,0,test,t1,id: 1,MyISAM,0,test,t1,id: 2
+RENAME,MyISAM,0,test,t1,id: 2,MyISAM,0,test,t2,id: 2
+RENAME,MyISAM,0,test,t2,id: 2,MyISAM,0,test,t1,id: 2
+repair,MyISAM,0,test,t1,id: 2,,0,,,
+optimize,MyISAM,0,test,t1,id: 2,,0,,,
+DROP,MyISAM,0,test,t1,id: 2,,0,,,
create table t1_innodb (a int) engine=innodb ;
insert into t1_innodb values (1),(2);
alter table t1_innodb add column b int;
@@ -34,6 +44,17 @@ test.t1_innodb optimize note Table does not support optimize, doing recreate + a
test.t1_innodb optimize status OK
drop table t1_innodb;
#
+# Reading backup ddl log file
+#
+CREATE,InnoDB,0,test,t1_innodb,id: 1,,0,,,
+ALTER,InnoDB,0,test,t1_innodb,id: 1,InnoDB,0,test,t1_innodb,id: 2
+RENAME,InnoDB,0,test,t1_innodb,id: 2,InnoDB,0,test,t2_innodb,id: 2
+RENAME,InnoDB,0,test,t2_innodb,id: 2,InnoDB,0,test,t1_innodb,id: 2
+TRUNCATE,InnoDB,0,test,t1_innodb,id: 2,,0,,,
+repair,InnoDB,0,test,t1_innodb,id: 2,,0,,,
+ALTER,InnoDB,0,test,t1_innodb,id: 2,InnoDB,0,test,t1_innodb,id: 3
+DROP,InnoDB,0,test,t1_innodb,id: 3,,0,,,
+#
# Testing with temporary tables (should not be logged)
#
create temporary table tmp_t10 (a int) engine=myisam;
@@ -43,6 +64,9 @@ rename table tmp_t11 to tmp_t10;
truncate table tmp_t10;
drop table tmp_t10;
#
+# Reading backup ddl log file
+#
+#
# Testing with mix of normal and temporary tables
#
create temporary table tmp_t20 (a int);
@@ -57,6 +81,13 @@ drop table if exists tmp_t21,t21;
Warnings:
Note 1051 Unknown table 'test.tmp_t21'
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t20,id: 1,,0,,,
+DROP,MyISAM,0,test,t20,id: 1,,0,,,
+CREATE,MyISAM,0,test,t21,id: 2,,0,,,
+DROP,MyISAM,0,test,t21,id: 2,,0,,,
+#
# Testing create select
#
create table t30 (a int) ;
@@ -69,7 +100,18 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
create table t32 (a int) ;
drop table if exists t30,t31,t32,tmp_t30;
Warnings:
-Note 1051 Unknown table 'test.t31,test.tmp_t30'
+Note 1051 Unknown table 'test.tmp_t30'
+#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t30,id: 1,,0,,,
+CREATE,MyISAM,0,test,t31,id: 2,,0,,,
+DROP,MyISAM,0,test,t31,id: 2,,0,,,
+CREATE,MyISAM,0,test,t31,id: 3,,0,,,
+CREATE,MyISAM,0,test,t32,id: 4,,0,,,
+DROP,MyISAM,0,test,t30,id: 1,,0,,,
+DROP,MyISAM,0,test,t31,id: 3,,0,,,
+DROP,MyISAM,0,test,t32,id: 4,,0,,,
#
# Testing create LIKE
#
@@ -86,6 +128,17 @@ t42 CREATE TABLE `t42` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t40, t41, t42;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t40,id: 1,,0,,,
+CREATE,InnoDB,0,test,t41,id: 2,,0,,,
+CREATE,MyISAM,0,test,t42,id: 3,,0,,,
+DROP,MyISAM,0,test,t42,id: 3,,0,,,
+CREATE,InnoDB,0,test,t42,id: 4,,0,,,
+DROP,MyISAM,0,test,t40,id: 1,,0,,,
+DROP,InnoDB,0,test,t41,id: 2,,0,,,
+DROP,InnoDB,0,test,t42,id: 4,,0,,,
+#
# Testing rename
#
create table t50 (a int) ;
@@ -94,6 +147,18 @@ rename table t50 to t52, t51 to t53;
rename table t52 to tmp, t53 to t52, tmp to t53;
drop table t52,t53;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t50,id: 1,,0,,,
+CREATE,MyISAM,0,test,t51,id: 2,,0,,,
+RENAME,MyISAM,0,test,t50,id: 1,MyISAM,0,test,t52,id: 1
+RENAME,MyISAM,0,test,t51,id: 2,MyISAM,0,test,t53,id: 2
+RENAME,MyISAM,0,test,t52,id: 1,MyISAM,0,test,tmp,id: 1
+RENAME,MyISAM,0,test,t53,id: 2,MyISAM,0,test,t52,id: 2
+RENAME,MyISAM,0,test,tmp,id: 1,MyISAM,0,test,t53,id: 1
+DROP,MyISAM,0,test,t52,id: 2,,0,,,
+DROP,MyISAM,0,test,t53,id: 1,,0,,,
+#
# Testing enable/disable keys
#
CREATE TABLE t60 (a int(10), index(a) ) ENGINE=Aria ;
@@ -107,6 +172,13 @@ INSERT INTO t61 VALUES(1),(2),(3);
ALTER TABLE t61 DISABLE KEYS;
DROP TABLE t61;
#
+# Reading backup ddl log file
+#
+CREATE,Aria,0,test,t60,id: 1,,0,,,
+CHANGE_INDEX,Aria,0,test,t60,id: 1,,0,,,
+CHANGE_INDEX,Aria,0,test,t60,id: 1,,0,,,
+DROP,Aria,0,test,t60,id: 1,,0,,,
+#
# Testing load data
#
create table t70 (a date, b date, c date not null, d date) engine=aria ;
@@ -123,11 +195,26 @@ insert into t71 select * from t70;
unlock tables;
drop table t70,t71;
#
+# Reading backup ddl log file
+#
+CREATE,Aria,0,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,0,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,0,test,t70,id: 1,,0,,,
+CREATE,Aria,0,test,t71,id: 2,,0,,,
+BULK_INSERT,Aria,0,test,t71,id: 2,,0,,,
+DROP,Aria,0,test,t70,id: 1,,0,,,
+DROP,Aria,0,test,t71,id: 2,,0,,,
+#
# Testing strange table names
#
create table `t 1` (a int) ;
drop table `t 1`;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t@00201,id: 1,,0,,,
+DROP,MyISAM,0,test,t@00201,id: 1,,0,,,
+#
# Testing views and triggers
#
create table t80 (a int, b int) engine=myisam ;
@@ -137,12 +224,27 @@ drop trigger trg;
drop view v1;
drop table t80;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t80,id: 1,,0,,,
+CREATE,VIEW,0,test,v1,,,0,,,
+CREATE,TRIGGER,0,test,trg,,,0,,,
+DROP,TRIGGER,0,test,trg,,,0,,,
+DROP,VIEW,0,test,v1,,,0,,,
+DROP,MyISAM,0,test,t80,id: 1,,0,,,
+#
# Testing alter to a new storage engine
#
create table t85 (a int primary key, b int) engine=myisam ;
alter table t85 engine=innodb;
drop table t85;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,0,test,t85,id: 1,,0,,,
+ALTER,MyISAM,0,test,t85,id: 1,InnoDB,0,test,t85,id: 2
+DROP,InnoDB,0,test,t85,id: 2,,0,,,
+#
# Testing create/drop/alter database
#
create database mysqltest;
@@ -151,6 +253,16 @@ create table mysqltest.t91 (a int primary key, b int) engine=innodb;
alter database mysqltest character set utf8;
drop database mysqltest;
#
+# Reading backup ddl log file
+#
+CREATE,DATABASE,0,mysqltest,,,,0,,,
+CREATE,MyISAM,0,mysqltest,t90,id: 1,,0,,,
+CREATE,InnoDB,0,mysqltest,t91,id: 2,,0,,,
+ALTER,DATABASE,0,mysqltest,,,,0,,,
+DROP,MyISAM,0,mysqltest,t90,id: 1,,0,,,
+DROP,InnoDB,0,mysqltest,t91,id: 2,,0,,,
+DROP,DATABASE,0,mysqltest,,,,0,,,
+#
# MENT-222 bug testing
#
CREATE TABLE IF NOT EXISTS t_exists LIKE t_exists_template;
@@ -159,80 +271,6 @@ Note 1050 Table 't_exists' already exists
#
# Reading backup ddl log file
#
-CREATE,MyISAM,0,test,t1,id: 1,,0,,,
-ALTER,MyISAM,0,test,t1,id: 1,MyISAM,0,test,t1,id: 2
-RENAME,MyISAM,0,test,t1,id: 2,MyISAM,0,test,t2,id: 2
-RENAME,MyISAM,0,test,t2,id: 2,MyISAM,0,test,t1,id: 2
-repair,MyISAM,0,test,t1,id: 2,,0,,,
-optimize,MyISAM,0,test,t1,id: 2,,0,,,
-DROP,MyISAM,0,test,t1,id: 2,,0,,,
-CREATE,InnoDB,0,test,t1_innodb,id: 3,,0,,,
-ALTER,InnoDB,0,test,t1_innodb,id: 3,InnoDB,0,test,t1_innodb,id: 4
-RENAME,InnoDB,0,test,t1_innodb,id: 4,InnoDB,0,test,t2_innodb,id: 4
-RENAME,InnoDB,0,test,t2_innodb,id: 4,InnoDB,0,test,t1_innodb,id: 4
-TRUNCATE,InnoDB,0,test,t1_innodb,id: 4,,0,,,
-repair,InnoDB,0,test,t1_innodb,id: 4,,0,,,
-ALTER,InnoDB,0,test,t1_innodb,id: 4,InnoDB,0,test,t1_innodb,id: 5
-DROP,InnoDB,0,test,t1_innodb,id: 5,,0,,,
-CREATE,MyISAM,0,test,t20,id: 6,,0,,,
-DROP,MyISAM,0,test,t20,id: 6,,0,,,
-CREATE,MyISAM,0,test,t21,id: 7,,0,,,
-DROP,MyISAM,0,test,t21,id: 7,,0,,,
-CREATE,MyISAM,0,test,t30,id: 8,,0,,,
-CREATE,MyISAM,0,test,t31,id: 9,,0,,,
-DROP,MyISAM,0,test,t31,id: 9,,0,,,
-CREATE,MyISAM,0,test,t31,id: 10,,0,,,
-DROP,MyISAM,0,test,t31,id: 10,,0,,,
-DROP_AFTER_CREATE,MyISAM,0,test,t31,id: 11,,0,,,
-CREATE,MyISAM,0,test,t32,id: 12,,0,,,
-DROP,MyISAM,0,test,t30,id: 8,,0,,,
-DROP,MyISAM,0,test,t32,id: 12,,0,,,
-CREATE,MyISAM,0,test,t40,id: 13,,0,,,
-CREATE,InnoDB,0,test,t41,id: 14,,0,,,
-CREATE,MyISAM,0,test,t42,id: 15,,0,,,
-DROP,MyISAM,0,test,t42,id: 15,,0,,,
-CREATE,InnoDB,0,test,t42,id: 16,,0,,,
-DROP,MyISAM,0,test,t40,id: 13,,0,,,
-DROP,InnoDB,0,test,t41,id: 14,,0,,,
-DROP,InnoDB,0,test,t42,id: 16,,0,,,
-CREATE,MyISAM,0,test,t50,id: 17,,0,,,
-CREATE,MyISAM,0,test,t51,id: 18,,0,,,
-RENAME,MyISAM,0,test,t50,id: 17,MyISAM,0,test,t52,id: 17
-RENAME,MyISAM,0,test,t51,id: 18,MyISAM,0,test,t53,id: 18
-RENAME,MyISAM,0,test,t52,id: 17,MyISAM,0,test,tmp,id: 17
-RENAME,MyISAM,0,test,t53,id: 18,MyISAM,0,test,t52,id: 18
-RENAME,MyISAM,0,test,tmp,id: 17,MyISAM,0,test,t53,id: 17
-DROP,MyISAM,0,test,t52,id: 18,,0,,,
-DROP,MyISAM,0,test,t53,id: 17,,0,,,
-CREATE,Aria,0,test,t60,id: 19,,0,,,
-CHANGE_INDEX,Aria,0,test,t60,id: 19,,0,,,
-CHANGE_INDEX,Aria,0,test,t60,id: 19,,0,,,
-DROP,Aria,0,test,t60,id: 19,,0,,,
-CREATE,Aria,0,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,0,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,0,test,t70,id: 20,,0,,,
-CREATE,Aria,0,test,t71,id: 21,,0,,,
-BULK_INSERT,Aria,0,test,t71,id: 21,,0,,,
-DROP,Aria,0,test,t70,id: 20,,0,,,
-DROP,Aria,0,test,t71,id: 21,,0,,,
-CREATE,MyISAM,0,test,t@00201,id: 22,,0,,,
-DROP,MyISAM,0,test,t@00201,id: 22,,0,,,
-CREATE,MyISAM,0,test,t80,id: 23,,0,,,
-CREATE,VIEW,0,test,v1,,,0,,,
-CREATE,TRIGGER,0,test,trg,,,0,,,
-DROP,TRIGGER,0,test,trg,,,0,,,
-DROP,VIEW,0,test,v1,,,0,,,
-DROP,MyISAM,0,test,t80,id: 23,,0,,,
-CREATE,MyISAM,0,test,t85,id: 24,,0,,,
-ALTER,MyISAM,0,test,t85,id: 24,InnoDB,0,test,t85,id: 25
-DROP,InnoDB,0,test,t85,id: 25,,0,,,
-CREATE,DATABASE,0,mysqltest,,,,0,,,
-CREATE,MyISAM,0,mysqltest,t90,id: 26,,0,,,
-CREATE,InnoDB,0,mysqltest,t91,id: 27,,0,,,
-ALTER,DATABASE,0,mysqltest,,,,0,,,
-DROP,MyISAM,0,mysqltest,t90,id: 26,,0,,,
-DROP,InnoDB,0,mysqltest,t91,id: 27,,0,,,
-DROP,DATABASE,0,mysqltest,,,,0,,,
#
# Cleanup
#
diff --git a/mysql-test/main/backup_log.test b/mysql-test/main/backup_log.test
index ee34484e92b..1ce6f840881 100644
--- a/mysql-test/main/backup_log.test
+++ b/mysql-test/main/backup_log.test
@@ -24,6 +24,8 @@ create table mysqltest.t91 (a int primary key, b int) engine=innodb;
alter database mysqltest character set utf8;
drop database mysqltest;
+--source backup_log_print.inc
+
--echo #
--echo # MENT-222 bug testing
--echo #
diff --git a/mysql-test/main/backup_log_print.inc b/mysql-test/main/backup_log_print.inc
new file mode 100644
index 00000000000..ad46dde49f9
--- /dev/null
+++ b/mysql-test/main/backup_log_print.inc
@@ -0,0 +1,7 @@
+--disable_query_log
+--source include/print_ddl_log.inc
+--connection con1
+backup stage end;
+backup stage start;
+--connection default
+--enable_query_log
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result
index e1670aff9ce..bbc42a8cec1 100644
--- a/mysql-test/main/create_or_replace.result
+++ b/mysql-test/main/create_or_replace.result
@@ -271,6 +271,7 @@ create or replace table test.t1;
ERROR 42000: A table must have at least 1 column
show tables;
Tables_in_test
+t1
t2
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
@@ -280,11 +281,20 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
create or replace table mysqltest2.t2;
ERROR 42000: A table must have at least 1 column
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
+# MDL_BACKUP_DDL NULL Backup lock
+# MDL_BACKUP_DML NULL Backup lock
+# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
+# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
+drop table mysqltest2.t2;
+drop table t1;
create table t1 (i int);
drop table t1;
create table test.t1 (i int);
@@ -303,6 +313,7 @@ create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a';
ERROR 42S21: Duplicate column name 'a'
show tables;
Tables_in_test
+t1
t2
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
@@ -312,11 +323,20 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a';
ERROR 42S21: Duplicate column name 'a'
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
+# MDL_BACKUP_DDL NULL Backup lock
+# MDL_BACKUP_DML NULL Backup lock
+# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
+# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
+# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
+drop table mysqltest2.t2;
+drop table t1;
create table t1 (i int);
drop table t1;
create table test.t1 (i int) engine=innodb;
@@ -361,6 +381,7 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a;
ERROR 22001: Data too long for column 'a' at row 1
+drop table t1;
show tables;
Tables_in_test
t2
@@ -578,3 +599,226 @@ ERROR HY000: Table 't3' was not locked with LOCK TABLES
UNLOCK TABLES;
DROP TABLE t3;
# End of 10.4 tests
+#
+# MDEV-25292 Atomic CREATE OR REPLACE TABLE
+#
+create table t1 (a int);
+insert t1 values (1), (1);
+create table t2 (c int);
+create or replace table t2 (a int, b int, key k (a), key k (b));
+ERROR 42000: Duplicate key name 'k'
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create or replace table t2 (a int, b int, key k (a), key k (b)) as select a, a as b from t1;
+ERROR 42000: Duplicate key name 'k'
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create or replace table t2 (a int primary key) as select * from t1;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+set @old_mode= @@sql_mode;
+set @@sql_mode='ALLOW_INVALID_DATES';
+create table t3 (dt datetime default '2008-02-31 00:00:00');
+set @@sql_mode= @old_mode;
+create or replace table t2 like t3;
+ERROR 42000: Invalid default value for 'dt'
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+# LOCK TABLES
+lock tables t2 write, t1 write;
+flush tables;
+show open tables like 't2';
+Database Table In_use Name_locked
+test t2 1 0
+create or replace table t2 (y int);
+flush tables;
+show open tables like 't2';
+Database Table In_use Name_locked
+test t2 1 0
+create or replace table t2 like t1;
+flush tables;
+show open tables like 't2';
+Database Table In_use Name_locked
+test t2 1 0
+create or replace table t2 (y int) as select * from t1;
+flush tables;
+show open tables like 't2';
+Database Table In_use Name_locked
+test t2 1 0
+unlock tables;
+# SP
+create or replace procedure sp(n int)
+begin
+select concat('sp call ', n, ':') as '';
+show open tables like 't2';
+create or replace table t2 (y int);
+select 'create or replace table t2 (y int);' as '';
+show open tables like 't2';
+insert into t2 values (2);
+select 'insert into t2 values (2);' as '';
+show open tables like 't2';
+create or replace table t2 like t1;
+select 'create or replace table t2 like t1;' as '';
+show open tables like 't2';
+create or replace table t2 (y int) as select * from t1;
+select 'create or replace table t2 (y int) as select * from t1;' as '';
+show open tables like 't2';
+select 'select * from t2;' as '';
+select * from t2;
+show open tables like 't2';
+end $
+flush tables;
+call sp(1);
+
+sp call 1:
+Database Table In_use Name_locked
+
+create or replace table t2 (y int);
+Database Table In_use Name_locked
+
+insert into t2 values (2);
+Database Table In_use Name_locked
+test t2 0 0
+
+create or replace table t2 like t1;
+Database Table In_use Name_locked
+
+create or replace table t2 (y int) as select * from t1;
+Database Table In_use Name_locked
+
+select * from t2;
+y a
+NULL 1
+NULL 1
+Database Table In_use Name_locked
+test t2 0 0
+call sp(2);
+
+sp call 2:
+Database Table In_use Name_locked
+test t2 0 0
+
+create or replace table t2 (y int);
+Database Table In_use Name_locked
+
+insert into t2 values (2);
+Database Table In_use Name_locked
+test t2 0 0
+
+create or replace table t2 like t1;
+Database Table In_use Name_locked
+
+create or replace table t2 (y int) as select * from t1;
+Database Table In_use Name_locked
+
+select * from t2;
+y a
+NULL 1
+NULL 1
+Database Table In_use Name_locked
+test t2 0 0
+# SP under LOCK TABLES
+lock tables t2 write, t1 write;
+call sp(3);
+
+sp call 3:
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 (y int);
+Database Table In_use Name_locked
+test t2 1 0
+
+insert into t2 values (2);
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 like t1;
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 (y int) as select * from t1;
+Database Table In_use Name_locked
+test t2 1 0
+
+select * from t2;
+y a
+NULL 1
+NULL 1
+Database Table In_use Name_locked
+test t2 1 0
+call sp(4);
+
+sp call 4:
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 (y int);
+Database Table In_use Name_locked
+test t2 1 0
+
+insert into t2 values (2);
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 like t1;
+Database Table In_use Name_locked
+test t2 1 0
+
+create or replace table t2 (y int) as select * from t1;
+Database Table In_use Name_locked
+test t2 1 0
+
+select * from t2;
+y a
+NULL 1
+NULL 1
+Database Table In_use Name_locked
+test t2 1 0
+unlock tables;
+drop procedure sp;
+drop tables t1, t2, t3;
+# Trigger
+create table t1 (a int);
+create trigger a before insert on t1 for each row set @s= 1;
+create or replace table t1 (old int);
+show create trigger a;
+ERROR HY000: Trigger does not exist
+drop table t1;
+# Foreign keys
+create table t1 (x int primary key, y int) engine innodb;
+create table t2 (x int references t1(x)) engine innodb;
+create or replace table t1 (x int primary key);
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+create or replace table t1 (x int primary key);
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+create table t3 (x int);
+create or replace table t1 like t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+create or replace table t1 like t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+create or replace table t1 select * from t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+create or replace table t1 select * from t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL,
+ `y` int(11) DEFAULT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop tables t3, t2, t1;
diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test
index 4b954263a87..d179ace3a1b 100644
--- a/mysql-test/main/create_or_replace.test
+++ b/mysql-test/main/create_or_replace.test
@@ -5,6 +5,8 @@
--source include/have_innodb.inc
--source include/have_metadata_lock_info.inc
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
#
# Create help table
#
@@ -227,6 +229,8 @@ create or replace table mysqltest2.t2;
--sorted_result
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
+drop table mysqltest2.t2;
+drop table t1;
create table t1 (i int);
drop table t1;
@@ -250,6 +254,8 @@ create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a';
--sorted_result
select * from information_schema.metadata_lock_info
where table_name not like 'innodb_%_stats';
+drop table mysqltest2.t2;
+drop table t1;
create table t1 (i int);
drop table t1;
@@ -288,6 +294,7 @@ lock table t1 write;
select * from information_schema.metadata_lock_info;
--error ER_DATA_TOO_LONG
create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a;
+drop table t1;
show tables;
--replace_column 1 #
--sorted_result
@@ -518,3 +525,101 @@ UNLOCK TABLES;
DROP TABLE t3;
--echo # End of 10.4 tests
+
+--echo #
+--echo # MDEV-25292 Atomic CREATE OR REPLACE TABLE
+--echo #
+create table t1 (a int);
+insert t1 values (1), (1);
+create table t2 (c int);
+--error ER_DUP_KEYNAME
+create or replace table t2 (a int, b int, key k (a), key k (b));
+show create table t2;
+--error ER_DUP_KEYNAME
+create or replace table t2 (a int, b int, key k (a), key k (b)) as select a, a as b from t1;
+show create table t2;
+--error ER_DUP_ENTRY
+create or replace table t2 (a int primary key) as select * from t1;
+show create table t2;
+set @old_mode= @@sql_mode;
+set @@sql_mode='ALLOW_INVALID_DATES';
+create table t3 (dt datetime default '2008-02-31 00:00:00');
+set @@sql_mode= @old_mode;
+--error ER_INVALID_DEFAULT
+create or replace table t2 like t3;
+show create table t2;
+--echo # LOCK TABLES
+lock tables t2 write, t1 write;
+flush tables;
+show open tables like 't2';
+create or replace table t2 (y int);
+flush tables;
+show open tables like 't2';
+create or replace table t2 like t1;
+flush tables;
+show open tables like 't2';
+create or replace table t2 (y int) as select * from t1;
+flush tables;
+show open tables like 't2';
+unlock tables;
+--echo # SP
+--delimiter $
+create or replace procedure sp(n int)
+begin
+ select concat('sp call ', n, ':') as '';
+ show open tables like 't2';
+ create or replace table t2 (y int);
+ select 'create or replace table t2 (y int);' as '';
+ show open tables like 't2';
+ insert into t2 values (2);
+ select 'insert into t2 values (2);' as '';
+ show open tables like 't2';
+ create or replace table t2 like t1;
+ select 'create or replace table t2 like t1;' as '';
+ show open tables like 't2';
+ create or replace table t2 (y int) as select * from t1;
+ select 'create or replace table t2 (y int) as select * from t1;' as '';
+ show open tables like 't2';
+ select 'select * from t2;' as '';
+ select * from t2;
+ show open tables like 't2';
+end $
+--delimiter ;
+flush tables;
+call sp(1); call sp(2);
+--echo # SP under LOCK TABLES
+lock tables t2 write, t1 write;
+call sp(3); call sp(4);
+unlock tables;
+drop procedure sp;
+drop tables t1, t2, t3;
+--echo # Trigger
+create table t1 (a int);
+create trigger a before insert on t1 for each row set @s= 1;
+create or replace table t1 (old int);
+--error ER_TRG_DOES_NOT_EXIST
+show create trigger a;
+drop table t1;
+--echo # Foreign keys
+--list_files $MYSQLD_DATADIR/test *sql*
+create table t1 (x int primary key, y int) engine innodb;
+create table t2 (x int references t1(x)) engine innodb;
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 (x int primary key);
+--list_files $MYSQLD_DATADIR/test *sql*
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 (x int primary key);
+create table t3 (x int);
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 like t3;
+--list_files $MYSQLD_DATADIR/test *sql*
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 like t3;
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 select * from t3;
+--error ER_ROW_IS_REFERENCED_2
+create or replace table t1 select * from t3;
+--list_files $MYSQLD_DATADIR/test *sql*
+
+show create table t1;
+drop tables t3, t2, t1;
diff --git a/mysql-test/main/create_or_replace2.result b/mysql-test/main/create_or_replace2.result
index 6be0d46bdc1..51b175d7c10 100644
--- a/mysql-test/main/create_or_replace2.result
+++ b/mysql-test/main/create_or_replace2.result
@@ -21,6 +21,13 @@ connection slave;
SHOW TABLES;
Tables_in_test
t1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
connection master;
drop temporary table if exists tmp;
drop table t1;
diff --git a/mysql-test/main/create_or_replace2.test b/mysql-test/main/create_or_replace2.test
index 80c8b635d8d..a347cc704f8 100644
--- a/mysql-test/main/create_or_replace2.test
+++ b/mysql-test/main/create_or_replace2.test
@@ -26,6 +26,7 @@ SHOW TABLES;
show create table t1;
--sync_slave_with_master
SHOW TABLES;
+show create table t1;
--connection master
--disable_warnings
diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result
index 493101f10ee..efe669c861b 100644
--- a/mysql-test/main/default.result
+++ b/mysql-test/main/default.result
@@ -430,14 +430,6 @@ a b c e
2 -1 1 1
drop table t1;
#
-# Create or replace can delete a table on error
-#
-create table t1 (a int);
-create or replace table t1 (a int default b, b int default a);
-ERROR 01000: Expression for field `a` is referring to uninitialized field `b`
-show create table t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
-#
# Refering to other columns
#
create or replace table t1 (a int default 1, b int default a);
@@ -455,11 +447,11 @@ ERROR 01000: Expression for field `a` is referring to uninitialized field `a`
create or replace table t1 (a int default b, b int default (1+1));
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
ERROR 01000: Expression for field `b` is referring to uninitialized field `c`
-CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
ERROR 01000: Expression for field `a` is referring to uninitialized field `a`
-CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a)));
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a)));
ERROR 01000: Expression for field `a` is referring to uninitialized field `b`
-CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL);
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL);
ERROR 01000: Expression for field `a` is referring to uninitialized field `b`
#
# Allow defaults to refer to not default fields
diff --git a/mysql-test/main/default.test b/mysql-test/main/default.test
index bcd6ef7a9fb..ce4e1b2e7a0 100644
--- a/mysql-test/main/default.test
+++ b/mysql-test/main/default.test
@@ -314,15 +314,6 @@ select * from t1;
drop table t1;
--echo #
---echo # Create or replace can delete a table on error
---echo #
-create table t1 (a int);
---error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
-create or replace table t1 (a int default b, b int default a);
---error ER_NO_SUCH_TABLE
-show create table t1;
-
---echo #
--echo # Refering to other columns
--echo #
@@ -344,11 +335,11 @@ create or replace table t1 (a int default b, b int default (1+1));
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
-CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
-CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a)));
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a)));
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
-CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL);
+CREATE OR REPLACE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL);
--echo #
--echo # Allow defaults to refer to not default fields
diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result
index ae736d625b2..f60c8f9449e 100644
--- a/mysql-test/main/long_unique_bugs.result
+++ b/mysql-test/main/long_unique_bugs.result
@@ -358,7 +358,8 @@ c d
create or replace table t2 (a int, b blob, unique(b)) as select * from t1;
ERROR 23000: Duplicate entry 'bar' for key 'b'
select * from t2;
-ERROR 42S02: Table 'test.t2' doesn't exist
+c d
+3 bar
create or replace table t2 (a int, b blob, unique(b)) ignore as select * from t1;
Warnings:
Warning 1062 Duplicate entry 'bar' for key 'b'
diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test
index 18bad7deac9..1284d3e4b62 100644
--- a/mysql-test/main/long_unique_bugs.test
+++ b/mysql-test/main/long_unique_bugs.test
@@ -440,7 +440,6 @@ delete from t2 using t1, t2 where t1.a=t2.c and t1.b='foo';
# CREATE...SELECT
--error ER_DUP_ENTRY
create or replace table t2 (a int, b blob, unique(b)) as select * from t1;
---error ER_NO_SUCH_TABLE
select * from t2;
create or replace table t2 (a int, b blob, unique(b)) ignore as select * from t1;
select * from t2;
diff --git a/mysql-test/suite/atomic/create_replace,expensive_rename,row.rdiff b/mysql-test/suite/atomic/create_replace,expensive_rename,row.rdiff
new file mode 100644
index 00000000000..09c0255a6ab
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,expensive_rename,row.rdiff
@@ -0,0 +1,333 @@
+--- create_replace.result
++++ create_replace,expensive_rename,row.reject
+@@ -14,60 +14,28 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+ t1.MAD
+@@ -80,16 +48,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+ t1.MAD
+@@ -133,60 +93,29 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+ t1.MAD
+@@ -200,16 +129,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+ t1.MAD
+@@ -257,108 +178,54 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++new b
++1 1
++2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+-t1.MAD
+-t1.MAI
+-t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `new` int(11) DEFAULT NULL,
+- `b` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-new b
+-1 1
+-2 2
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -372,7 +239,11 @@
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -386,7 +257,11 @@
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
diff --git a/mysql-test/suite/atomic/create_replace,expensive_rename.rdiff b/mysql-test/suite/atomic/create_replace,expensive_rename.rdiff
new file mode 100644
index 00000000000..ccc2919a33a
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,expensive_rename.rdiff
@@ -0,0 +1,289 @@
+--- create_replace.result
++++ create_replace,expensive_rename.reject
+@@ -14,60 +14,28 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+ t1.MAD
+@@ -80,16 +48,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+ t1.MAD
+@@ -133,60 +93,29 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+ t1.MAD
+@@ -200,16 +129,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+ t1.MAD
+@@ -257,89 +178,38 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
++# No crash!
+ t1.MAD
+ t1.MAI
+-t1.TRG
+ t1.frm
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++new b
++1 1
++2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+-t1.TRG
+-t1.frm
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `old` int(11) DEFAULT NULL
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-old
++master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by ddl recovery */
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+-a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ t1.MAD
+ t1.MAI
+@@ -350,10 +220,6 @@
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-Warnings:
+-Error 145 Table './test/t1' is marked as crashed and should be repaired
+-Warning 1034 1 client is using or hasn't closed the table properly
+-Note 1034 Table is fixed
+ new b
+ 1 1
+ 2 2
diff --git a/mysql-test/suite/atomic/create_replace,ib,row.rdiff b/mysql-test/suite/atomic/create_replace,ib,row.rdiff
new file mode 100644
index 00000000000..37514617edf
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,ib,row.rdiff
@@ -0,0 +1,410 @@
+--- create_replace.result
++++ create_replace,ib,row.reject
+@@ -14,10 +14,9 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -25,10 +24,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -36,10 +34,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -47,10 +44,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -58,10 +54,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -70,9 +65,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -80,10 +74,9 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -92,9 +85,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -102,9 +94,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -112,9 +103,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -122,9 +112,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -133,10 +122,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -144,10 +132,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -155,10 +142,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -166,10 +152,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -177,10 +162,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -189,9 +173,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -200,10 +183,9 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -212,9 +194,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -223,9 +204,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -234,9 +214,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -245,9 +224,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -257,10 +235,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -269,10 +246,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -281,10 +257,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -293,10 +268,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -305,10 +279,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -317,10 +290,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -329,10 +301,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -341,24 +312,24 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+-t1.MAD
+-t1.MAI
++t1.TRG
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `new` int(11) DEFAULT NULL,
+- `b` int(11) DEFAULT NULL
++ `old` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-new b
+-1 1
+-2 2
++old
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
++a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++t1.ibd
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -369,10 +340,13 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++t1.ibd
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -383,10 +357,13 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++t1.ibd
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
diff --git a/mysql-test/suite/atomic/create_replace,ib.rdiff b/mysql-test/suite/atomic/create_replace,ib.rdiff
new file mode 100644
index 00000000000..5fe2849545f
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,ib.rdiff
@@ -0,0 +1,384 @@
+--- create_replace.result
++++ create_replace,ib.reject
+@@ -14,10 +14,9 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -25,10 +24,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -36,10 +34,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -47,10 +44,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -58,10 +54,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -70,9 +65,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -80,10 +74,9 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -92,9 +85,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -102,9 +94,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -112,9 +103,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -122,9 +112,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -133,10 +122,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -144,10 +132,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -155,10 +142,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -166,10 +152,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -177,10 +162,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -189,9 +173,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -200,10 +183,9 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -212,9 +194,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -223,9 +204,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -234,9 +214,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -245,9 +224,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -257,10 +235,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -269,10 +246,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -281,10 +257,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -293,10 +268,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -305,10 +279,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -317,10 +290,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -329,10 +301,9 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
+ t1.TRG
+ t1.frm
++t1.ibd
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+@@ -341,9 +312,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -355,9 +325,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -369,9 +338,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+@@ -383,9 +351,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
+ t1.frm
++t1.ibd
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
diff --git a/mysql-test/suite/atomic/create_replace,myisam,row.rdiff b/mysql-test/suite/atomic/create_replace,myisam,row.rdiff
new file mode 100644
index 00000000000..8c10bee1082
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,myisam,row.rdiff
@@ -0,0 +1,395 @@
+--- create_replace.result
++++ create_replace,myisam,row.reject
+@@ -14,8 +14,8 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -25,8 +25,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -36,8 +36,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -47,8 +47,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -58,8 +58,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -70,8 +70,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -80,8 +80,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -92,8 +92,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -102,8 +102,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -112,8 +112,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -122,8 +122,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -133,8 +133,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -144,8 +144,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -155,8 +155,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -166,8 +166,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -177,8 +177,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -189,8 +189,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -200,8 +200,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -212,8 +212,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -223,8 +223,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -234,8 +234,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -245,8 +245,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -257,8 +257,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -269,8 +269,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -281,8 +281,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -293,8 +293,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -305,8 +305,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -317,8 +317,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -329,8 +329,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -341,24 +341,26 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
++t1.TRG
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `new` int(11) DEFAULT NULL,
+- `b` int(11) DEFAULT NULL
++ `old` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-new b
+-1 1
+-2 2
++old
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
++a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -369,10 +371,14 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -383,10 +389,14 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++)
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
diff --git a/mysql-test/suite/atomic/create_replace,myisam.rdiff b/mysql-test/suite/atomic/create_replace,myisam.rdiff
new file mode 100644
index 00000000000..4f22d61feda
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,myisam.rdiff
@@ -0,0 +1,365 @@
+--- create_replace.result
++++ create_replace,myisam.reject
+@@ -14,8 +14,8 @@
+ flush tables;
+ # QUERY: CREATE OR REPLACE TABLE t1 (new int)
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -25,8 +25,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -36,8 +36,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -47,8 +47,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -58,8 +58,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -70,8 +70,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -80,8 +80,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -92,8 +92,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -102,8 +102,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -112,8 +112,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -122,8 +122,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+ Table Create Table
+@@ -133,8 +133,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -144,8 +144,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -155,8 +155,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -166,8 +166,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -177,8 +177,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -189,8 +189,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -200,8 +200,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -212,8 +212,8 @@
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ # No crash!
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -223,8 +223,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -234,8 +234,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -245,8 +245,8 @@
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+ Table Create Table
+@@ -257,8 +257,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ # CRASH POINT: ddl_log_create_after_log_rename
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -269,8 +269,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_frm
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -281,8 +281,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -293,8 +293,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_create_table
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -305,8 +305,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_drop
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -317,8 +317,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_send_data
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -329,8 +329,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_before_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.TRG
+ t1.frm
+ Table Create Table
+@@ -341,8 +341,8 @@
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+@@ -355,8 +355,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_after_binlog
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+@@ -369,8 +369,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_before_remove_backup
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+@@ -383,8 +383,8 @@
+ 2 2
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+ # CRASH POINT: ddl_log_create_log_complete
+-t1.MAD
+-t1.MAI
++t1.MYD
++t1.MYI
+ t1.frm
+ master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
diff --git a/mysql-test/suite/atomic/create_replace,row.rdiff b/mysql-test/suite/atomic/create_replace,row.rdiff
new file mode 100644
index 00000000000..b926ba9d792
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace,row.rdiff
@@ -0,0 +1,60 @@
+--- create_replace.result
++++ create_replace,row.reject
+@@ -343,22 +343,24 @@
+ # CRASH POINT: ddl_log_create_after_prepare_eof
+ t1.MAD
+ t1.MAI
++t1.TRG
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+- `new` int(11) DEFAULT NULL,
+- `b` int(11) DEFAULT NULL
++ `old` int(11) DEFAULT NULL
+ ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+-new b
+-1 1
+-2 2
++old
+ Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
++a INSERT t1 set @s= 1 BEFORE
+ # CRASH POINT: ddl_log_create_after_binlog
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -372,7 +374,11 @@
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+@@ -386,7 +392,11 @@
+ t1.MAD
+ t1.MAI
+ t1.frm
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
++ `new` int(11) DEFAULT NULL,
++ `b` int(11) DEFAULT NULL
++) PAGE_CHECKSUM=1
++master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t1 SELECT * from const_table
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
diff --git a/mysql-test/suite/atomic/create_replace.combinations b/mysql-test/suite/atomic/create_replace.combinations
new file mode 100644
index 00000000000..72a359c77eb
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace.combinations
@@ -0,0 +1,5 @@
+[ib]
+[myisam]
+[aria]
+[aria_notrans]
+[expensive_rename]
diff --git a/mysql-test/suite/atomic/create_replace.result b/mysql-test/suite/atomic/create_replace.result
new file mode 100644
index 00000000000..7e09920fbfb
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace.result
@@ -0,0 +1,400 @@
+create table t1 (c int);
+create or replace table t1 (a int, b int, key k (a), key k (b));
+ERROR 42000: Duplicate key name 'k'
+create or replace table t1 (a int, b int, key k (a), key k (b));
+ERROR 42000: Duplicate key name 'k'
+drop table t1;
+# Crash recovery
+Table Create Table
+const_table CREATE TABLE `const_table` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+insert into const_table values (1, 1), (2, 2);
+flush tables;
+# QUERY: CREATE OR REPLACE TABLE t1 (new int)
+# CRASH POINT: ddl_log_create_after_log_rename
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_frm
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_drop
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_send_data
+# No crash!
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_before_binlog
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_prepare_eof
+# No crash!
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_after_binlog
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_before_remove_backup
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_log_complete
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (new int)
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# QUERY: CREATE OR REPLACE TABLE t1 LIKE const_table
+# CRASH POINT: ddl_log_create_after_log_rename
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_frm
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_drop
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_send_data
+# No crash!
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_before_binlog
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_prepare_eof
+# No crash!
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_after_binlog
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_before_remove_backup
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_log_complete
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# QUERY: CREATE OR REPLACE TABLE t1 SELECT * from const_table
+# CRASH POINT: ddl_log_create_after_log_rename
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_frm
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_create_table
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_drop
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_send_data
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_before_binlog
+t1.MAD
+t1.MAI
+t1.TRG
+t1.frm
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `old` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+old
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+a INSERT t1 set @s= 1 BEFORE
+# CRASH POINT: ddl_log_create_after_prepare_eof
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+new b
+1 1
+2 2
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_after_binlog
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+new b
+1 1
+2 2
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_before_remove_backup
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+new b
+1 1
+2 2
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+# CRASH POINT: ddl_log_create_log_complete
+t1.MAD
+t1.MAI
+t1.frm
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 SELECT * from const_table
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `new` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+new b
+1 1
+2 2
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+Warnings:
+Note 1051 Unknown table 'test.t1'
diff --git a/mysql-test/suite/atomic/create_replace.test b/mysql-test/suite/atomic/create_replace.test
new file mode 100644
index 00000000000..c16165f96ef
--- /dev/null
+++ b/mysql-test/suite/atomic/create_replace.test
@@ -0,0 +1,193 @@
+--source include/have_debug.inc
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+--source include/log_bin.inc
+--source include/not_valgrind.inc
+
+--disable_query_log
+let $default_engine=InnoDB;
+let $extra_option=;
+let $save_debug=`select @@debug_dbug`;
+let $show_error=0;
+let $drop_error=0;
+
+if ($MTR_COMBINATION_MYISAM)
+{
+ let $default_engine=MyISAM;
+}
+if ($MTR_COMBINATION_ARIA)
+{
+ let $default_engine=Aria;
+ call mtr.add_suppression("Checking table");
+ call mtr.add_suppression("marked as crashed");
+}
+if ($MTR_COMBINATION_ARIA_NOTRANS)
+{
+ let $default_engine=Aria;
+ # FIXME: extra option not used
+ let $extra_option=transactional=0;
+ call mtr.add_suppression("Checking table");
+ call mtr.add_suppression("marked as crashed");
+}
+if ($MTR_COMBINATION_EXPENSIVE_RENAME)
+{
+ let $default_engine=Aria;
+ let $extra_option=transactional=0;
+ let $show_error=0, ER_NO_SUCH_TABLE;
+ let $drop_error=0, ER_BAD_TABLE_ERROR;
+ set @@debug_dbug="+d,ddl_log_expensive_rename";
+}
+
+if ($MTR_COMBINATION_STMT)
+{
+ let $binlog_format=include/set_binlog_format_statement.sql;
+}
+if ($MTR_COMBINATION_ROW)
+{
+ let $binlog_format=include/set_binlog_format_row.sql;
+}
+if ($MTR_COMBINATION_MIX)
+{
+ --skip same as stmt
+}
+
+--eval set @@default_storage_engine=$default_engine
+--enable_query_log
+
+# Put entry_pos into higher position, so drop chain executes before create chain
+create table t1 (c int);
+--error ER_DUP_KEYNAME
+create or replace table t1 (a int, b int, key k (a), key k (b));
+--error ER_DUP_KEYNAME
+create or replace table t1 (a int, b int, key k (a), key k (b));
+--error $drop_error
+drop table t1;
+
+--echo # Crash recovery
+
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
+let $crash_count=11;
+let $crash_points='ddl_log_create_after_log_rename',
+ 'ddl_log_create_before_create_frm',
+ 'ddl_log_create_before_create_table',
+ 'ddl_log_create_after_create_table',
+ 'ddl_log_create_after_drop',
+ 'ddl_log_create_after_send_data',
+ 'ddl_log_create_before_binlog',
+ 'ddl_log_create_after_prepare_eof',
+ 'ddl_log_create_after_binlog',
+ 'ddl_log_create_before_remove_backup',
+ 'ddl_log_create_log_complete';
+
+#let $crash_count=1;
+#let $crash_points='ddl_log_create_log_complete';
+
+let $statement_count=3;
+let $statements='CREATE OR REPLACE TABLE t1 (new int)',
+ 'CREATE OR REPLACE TABLE t1 LIKE const_table',
+ 'CREATE OR REPLACE TABLE t1 SELECT * from const_table';
+
+#let $statement_count=1;
+#let $statements='CREATE OR REPLACE TABLE t1 SELECT * from const_table';
+
+--disable_query_log
+eval create table const_table (new int, b int) $extra_option;
+--replace_result $default_engine DEFAULT_ENGINE ' PAGE_CHECKSUM=1' '' ' TRANSACTIONAL=0' ''
+show create table const_table;
+--enable_query_log
+insert into const_table values (1, 1), (2, 2);
+flush tables;
+
+let $old_debug=`select @@debug_dbug`;
+
+let $keep_include_silent=1;
+let $grep_script=CREATE|DROP;
+--disable_query_log
+
+let $r=0;
+while ($r < $statement_count)
+{
+ inc $r;
+ let $STATEMENT=`select ELT($r, $statements)`;
+ if ($r == 0)
+ {
+ let $STATEMENT= $STATEMENT $extra_option;
+ }
+ --echo # QUERY: $STATEMENT
+
+ let $c=0;
+ while ($c < $crash_count)
+ {
+ inc $c;
+ let $crash=`select ELT($c, $crash_points)`;
+
+ --eval set @@default_storage_engine=$default_engine
+ create or replace table t1 (old int);
+ create trigger a before insert on t1 for each row set @s= 1;
+ flush tables;
+ if (!$c)
+ {
+ lock tables t1 write;
+ }
+
+ --source $binlog_format
+
+ RESET MASTER;
+ --echo # CRASH POINT: $crash
+ --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+ --disable_reconnect
+ --eval set @@debug_dbug="+d,$crash",@debug_crash_counter=1
+ let $errno=0;
+ --error 0,2013
+ eval $STATEMENT;
+ let $error=$errno;
+ --enable_reconnect
+ --source include/wait_until_connected_again.inc
+ --disable_query_log
+ --eval set @@debug_dbug="$old_debug"
+
+ if ($error == 0)
+ {
+ --echo # No crash!
+ }
+ # Check which tables still exists
+ --list_files $MYSQLD_DATADIR/test t*
+ --list_files $MYSQLD_DATADIR/test *sql*
+
+ --let $binlog_file=master-bin.000001
+ --source include/show_binlog_events.inc
+ if ($error)
+ {
+ --let $binlog_file=master-bin.000002
+ --source include/show_binlog_events.inc
+ }
+
+ if ($default_engine == Aria)
+ {
+ # Again we suppress 'marked as crashed', it works differently in --ps
+ --disable_warnings
+ }
+ --replace_result $default_engine DEFAULT_ENGINE ' PAGE_CHECKSUM=1' '' ' TRANSACTIONAL=0' ''
+ --error $show_error
+ show create table t1;
+ --enable_warnings
+ if (`select locate('SELECT', '$STATEMENT')`)
+ {
+ --error $show_error
+ select * from t1;
+ }
+ --enable_warnings
+ --replace_column 6 '' 7 '' 8 '' 9 '' 10 '' 11 ''
+ show triggers;
+ # Drop the tables. The warnings will show what was dropped
+ --disable_warnings
+ --error $drop_error
+ drop table t1;
+ --enable_warnings
+ }
+}
+drop table if exists t1,const_table;
+--eval set @@debug_dbug="$save_debug"
+
+--enable_query_log
diff --git a/mysql-test/suite/atomic/create_table.result b/mysql-test/suite/atomic/create_table.result
index acc78c76d25..82c757a271d 100644
--- a/mysql-test/suite/atomic/create_table.result
+++ b/mysql-test/suite/atomic/create_table.result
@@ -55,7 +55,6 @@ t2.MYI
t2.frm
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
crash point: ddl_log_create_log_complete
-"No crash!"
t1.MYD
t1.MYI
t1.frm
@@ -63,40 +62,6 @@ t2.MYD
t2.MYI
t2.frm
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
-query: CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_after_binlog
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_log_complete
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
query: CREATE TABLE t1 LIKE const_table
crash point: ddl_log_create_before_create_frm
t2.MYD
@@ -150,7 +115,6 @@ t2.MYI
t2.frm
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 LIKE const_table
crash point: ddl_log_create_log_complete
-"No crash!"
t1.MYD
t1.MYI
t1.frm
@@ -158,40 +122,6 @@ t2.MYD
t2.MYI
t2.frm
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 LIKE const_table
-query: CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_after_binlog
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_log_complete
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
query: CREATE TABLE t1 SELECT * from t2
crash point: ddl_log_create_before_create_frm
t2.MYD
@@ -259,47 +189,6 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE `t1` (
`seq` bigint(20) unsigned NOT NULL
)
master-bin.000001 # Annotate_rows # # CREATE TABLE t1 SELECT * from t2
-query: CREATE OR REPLACE TABLE t2 SELECT * from const_table
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
- `a` int(11) DEFAULT NULL,
- `b` int(11) DEFAULT NULL
-)
-master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t2 SELECT * from const_table
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_binlog
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
- `a` int(11) DEFAULT NULL,
- `b` int(11) DEFAULT NULL
-)
-master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t2 SELECT * from const_table
-crash point: ddl_log_create_log_complete
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
- `a` int(11) DEFAULT NULL,
- `b` int(11) DEFAULT NULL
-)
-master-bin.000001 # Annotate_rows # # CREATE OR REPLACE TABLE t2 SELECT * from const_table
engine: innodb
query: CREATE TABLE t1 (a int)
crash point: ddl_log_create_before_create_frm
@@ -342,42 +231,11 @@ t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
crash point: ddl_log_create_log_complete
-"No crash!"
t1.frm
t1.ibd
t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
-query: CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-"No crash!"
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_after_binlog
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
-crash point: ddl_log_create_log_complete
-"No crash!"
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 (a int)
query: CREATE TABLE t1 LIKE const_table
crash point: ddl_log_create_before_create_frm
t2.frm
@@ -423,47 +281,12 @@ t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 LIKE const_table
crash point: ddl_log_create_log_complete
-"No crash!"
t1.MYD
t1.MYI
t1.frm
t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 LIKE const_table
-query: CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_after_binlog
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
-crash point: ddl_log_create_log_complete
-"No crash!"
-t2.MYD
-t2.MYI
-t2.frm
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 LIKE const_table
query: CREATE TABLE t1 SELECT * from t2
crash point: ddl_log_create_before_create_frm
t2.frm
@@ -492,46 +315,22 @@ crash point: ddl_log_create_before_binlog
t2.frm
t2.ibd
crash point: ddl_log_create_after_prepare_eof
+t1.frm
+t1.ibd
t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 SELECT * from t2
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
crash point: ddl_log_create_after_binlog
+t1.frm
+t1.ibd
t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 SELECT * from t2
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t1` /* generated by ddl recovery */
crash point: ddl_log_create_log_complete
t1.frm
t1.ibd
t2.frm
t2.ibd
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 SELECT * from t2
-query: CREATE OR REPLACE TABLE t2 SELECT * from const_table
-crash point: ddl_log_create_before_create_frm
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: storage_engine_middle_of_create
-"No crash!"
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 SELECT * from const_table
-crash point: ddl_log_create_before_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_create_table
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_drop
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_before_binlog
-master-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_prepare_eof
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 SELECT * from const_table
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t2` /* generated by ddl recovery */
-crash point: ddl_log_create_after_binlog
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 SELECT * from const_table
-master-bin.000002 # Query # # DROP TABLE IF EXISTS `test`.`t2` /* generated by ddl recovery */
-crash point: ddl_log_create_log_complete
-t2.frm
-t2.ibd
-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t2 SELECT * from const_table
Warnings:
Note 1051 Unknown table 'test.t1,test.t2'
diff --git a/mysql-test/suite/atomic/create_table.test b/mysql-test/suite/atomic/create_table.test
index ff53a12ebab..5cb3b03fa7d 100644
--- a/mysql-test/suite/atomic/create_table.test
+++ b/mysql-test/suite/atomic/create_table.test
@@ -30,13 +30,10 @@ if ($engine_count == "")
let $crash_count=9;
let $crash_points='ddl_log_create_before_create_frm', 'storage_engine_middle_of_create', 'ddl_log_create_before_create_table', 'ddl_log_create_after_create_table', 'ddl_log_create_after_drop', 'ddl_log_create_before_binlog', 'ddl_log_create_after_prepare_eof', 'ddl_log_create_after_binlog', 'ddl_log_create_log_complete';
-let $statement_count=6;
+let $statement_count=3;
let $statements='CREATE TABLE t1 (a int)',
- 'CREATE OR REPLACE TABLE t2 (a int)',
'CREATE TABLE t1 LIKE const_table',
- 'CREATE OR REPLACE TABLE t2 LIKE const_table',
- 'CREATE TABLE t1 SELECT * from t2',
- 'CREATE OR REPLACE TABLE t2 SELECT * from const_table';
+ 'CREATE TABLE t1 SELECT * from t2';
create table const_table (a int, b int) engine=myisam;
insert into const_table values (1,1),(2,2);
@@ -58,6 +55,7 @@ while ($e < $engine_count)
if ($engine == "aria")
{
+ # TODO: unused $extra_option
let $extra_option=transactional=1;
}
if ($engine == "aria_notrans")
diff --git a/mysql-test/suite/parts/r/backup_log.result b/mysql-test/suite/parts/r/backup_log.result
index 3a220491027..4664d611f1f 100644
--- a/mysql-test/suite/parts/r/backup_log.result
+++ b/mysql-test/suite/parts/r/backup_log.result
@@ -2,7 +2,7 @@ connect con1,localhost,root,,;
BACKUP STAGE START;
connection default;
#
-# Testing with normal tables
+# Testing normal tables
#
create table t1 (a int) engine=myisam PARTITION BY HASH(a) PARTITIONS 2;
insert into t1 values (1),(2);
@@ -17,6 +17,17 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
drop table t1;
+#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t1,id: 1,,0,,,
+ALTER,MyISAM,1,test,t1,id: 1,MyISAM,1,test,t1,id: 2
+RENAME,MyISAM,1,test,t1,id: 2,MyISAM,1,test,t2,id: 2
+RENAME,MyISAM,1,test,t2,id: 2,MyISAM,1,test,t1,id: 2
+TRUNCATE,MyISAM,1,test,t1,id: 2,,0,,,
+repair,MyISAM,1,test,t1,id: 2,,0,,,
+optimize,MyISAM,1,test,t1,id: 2,,0,,,
+DROP,MyISAM,1,test,t1,id: 2,,0,,,
create table t1_innodb (a int) engine=innodb PARTITION BY HASH(a) PARTITIONS 2;
insert into t1_innodb values (1),(2);
alter table t1_innodb add column b int;
@@ -32,6 +43,17 @@ test.t1_innodb optimize note Table does not support optimize, doing recreate + a
test.t1_innodb optimize status OK
drop table t1_innodb;
#
+# Reading backup ddl log file
+#
+CREATE,InnoDB,1,test,t1_innodb,id: 1,,0,,,
+ALTER,InnoDB,1,test,t1_innodb,id: 1,InnoDB,1,test,t1_innodb,id: 2
+RENAME,InnoDB,1,test,t1_innodb,id: 2,InnoDB,1,test,t2_innodb,id: 2
+RENAME,InnoDB,1,test,t2_innodb,id: 2,InnoDB,1,test,t1_innodb,id: 2
+TRUNCATE,InnoDB,1,test,t1_innodb,id: 2,,0,,,
+repair,InnoDB,1,test,t1_innodb,id: 2,,0,,,
+ALTER,InnoDB,1,test,t1_innodb,id: 2,InnoDB,1,test,t1_innodb,id: 3
+DROP,InnoDB,1,test,t1_innodb,id: 3,,0,,,
+#
# Testing with temporary tables (should not be logged)
#
create temporary table tmp_t10 (a int) engine=myisam;
@@ -41,6 +63,9 @@ rename table tmp_t11 to tmp_t10;
truncate table tmp_t10;
drop table tmp_t10;
#
+# Reading backup ddl log file
+#
+#
# Testing with mix of normal and temporary tables
#
create temporary table tmp_t20 (a int);
@@ -55,6 +80,13 @@ drop table if exists tmp_t21,t21;
Warnings:
Note 1051 Unknown table 'test.tmp_t21'
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t20,id: 1,,0,,,
+DROP,MyISAM,1,test,t20,id: 1,,0,,,
+CREATE,MyISAM,1,test,t21,id: 2,,0,,,
+DROP,MyISAM,1,test,t21,id: 2,,0,,,
+#
# Testing create select
#
create table t30 (a int) PARTITION BY HASH(a) PARTITIONS 2;
@@ -67,7 +99,18 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
create table t32 (a int) PARTITION BY HASH(a) PARTITIONS 2;
drop table if exists t30,t31,t32,tmp_t30;
Warnings:
-Note 1051 Unknown table 'test.t31,test.tmp_t30'
+Note 1051 Unknown table 'test.tmp_t30'
+#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t30,id: 1,,0,,,
+CREATE,MyISAM,1,test,t31,id: 2,,0,,,
+DROP,MyISAM,1,test,t31,id: 2,,0,,,
+CREATE,MyISAM,0,test,t31,id: 3,,0,,,
+CREATE,MyISAM,1,test,t32,id: 4,,0,,,
+DROP,MyISAM,1,test,t30,id: 1,,0,,,
+DROP,MyISAM,0,test,t31,id: 3,,0,,,
+DROP,MyISAM,1,test,t32,id: 4,,0,,,
#
# Testing create LIKE
#
@@ -85,6 +128,17 @@ t42 CREATE TABLE `t42` (
PARTITIONS 2
drop table t40, t41, t42;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t40,id: 1,,0,,,
+CREATE,InnoDB,1,test,t41,id: 2,,0,,,
+CREATE,partition,0,test,t42,id: 3,,0,,,
+DROP,MyISAM,1,test,t42,id: 3,,0,,,
+CREATE,partition,0,test,t42,id: 4,,0,,,
+DROP,MyISAM,1,test,t40,id: 1,,0,,,
+DROP,InnoDB,1,test,t41,id: 2,,0,,,
+DROP,InnoDB,1,test,t42,id: 4,,0,,,
+#
# Testing rename
#
create table t50 (a int) PARTITION BY HASH(a) PARTITIONS 2;
@@ -93,6 +147,18 @@ rename table t50 to t52, t51 to t53;
rename table t52 to tmp, t53 to t52, tmp to t53;
drop table t52,t53;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t50,id: 1,,0,,,
+CREATE,MyISAM,1,test,t51,id: 2,,0,,,
+RENAME,MyISAM,1,test,t50,id: 1,MyISAM,1,test,t52,id: 1
+RENAME,MyISAM,1,test,t51,id: 2,MyISAM,1,test,t53,id: 2
+RENAME,MyISAM,1,test,t52,id: 1,MyISAM,1,test,tmp,id: 1
+RENAME,MyISAM,1,test,t53,id: 2,MyISAM,1,test,t52,id: 2
+RENAME,MyISAM,1,test,tmp,id: 1,MyISAM,1,test,t53,id: 1
+DROP,MyISAM,1,test,t52,id: 2,,0,,,
+DROP,MyISAM,1,test,t53,id: 1,,0,,,
+#
# Testing enable/disable keys
#
CREATE TABLE t60 (a int(10), index(a) ) ENGINE=Aria PARTITION BY HASH(a) PARTITIONS 2;
@@ -106,6 +172,13 @@ INSERT INTO t61 VALUES(1),(2),(3);
ALTER TABLE t61 DISABLE KEYS;
DROP TABLE t61;
#
+# Reading backup ddl log file
+#
+CREATE,Aria,1,test,t60,id: 1,,0,,,
+CHANGE_INDEX,Aria,1,test,t60,id: 1,,0,,,
+CHANGE_INDEX,Aria,1,test,t60,id: 1,,0,,,
+DROP,Aria,1,test,t60,id: 1,,0,,,
+#
# Testing load data
#
create table t70 (a date, b date, c date not null, d date) engine=aria PARTITION BY HASH(YEAR(a)) PARTITIONS 2;
@@ -122,11 +195,30 @@ insert into t71 select * from t70;
unlock tables;
drop table t70,t71;
#
+# Reading backup ddl log file
+#
+CREATE,Aria,1,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,1,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,1,test,t70,id: 1,,0,,,
+TRUNCATE,Aria,1,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,1,test,t70,id: 1,,0,,,
+BULK_INSERT,Aria,1,test,t70,id: 1,,0,,,
+CREATE,Aria,1,test,t71,id: 2,,0,,,
+BULK_INSERT,Aria,1,test,t71,id: 2,,0,,,
+BULK_INSERT,Aria,1,test,t71,id: 2,,0,,,
+DROP,Aria,1,test,t70,id: 1,,0,,,
+DROP,Aria,1,test,t71,id: 2,,0,,,
+#
# Testing strange table names
#
create table `t 1` (a int) PARTITION BY HASH(a) PARTITIONS 2;
drop table `t 1`;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t@00201,id: 1,,0,,,
+DROP,MyISAM,1,test,t@00201,id: 1,,0,,,
+#
# Testing views and triggers
#
create table t80 (a int, b int) engine=myisam PARTITION BY HASH(a) PARTITIONS 2;
@@ -136,12 +228,27 @@ drop trigger trg;
drop view v1;
drop table t80;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t80,id: 1,,0,,,
+CREATE,VIEW,0,test,v1,,,0,,,
+CREATE,TRIGGER,0,test,trg,,,0,,,
+DROP,TRIGGER,0,test,trg,,,0,,,
+DROP,VIEW,0,test,v1,,,0,,,
+DROP,MyISAM,1,test,t80,id: 1,,0,,,
+#
# Testing alter to a new storage engine
#
create table t85 (a int primary key, b int) engine=myisam PARTITION BY HASH(a) PARTITIONS 2;
alter table t85 engine=innodb;
drop table t85;
#
+# Reading backup ddl log file
+#
+CREATE,MyISAM,1,test,t85,id: 1,,0,,,
+ALTER,MyISAM,1,test,t85,id: 1,InnoDB,1,test,t85,id: 2
+DROP,InnoDB,1,test,t85,id: 2,,0,,,
+#
# Testing backup ddl log for partitioned tables
#
CREATE TABLE t200(a INT, b INT) ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1;
@@ -184,94 +291,22 @@ DROP TABLE t220;
#
# Reading backup ddl log file
#
-CREATE,MyISAM,1,test,t1,id: 1,,0,,,
-ALTER,MyISAM,1,test,t1,id: 1,MyISAM,1,test,t1,id: 2
-RENAME,MyISAM,1,test,t1,id: 2,MyISAM,1,test,t2,id: 2
-RENAME,MyISAM,1,test,t2,id: 2,MyISAM,1,test,t1,id: 2
-TRUNCATE,MyISAM,1,test,t1,id: 2,,0,,,
-repair,MyISAM,1,test,t1,id: 2,,0,,,
-optimize,MyISAM,1,test,t1,id: 2,,0,,,
-DROP,MyISAM,1,test,t1,id: 2,,0,,,
-CREATE,InnoDB,1,test,t1_innodb,id: 3,,0,,,
-ALTER,InnoDB,1,test,t1_innodb,id: 3,InnoDB,1,test,t1_innodb,id: 4
-RENAME,InnoDB,1,test,t1_innodb,id: 4,InnoDB,1,test,t2_innodb,id: 4
-RENAME,InnoDB,1,test,t2_innodb,id: 4,InnoDB,1,test,t1_innodb,id: 4
-TRUNCATE,InnoDB,1,test,t1_innodb,id: 4,,0,,,
-repair,InnoDB,1,test,t1_innodb,id: 4,,0,,,
-ALTER,InnoDB,1,test,t1_innodb,id: 4,InnoDB,1,test,t1_innodb,id: 5
-DROP,InnoDB,1,test,t1_innodb,id: 5,,0,,,
-CREATE,MyISAM,1,test,t20,id: 6,,0,,,
-DROP,MyISAM,1,test,t20,id: 6,,0,,,
-CREATE,MyISAM,1,test,t21,id: 7,,0,,,
-DROP,MyISAM,1,test,t21,id: 7,,0,,,
-CREATE,MyISAM,1,test,t30,id: 8,,0,,,
-CREATE,MyISAM,1,test,t31,id: 9,,0,,,
-DROP,MyISAM,1,test,t31,id: 9,,0,,,
-CREATE,MyISAM,0,test,t31,id: 10,,0,,,
-DROP,MyISAM,0,test,t31,id: 10,,0,,,
-DROP_AFTER_CREATE,MyISAM,1,test,t31,id: 11,,0,,,
-CREATE,MyISAM,1,test,t32,id: 12,,0,,,
-DROP,MyISAM,1,test,t30,id: 8,,0,,,
-DROP,MyISAM,1,test,t32,id: 12,,0,,,
-CREATE,MyISAM,1,test,t40,id: 13,,0,,,
-CREATE,InnoDB,1,test,t41,id: 14,,0,,,
-CREATE,partition,0,test,t42,id: 15,,0,,,
-DROP,MyISAM,1,test,t42,id: 15,,0,,,
-CREATE,partition,0,test,t42,id: 16,,0,,,
-DROP,MyISAM,1,test,t40,id: 13,,0,,,
-DROP,InnoDB,1,test,t41,id: 14,,0,,,
-DROP,InnoDB,1,test,t42,id: 16,,0,,,
-CREATE,MyISAM,1,test,t50,id: 17,,0,,,
-CREATE,MyISAM,1,test,t51,id: 18,,0,,,
-RENAME,MyISAM,1,test,t50,id: 17,MyISAM,1,test,t52,id: 17
-RENAME,MyISAM,1,test,t51,id: 18,MyISAM,1,test,t53,id: 18
-RENAME,MyISAM,1,test,t52,id: 17,MyISAM,1,test,tmp,id: 17
-RENAME,MyISAM,1,test,t53,id: 18,MyISAM,1,test,t52,id: 18
-RENAME,MyISAM,1,test,tmp,id: 17,MyISAM,1,test,t53,id: 17
-DROP,MyISAM,1,test,t52,id: 18,,0,,,
-DROP,MyISAM,1,test,t53,id: 17,,0,,,
-CREATE,Aria,1,test,t60,id: 19,,0,,,
-CHANGE_INDEX,Aria,1,test,t60,id: 19,,0,,,
-CHANGE_INDEX,Aria,1,test,t60,id: 19,,0,,,
-DROP,Aria,1,test,t60,id: 19,,0,,,
-CREATE,Aria,1,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,1,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,1,test,t70,id: 20,,0,,,
-TRUNCATE,Aria,1,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,1,test,t70,id: 20,,0,,,
-BULK_INSERT,Aria,1,test,t70,id: 20,,0,,,
-CREATE,Aria,1,test,t71,id: 21,,0,,,
-BULK_INSERT,Aria,1,test,t71,id: 21,,0,,,
-BULK_INSERT,Aria,1,test,t71,id: 21,,0,,,
-DROP,Aria,1,test,t70,id: 20,,0,,,
-DROP,Aria,1,test,t71,id: 21,,0,,,
-CREATE,MyISAM,1,test,t@00201,id: 22,,0,,,
-DROP,MyISAM,1,test,t@00201,id: 22,,0,,,
-CREATE,MyISAM,1,test,t80,id: 23,,0,,,
-CREATE,VIEW,0,test,v1,,,0,,,
-CREATE,TRIGGER,0,test,trg,,,0,,,
-DROP,TRIGGER,0,test,trg,,,0,,,
-DROP,VIEW,0,test,v1,,,0,,,
-DROP,MyISAM,1,test,t80,id: 23,,0,,,
-CREATE,MyISAM,1,test,t85,id: 24,,0,,,
-ALTER,MyISAM,1,test,t85,id: 24,InnoDB,1,test,t85,id: 25
-DROP,InnoDB,1,test,t85,id: 25,,0,,,
-CREATE,Aria,0,test,t200,id: 26,,0,,,
-ALTER,Aria,0,test,t200,id: 26,Aria,1,test,t200,id: 27
-CREATE,Aria,0,test,t210,id: 28,,0,,,
-EXCHANGE_PARTITION,Aria,1,test,t200,id: 27,Aria,0,test,t210,id: 28
-ALTER,Aria,1,test,t200,id: 27,Aria,1,test,t200,id: 29
-ALTER,Aria,1,test,t200,id: 29,Aria,1,test,t200,id: 30
-ALTER,Aria,1,test,t200,id: 30,Aria,1,test,t200,id: 31
-ALTER,Aria,1,test,t200,id: 31,Aria,1,test,t200,id: 32
-ALTER,Aria,1,test,t200,id: 32,Aria,1,test,t200,id: 33
-ALTER,Aria,1,test,t200,id: 33,Aria,1,test,t200,id: 34
-ALTER,Aria,1,test,t200,id: 34,Aria,1,test,t200,id: 35
-ALTER,Aria,1,test,t200,id: 35,Aria,0,test,t200,id: 36
-DROP,Aria,0,test,t200,id: 36,,0,,,
-DROP,Aria,0,test,t210,id: 28,,0,,,
-CREATE,Aria,1,test,t220,id: 37,,0,,,
-DROP,Aria,1,test,t220,id: 37,,0,,,
+CREATE,Aria,0,test,t200,id: 1,,0,,,
+ALTER,Aria,0,test,t200,id: 1,Aria,1,test,t200,id: 2
+CREATE,Aria,0,test,t210,id: 3,,0,,,
+EXCHANGE_PARTITION,Aria,1,test,t200,id: 2,Aria,0,test,t210,id: 3
+ALTER,Aria,1,test,t200,id: 2,Aria,1,test,t200,id: 4
+ALTER,Aria,1,test,t200,id: 4,Aria,1,test,t200,id: 5
+ALTER,Aria,1,test,t200,id: 5,Aria,1,test,t200,id: 6
+ALTER,Aria,1,test,t200,id: 6,Aria,1,test,t200,id: 7
+ALTER,Aria,1,test,t200,id: 7,Aria,1,test,t200,id: 8
+ALTER,Aria,1,test,t200,id: 8,Aria,1,test,t200,id: 9
+ALTER,Aria,1,test,t200,id: 9,Aria,1,test,t200,id: 10
+ALTER,Aria,1,test,t200,id: 10,Aria,0,test,t200,id: 11
+DROP,Aria,0,test,t200,id: 11,,0,,,
+DROP,Aria,0,test,t210,id: 3,,0,,,
+CREATE,Aria,1,test,t220,id: 12,,0,,,
+DROP,Aria,1,test,t220,id: 12,,0,,,
#
# Cleanup
#
diff --git a/mysql-test/suite/rpl/r/create_or_replace2,stmt.rdiff b/mysql-test/suite/rpl/r/create_or_replace2,stmt.rdiff
new file mode 100644
index 00000000000..52dd3828b38
--- /dev/null
+++ b/mysql-test/suite/rpl/r/create_or_replace2,stmt.rdiff
@@ -0,0 +1,17 @@
+--- create_or_replace2.result
++++ create_or_replace2,stmt.reject
+@@ -34,9 +34,11 @@
+ master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+ RETURN ( SELECT MAX(a) FROM t1 )
+ master-bin.000001 # Gtid # # GTID #-#-#
+-master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
+- `b` int(11) DEFAULT NULL
+-) ENGINE=InnoDB
++master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB
++master-bin.000001 # Gtid # # GTID #-#-#
++master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 LIKE tmp
++master-bin.000001 # Gtid # # GTID #-#-#
++master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `tmp`
+ drop function f1;
+ drop table t1;
+ include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/create_or_replace2.result b/mysql-test/suite/rpl/r/create_or_replace2.result
index b96a0f8ae13..a179c261281 100644
--- a/mysql-test/suite/rpl/r/create_or_replace2.result
+++ b/mysql-test/suite/rpl/r/create_or_replace2.result
@@ -26,6 +26,17 @@ unlock tables;
connection default;
ERROR 42S22: Unknown column 'a' in 'field list'
disconnect con1;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) ENGINE=InnoDB
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+RETURN ( SELECT MAX(a) FROM t1 )
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` (
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB
drop function f1;
drop table t1;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/create_or_replace_mix.result b/mysql-test/suite/rpl/r/create_or_replace_mix.result
index 9036ab425ae..75f7ca2a828 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_mix.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_mix.result
@@ -64,13 +64,12 @@ create table t1 (a int);
create or replace table t1;
ERROR 42000: A table must have at least 1 column
drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
-create or replace table t1 (a int primary key) select a from t2;
+create or replace table t1 (b int primary key) select a as b from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
-create table t1 (a int);
-create or replace table t1 (a int primary key) select a from t2;
+create table t1 (c int);
+create or replace table t1 (d int primary key) select a as d from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+drop table t1;
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
@@ -80,34 +79,26 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create or replace table t1
-master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Query # # use `test`; create table t1 (c int)
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t9 (a int)
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t9`/* Generated to handle failed CREATE OR REPLACE */
connection server_2;
show tables;
Tables_in_test
t2
connection server_1;
-create table t1 (a int);
+create table t1 (e int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # use `test`; create table t1 (e int)
drop table if exists t1,t2;
-Warnings:
-Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
@@ -159,7 +150,7 @@ slave-bin.000001 # Query # # use `test`; create table t4 (server_2_to_be_delete
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create table t1 (new_table int)
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
+slave-bin.000001 # Query # # use `test`; CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
)
slave-bin.000001 # Annotate_rows # # create table t2 select * from t9
@@ -217,7 +208,7 @@ drop table t1;
#
connection server_2;
connection server_1;
-create table t1 (a int);
+create table t1 (f int);
insert into t1 values (0),(1),(2);
create table t2 engine=myisam select * from t1;
create or replace table t2 engine=innodb select * from t1;
@@ -226,7 +217,7 @@ binlog from server 2
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1 (a int)
+slave-bin.000001 # Query # # use `test`; create table t1 (f int)
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into t1 values (0),(1),(2)
slave-bin.000001 # Query # # COMMIT
diff --git a/mysql-test/suite/rpl/r/create_or_replace_row.result b/mysql-test/suite/rpl/r/create_or_replace_row.result
index 16f92b5e4b6..9b3ffb6777e 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_row.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_row.result
@@ -92,13 +92,12 @@ create table t1 (a int);
create or replace table t1;
ERROR 42000: A table must have at least 1 column
drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
-create or replace table t1 (a int primary key) select a from t2;
+create or replace table t1 (b int primary key) select a as b from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
-create table t1 (a int);
-create or replace table t1 (a int primary key) select a from t2;
+create table t1 (c int);
+create or replace table t1 (d int primary key) select a as d from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+drop table t1;
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
@@ -108,32 +107,24 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create or replace table t1
-master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
-master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # use `test`; create table t1 (c int)
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
connection server_2;
show tables;
Tables_in_test
t2
connection server_1;
-create table t1 (a int);
+create table t1 (e int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
-master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # use `test`; create table t1 (e int)
drop table if exists t1,t2;
-Warnings:
-Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
@@ -243,7 +234,7 @@ drop table t1;
#
connection server_2;
connection server_1;
-create table t1 (a int);
+create table t1 (f int);
insert into t1 values (0),(1),(2);
create table t2 engine=myisam select * from t1;
create or replace table t2 engine=innodb select * from t1;
@@ -252,7 +243,7 @@ binlog from server 2
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1 (a int)
+slave-bin.000001 # Query # # use `test`; create table t1 (f int)
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Annotate_rows # # insert into t1 values (0),(1),(2)
slave-bin.000001 # Table_map # # table_id: # (test.t1)
@@ -260,7 +251,7 @@ slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; CREATE TABLE `t2` (
- `a` int(11) DEFAULT NULL
+ `f` int(11) DEFAULT NULL
) ENGINE=MyISAM
slave-bin.000001 # Annotate_rows # # create table t2 engine=myisam select * from t1
slave-bin.000001 # Table_map # # table_id: # (test.t2)
@@ -268,7 +259,7 @@ slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
- `a` int(11) DEFAULT NULL
+ `f` int(11) DEFAULT NULL
) ENGINE=InnoDB
slave-bin.000001 # Annotate_rows # # create or replace table t2 engine=innodb select * from t1
slave-bin.000001 # Table_map # # table_id: # (test.t2)
diff --git a/mysql-test/suite/rpl/r/create_or_replace_statement.result b/mysql-test/suite/rpl/r/create_or_replace_statement.result
index 9036ab425ae..75f7ca2a828 100644
--- a/mysql-test/suite/rpl/r/create_or_replace_statement.result
+++ b/mysql-test/suite/rpl/r/create_or_replace_statement.result
@@ -64,13 +64,12 @@ create table t1 (a int);
create or replace table t1;
ERROR 42000: A table must have at least 1 column
drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
-create or replace table t1 (a int primary key) select a from t2;
+create or replace table t1 (b int primary key) select a as b from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
-create table t1 (a int);
-create or replace table t1 (a int primary key) select a from t2;
+create table t1 (c int);
+create or replace table t1 (d int primary key) select a as d from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+drop table t1;
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
@@ -80,34 +79,26 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create or replace table t1
-master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Query # # use `test`; create table t1 (c int)
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t9 (a int)
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t9`/* Generated to handle failed CREATE OR REPLACE */
connection server_2;
show tables;
Tables_in_test
t2
connection server_1;
-create table t1 (a int);
+create table t1 (e int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (a int)
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
+master-bin.000001 # Query # # use `test`; create table t1 (e int)
drop table if exists t1,t2;
-Warnings:
-Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
@@ -159,7 +150,7 @@ slave-bin.000001 # Query # # use `test`; create table t4 (server_2_to_be_delete
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create table t1 (new_table int)
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` (
+slave-bin.000001 # Query # # use `test`; CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
)
slave-bin.000001 # Annotate_rows # # create table t2 select * from t9
@@ -217,7 +208,7 @@ drop table t1;
#
connection server_2;
connection server_1;
-create table t1 (a int);
+create table t1 (f int);
insert into t1 values (0),(1),(2);
create table t2 engine=myisam select * from t1;
create or replace table t2 engine=innodb select * from t1;
@@ -226,7 +217,7 @@ binlog from server 2
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1 (a int)
+slave-bin.000001 # Query # # use `test`; create table t1 (f int)
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into t1 values (0),(1),(2)
slave-bin.000001 # Query # # COMMIT
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_strict.result b/mysql-test/suite/rpl/r/rpl_gtid_strict.result
index 27e7d105125..d95d06d142e 100644
--- a/mysql-test/suite/rpl/r/rpl_gtid_strict.result
+++ b/mysql-test/suite/rpl/r/rpl_gtid_strict.result
@@ -68,9 +68,6 @@ SET gtid_seq_no= 1;
SET SESSION debug_dbug=@old_dbug;
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM;
ERROR HY000: An attempt was made to binlog GTID 0-3-1 which would create an out-of-order sequence number with existing GTID 0-1-4, and gtid strict mode is enabled
-SET sql_log_bin= 0;
-DROP TABLE t2;
-SET sql_log_bin= 1;
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM;
SET gtid_seq_no= 1;
ERROR HY000: An attempt was made to binlog GTID 0-3-1 which would create an out-of-order sequence number with existing GTID 0-3-5, and gtid strict mode is enabled
diff --git a/mysql-test/suite/rpl/t/create_or_replace.inc b/mysql-test/suite/rpl/t/create_or_replace.inc
index df46cc36e97..bdde953f7dc 100644
--- a/mysql-test/suite/rpl/t/create_or_replace.inc
+++ b/mysql-test/suite/rpl/t/create_or_replace.inc
@@ -47,12 +47,13 @@ create or replace table t1;
drop table if exists t1;
# The following is not logged as t1 does not exists;
--error ER_DUP_ENTRY
-create or replace table t1 (a int primary key) select a from t2;
+create or replace table t1 (b int primary key) select a as b from t2;
-create table t1 (a int);
+create table t1 (c int);
# This should as a delete as we will delete t1
--error ER_DUP_ENTRY
-create or replace table t1 (a int primary key) select a from t2;
+create or replace table t1 (d int primary key) select a as d from t2;
+drop table t1;
# Same with temporary table
create temporary table t9 (a int);
@@ -69,7 +70,7 @@ show tables;
connection server_1;
--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1)
-create table t1 (a int);
+create table t1 (e int);
--error ER_DUP_FIELDNAME
create or replace table t1 (a int, a int) select * from t2;
--source include/show_binlog_events.inc
@@ -169,7 +170,7 @@ sync_with_master;
--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1)
connection server_1;
-create table t1 (a int);
+create table t1 (f int);
insert into t1 values (0),(1),(2);
create table t2 engine=myisam select * from t1;
create or replace table t2 engine=innodb select * from t1;
diff --git a/mysql-test/suite/rpl/t/create_or_replace2.test b/mysql-test/suite/rpl/t/create_or_replace2.test
index f0091db7fb9..0208be577a7 100644
--- a/mysql-test/suite/rpl/t/create_or_replace2.test
+++ b/mysql-test/suite/rpl/t/create_or_replace2.test
@@ -36,6 +36,8 @@ unlock tables;
--reap
--disconnect con1
+--source include/show_binlog_events.inc
+
# Cleanup
drop function f1;
drop table t1;
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_strict.test b/mysql-test/suite/rpl/t/rpl_gtid_strict.test
index 56ebba824c4..091dbadefa4 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_strict.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_strict.test
@@ -58,11 +58,6 @@ SET gtid_seq_no= 1;
SET SESSION debug_dbug=@old_dbug;
--error ER_GTID_STRICT_OUT_OF_ORDER
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM;
-# The table is still created, DDL cannot be rolled back.
-# Fix it up for replication.
-SET sql_log_bin= 0;
-DROP TABLE t2;
-SET sql_log_bin= 1;
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM;
--error ER_GTID_STRICT_OUT_OF_ORDER
diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result
index 6f70f335d88..84122946870 100644
--- a/mysql-test/suite/sql_sequence/create.result
+++ b/mysql-test/suite/sql_sequence/create.result
@@ -60,8 +60,6 @@ next_not_cached_value minimum_value maximum_value start_value increment cache_si
1 1 9223372036854775806 1 1 1000 0 0
create or replace sequence t1 engine=archive;
ERROR HY000: Table storage engine 'ARCHIVE' does not support the create option 'SEQUENCE'
-show create table t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
create or replace sequence t1 start with 10;
show create sequence t1;
Table Create Table
diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test
index 61430740560..5f53daabbd7 100644
--- a/mysql-test/suite/sql_sequence/create.test
+++ b/mysql-test/suite/sql_sequence/create.test
@@ -24,12 +24,6 @@ show create table t1;
select * from t1;
--error ER_ILLEGAL_HA_CREATE_OPTION
create or replace sequence t1 engine=archive;
-#
-# The following error should be fixed. We shouldn't delete old table on errors
-#
---error ER_NO_SUCH_TABLE
-show create table t1;
-
# Check start values
create or replace sequence t1 start with 10;
diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc
index 418b5f3b5b0..90ae31cadcd 100644
--- a/sql/ddl_log.cc
+++ b/sql/ddl_log.cc
@@ -135,6 +135,13 @@ public:
char current_db[NAME_LEN];
uint execute_entry_pos;
ulonglong xid;
+ void free()
+ {
+ drop_table.free();
+ drop_view.free();
+ query.free();
+ db.free();
+ }
};
static st_global_ddl_log global_ddl_log;
@@ -455,7 +462,7 @@ bool ddl_log_disable_execute_entry(DDL_LOG_MEMORY_ENTRY **active_entry)
static bool is_execute_entry_active(uint entry_pos)
{
uchar buff[1];
- DBUG_ENTER("disable_execute_entry");
+ DBUG_ENTER("is_execute_entry_active");
if (mysql_file_pread(global_ddl_log.file_id, buff, sizeof(buff),
global_ddl_log.io_size * entry_pos +
@@ -1081,15 +1088,15 @@ static handler *create_handler(THD *thd, MEM_ROOT *mem_root,
like connect, needs the .frm file to exists to be able to do an rename.
*/
-static void execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file,
- const LEX_CSTRING *from_db,
- const LEX_CSTRING *from_table,
- const LEX_CSTRING *to_db,
- const LEX_CSTRING *to_table,
- uint flags,
- char *from_path, char *to_path)
+static int execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file,
+ const LEX_CSTRING *from_db,
+ const LEX_CSTRING *from_table,
+ const LEX_CSTRING *to_db,
+ const LEX_CSTRING *to_table, uint flags,
+ char *from_path, char *to_path)
{
uint to_length=0, fr_length=0;
+ int err;
DBUG_ENTER("execute_rename_table");
if (file->needs_lower_case_filenames())
@@ -1102,14 +1109,14 @@ static void execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file,
}
else
{
- fr_length= build_table_filename(from_path, FN_REFLEN,
- from_db->str, from_table->str, "",
- flags & FN_TO_IS_TMP);
+ fr_length=
+ build_table_filename(from_path, FN_REFLEN, from_db->str,
+ from_table->str, "", flags & FN_FROM_IS_TMP);
to_length= build_table_filename(to_path, FN_REFLEN,
to_db->str, to_table->str, "",
flags & FN_TO_IS_TMP);
}
- file->ha_rename_table(from_path, to_path);
+ err= file->ha_rename_table(from_path, to_path);
if (file->needs_lower_case_filenames())
{
/*
@@ -1130,7 +1137,7 @@ static void execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file,
}
if (!access(from_path, F_OK))
(void) mysql_file_rename(key_file_frm, from_path, to_path, MYF(MY_WME));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(err);
}
@@ -1287,7 +1294,8 @@ static void rename_in_stat_tables(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
*/
static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
- DDL_LOG_ENTRY *ddl_log_entry)
+ DDL_LOG_ENTRY *ddl_log_entry,
+ bool report_error)
{
LEX_CSTRING handler_name;
handler *file= NULL;
@@ -1295,15 +1303,15 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
handlerton *hton= 0;
ddl_log_error_handler no_such_table_handler;
uint entry_pos= ddl_log_entry->entry_pos;
- int error;
+ int error= 0;
+ uint flags;
bool frm_action= FALSE;
DBUG_ENTER("ddl_log_execute_action");
mysql_mutex_assert_owner(&LOCK_gdl);
DBUG_PRINT("ddl_log",
- ("pos: %u=>%u->%u type: %u action: %u (%s) phase: %u "
+ ("pos: %u->%u type: %u action: %u (%s) phase: %u "
"handler: '%s' name: '%s' from_name: '%s' tmp_name: '%s'",
- recovery_state.execute_entry_pos,
ddl_log_entry->entry_pos,
ddl_log_entry->next_entry,
(uint) ddl_log_entry->entry_type,
@@ -1320,7 +1328,8 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
DBUG_RETURN(FALSE);
handler_name= ddl_log_entry->handler_name;
- thd->push_internal_handler(&no_such_table_handler);
+ if (!report_error)
+ thd->push_internal_handler(&no_such_table_handler);
if (!strcmp(ddl_log_entry->handler_name.str, reg_ext))
frm_action= TRUE;
@@ -1374,24 +1383,28 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
/* fall through */
case DDL_LOG_RENAME_ACTION:
{
- error= TRUE;
if (frm_action)
{
strxmov(to_path, ddl_log_entry->name.str, reg_ext, NullS);
strxmov(from_path, ddl_log_entry->from_name.str, reg_ext, NullS);
- (void) mysql_file_rename(key_file_frm, from_path, to_path, MYF(MY_WME));
+ error= mysql_file_rename(key_file_frm, from_path, to_path, MYF(MY_WME));
#ifdef WITH_PARTITION_STORAGE_ENGINE
strxmov(to_path, ddl_log_entry->name.str, PAR_EXT, NullS);
strxmov(from_path, ddl_log_entry->from_name.str, PAR_EXT, NullS);
- (void) mysql_file_rename(key_file_partition_ddl_log, from_path, to_path,
- MYF(MY_WME));
+ int err2= mysql_file_rename(key_file_partition_ddl_log, from_path,
+ to_path, MYF(MY_WME));
+ if (!error)
+ error= err2;
#endif
}
else
- (void) file->ha_rename_table(ddl_log_entry->from_name.str,
+ error= file->ha_rename_table(ddl_log_entry->from_name.str,
ddl_log_entry->name.str);
if (increment_phase(entry_pos))
+ {
+ error= -1;
break;
+ }
break;
}
case DDL_LOG_EXCHANGE_ACTION:
@@ -1459,11 +1472,11 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
/* fall through */
case DDL_RENAME_PHASE_TABLE:
/* Restore frm and table to original names */
- execute_rename_table(ddl_log_entry, file,
- &ddl_log_entry->db, &ddl_log_entry->name,
- &ddl_log_entry->from_db, &ddl_log_entry->from_name,
- 0,
- from_path, to_path);
+ flags= report_error ? FN_FROM_IS_TMP : 0;
+ error= execute_rename_table(ddl_log_entry, file,
+ &ddl_log_entry->db, &ddl_log_entry->name,
+ &ddl_log_entry->from_db, &ddl_log_entry->from_name,
+ flags, from_path, to_path);
if (ddl_log_entry->flags & DDL_LOG_FLAG_UPDATE_STAT)
{
@@ -1569,8 +1582,15 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
break;
/* Fall through */
case DDL_DROP_PHASE_TRIGGER:
+ /*
+ Note: frm is already deleted and build_table_filename() will not detect
+ FN_IS_TMP flag.
+ */
+ flags= (ddl_log_entry->flags & DDL_LOG_FLAG_TMP_TABLE) ? FN_IS_TMP : 0;
+
Table_triggers_list::drop_all_triggers(thd, &db, &table,
- MYF(MY_WME | MY_IGNORE_ENOENT));
+ MYF(MY_WME | MY_IGNORE_ENOENT),
+ flags);
if (increment_phase(entry_pos))
break;
/* Fall through */
@@ -1765,31 +1785,6 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
}
strxnmov(to_path, sizeof(to_path)-1, path.str, reg_ext, NullS);
mysql_file_delete(key_file_frm, to_path, MYF(MY_WME|MY_IGNORE_ENOENT));
- if (ddl_log_entry->phase == DDL_CREATE_TABLE_PHASE_LOG)
- {
- /*
- The server logged CREATE TABLE ... SELECT into binary log
- before crashing. As the commit failed and we have delete the
- table above, we have now to log the DROP of the created table.
- */
-
- String *query= &recovery_state.drop_table;
- query->length(0);
- query->append(STRING_WITH_LEN("DROP TABLE IF EXISTS "));
- append_identifier(thd, query, &db);
- query->append('.');
- append_identifier(thd, query, &table);
- query->append(&end_comment);
-
- if (mysql_bin_log.is_open())
- {
- mysql_mutex_unlock(&LOCK_gdl);
- (void) thd->binlog_query(THD::STMT_QUERY_TYPE,
- query->ptr(), query->length(),
- TRUE, FALSE, FALSE, 0);
- mysql_mutex_lock(&LOCK_gdl);
- }
- }
(void) update_phase(entry_pos, DDL_LOG_FINAL_PHASE);
error= 0;
break;
@@ -2296,11 +2291,28 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root,
}
end:
+ if (report_error)
+ {
+ if (error && file)
+ {
+ TABLE_SHARE share;
+ bzero(&share, sizeof(share));
+ share.db= ddl_log_entry->db;
+ share.table_name= ddl_log_entry->name;
+ share.normalized_path= ddl_log_entry->tmp_name;
+ /* TODO: make TABLE_SHARE-independent handler::print_error()? */
+ file->change_table_ptr(NULL, &share);
+ file->print_error(error, MYF(0));
+ }
+ }
+ else
+ {
+ /* We are only interested in errors that where not ignored */
+ if ((error= (no_such_table_handler.unhandled_errors > 0)))
+ my_errno= no_such_table_handler.first_error;
+ thd->pop_internal_handler();
+ }
delete file;
- /* We are only interested in errors that where not ignored */
- if ((error= (no_such_table_handler.unhandled_errors > 0)))
- my_errno= no_such_table_handler.first_error;
- thd->pop_internal_handler();
DBUG_RETURN(error);
}
@@ -2395,11 +2407,13 @@ void ddl_log_release_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
@retval FALSE Success
*/
-static bool ddl_log_execute_entry_no_lock(THD *thd, uint first_entry)
+static bool ddl_log_execute_entry_no_lock(THD *thd, uint first_entry,
+ bool report_error)
{
DDL_LOG_ENTRY ddl_log_entry;
uint read_entry= first_entry;
MEM_ROOT mem_root;
+ bool result= false;
DBUG_ENTER("ddl_log_execute_entry_no_lock");
mysql_mutex_assert_owner(&LOCK_gdl);
@@ -2415,24 +2429,29 @@ static bool ddl_log_execute_entry_no_lock(THD *thd, uint first_entry)
DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
ddl_log_entry.entry_type == DDL_LOG_IGNORE_ENTRY_CODE);
- if (ddl_log_execute_action(thd, &mem_root, &ddl_log_entry))
+ if (ddl_log_execute_action(thd, &mem_root, &ddl_log_entry, report_error))
{
uint action_type= ddl_log_entry.action_type;
if (action_type >= DDL_LOG_LAST_ACTION)
action_type= 0;
- /* Write to error log and continue with next log entry */
- sql_print_error("DDL_LOG: Got error %d when trying to execute action "
- "for entry %u of type '%s'",
- (int) my_errno, read_entry,
- ddl_log_action_name[action_type]);
+ if (!report_error)
+ {
+ /* Write to error log and continue with next log entry */
+ sql_print_error("DDL_LOG: Got error %d when trying to execute action "
+ "for entry %u of type '%s'",
+ (int) my_errno, read_entry,
+ ddl_log_action_name[action_type]);
+ }
+ result= true;
break;
}
read_entry= ddl_log_entry.next_entry;
} while (read_entry);
+ recovery_state.free(); // FIXME: is this correct?
free_root(&mem_root, MYF(0));
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(result);
}
@@ -2638,7 +2657,7 @@ bool ddl_log_execute_entry(THD *thd, uint first_entry)
DBUG_ENTER("ddl_log_execute_entry");
mysql_mutex_lock(&LOCK_gdl);
- error= ddl_log_execute_entry_no_lock(thd, first_entry);
+ error= ddl_log_execute_entry_no_lock(thd, first_entry, false);
mysql_mutex_unlock(&LOCK_gdl);
DBUG_RETURN(error);
}
@@ -2761,7 +2780,7 @@ int ddl_log_execute_recovery()
if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
{
/*
- Remeber information about executive ddl log entry,
+ Remember information about executive ddl log entry,
used for binary logging during recovery
*/
recovery_state.execute_entry_pos= i;
@@ -2792,7 +2811,7 @@ int ddl_log_execute_recovery()
continue;
}
- if (ddl_log_execute_entry_no_lock(thd, ddl_log_entry.next_entry))
+ if (ddl_log_execute_entry_no_lock(thd, ddl_log_entry.next_entry, false))
{
/* Real unpleasant scenario but we have to continue anyway */
error= -1;
@@ -2930,7 +2949,7 @@ void ddl_log_complete(DDL_LOG_STATE *state)
This is called for failed rename table, create trigger or drop trigger.
*/
-bool ddl_log_revert(THD *thd, DDL_LOG_STATE *state)
+bool ddl_log_revert(THD *thd, DDL_LOG_STATE *state, bool report_error)
{
bool res= 0;
DBUG_ENTER("ddl_log_revert");
@@ -2941,7 +2960,8 @@ bool ddl_log_revert(THD *thd, DDL_LOG_STATE *state)
mysql_mutex_lock(&LOCK_gdl);
if (likely(state->execute_entry))
{
- res= ddl_log_execute_entry_no_lock(thd, state->list->entry_pos);
+ res= ddl_log_execute_entry_no_lock(thd, state->list->entry_pos,
+ report_error);
ddl_log_disable_execute_entry(&state->execute_entry);
}
ddl_log_release_entries(state);
@@ -3042,6 +3062,7 @@ static bool ddl_log_write(DDL_LOG_STATE *ddl_state,
mysql_mutex_lock(&LOCK_gdl);
error= ((ddl_log_write_entry(ddl_log_entry, &log_entry)) ||
ddl_log_write_execute_entry(log_entry->entry_pos,
+ ddl_state->master_chain_pos,
&ddl_state->execute_entry));
mysql_mutex_unlock(&LOCK_gdl);
if (error)
@@ -3121,16 +3142,16 @@ bool ddl_log_rename_view(THD *thd, DDL_LOG_STATE *ddl_state,
*/
static bool ddl_log_drop_init(THD *thd, DDL_LOG_STATE *ddl_state,
- ddl_log_action_code action_code,
const LEX_CSTRING *db,
const LEX_CSTRING *comment)
{
DDL_LOG_ENTRY ddl_log_entry;
- DBUG_ENTER("ddl_log_drop_file");
+ DBUG_ENTER("ddl_log_drop_init");
bzero(&ddl_log_entry, sizeof(ddl_log_entry));
- ddl_log_entry.action_type= action_code;
+ ddl_log_entry.action_type= DDL_LOG_DROP_INIT_ACTION;
+ ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
ddl_log_entry.from_db= *const_cast<LEX_CSTRING*>(db);
ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(comment);
@@ -3142,15 +3163,13 @@ bool ddl_log_drop_table_init(THD *thd, DDL_LOG_STATE *ddl_state,
const LEX_CSTRING *db,
const LEX_CSTRING *comment)
{
- return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_INIT_ACTION,
- db, comment);
+ return ddl_log_drop_init(thd, ddl_state, db, comment);
}
bool ddl_log_drop_view_init(THD *thd, DDL_LOG_STATE *ddl_state,
const LEX_CSTRING *db)
{
- return ddl_log_drop_init(thd, ddl_state, DDL_LOG_DROP_INIT_ACTION,
- db, &empty_clex_str);
+ return ddl_log_drop_init(thd, ddl_state, db, &empty_clex_str);
}
@@ -3172,7 +3191,7 @@ static bool ddl_log_drop(THD *thd, DDL_LOG_STATE *ddl_state,
const LEX_CSTRING *table)
{
DDL_LOG_ENTRY ddl_log_entry;
- DDL_LOG_MEMORY_ENTRY *log_entry;
+ DDL_LOG_MEMORY_ENTRY *log_entry, *first_entry= NULL;
DBUG_ENTER("ddl_log_drop");
DBUG_ASSERT(ddl_state->list);
@@ -3187,6 +3206,25 @@ static bool ddl_log_drop(THD *thd, DDL_LOG_STATE *ddl_state,
ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(path);
ddl_log_entry.phase= (uchar) phase;
+ /*
+ Get first entry in the chain and if it is not DDL_LOG_DROP_INIT_ACTION
+ place it after this action. Required for logging rename before drop,
+ but replaying rename after drop.
+ */
+ for (log_entry= ddl_state->list->next_active_log_entry; log_entry;
+ first_entry= log_entry, log_entry= log_entry->next_active_log_entry);
+
+ if (first_entry)
+ {
+ DDL_LOG_ENTRY first;
+ mysql_mutex_lock(&LOCK_gdl);
+ (void) read_ddl_log_entry(first_entry->entry_pos, &first);
+ mysql_mutex_unlock(&LOCK_gdl);
+ if (first.action_type != DDL_LOG_DROP_INIT_ACTION)
+ ddl_log_entry.next_entry=
+ ddl_state->list->next_active_log_entry->entry_pos;
+ }
+
mysql_mutex_lock(&LOCK_gdl);
if (ddl_log_write_entry(&ddl_log_entry, &log_entry))
goto error;
@@ -3324,6 +3362,7 @@ bool ddl_log_create_table(THD *thd, DDL_LOG_STATE *ddl_state,
ddl_log_entry.name= *const_cast<LEX_CSTRING*>(table);
ddl_log_entry.tmp_name= *const_cast<LEX_CSTRING*>(path);
ddl_log_entry.flags= only_frm ? DDL_LOG_FLAG_ONLY_FRM : 0;
+ ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0;
DBUG_RETURN(ddl_log_write(ddl_state, &ddl_log_entry));
}
@@ -3577,3 +3616,16 @@ bool ddl_log_delete_frm(DDL_LOG_STATE *ddl_state, const char *to_path)
ddl_log_add_entry(ddl_state, log_entry);
DBUG_RETURN(0);
}
+
+/*
+ Link the ddl_log_state to another (master) chain. If the master
+ chain is active during DDL recovery, this event will not be executed.
+
+ This is used for DROP TABLE of the original table when
+ CREATE OR REPLACE ... is used.
+*/
+void ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state)
+{
+ DBUG_ASSERT(master_state->execute_entry);
+ state->master_chain_pos= master_state->execute_entry->entry_pos;
+}
diff --git a/sql/ddl_log.h b/sql/ddl_log.h
index 9960855a813..9f8a9beedee 100644
--- a/sql/ddl_log.h
+++ b/sql/ddl_log.h
@@ -126,7 +126,6 @@ enum enum_ddl_log_drop_db_phase {
enum enum_ddl_log_create_table_phase {
DDL_CREATE_TABLE_PHASE_INIT=0,
- DDL_CREATE_TABLE_PHASE_LOG,
DDL_CREATE_TABLE_PHASE_END
};
@@ -173,6 +172,7 @@ enum enum_ddl_log_alter_table_phase {
engine is not changed
*/
#define DDL_LOG_FLAG_ALTER_PARTITION (1 << 4)
+#define DDL_LOG_FLAG_TMP_TABLE (1 << 5)
/*
Setting ddl_log_entry.phase to this has the same effect as setting
@@ -248,6 +248,7 @@ typedef struct st_ddl_log_state
*/
DDL_LOG_MEMORY_ENTRY *main_entry;
uint16 flags; /* Cache for flags */
+ ulonglong master_chain_pos;
bool is_active() { return list != 0; }
} DDL_LOG_STATE;
@@ -273,7 +274,8 @@ bool ddl_log_write_execute_entry(uint first_entry,
bool ddl_log_disable_execute_entry(DDL_LOG_MEMORY_ENTRY **active_entry);
void ddl_log_complete(DDL_LOG_STATE *ddl_log_state);
-bool ddl_log_revert(THD *thd, DDL_LOG_STATE *ddl_log_state);
+bool ddl_log_revert(THD *thd, DDL_LOG_STATE *ddl_log_state,
+ bool report_error= false);
bool ddl_log_update_phase(DDL_LOG_STATE *entry, uchar phase);
bool ddl_log_add_flag(DDL_LOG_STATE *entry, uint16 flag);
@@ -356,5 +358,6 @@ bool ddl_log_alter_table(THD *thd, DDL_LOG_STATE *ddl_state,
bool ddl_log_store_query(THD *thd, DDL_LOG_STATE *ddl_log_state,
const char *query, size_t length);
bool ddl_log_delete_frm(DDL_LOG_STATE *ddl_state, const char *to_path);
+void ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state);
extern mysql_mutex_t LOCK_gdl;
#endif /* DDL_LOG_INCLUDED */
diff --git a/sql/handler.cc b/sql/handler.cc
index 57992d98c04..0b922a3cfc8 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -6922,6 +6922,8 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
RETURN VALUE
0 No binary logging in row format
1 Row needs to be logged
+
+ TODO: remove needless proxy
*/
bool handler::check_table_binlog_row_based()
@@ -6987,8 +6989,7 @@ int handler::binlog_log_row(TABLE *table,
THD *thd= table->in_use;
DBUG_ENTER("binlog_log_row");
- if (!thd->binlog_table_maps &&
- thd->binlog_write_table_maps())
+ if (!thd->binlog_table_maps && thd->binlog_write_table_maps(table))
DBUG_RETURN(HA_ERR_RBR_LOGGING_FAILED);
error= (*log_func)(thd, table, row_logging_has_trans,
@@ -8317,7 +8318,7 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
bool Table_scope_and_contents_source_st::vers_check_system_fields(
THD *thd, Alter_info *alter_info, const Lex_table_name &table_name,
- const Lex_table_name &db, int select_count)
+ const Lex_table_name &db)
{
if (!(options & HA_VERSIONED_TABLE))
return false;
@@ -8337,7 +8338,7 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields(
SELECT go last there.
*/
bool is_dup= false;
- if (fieldnr >= alter_info->create_list.elements - select_count)
+ if (fieldnr >= alter_info->field_count())
{
List_iterator<Create_field> dup_it(alter_info->create_list);
for (Create_field *dup= dup_it++; !is_dup && dup != f; dup= dup_it++)
@@ -8745,12 +8746,11 @@ bool Table_period_info::check_field(const Create_field* f,
}
bool Table_scope_and_contents_source_st::check_fields(
- THD *thd, Alter_info *alter_info,
- const Lex_table_name &table_name, const Lex_table_name &db, int select_count)
+ THD *thd, Alter_info *alter_info, const Lex_table_name &table_name,
+ const Lex_table_name &db)
{
- return vers_check_system_fields(thd, alter_info,
- table_name, db, select_count) ||
- check_period_fields(thd, alter_info);
+ return vers_check_system_fields(thd, alter_info, table_name, db) ||
+ check_period_fields(thd, alter_info);
}
bool Table_scope_and_contents_source_st::check_period_fields(
diff --git a/sql/handler.h b/sql/handler.h
index fe61666bf20..1a2156e7c46 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -35,6 +35,7 @@
#include "sql_array.h" /* Dynamic_array<> */
#include "mdl.h"
#include "vers_string.h"
+#include "backup.h"
#include "sql_analyze_stmt.h" // for Exec_time_tracker
@@ -1827,6 +1828,12 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
*/
#define HTON_REQUIRES_NOTIFY_TABLEDEF_CHANGED_AFTER_COMMIT (1 << 20)
+/*
+ Indicates that rename table is expensive operation.
+ When set atomic CREATE OR REPLACE TABLE is not used.
+*/
+#define HTON_EXPENSIVE_RENAME (1 << 21)
+
class Ha_trx_info;
struct THD_TRANS
@@ -2303,8 +2310,7 @@ struct Table_scope_and_contents_source_st:
bool fix_period_fields(THD *thd, Alter_info *alter_info);
bool check_fields(THD *thd, Alter_info *alter_info,
const Lex_table_name &table_name,
- const Lex_table_name &db,
- int select_count= 0);
+ const Lex_table_name &db);
bool check_period_fields(THD *thd, Alter_info *alter_info);
bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
@@ -2312,9 +2318,33 @@ struct Table_scope_and_contents_source_st:
bool vers_check_system_fields(THD *thd, Alter_info *alter_info,
const Lex_table_name &table_name,
- const Lex_table_name &db,
- int select_count= 0);
+ const Lex_table_name &db);
+};
+typedef struct st_ddl_log_state DDL_LOG_STATE;
+
+struct Atomic_info
+{
+ TABLE_LIST *tmp_name;
+ DDL_LOG_STATE *ddl_log_state_create;
+ DDL_LOG_STATE *ddl_log_state_rm;
+ backup_log_info drop_entry;
+
+ Atomic_info() :
+ tmp_name(NULL),
+ ddl_log_state_create(NULL),
+ ddl_log_state_rm(NULL)
+ {
+ bzero(&drop_entry, sizeof(drop_entry));
+ }
+
+ Atomic_info(DDL_LOG_STATE *ddl_log_state_rm) :
+ tmp_name(NULL),
+ ddl_log_state_create(NULL),
+ ddl_log_state_rm(ddl_log_state_rm)
+ {
+ bzero(&drop_entry, sizeof(drop_entry));
+ }
};
@@ -2324,7 +2354,8 @@ struct Table_scope_and_contents_source_st:
parts are handled on the SQL level and are not needed on the handler level.
*/
struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
- public Schema_specification_st
+ public Schema_specification_st,
+ public Atomic_info
{
/* TODO: remove after MDEV-20865 */
Alter_info *alter_info;
@@ -2369,6 +2400,16 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
else
return table_options;
}
+ bool ok_atomic_replace() const
+ {
+ return !tmp_table() && !sequence &&
+ !(db_type->flags & HTON_EXPENSIVE_RENAME) &&
+ !DBUG_IF("ddl_log_expensive_rename");
+ }
+ bool handle_atomic_replace(THD *thd, const LEX_CSTRING &db,
+ const LEX_CSTRING &table_name,
+ const DDL_options_st options);
+ bool finalize_ddl(THD *thd);
};
@@ -2401,6 +2442,10 @@ struct Table_specification_st: public HA_CREATE_INFO,
HA_CREATE_INFO::options= 0;
DDL_options_st::init();
}
+ bool is_atomic_replace() const
+ {
+ return or_replace() && ok_atomic_replace();
+ }
};
diff --git a/sql/log.cc b/sql/log.cc
index 70ceecc66f8..5bdf23a17e4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5953,7 +5953,7 @@ bool THD::binlog_write_annotated_row(Log_event_writer *writer)
THD::binlog_prepare_for_row_logging
*/
-bool THD::binlog_write_table_maps()
+bool THD::binlog_write_table_maps(TABLE *cur_table)
{
bool with_annotate;
MYSQL_LOCK *locks[2], **locks_end= locks;
@@ -6006,6 +6006,11 @@ bool THD::binlog_write_table_maps()
}
}
}
+ if (cur_table->s->tmp_table && cur_table->file->row_logging)
+ {
+ if (binlog_write_table_map(cur_table, with_annotate))
+ DBUG_RETURN(1);
+ }
binlog_table_maps= 1; // Table maps written
DBUG_RETURN(0);
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 3adc7a26d93..09407f0ae0b 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -695,9 +695,11 @@ enum Log_event_type
/* New MySQL/Sun events are to be added right above this comment */
MYSQL_EVENTS_END,
- MARIA_EVENTS_BEGIN= 160,
/* New Maria event numbers start from here */
ANNOTATE_ROWS_EVENT= 160,
+ /* Keep that here for GDB to display ANNOTATE_ROWS_EVENT */
+ MARIA_EVENTS_BEGIN= 160,
+
/*
Binlog checkpoint event. Used for XA crash recovery on the master, not used
in replication.
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 58902fc859f..4d13cac704a 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -27,6 +27,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
key_list(rhs.key_list, mem_root),
alter_rename_key_list(rhs.alter_rename_key_list, mem_root),
create_list(rhs.create_list, mem_root),
+ select_field_count(rhs.select_field_count),
alter_index_ignorability_list(rhs.alter_index_ignorability_list, mem_root),
check_constraint_list(rhs.check_constraint_list, mem_root),
flags(rhs.flags), partition_flags(rhs.partition_flags),
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index bf1edd4c964..142b71c725a 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -96,6 +96,7 @@ public:
List<Alter_rename_key> alter_rename_key_list;
// List of columns, used by both CREATE and ALTER TABLE.
List<Create_field> create_list;
+ uint select_field_count;
// Indexes whose ignorability needs to be changed.
List<Alter_index_ignorability> alter_index_ignorability_list;
List<Virtual_column_info> check_constraint_list;
@@ -118,6 +119,7 @@ public:
Alter_info() :
+ select_field_count(0),
flags(0), partition_flags(0),
keys_onoff(LEAVE_AS_IS),
num_parts(0),
@@ -134,6 +136,7 @@ public:
create_list.empty();
alter_index_ignorability_list.empty();
check_constraint_list.empty();
+ select_field_count= 0;
flags= 0;
partition_flags= 0;
keys_onoff= LEAVE_AS_IS;
@@ -234,6 +237,11 @@ public:
*/
enum_alter_table_algorithm algorithm(const THD *thd) const;
+ uint field_count() const
+ {
+ return create_list.elements - select_field_count;
+ }
+
private:
Alter_info &operator=(const Alter_info &rhs); // not implemented
Alter_info(const Alter_info &rhs); // not implemented
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0d02f74686f..2e445eebacd 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2886,7 +2886,7 @@ public:
bool prepare_handlers_for_update(uint flag);
bool binlog_write_annotated_row(Log_event_writer *writer);
void binlog_prepare_for_row_logging();
- bool binlog_write_table_maps();
+ bool binlog_write_table_maps(TABLE *cur_table);
bool binlog_write_table_map(TABLE *table, bool with_annotate);
static void binlog_prepare_row_images(TABLE* table);
@@ -6021,6 +6021,9 @@ class select_insert :public select_result_interceptor {
ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
COPY_INFO info;
bool insert_into_view;
+ bool binary_logged;
+ bool atomic_replace;
+
select_insert(THD *thd_arg, TABLE_LIST *table_list_par, TABLE *table_par,
List<Item> *fields_par, List<Item> *update_fields,
List<Item> *update_values, enum_duplicates duplic,
@@ -6042,6 +6045,8 @@ class select_insert :public select_result_interceptor {
class select_create: public select_insert {
TABLE_LIST *create_table;
+ TABLE_LIST *orig_table;
+ TABLE_LIST new_table;
Table_specification_st *create_info;
TABLE_LIST *select_tables;
Alter_info *alter_info;
@@ -6063,6 +6068,7 @@ public:
select_insert(thd_arg, table_arg, NULL, &select_fields, 0, 0, duplic,
ignore, NULL),
create_table(table_arg),
+ orig_table(table_arg),
create_info(create_info_par),
select_tables(select_tables_arg),
alter_info(alter_info_arg),
@@ -6071,6 +6077,9 @@ public:
{
bzero(&ddl_log_state_create, sizeof(ddl_log_state_create));
bzero(&ddl_log_state_rm, sizeof(ddl_log_state_rm));
+ atomic_replace= create_info->is_atomic_replace();
+ create_info->ddl_log_state_create= &ddl_log_state_create;
+ create_info->ddl_log_state_rm= &ddl_log_state_rm;
}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c5defc1959c..a053569f94d 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1044,6 +1044,7 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists,
TABLE_LIST *tables= NULL;
TABLE_LIST *table;
DDL_LOG_STATE ddl_log_state;
+ Atomic_info atomic_replace_info(&ddl_log_state);
Drop_table_error_handler err_handler;
LEX_CSTRING rm_db;
char db_tmp[SAFE_NAME_LEN+1];
@@ -1121,8 +1122,8 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists,
thd->push_internal_handler(&err_handler);
if (!thd->killed &&
!(tables &&
- mysql_rm_table_no_locks(thd, tables, &rm_db, &ddl_log_state, true, false,
- true, false, true, false)))
+ mysql_rm_table_no_locks(thd, tables, &rm_db, &atomic_replace_info,
+ true, false, true, false, true, false)))
{
debug_crash_here("ddl_log_drop_after_drop_tables");
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 707b8a0d3bf..1f462009c15 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3834,7 +3834,8 @@ select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
sel_result(result),
table_list(table_list_par), table(table_par), fields(fields_par),
autoinc_value_of_last_inserted_row(0),
- insert_into_view(table_list_par && table_list_par->view != 0)
+ insert_into_view(table_list_par && table_list_par->view != 0),
+ binary_logged(false), atomic_replace(false)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates= duplic;
@@ -4166,7 +4167,6 @@ bool select_insert::prepare_eof()
int error;
bool const trans_table= table->file->has_transactions_and_rollback();
bool changed;
- bool binary_logged= 0;
killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::prepare_eof");
@@ -4185,8 +4185,8 @@ bool select_insert::prepare_eof()
error= thd->get_stmt_da()->sql_errno();
if (info.ignore || info.handle_duplicates != DUP_ERROR)
- if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
- table->file->ha_rnd_end();
+ if (!atomic_replace && table->file->ha_table_flags() & HA_DUPLICATE_POS)
+ table->file->ha_rnd_end();
table->file->extra(HA_EXTRA_END_ALTER_COPY);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -4231,6 +4231,11 @@ bool select_insert::prepare_eof()
table->file->ha_release_auto_increment();
DBUG_RETURN(true);
}
+ /*
+ FIXME: bad check !table->s->tmp_table in case of atomic_replace.
+ The better check is create_info->tmp_table(). The even better is to
+ update binary_logged in do_postlock() for RBR.
+ */
binary_logged= res == 0 || !table->s->tmp_table;
}
table->s->table_creation_was_logged|= binary_logged;
@@ -4349,6 +4354,12 @@ void select_insert::abort_result_set()
res= thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
transactional_table, FALSE, FALSE, errcode);
+
+ /*
+ FIXME: bad check !table->s->tmp_table in case of atomic_replace.
+ The better check is create_info->tmp_table(). The even better is to
+ update binary_logged in do_postlock() for RBR.
+ */
binary_logged= res == 0 || !table->s->tmp_table;
}
if (changed)
@@ -4423,11 +4434,13 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
TABLE tmp_table; // Used during 'Create_field()'
TABLE_SHARE share;
TABLE *table= 0;
- uint select_field_count= items->elements;
+ alter_info->select_field_count= items->elements;
/* Add selected items to field list */
List_iterator_fast<Item> it(*items);
Item *item;
bool save_table_creation_was_logged;
+ int create_table_mode= CREATE_ORDINARY;
+ LEX_CUSTRING frm= {0, 0};
DBUG_ENTER("select_create::create_table_from_items");
tmp_table.s= &share;
@@ -4481,10 +4494,8 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
alter_info->create_list.push_back(cr_field, thd->mem_root);
}
- if (create_info->check_fields(thd, alter_info,
- create_table->table_name,
- create_table->db,
- select_field_count))
+ if (create_info->check_fields(thd, alter_info, create_table->table_name,
+ create_table->db))
DBUG_RETURN(NULL);
DEBUG_SYNC(thd,"create_table_select_before_create");
@@ -4499,6 +4510,20 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
create_info->mdl_ticket= create_table->table->mdl_ticket;
}
+ if (atomic_replace)
+ {
+ DBUG_ASSERT(!create_info->tmp_table()); // FIXME: test
+ if (make_tmp_name(thd, "create", create_table, &new_table))
+ DBUG_RETURN(NULL);
+ create_table_mode|= CREATE_TMP_TABLE;
+ DBUG_ASSERT(!(create_info->options & HA_CREATE_TMP_ALTER));
+ // FIXME: restore options?
+ create_info->options|= HA_CREATE_TMP_ALTER;
+ select_create::create_table= &new_table;
+ select_insert::table_list= &new_table;
+ create_info->tmp_name= &new_table;
+ }
+
/*
Create and lock table.
@@ -4516,11 +4541,14 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
open_table().
*/
- if (!mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm,
+ if (!mysql_create_table_no_lock(thd,
+ &orig_table->db,
+ &orig_table->table_name,
&create_table->db,
&create_table->table_name,
create_info, alter_info, NULL,
- select_field_count, create_table))
+ create_table_mode, create_table,
+ atomic_replace ? &frm : NULL))
{
DEBUG_SYNC(thd,"create_table_select_before_open");
@@ -4530,7 +4558,44 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
*/
create_table->table= 0;
- if (!create_info->tmp_table())
+ if (atomic_replace)
+ {
+ char tmp_path[FN_REFLEN + 1];
+ build_table_filename(tmp_path, sizeof(tmp_path) - 1, new_table.db.str,
+ new_table.table_name.str, "", FN_IS_TMP);
+
+ create_table->table=
+ thd->create_and_open_tmp_table(&frm, tmp_path, orig_table->db.str,
+ orig_table->table_name.str, true);
+ /* NOTE: if create_and_open_tmp_table() fails the table is dropped by
+ * ddl_log_state_create */
+ if (create_table->table)
+ {
+ /*
+ NOTE: Aria tables require table locking to work in transactional
+ mode. Since we don't lock our temporary table we get problems with
+ unproperly initialized transactional mode: seg-fault while accessing
+ uninitialized trn member (reproduced by
+ atomic.create_replace,aria,stmt).
+
+ This hack disables logging for Aria table (that is not needed anyway
+ for a temporary table).
+ */
+ bool on_save= thd->transaction->on;
+ thd->transaction->on= false;
+ if (create_table->table->file->ha_external_lock(thd, F_WRLCK))
+ {
+ // FIXME: test
+ create_table->table= 0;
+ thd->transaction->on= on_save;
+ goto err;
+ }
+
+ thd->transaction->on= on_save;
+ create_table->table->s->can_do_row_logging= 1;
+ }
+ }
+ else if (!create_info->tmp_table())
{
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
TABLE_LIST::enum_open_strategy save_open_strategy;
@@ -4571,13 +4636,20 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
}
else
create_table->table= 0; // Create failed
-
+
+err:
+ DBUG_ASSERT(!create_table->table || frm.str || !atomic_replace);
+ my_free(const_cast<uchar *>(frm.str));
+
if (unlikely(!(table= create_table->table)))
{
if (likely(!thd->is_error())) // CREATE ... IF NOT EXISTS
my_ok(thd); // succeed, but did nothing
+ if (ddl_log_state_rm.is_active())
+ (void) ddl_log_revert(thd, &ddl_log_state_create);
+ else
+ ddl_log_complete(&ddl_log_state_create);
ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
DBUG_RETURN(NULL);
}
@@ -4598,8 +4670,9 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
since it won't wait for the table lock (we have exclusive metadata lock on
the table) and thus can't get aborted.
*/
- if (unlikely(!((*lock)= mysql_lock_tables(thd, &table, 1, 0)) ||
- hooks->postlock(&table, 1)))
+ if ((!atomic_replace &&
+ unlikely(!((*lock)= mysql_lock_tables(thd, &table, 1, 0)))) ||
+ hooks->postlock(&table, 1))
{
/* purecov: begin tested */
/*
@@ -4616,13 +4689,20 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
*lock= 0;
}
drop_open_table(thd, table, &create_table->db, &create_table->table_name);
+ if (ddl_log_state_rm.is_active())
+ (void) ddl_log_revert(thd, &ddl_log_state_create);
+ else
+ ddl_log_complete(&ddl_log_state_create);
ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
DBUG_RETURN(NULL);
/* purecov: end */
}
+ DBUG_ASSERT(
+ create_info->tmp_table() ||
+ thd->mdl_context.is_lock_owner(MDL_key::TABLE, orig_table->db.str,
+ orig_table->table_name.str, MDL_SHARED));
table->s->table_creation_was_logged= save_table_creation_was_logged;
- if (!table->s->tmp_table)
+ if (!create_info->tmp_table())
table->file->prepare_for_row_logging();
/*
@@ -4677,6 +4757,11 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
private:
virtual int do_postlock(TABLE **tables, uint count)
{
+ /*
+ NOTE: for row format CREATE TABLE must be logged before row data.
+
+ TODO: Remove creepy TABLEOP_HOOKS interface?
+ */
int error;
THD *thd= const_cast<THD*>(ptr->get_thd());
TABLE_LIST *save_next_global= create_table->next_global;
@@ -4690,10 +4775,23 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
if (unlikely(error))
return error;
- TABLE const *const table = *tables;
if (thd->is_current_stmt_binlog_format_row() &&
- !table->s->tmp_table)
- return binlog_show_create_table(thd, *tables, ptr->create_info);
+ !ptr->create_info->tmp_table())
+ {
+ thd->binlog_xid= thd->query_id;
+ /*
+ Remember xid's for the case of row based logging. Note that binary
+ log is not flushed until the end of statement, so it is OK to write
+ it now and if crash happens until we closed ddl_log_state_rm we
+ won't see CREATE OR REPLACE event in the binary log.
+ */
+ ddl_log_update_xid(&ptr->ddl_log_state_create, thd->binlog_xid);
+ if (ptr->ddl_log_state_rm.is_active() &&
+ !ptr->create_info->is_atomic_replace())
+ ddl_log_update_xid(&ptr->ddl_log_state_rm, thd->binlog_xid);
+ error= binlog_show_create_table(thd, *tables, ptr->create_info);
+ return error;
+ }
return 0;
}
select_create *ptr;
@@ -4720,8 +4818,9 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
if (!(table= create_table_from_items(thd, &values, &extra_lock, hook_ptr)))
{
- if (create_info->or_replace())
+ if (create_info->or_replace() && !atomic_replace)
{
+ /* TODO: why create_info->table_was_deleted not used? */
/* Original table was deleted. We have to log it */
log_drop_table(thd, &create_table->db, &create_table->table_name,
&create_info->org_storage_engine_name,
@@ -4734,6 +4833,8 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
DBUG_RETURN(-1);
}
+ DBUG_ASSERT(table == create_table->table);
+
if (create_info->tmp_table())
{
/*
@@ -4743,14 +4844,14 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
list to keep them inaccessible from inner statements.
e.g. CREATE TEMPORARY TABLE `t1` AS SELECT * FROM `t1`;
*/
- saved_tmp_table_share= thd->save_tmp_table_share(create_table->table);
+ saved_tmp_table_share= thd->save_tmp_table_share(table);
}
if (extra_lock)
{
DBUG_ASSERT(m_plock == NULL);
- if (create_info->tmp_table())
+ if (table->s->tmp_table)
m_plock= &m_lock;
else
m_plock= &thd->extra_lock;
@@ -4845,6 +4946,10 @@ static int binlog_show_create_table(THD *thd, TABLE *table,
create_info, WITH_DB_NAME);
DBUG_ASSERT(result == 0); /* show_create_table() always return 0 */
+ /*
+ TODO (optimization): why it does show_create_table() even if
+ !mysql_bin_log.is_open()?
+ */
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
@@ -4966,28 +5071,42 @@ bool select_create::send_eof()
is in select_insert::prepare_eof(). For that reason, we
mark the flag at this point.
*/
- if (table->s->tmp_table)
+ if (create_info->tmp_table())
thd->transaction->stmt.mark_created_temp_table();
if (thd->slave_thread)
thd->variables.binlog_annotate_row_events= 0;
+ if (atomic_replace)
+ {
+ DBUG_ASSERT(table->s->tmp_table);
+
+ int result;
+ if (table->file->ha_index_or_rnd_end() ||
+ table->file->ha_external_lock(thd, F_UNLCK))
+ {
+ abort_result_set();
+ DBUG_RETURN(true);
+ }
+
+ create_info->table= orig_table->table;
+ if (create_table_handle_exists(thd, orig_table->db, orig_table->table_name,
+ *create_info, create_info, result))
+ {
+ abort_result_set();
+ DBUG_RETURN(true);
+ }
+ }
+
debug_crash_here("ddl_log_create_before_binlog");
- /*
- In case of crash, we have to add DROP TABLE to the binary log as
- the CREATE TABLE will already be logged if we are not using row based
- replication.
- */
- if (!thd->is_current_stmt_binlog_format_row())
+ if (!thd->binlog_xid && !create_info->tmp_table())
{
- if (ddl_log_state_create.is_active()) // Not temporary table
- ddl_log_update_phase(&ddl_log_state_create, DDL_CREATE_TABLE_PHASE_LOG);
- /*
- We can ignore if we replaced an old table as ddl_log_state_create will
- now handle the logging of the drop if needed.
- */
- ddl_log_complete(&ddl_log_state_rm);
+ thd->binlog_xid= thd->query_id;
+ /* Remember xid's for the case of row based logging */
+ ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
+ if (ddl_log_state_rm.is_active() && !atomic_replace)
+ ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
}
if (prepare_eof())
@@ -4997,7 +5116,7 @@ bool select_create::send_eof()
}
debug_crash_here("ddl_log_create_after_prepare_eof");
- if (table->s->tmp_table)
+ if (create_info->tmp_table())
{
/*
Now is good time to add the new table to THD temporary tables list.
@@ -5017,17 +5136,25 @@ bool select_create::send_eof()
thd->restore_tmp_table_share(saved_tmp_table_share);
}
}
+ else if (atomic_replace)
+ {
+ create_table= orig_table;
+ create_info->table= NULL;
+ table->file->ha_reset();
+ thd->drop_temporary_table(table, NULL, false);
+ table= NULL;
+ }
/*
Do an implicit commit at end of statement for non-temporary
tables. This can fail, but we should unlock the table
nevertheless.
*/
- if (!table->s->tmp_table)
+ if (!create_info->tmp_table())
{
#ifdef WITH_WSREP
if (WSREP(thd) &&
- table->file->ht->db_type == DB_TYPE_INNODB)
+ create_info->db_type->db_type == DB_TYPE_INNODB)
{
if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID)
{
@@ -5062,10 +5189,6 @@ bool select_create::send_eof()
thd->get_stmt_da()->set_overwrite_status(true);
}
#endif /* WITH_WSREP */
- thd->binlog_xid= thd->query_id;
- /* Remember xid's for the case of row based logging */
- ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
- ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
trans_commit_stmt(thd);
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
trans_commit_implicit(thd);
@@ -5102,6 +5225,11 @@ bool select_create::send_eof()
ddl_log.org_database= create_table->db;
ddl_log.org_table= create_table->table_name;
ddl_log.org_table_id= create_info->tabledef_version;
+ if (create_info->drop_entry.query.length)
+ {
+ DBUG_ASSERT(atomic_replace);
+ backup_log_ddl(&create_info->drop_entry);
+ }
backup_log_ddl(&ddl_log);
}
/*
@@ -5110,9 +5238,17 @@ bool select_create::send_eof()
(as the query was logged before commit!)
*/
debug_crash_here("ddl_log_create_after_binlog");
- ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
- debug_crash_here("ddl_log_create_log_complete");
+ if (create_info->finalize_ddl(thd))
+ {
+ if (atomic_replace)
+ {
+ /* Now we have to log DROP_AFTER_CREATE */
+ atomic_replace= false;
+ create_table= &new_table;
+ }
+ abort_result_set();
+ DBUG_RETURN(true);
+ }
/*
exit_done must only be set after last potential call to
@@ -5120,10 +5256,9 @@ bool select_create::send_eof()
*/
exit_done= 1; // Avoid double calls
- send_ok_packet();
-
if (m_plock)
{
+ DBUG_ASSERT(!atomic_replace);
MYSQL_LOCK *lock= *m_plock;
*m_plock= NULL;
m_plock= NULL;
@@ -5142,11 +5277,37 @@ bool select_create::send_eof()
create_info->
pos_in_locked_tables,
table, lock))
+ {
+ send_ok_packet();
DBUG_RETURN(false); // ok
+ }
/* Fail. Continue without locking the table */
}
mysql_unlock_tables(thd, lock);
}
+ else if (atomic_replace && create_info->pos_in_locked_tables)
+ {
+ DBUG_ASSERT(thd->locked_tables_mode);
+ DBUG_ASSERT(thd->variables.option_bits & OPTION_TABLE_LOCK);
+ TABLE_LIST *pos_in_locked_tables= create_info->pos_in_locked_tables;
+ /*
+ Add back the deleted table and re-created table as a locked table
+ This should always work as we have a meta lock on the table.
+ */
+ thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
+ if (thd->locked_tables_list.reopen_tables(thd, false))
+ {
+ thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
+ DBUG_RETURN(true);
+ }
+ else
+ {
+ TABLE *table= pos_in_locked_tables->table;
+ table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
+ }
+ }
+
+ send_ok_packet();
DBUG_RETURN(false);
}
@@ -5191,14 +5352,14 @@ void select_create::abort_result_set()
if (table)
{
- bool tmp_table= table->s->tmp_table;
- bool table_creation_was_logged= (!tmp_table ||
- table->s->table_creation_was_logged);
+ bool tmp_table= create_info->tmp_table();
if (tmp_table)
{
DBUG_ASSERT(saved_tmp_table_share);
thd->restore_tmp_table_share(saved_tmp_table_share);
}
+ else if (atomic_replace)
+ create_table= &new_table;
if (table->file->inited &&
(info.ignore || info.handle_duplicates != DUP_ERROR) &&
@@ -5215,7 +5376,14 @@ void select_create::abort_result_set()
m_plock= NULL;
}
- drop_open_table(thd, table, &create_table->db, &create_table->table_name);
+ if (atomic_replace)
+ {
+ (void) table->file->ha_external_lock(thd, F_UNLCK);
+ (void) thd->drop_temporary_table(table, NULL, true);
+ }
+ else
+ drop_open_table(thd, table, &create_table->db,
+ &create_table->table_name);
table=0; // Safety
if (thd->log_current_statement)
{
@@ -5223,39 +5391,30 @@ void select_create::abort_result_set()
{
/* Remove logging of drop, create + insert rows */
binlog_reset_cache(thd);
- /* Original table was deleted. We have to log it */
- if (table_creation_was_logged)
- {
- thd->binlog_xid= thd->query_id;
- ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
- ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
- debug_crash_here("ddl_log_create_before_binlog");
- log_drop_table(thd, &create_table->db, &create_table->table_name,
- &create_info->org_storage_engine_name,
- create_info->db_type == partition_hton,
- &create_info->tabledef_version,
- tmp_table);
- debug_crash_here("ddl_log_create_after_binlog");
- thd->binlog_xid= 0;
- }
}
- else if (!tmp_table)
+ else if (!tmp_table && !atomic_replace)
{
backup_log_info ddl_log;
bzero(&ddl_log, sizeof(ddl_log));
ddl_log.query= { C_STRING_WITH_LEN("DROP_AFTER_CREATE") };
ddl_log.org_partitioned= (create_info->db_type == partition_hton);
ddl_log.org_storage_engine_name= create_info->org_storage_engine_name;
- ddl_log.org_database= create_table->db;
- ddl_log.org_table= create_table->table_name;
+ ddl_log.org_database= orig_table->db;
+ ddl_log.org_table= orig_table->table_name;
ddl_log.org_table_id= create_info->tabledef_version;
backup_log_ddl(&ddl_log);
}
}
}
-
- ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
+ if (!binary_logged)
+ {
+ if (ddl_log_state_rm.is_active())
+ (void) ddl_log_revert(thd, &ddl_log_state_create);
+ else
+ ddl_log_complete(&ddl_log_state_create);
+ ddl_log_complete(&ddl_log_state_rm);
+ }
+ thd->binlog_xid= 0;
if (create_info->table_was_deleted)
{
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index b75a318ab65..8f2ecdcfafc 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -7003,6 +7003,8 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
{
THD *thd= lpt->thd;
partition_info *part_info= lpt->part_info->get_clone(thd);
+ /* TABLE is going to be released, we should not access old part_info anymore */
+ lpt->part_info= part_info;
TABLE *table= lpt->table;
DBUG_ENTER("handle_alter_part_error");
DBUG_ASSERT(table->needs_reopen());
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a357d4f8c8a..955e76f537b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -55,6 +55,7 @@
#include "sql_window.h"
#include "tztime.h"
+#include "debug.h"
#include "debug_sync.h" // DEBUG_SYNC
#include <m_ctype.h>
#include <my_bit.h>
@@ -22308,6 +22309,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
// error < 0 => duplicate row
join->duplicate_rows++;
}
+ debug_crash_here("ddl_log_create_after_send_data");
}
join->send_records++;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d01f84fe7d1..a138b2d51e6 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2107,7 +2107,8 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list,
!create_info_arg->or_replace_slave_generated()) ||
create_info_arg->table_was_deleted))
packet->append(STRING_WITH_LEN("OR REPLACE "));
- if (share->tmp_table)
+ if (share->tmp_table &&
+ !(create_info_arg && create_info_arg->is_atomic_replace()))
packet->append(STRING_WITH_LEN("TEMPORARY "));
packet->append(STRING_WITH_LEN("TABLE "));
if (create_info_arg && create_info_arg->if_not_exists())
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b07efb29bba..7e08ad7b801 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -742,7 +742,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
if (mysql_prepare_create_table(lpt->thd, lpt->create_info, lpt->alter_info,
&lpt->db_options, lpt->table->file,
&lpt->key_info_buffer, &lpt->key_count,
- C_ALTER_TABLE, lpt->db, lpt->table_name))
+ CREATE_TMP_TABLE, lpt->db, lpt->table_name))
{
DBUG_RETURN(TRUE);
}
@@ -816,7 +816,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
if (mysql_prepare_create_table(thd, create_info, lpt->alter_info,
&lpt->db_options, file,
&lpt->key_info_buffer, &lpt->key_count,
- C_ALTER_TABLE, alter_ctx->new_db,
+ CREATE_TMP_TABLE, alter_ctx->new_db,
alter_ctx->new_name))
DBUG_RETURN(TRUE);
@@ -1144,11 +1144,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
/* mark for close and remove all cached entries */
thd->push_internal_handler(&err_handler);
- error= mysql_rm_table_no_locks(thd, tables, &thd->db, (DDL_LOG_STATE*) 0,
- if_exists,
- drop_temporary,
- false, drop_sequence, dont_log_query,
- false);
+ error= mysql_rm_table_no_locks(thd, tables, &thd->db, NULL, if_exists,
+ drop_temporary, false, drop_sequence,
+ dont_log_query, false);
thd->pop_internal_handler();
if (unlikely(error))
@@ -1203,6 +1201,39 @@ static uint32 get_comment(THD *thd, uint32 comment_pos,
return 0;
}
+bool make_tmp_name(THD *thd, const char *prefix, const TABLE_LIST *orig,
+ TABLE_LIST *res)
+{
+ char res_name[NAME_LEN + 1];
+ char file_name[FN_REFLEN];
+ LEX_CSTRING table_name;
+
+ (void) tablename_to_filename(orig->table_name.str, file_name,
+ sizeof(file_name));
+ size_t len= my_snprintf(res_name, sizeof(res_name) - 1,
+ tmp_file_prefix "-%s-%lx-%llx-%s", prefix,
+ current_pid, thd->thread_id, file_name);
+
+ table_name.str= strmake_root(thd->mem_root, res_name, len);
+ if (!table_name.str)
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ return true;
+ }
+
+ table_name.length= len;
+
+ if (lower_case_table_names)
+ {
+ my_casedn_str(system_charset_info, res_name);
+ table_name.str= strmake_root(thd->mem_root, res_name, len);
+ }
+
+ res->init_one_table(&orig->db, &table_name, NULL, orig->lock_type);
+ return false;
+}
+
+
/**
Execute the drop of a sequence, view or table (normal or temporary).
@@ -1243,7 +1274,7 @@ static uint32 get_comment(THD *thd, uint32 comment_pos,
int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
const LEX_CSTRING *current_db,
- DDL_LOG_STATE *ddl_log_state,
+ Atomic_info *atomic_info,
bool if_exists,
bool drop_temporary, bool drop_view,
bool drop_sequence,
@@ -1271,6 +1302,15 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
String built_trans_tmp_query, built_non_trans_tmp_query;
DBUG_ENTER("mysql_rm_table_no_locks");
+ DDL_LOG_STATE *ddl_log_state= NULL;
+ bool atomic_replace= false;
+
+ if (atomic_info)
+ {
+ ddl_log_state= atomic_info->ddl_log_state_rm;
+ atomic_replace= (atomic_info->tmp_name != NULL);
+ }
+
if (!ddl_log_state)
{
ddl_log_state= &local_ddl_log_state;
@@ -1456,12 +1496,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db.str,
table_name.str, MDL_SHARED));
+ /* NOTE: alias holds original table name, table_name holds lowercase name */
alias= (lower_case_table_names == 2) ? table->alias : table_name;
/* remove .frm file and engine files */
path_length= build_table_filename(path, sizeof(path) - 1, db.str,
alias.str, reg_ext, 0);
path_end= path + path_length - reg_ext_length;
- }
+ } /* if (!drop_temporary) */
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
if (drop_temporary)
@@ -1569,6 +1610,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
}
debug_crash_here("ddl_log_drop_before_delete_table");
+ if (atomic_replace)
+ goto report_error;
error= ha_delete_table(thd, hton, path, &db, &table_name,
enoent_warning);
debug_crash_here("ddl_log_drop_after_delete_table");
@@ -1638,6 +1681,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
int ferror= 0;
DBUG_ASSERT(!was_view);
+ /* We've already logged drop and we don't need that entry anymore. */
+ ddl_log_disable_entry(ddl_log_state);
if (ddl_log_drop_table(thd, ddl_log_state, 0, &cpath, &db,
&table_name))
{
@@ -1734,29 +1779,42 @@ report_error:
if (if_exists && non_existing_table_error(error))
error= 0;
- if (!error && table_dropped)
+ if (!error)
{
- PSI_CALL_drop_table_share(temporary_table_was_dropped,
- db.str, (uint)db.length,
- table_name.str, (uint)table_name.length);
- mysql_audit_drop_table(thd, table);
- if (!is_temporary)
+ if (table_dropped)
+ {
+ PSI_CALL_drop_table_share(temporary_table_was_dropped, db.str,
+ (uint) db.length, table_name.str,
+ (uint) table_name.length);
+ mysql_audit_drop_table(thd, table);
+ }
+ if (!is_temporary && (atomic_replace || table_dropped))
{
backup_log_info ddl_log;
- bzero(&ddl_log, sizeof(ddl_log));
- ddl_log.query= { C_STRING_WITH_LEN("DROP") };
- if ((ddl_log.org_partitioned= (partition_engine_name.str != 0)))
- ddl_log.org_storage_engine_name= partition_engine_name;
+ backup_log_info *d;
+ DBUG_ASSERT(!atomic_replace || atomic_info);
+ DBUG_ASSERT(!(atomic_replace && table_dropped));
+ if (atomic_replace)
+ d= &atomic_info->drop_entry;
else
- lex_string_set(&ddl_log.org_storage_engine_name,
+ {
+ d= &ddl_log;
+ bzero(d, sizeof(*d));
+ }
+ d->query= { C_STRING_WITH_LEN("DROP") };
+ if ((d->org_partitioned= (partition_engine_name.str != 0)))
+ d->org_storage_engine_name= partition_engine_name;
+ else
+ lex_string_set(&d->org_storage_engine_name,
ha_resolve_storage_engine_name(hton));
- ddl_log.org_database= table->db;
- ddl_log.org_table= table->table_name;
- ddl_log.org_table_id= version;
- backup_log_ddl(&ddl_log);
+ d->org_database= table->db;
+ d->org_table= table->table_name;
+ d->org_table_id= version;
+ if (table_dropped)
+ backup_log_ddl(d);
}
}
- if (!was_view)
+ if (!was_view && !atomic_replace)
ddl_log_update_phase(ddl_log_state, DDL_DROP_PHASE_BINLOG);
if (!dont_log_query &&
@@ -2684,8 +2742,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
List_iterator_fast<Create_field> it(alter_info->create_list);
List_iterator<Create_field> it2(alter_info->create_list);
uint total_uneven_bit_length= 0;
- int select_field_count= C_CREATE_SELECT(create_table_mode);
- bool tmp_table= create_table_mode == C_ALTER_TABLE;
+ bool tmp_table= (create_table_mode & CREATE_TMP_TABLE);
const bool create_simple= thd->lex->create_simple();
bool is_hash_field_needed= false;
const Column_derived_attributes dattr(create_info->default_table_charset);
@@ -2724,7 +2781,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE);
}
- select_field_pos= alter_info->create_list.elements - select_field_count;
+ select_field_pos= alter_info->field_count();
null_fields= 0;
create_info->varchar= 0;
max_key_length= file->max_key_length();
@@ -2899,7 +2956,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
from the select tables. This order may differ on master and slave. We
therefore mark it as unsafe.
*/
- if (select_field_count > 0 && auto_increment)
+ if (alter_info->select_field_count > 0 && auto_increment)
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_SELECT_AUTOINC);
/* Create keys */
@@ -2935,6 +2992,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
ER_THD(thd, ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
DBUG_RETURN(TRUE);
}
+ if (create_info->tmp_name &&
+ !lex_string_cmp(table_alias_charset, &table_name,
+ &fk_key->ref_table))
+ {
+ fk_key->ref_table= create_info->tmp_name->table_name;
+ }
continue;
}
(*key_count)++;
@@ -4246,6 +4309,155 @@ err:
DBUG_RETURN(NULL);
}
+inline bool
+HA_CREATE_INFO::handle_atomic_replace(THD *thd, const LEX_CSTRING &db,
+ const LEX_CSTRING &table_name,
+ const DDL_options_st options)
+{
+ DBUG_ASSERT(options.or_replace());
+ DBUG_ASSERT(ok_atomic_replace());
+ ddl_log_link_chains(ddl_log_state_rm, ddl_log_state_create);
+ if (ddl_log_rename_table(thd, ddl_log_state_rm, db_type, &db, &table_name,
+ &tmp_name->db, &tmp_name->table_name))
+ return true;
+ debug_crash_here("ddl_log_create_after_log_rename");
+ return false;
+}
+
+bool HA_CREATE_INFO::finalize_ddl(THD *thd)
+{
+ bool result;
+ if (ddl_log_state_create->execute_entry)
+ {
+ DBUG_ASSERT(ddl_log_state_create->is_active());
+ mysql_mutex_lock(&LOCK_gdl);
+ ddl_log_disable_execute_entry(&ddl_log_state_create->execute_entry);
+ mysql_mutex_unlock(&LOCK_gdl);
+ }
+ debug_crash_here("ddl_log_create_before_remove_backup");
+ /* NOTE: holds "drop old table; rename tmp table" */
+ result= ddl_log_revert(thd, ddl_log_state_rm, true);
+ if (result && ddl_log_state_create->is_active())
+ {
+ /* In case roll forward fails we must roll back to drop tmp table */
+ mysql_mutex_lock(&LOCK_gdl);
+ ddl_log_write_execute_entry(ddl_log_state_create->list->entry_pos, 0,
+ &ddl_log_state_create->execute_entry);
+ mysql_mutex_unlock(&LOCK_gdl);
+ (void) ddl_log_revert(thd, ddl_log_state_create);
+ }
+ else
+ {
+ mysql_mutex_lock(&LOCK_gdl);
+ ddl_log_release_entries(ddl_log_state_create);
+ mysql_mutex_unlock(&LOCK_gdl);
+ ddl_log_state_create->list= 0;
+ }
+ debug_crash_here("ddl_log_create_log_complete");
+ return result;
+}
+
+bool create_table_handle_exists(THD *thd, const LEX_CSTRING &db,
+ const LEX_CSTRING &table_name,
+ const DDL_options_st options,
+ HA_CREATE_INFO *create_info, int &error)
+{
+ handlerton *db_type;
+ const bool atomic_replace= create_info->tmp_name != NULL;
+
+ if (!ha_table_exists(thd, &db, &table_name,
+ &create_info->org_tabledef_version, NULL, &db_type))
+ {
+ if (atomic_replace &&
+ create_info->handle_atomic_replace(thd, db, table_name, options))
+ return true;
+ return false;
+ }
+
+ if (ha_check_if_updates_are_ignored(thd, db_type, "CREATE"))
+ {
+ /* Don't create table. CREATE will still be logged in binary log */
+ error= 0;
+ return true;
+ }
+
+ if (options.or_replace())
+ {
+ (void) delete_statistics_for_table(thd, &db, &table_name);
+
+ TABLE_LIST table_list;
+ table_list.init_one_table(&db, &table_name, 0, TL_WRITE_ALLOW_WRITE);
+ table_list.table= create_info->table;
+
+ if (check_if_log_table(&table_list, TRUE, "CREATE OR REPLACE"))
+ return true;
+
+ if (atomic_replace)
+ {
+ /*
+ NOTE: we must log rename before drop! Otherwise we may recover into
+ drop, but not do rename. See next_active_log_entry handling in
+ ddl_log_drop().
+ */
+ if (create_info->handle_atomic_replace(thd, db, table_name, options))
+ return true;
+ }
+ else
+ {
+ /*
+ Rollback the empty transaction started in mysql_create_table()
+ call to open_and_lock_tables() when we are using LOCK TABLES.
+ */
+ (void) trans_rollback_stmt(thd);
+ }
+ /* Remove normal table without logging. Keep tables locked */
+ if (mysql_rm_table_no_locks(thd, &table_list, &thd->db, create_info, 0, 0,
+ 0, 0, 1, 1))
+ return true;
+
+ debug_crash_here("ddl_log_create_after_drop");
+
+ /*
+ We have to log this query, even if it failed later to ensure the
+ drop is done.
+ */
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
+ thd->log_current_statement= 1;
+ if (!atomic_replace)
+ create_info->table_was_deleted= 1;
+ lex_string_set(&create_info->org_storage_engine_name,
+ ha_resolve_storage_engine_name(db_type));
+ DBUG_EXECUTE_IF("send_kill_after_delete", thd->set_killed(KILL_QUERY););
+ /*
+ Restart statement transactions for the case of CREATE ... SELECT.
+ */
+ if (!atomic_replace && thd->lex->first_select_lex()->item_list.elements &&
+ restart_trans_for_tables(thd, thd->lex->query_tables))
+ return true;
+ }
+ else if (options.if_not_exists())
+ {
+ /*
+ We never come here as part of normal create table as table existance
+ is checked in open_and_lock_tables(). We may come here as part of
+ ALTER TABLE when converting a table for a distributed engine to a
+ a local one.
+ */
+
+ /* Log CREATE IF NOT EXISTS on slave for distributed engines */
+ if (thd->slave_thread && (db_type && db_type->flags & HTON_IGNORE_UPDATES))
+ thd->log_current_statement= 1;
+ error= -1;
+ return true;
+ }
+ else
+ {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name.str);
+ return true;
+ }
+ return false;
+}
+
/**
Create a table
@@ -4286,8 +4498,6 @@ err:
*/
int create_table_impl(THD *thd,
- DDL_LOG_STATE *ddl_log_state_create,
- DDL_LOG_STATE *ddl_log_state_rm,
const LEX_CSTRING &orig_db,
const LEX_CSTRING &orig_table_name,
const LEX_CSTRING &db, const LEX_CSTRING &table_name,
@@ -4296,22 +4506,17 @@ int create_table_impl(THD *thd,
int create_table_mode, bool *is_trans, KEY **key_info,
uint *key_count, LEX_CUSTRING *frm)
{
- LEX_CSTRING *alias;
+ LEX_CSTRING *alias= const_cast<LEX_CSTRING*>(table_case_name(create_info, &table_name));
handler *file= 0;
int error= 1;
- bool frm_only= create_table_mode == C_ALTER_TABLE_FRM_ONLY;
- bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || frm_only;
+ bool frm_only= (create_table_mode & CREATE_FRM_ONLY);
+ bool internal_tmp_table= (create_table_mode & CREATE_TMP_TABLE) || frm_only;
+ /* Easy check for ddl logging if we are creating a temporary table */
+ DDL_LOG_STATE *ddl_log_state_create= create_info->tmp_table() ? 0 : create_info->ddl_log_state_create;
DBUG_ENTER("create_table_impl");
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d path: %s",
db.str, table_name.str, internal_tmp_table, path.str));
- /* Easy check for ddl logging if we are creating a temporary table */
- if (create_info->tmp_table())
- {
- ddl_log_state_create= 0;
- ddl_log_state_rm= 0;
- }
-
if (fix_constraints_names(thd, &alter_info->check_constraint_list,
create_info))
DBUG_RETURN(1);
@@ -4340,8 +4545,6 @@ int create_table_impl(THD *thd,
goto err;
}
- alias= const_cast<LEX_CSTRING*>(table_case_name(create_info, &table_name));
-
/* Check if table exists */
if (create_info->tmp_table())
{
@@ -4365,7 +4568,10 @@ int create_table_impl(THD *thd,
goto err;
}
else if (options.if_not_exists())
- goto warn;
+ {
+ error= -1;
+ goto err;
+ }
else
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias->str);
@@ -4396,81 +4602,10 @@ int create_table_impl(THD *thd,
goto err;
}
- handlerton *db_type;
if (!internal_tmp_table &&
- ha_table_exists(thd, &db, &table_name,
- &create_info->org_tabledef_version, NULL, &db_type))
- {
- if (ha_check_if_updates_are_ignored(thd, db_type, "CREATE"))
- {
- /* Don't create table. CREATE will still be logged in binary log */
- error= 0;
- goto err;
- }
-
- if (options.or_replace())
- {
- (void) delete_statistics_for_table(thd, &db, &table_name);
-
- TABLE_LIST table_list;
- table_list.init_one_table(&db, &table_name, 0, TL_WRITE_ALLOW_WRITE);
- table_list.table= create_info->table;
-
- if (check_if_log_table(&table_list, TRUE, "CREATE OR REPLACE"))
- goto err;
-
- /*
- Rollback the empty transaction started in mysql_create_table()
- call to open_and_lock_tables() when we are using LOCK TABLES.
- */
- (void) trans_rollback_stmt(thd);
- /* Remove normal table without logging. Keep tables locked */
- if (mysql_rm_table_no_locks(thd, &table_list, &thd->db,
- ddl_log_state_rm,
- 0, 0, 0, 0, 1, 1))
- goto err;
-
- debug_crash_here("ddl_log_create_after_drop");
-
- /*
- We have to log this query, even if it failed later to ensure the
- drop is done.
- */
- thd->variables.option_bits|= OPTION_KEEP_LOG;
- thd->log_current_statement= 1;
- create_info->table_was_deleted= 1;
- lex_string_set(&create_info->org_storage_engine_name,
- ha_resolve_storage_engine_name(db_type));
- DBUG_EXECUTE_IF("send_kill_after_delete",
- thd->set_killed(KILL_QUERY););
- /*
- Restart statement transactions for the case of CREATE ... SELECT.
- */
- if (thd->lex->first_select_lex()->item_list.elements &&
- restart_trans_for_tables(thd, thd->lex->query_tables))
- goto err;
- }
- else if (options.if_not_exists())
- {
- /*
- We never come here as part of normal create table as table existance
- is checked in open_and_lock_tables(). We may come here as part of
- ALTER TABLE when converting a table for a distributed engine to a
- a local one.
- */
-
- /* Log CREATE IF NOT EXISTS on slave for distributed engines */
- if (thd->slave_thread && (db_type && db_type->flags &
- HTON_IGNORE_UPDATES))
- thd->log_current_statement= 1;
- goto warn;
- }
- else
- {
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name.str);
- goto err;
- }
- }
+ create_table_handle_exists(thd, db, table_name, options, create_info,
+ error))
+ goto err;
}
THD_STAGE_INFO(thd, stage_creating_table);
@@ -4478,7 +4613,7 @@ int create_table_impl(THD *thd,
if (check_engine(thd, orig_db.str, orig_table_name.str, create_info))
goto err;
- if (create_table_mode == C_ASSISTED_DISCOVERY)
+ if (create_table_mode & CREATE_ASSISTED)
{
/* check that it's used correctly */
DBUG_ASSERT(alter_info->create_list.elements == 0);
@@ -4564,8 +4699,8 @@ int create_table_impl(THD *thd,
if (!frm_only)
{
debug_crash_here("ddl_log_create_before_create_table");
- if (ha_create_table(thd, path.str, db.str, table_name.str, create_info,
- frm, 0))
+ if (ha_create_table(thd, path.str, orig_db.str, orig_table_name.str,
+ create_info, frm, 0))
{
file->ha_create_partitioning_metadata(path.str, NULL, CHF_DELETE_FLAG);
deletefrm(path.str);
@@ -4597,6 +4732,12 @@ int create_table_impl(THD *thd,
error= 0;
err:
+ if (error == -1)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_TABLE_EXISTS_ERROR,
+ ER_THD(thd, ER_TABLE_EXISTS_ERROR), alias->str);
+ }
if (unlikely(error) && ddl_log_state_create)
{
/* Table was never created, so we can ignore the ddl log entry */
@@ -4607,14 +4748,6 @@ err:
delete file;
DBUG_PRINT("exit", ("return: %d", error));
DBUG_RETURN(error);
-
-warn:
- error= -1;
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_TABLE_EXISTS_ERROR,
- ER_THD(thd, ER_TABLE_EXISTS_ERROR),
- alias->str);
- goto err;
}
/**
@@ -4626,16 +4759,18 @@ warn:
2 error; Don't log create statement
0 ok
-1 Table was used with IF NOT EXISTS and table existed (warning, not error)
+
+ TODO: orig_db, orig_table_name, db, table_name should be moved to create_info
*/
-int mysql_create_table_no_lock(THD *thd,
- DDL_LOG_STATE *ddl_log_state_create,
- DDL_LOG_STATE *ddl_log_state_rm,
+int mysql_create_table_no_lock(THD *thd, const LEX_CSTRING *orig_db,
+ const LEX_CSTRING *orig_table_name,
const LEX_CSTRING *db,
const LEX_CSTRING *table_name,
Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans,
- int create_table_mode, TABLE_LIST *table_list)
+ int create_table_mode, TABLE_LIST *table_list,
+ LEX_CUSTRING *frm)
{
KEY *not_used_1;
uint not_used_2;
@@ -4643,16 +4778,21 @@ int mysql_create_table_no_lock(THD *thd,
uint path_length;
char path[FN_REFLEN + 1];
LEX_CSTRING cpath;
- LEX_CUSTRING frm= {0,0};
+ LEX_CUSTRING frm_local;
+ if (!frm)
+ {
+ frm_local= {0, 0};
+ frm= &frm_local;
+ }
if (create_info->tmp_table())
path_length= build_tmptable_filename(thd, path, sizeof(path));
else
{
const LEX_CSTRING *alias= table_case_name(create_info, table_name);
+ uint flags= (create_info->options & HA_CREATE_TMP_ALTER) ? FN_IS_TMP : 0;
path_length= build_table_filename(path, sizeof(path) - 1, db->str,
- alias->str,
- "", 0);
+ alias->str, "", flags);
// Check if we hit FN_REFLEN bytes along with file extension.
if (path_length+reg_ext_length > FN_REFLEN)
{
@@ -4663,12 +4803,12 @@ int mysql_create_table_no_lock(THD *thd,
}
lex_string_set3(&cpath, path, path_length);
- res= create_table_impl(thd, ddl_log_state_create, ddl_log_state_rm,
- *db, *table_name, *db, *table_name, cpath,
- *create_info, create_info,
- alter_info, create_table_mode,
- is_trans, &not_used_1, &not_used_2, &frm);
- my_free(const_cast<uchar*>(frm.str));
+ res= create_table_impl(thd, *orig_db, *orig_table_name, *db, *table_name,
+ cpath, *create_info, create_info, alter_info,
+ create_table_mode, is_trans, &not_used_1, &not_used_2,
+ frm);
+ if (frm == &frm_local)
+ my_free(const_cast<uchar *>(frm_local.str));
if (!res && create_info->sequence)
{
@@ -4683,8 +4823,7 @@ int mysql_create_table_no_lock(THD *thd,
DBUG_ASSERT(thd->is_error());
/* Drop the table as it wasn't completely done */
if (!mysql_rm_table_no_locks(thd, table_list, &thd->db,
- (DDL_LOG_STATE*) 0,
- 1,
+ NULL, 1,
create_info->tmp_table(),
false, true /* Sequence*/,
true /* Don't log_query */,
@@ -4723,13 +4862,20 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
int create_table_mode;
uint save_thd_create_info_options;
bool is_trans= FALSE;
- bool result;
+ int result;
+ TABLE_LIST new_table;
+ TABLE_LIST *orig_table= create_table;
+ const bool atomic_replace= create_info->is_atomic_replace();
DBUG_ENTER("mysql_create_table");
DBUG_ASSERT(create_table == thd->lex->query_tables);
bzero(&ddl_log_state_create, sizeof(ddl_log_state_create));
bzero(&ddl_log_state_rm, sizeof(ddl_log_state_rm));
+ if (atomic_replace)
+ create_info->tmp_name= &new_table;
+ create_info->ddl_log_state_create= &ddl_log_state_create;
+ create_info->ddl_log_state_rm= &ddl_log_state_rm;
/* Copy temporarily the statement flags to thd for lock_table_names() */
save_thd_create_info_options= thd->lex->create_info.options;
@@ -4765,9 +4911,9 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
DEBUG_SYNC(thd, "locked_table_name");
if (alter_info->create_list.elements || alter_info->key_list.elements)
- create_table_mode= C_ORDINARY_CREATE;
+ create_table_mode= CREATE_ORDINARY;
else
- create_table_mode= C_ASSISTED_DISCOVERY;
+ create_table_mode= CREATE_ASSISTED;
if (!opt_explicit_defaults_for_timestamp)
promote_first_timestamp_column(&alter_info->create_list);
@@ -4775,7 +4921,23 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
/* We can abort create table for any table type */
thd->abort_on_warning= thd->is_strict_mode();
- if (mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm,
+ if (atomic_replace)
+ {
+ if (make_tmp_name(thd, "create", create_table, &new_table))
+ {
+ result= 1;
+ goto err;
+ }
+ create_table_mode|= CREATE_TMP_TABLE;
+ DBUG_ASSERT(!(create_info->options & HA_CREATE_TMP_ALTER));
+ // FIXME: restore options?
+ create_info->options|= HA_CREATE_TMP_ALTER;
+ create_table= &new_table;
+ }
+
+ if (mysql_create_table_no_lock(thd,
+ &orig_table->db,
+ &orig_table->table_name,
&create_table->db,
&create_table->table_name, create_info,
alter_info,
@@ -4786,30 +4948,17 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
goto err;
}
- /*
- Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES
- on a non temporary table
- */
- if (thd->locked_tables_mode && pos_in_locked_tables &&
- create_info->or_replace())
+ if (atomic_replace)
{
- DBUG_ASSERT(thd->variables.option_bits & OPTION_TABLE_LOCK);
- /*
- Add back the deleted table and re-created table as a locked table
- This should always work as we have a meta lock on the table.
- */
- thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
- if (thd->locked_tables_list.reopen_tables(thd, false))
+ create_info->table= orig_table->table;
+ if (create_table_handle_exists(thd, orig_table->db, orig_table->table_name,
+ *create_info, create_info, result))
{
- thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
result= 1;
goto err;
}
- else
- {
- TABLE *table= pos_in_locked_tables->table;
- table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
- }
+ create_table= orig_table;
+ create_info->table= 0;
}
err:
@@ -4845,12 +4994,15 @@ err:
we should log a delete of it.
If create_info->table was not set, it's a normal table and
table_creation_was_logged will be set when the share is created.
+
+ NOTE: this is only needed for non-atomic CREATE OR REPLACE
*/
+ DBUG_ASSERT(!atomic_replace);
create_info->table->s->table_creation_was_logged= 1;
}
thd->binlog_xid= thd->query_id;
ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
- if (ddl_log_state_rm.is_active())
+ if (!atomic_replace)
ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
debug_crash_here("ddl_log_create_before_binlog");
if (unlikely(write_bin_log(thd, result ? FALSE : TRUE, thd->query(),
@@ -4869,11 +5021,48 @@ err:
ddl_log.org_database= create_table->db;
ddl_log.org_table= create_table->table_name;
ddl_log.org_table_id= create_info->tabledef_version;
+ if (create_info->drop_entry.query.length)
+ {
+ DBUG_ASSERT(atomic_replace);
+ backup_log_ddl(&create_info->drop_entry);
+ }
backup_log_ddl(&ddl_log);
}
}
- ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
+ if (result)
+ {
+ (void) ddl_log_revert(thd, &ddl_log_state_create);
+ ddl_log_complete(&ddl_log_state_rm);
+ }
+ else
+ result= create_info->finalize_ddl(thd);
+
+ /*
+ Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES
+ on a non temporary table
+ */
+ if (thd->locked_tables_mode && pos_in_locked_tables &&
+ create_info->or_replace())
+ {
+ DBUG_ASSERT(thd->variables.option_bits & OPTION_TABLE_LOCK);
+ /*
+ Add back the deleted table and re-created table as a locked table
+ This should always work as we have a meta lock on the table.
+ */
+ thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
+ if (thd->locked_tables_list.reopen_tables(thd, false))
+ {
+ thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
+ result= 1;
+ goto err;
+ }
+ else
+ {
+ TABLE *table= pos_in_locked_tables->table;
+ table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
+ }
+ }
+
DBUG_RETURN(result);
}
@@ -5180,10 +5369,18 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
bool src_table_exists= FALSE;
uint not_used;
int create_res;
+ TABLE_LIST new_table;
+ TABLE_LIST *orig_table= table;
+ const bool atomic_replace= create_info->is_atomic_replace();
+ int create_table_mode= CREATE_ORDINARY;
DBUG_ENTER("mysql_create_like_table");
bzero(&ddl_log_state_create, sizeof(ddl_log_state_create));
bzero(&ddl_log_state_rm, sizeof(ddl_log_state_rm));
+ if (atomic_replace)
+ local_create_info.tmp_name= &new_table;
+ local_create_info.ddl_log_state_create= &ddl_log_state_create;
+ local_create_info.ddl_log_state_rm= &ddl_log_state_rm;
#ifdef WITH_WSREP
if (WSREP(thd) && !thd->wsrep_applier &&
@@ -5276,60 +5473,46 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
/* The following is needed only in case of lock tables */
if ((local_create_info.table= thd->lex->query_tables->table))
- pos_in_locked_tables= local_create_info.table->pos_in_locked_tables;
+ pos_in_locked_tables= local_create_info.table->pos_in_locked_tables;
+
+ if (atomic_replace)
+ {
+ if (make_tmp_name(thd, "create", table, &new_table))
+ {
+ goto err;
+ }
+ create_table_mode|= CREATE_TMP_TABLE;
+ DBUG_ASSERT(!(create_info->options & HA_CREATE_TMP_ALTER));
+ // FIXME: restore options?
+ local_create_info.options|= HA_CREATE_TMP_ALTER;
+ new_table.mdl_request.duration= MDL_EXPLICIT;
+ table= &new_table;
+ }
res= ((create_res=
mysql_create_table_no_lock(thd,
- &ddl_log_state_create, &ddl_log_state_rm,
+ &orig_table->db,
+ &orig_table->table_name,
&table->db, &table->table_name,
&local_create_info, &local_alter_info,
- &is_trans, C_ORDINARY_CREATE,
+ &is_trans, create_table_mode,
table)) > 0);
/* Remember to log if we deleted something */
do_logging= thd->log_current_statement;
if (res)
goto err;
- /*
- Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES
- on a non temporary table
- */
- if (thd->locked_tables_mode && pos_in_locked_tables &&
- create_info->or_replace())
- {
- /*
- Add back the deleted table and re-created table as a locked table
- This should always work as we have a meta lock on the table.
- */
- thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
- if (thd->locked_tables_list.reopen_tables(thd, false))
- {
- thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
- res= 1; // We got an error
- }
- else
- {
- /*
- Get pointer to the newly opened table. We need this to ensure we
- don't reopen the table when doing statment logging below.
- */
- table->table= pos_in_locked_tables->table;
- table->table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
- }
- }
- else
+ if (atomic_replace)
{
+ local_create_info.table= orig_table->table;
+ if (create_table_handle_exists(thd, orig_table->db, orig_table->table_name,
+ local_create_info, &local_create_info, res))
+ goto err;
/*
- Ensure that we have an exclusive lock on target table if we are creating
- non-temporary table. We don't have or need the lock if the create failed
- because of existing table when using "if exists".
+ NOTE: orig_table->table is reopened and now is the same share as
+ new_table.
*/
- DBUG_ASSERT((create_info->tmp_table()) || create_res < 0 ||
- thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str,
- table->table_name.str,
- MDL_EXCLUSIVE) ||
- (thd->locked_tables_mode && pos_in_locked_tables &&
- create_info->if_not_exists()));
+ local_create_info.table= 0;
}
DEBUG_SYNC(thd, "create_table_like_before_binlog");
@@ -5371,6 +5554,14 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
5 any shared Generated statement if the table
was created if engine changed
==== ========= ========= ==============================
+
+ TODO: why this is in a separate branch? All logging should be done in
+ single branch (if (do_logging)), possibly moved out to a separate
+ function. Along with backup logging, XID update, etc. This branch is not
+ properly tested now, AFAICS this is tested only by
+ rpl.create_or_replace2.
+
+ Why "generated statement" is needed? No explanation in this comment...
*/
if (!(create_info->tmp_table()) || force_generated_create)
{
@@ -5382,7 +5573,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
query.length(0); // Have to zero it since constructor doesn't
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN |
MYSQL_OPEN_IGNORE_KILLED);
- bool new_table= FALSE; // Whether newly created table is open.
+ bool opened_new_table= FALSE; // Whether newly created table is open.
if (create_res != 0)
{
@@ -5401,6 +5592,19 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
save_open_strategy= table->open_strategy;
table->open_strategy= TABLE_LIST::OPEN_NORMAL;
+ if (atomic_replace &&
+ thd->mdl_context.acquire_lock(&table->mdl_request,
+ thd->variables.lock_wait_timeout))
+ {
+ /*
+ NOTE: We acquire lock for temporary table just to make
+ close_thread_table() happy. We open it like a normal table
+ because it's too complex to open it like tmp_table here.
+ */
+ res= 1;
+ goto err;
+ }
+
/*
In order for show_create_table() to work we need to open
destination table if it is not already open (i.e. if it
@@ -5417,7 +5621,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
res= 1;
goto err;
}
- new_table= TRUE;
+ opened_new_table= TRUE;
}
/*
We have to re-test if the table was a view as the view may not
@@ -5440,18 +5644,40 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
*/
create_info->used_fields|= HA_CREATE_USED_ENGINE;
+ if (atomic_replace)
+ {
+ DBUG_ASSERT(!table->schema_table);
+ table->table->s->table_name.str=
+ strmake_root(&table->table->s->mem_root,
+ LEX_STRING_WITH_LEN(orig_table->table_name));
+ table->table->s->table_name.length= orig_table->table_name.length;
+ table->table->alias.copy(LEX_STRING_WITH_LEN(orig_table->alias),
+ system_charset_info);
+ }
+
int result __attribute__((unused))=
show_create_table(thd, table, &query, create_info, WITH_DB_NAME);
DBUG_ASSERT(result == 0); // show_create_table() always return 0
do_logging= FALSE;
+ thd->binlog_xid= thd->query_id;
+
+ thd->binlog_xid= thd->query_id;
+ ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
+ if (ddl_log_state_rm.is_active() && !atomic_replace)
+ ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
+ debug_crash_here("ddl_log_create_before_binlog");
+
if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
{
res= 1;
goto err;
}
- if (new_table)
+ debug_crash_here("ddl_log_create_after_binlog");
+ thd->binlog_xid= 0;
+
+ if (opened_new_table)
{
DBUG_ASSERT(thd->open_tables == table->table);
/*
@@ -5459,7 +5685,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
(MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table
without risking to close some locked table.
*/
+ table->table->s->tdc->flushed= true;
close_thread_table(thd, &thd->open_tables);
+ if (atomic_replace)
+ thd->mdl_context.release_lock(table->mdl_request.ticket);
}
}
}
@@ -5483,21 +5712,42 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
/*
Remember that tmp table creation was logged so that we know if
we should log a delete of it.
+
+ NOTE: this is only needed for non-atomic CREATE OR REPLACE
*/
+ DBUG_ASSERT(!atomic_replace);
local_create_info.table->s->table_creation_was_logged= 1;
}
}
do_logging= TRUE;
}
+ if (!(thd->locked_tables_mode && pos_in_locked_tables &&
+ create_info->or_replace()))
+ {
+ /*
+ Ensure that we have an exclusive lock on target table if we are creating
+ non-temporary table. We don't have or need the lock if the create failed
+ because of existing table when using "if exists".
+ */
+ DBUG_ASSERT((create_info->tmp_table()) || create_res < 0 ||
+ thd->mdl_context.is_lock_owner(MDL_key::TABLE, orig_table->db.str,
+ orig_table->table_name.str,
+ MDL_EXCLUSIVE) ||
+ (thd->locked_tables_mode && pos_in_locked_tables &&
+ create_info->if_not_exists()));
+ }
+
err:
+ table= orig_table;
+
if (do_logging)
{
thd->binlog_xid= thd->query_id;
ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
- if (ddl_log_state_rm.is_active())
+ if (ddl_log_state_rm.is_active() && !atomic_replace)
ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
- debug_crash_here("ddl_log_create_before_binlog");
+ debug_crash_here("ddl_log_create_before_binlog");
if (res && create_info->table_was_deleted)
{
/*
@@ -5505,6 +5755,7 @@ err:
We have to log it.
*/
DBUG_ASSERT(ddl_log_state_rm.is_active());
+ DBUG_ASSERT(!atomic_replace);
log_drop_table(thd, &table->db, &table->table_name,
&create_info->org_storage_engine_name,
create_info->db_type == partition_hton,
@@ -5530,11 +5781,56 @@ err:
ddl_log.org_database= table->db;
ddl_log.org_table= table->table_name;
ddl_log.org_table_id= local_create_info.tabledef_version;
+ if (local_create_info.drop_entry.query.length)
+ {
+ DBUG_ASSERT(atomic_replace);
+ backup_log_ddl(&local_create_info.drop_entry);
+ }
backup_log_ddl(&ddl_log);
}
- ddl_log_complete(&ddl_log_state_rm);
- ddl_log_complete(&ddl_log_state_create);
+ if (res)
+ {
+ if (ddl_log_state_rm.is_active() &&
+ ddl_log_revert(thd, &ddl_log_state_create))
+ res= 1;
+ else
+ ddl_log_complete(&ddl_log_state_create);
+ ddl_log_complete(&ddl_log_state_rm);
+ }
+ else
+ {
+ res= local_create_info.finalize_ddl(thd);
+ }
+
+ /*
+ Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES
+ on a non temporary table
+ */
+ if (thd->locked_tables_mode && pos_in_locked_tables &&
+ create_info->or_replace())
+ {
+ /*
+ Add back the deleted table and re-created table as a locked table
+ This should always work as we have a meta lock on the table.
+ */
+ thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
+ if (thd->locked_tables_list.reopen_tables(thd, false))
+ {
+ thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
+ res= 1; // We got an error
+ }
+ else
+ {
+ /*
+ Get pointer to the newly opened table. We need this to ensure we
+ don't reopen the table when doing statment logging below.
+ */
+ table->table= pos_in_locked_tables->table;
+ table->table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
+ }
+ }
+
DBUG_RETURN(res != 0);
}
@@ -7000,7 +7296,7 @@ bool mysql_compare_tables(TABLE *table,
/* Create the prepared information. */
int create_table_mode= table->s->tmp_table == NO_TMP_TABLE ?
- C_ORDINARY_CREATE : C_ALTER_TABLE;
+ CREATE_ORDINARY : CREATE_TMP_TABLE;
if (mysql_prepare_create_table(thd, create_info, &tmp_alter_info,
&db_options, table->file, &key_info_buffer,
&key_count, create_table_mode, db, table_name))
@@ -10180,12 +10476,11 @@ do_continue:;
No ddl logging needed as ddl_log_alter_query will take care of failed
table creations.
*/
- error= create_table_impl(thd, (DDL_LOG_STATE*) 0, (DDL_LOG_STATE*) 0,
- alter_ctx.db, alter_ctx.table_name,
+ error= create_table_impl(thd, alter_ctx.db, alter_ctx.table_name,
alter_ctx.new_db, alter_ctx.tmp_name,
alter_ctx.get_tmp_cstring_path(),
thd->lex->create_info, create_info, alter_info,
- C_ALTER_TABLE_FRM_ONLY, NULL,
+ CREATE_FRM_ONLY, NULL,
&key_info, &key_count, &frm);
reenable_binlog(thd);
diff --git a/sql/sql_table.h b/sql/sql_table.h
index eaa03bfaf8c..d29dc3945a2 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -96,50 +96,20 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
bool add_keyword_to_query(THD *thd, String *result, const LEX_CSTRING *keyword,
const LEX_CSTRING *add);
-/*
- mysql_create_table_no_lock can be called in one of the following
- mutually exclusive situations:
-
- - Just a normal ordinary CREATE TABLE statement that explicitly
- defines the table structure.
-
- - CREATE TABLE ... SELECT. It is special, because only in this case,
- the list of fields is allowed to have duplicates, as long as one of the
- duplicates comes from the select list, and the other doesn't. For
- example in
-
- CREATE TABLE t1 (a int(5) NOT NUL) SELECT b+10 as a FROM t2;
-
- the list in alter_info->create_list will have two fields `a`.
-
- - ALTER TABLE, that creates a temporary table #sql-xxx, which will be later
- renamed to replace the original table.
-
- - ALTER TABLE as above, but which only modifies the frm file, it only
- creates an frm file for the #sql-xxx, the table in the engine is not
- created.
-
- - Assisted discovery, CREATE TABLE statement without the table structure.
-
- These situations are distinguished by the following "create table mode"
- values, where a CREATE ... SELECT is denoted by any non-negative number
- (which should be the number of fields in the SELECT ... part), and other
- cases use constants as defined below.
-*/
-#define C_CREATE_SELECT(X) ((X) > 0 ? (X) : 0)
-#define C_ORDINARY_CREATE 0
-#define C_ALTER_TABLE -1
-#define C_ALTER_TABLE_FRM_ONLY -2
-#define C_ASSISTED_DISCOVERY -3
+#define CREATE_ORDINARY 0
+#define CREATE_TMP_TABLE 1
+#define CREATE_FRM_ONLY 2
+#define CREATE_ASSISTED 4
int mysql_create_table_no_lock(THD *thd,
- DDL_LOG_STATE *ddl_log_state,
- DDL_LOG_STATE *ddl_log_state_rm,
+ const LEX_CSTRING *orig_db,
+ const LEX_CSTRING *orig_table_name,
const LEX_CSTRING *db,
const LEX_CSTRING *table_name,
Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans,
- int create_table_mode, TABLE_LIST *table);
+ int create_table_mode, TABLE_LIST *table,
+ LEX_CUSTRING *frm= NULL);
handler *mysql_create_frm_image(THD *thd,
const LEX_CSTRING &db,
@@ -192,7 +162,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
bool dont_log_query);
int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables,
const LEX_CSTRING *db,
- DDL_LOG_STATE *ddl_log_state,
+ Atomic_info *atomic_info,
bool if_exists,
bool drop_temporary, bool drop_view,
bool drop_sequence,
@@ -226,4 +196,12 @@ extern MYSQL_PLUGIN_IMPORT const LEX_CSTRING primary_key_name;
bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *);
+bool make_tmp_name(THD *thd, const char *prefix, const TABLE_LIST *orig,
+ TABLE_LIST *res);
+
+bool create_table_handle_exists(THD *thd, const LEX_CSTRING &db,
+ const LEX_CSTRING &table_name,
+ const DDL_options_st options,
+ HA_CREATE_INFO *create_info, int &error);
+
#endif /* SQL_TABLE_INCLUDED */
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 7b3db324db7..0a3ce76d35b 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1174,9 +1174,11 @@ bool Trigger::add_to_file_list(void* param_arg)
*/
static bool rm_trigger_file(char *path, const LEX_CSTRING *db,
- const LEX_CSTRING *table_name, myf MyFlags)
+ const LEX_CSTRING *table_name, myf MyFlags,
+ uint flags= 0)
{
- build_table_filename(path, FN_REFLEN-1, db->str, table_name->str, TRG_EXT, 0);
+ build_table_filename(path, FN_REFLEN - 1, db->str, table_name->str, TRG_EXT,
+ flags);
return mysql_file_delete(key_file_trg, path, MyFlags);
}
@@ -1502,7 +1504,8 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
const LEX_CSTRING *table_name,
TABLE *table,
- bool names_only)
+ bool names_only,
+ uint flags)
{
char path_buff[FN_REFLEN];
LEX_CSTRING path;
@@ -1511,7 +1514,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
DBUG_ENTER("Table_triggers_list::check_n_load");
path.length= build_table_filename(path_buff, FN_REFLEN - 1,
- db->str, table_name->str, TRG_EXT, 0);
+ db->str, table_name->str, TRG_EXT, flags);
path.str= path_buff;
// QQ: should we analyze errno somehow ?
@@ -2001,7 +2004,7 @@ bool add_table_for_trigger(THD *thd,
bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
const LEX_CSTRING *name,
- myf MyFlags)
+ myf MyFlags, uint flags)
{
TABLE table;
char path[FN_REFLEN];
@@ -2012,11 +2015,11 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
init_sql_alloc(key_memory_Table_trigger_dispatcher,
&table.mem_root, 8192, 0, MYF(MY_WME));
- if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
+ if (Table_triggers_list::check_n_load(thd, db, name, &table, 1, flags))
{
result= 1;
/* We couldn't parse trigger file, best to just remove it */
- rm_trigger_file(path, db, name, MyFlags);
+ rm_trigger_file(path, db, name, MyFlags, flags);
goto end;
}
if (table.triggers)
@@ -2050,7 +2053,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
}
}
}
- if (rm_trigger_file(path, db, name, MyFlags))
+ if (rm_trigger_file(path, db, name, MyFlags, flags))
result= 1;
delete table.triggers;
}
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 739669c86a5..61925c2eb73 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -258,9 +258,10 @@ public:
bool save_trigger_file(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name);
static bool check_n_load(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
- TABLE *table, bool names_only);
+ TABLE *table, bool names_only, uint flags= 0);
static bool drop_all_triggers(THD *thd, const LEX_CSTRING *db,
- const LEX_CSTRING *table_name, myf MyFlags);
+ const LEX_CSTRING *table_name, myf MyFlags,
+ uint flags= 0);
static bool prepare_for_rename(THD *thd, TRIGGER_RENAME_PARAM *param,
const LEX_CSTRING *db,
const LEX_CSTRING *old_alias,
diff --git a/sql/table.cc b/sql/table.cc
index b1a7b6bfe2b..3933b5220b1 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3509,7 +3509,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
promote_first_timestamp_column(&thd->lex->alter_info.create_list);
file= mysql_create_frm_image(thd, db, table_name,
&thd->lex->create_info, &thd->lex->alter_info,
- C_ORDINARY_CREATE, &unused1, &unused2, &frm);
+ CREATE_ORDINARY, &unused1, &unused2, &frm);
error|= file == 0;
delete file;
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index a990a518d5b..c62219fd6d3 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -3273,7 +3273,8 @@ dict_get_referenced_table(
ulint table_name_len, /*!< in: table name length */
dict_table_t** table, /*!< out: table object or NULL */
mem_heap_t* heap, /*!< in/out: heap memory */
- CHARSET_INFO* from_cs) /*!< in: table name charset */
+ CHARSET_INFO* from_cs, /*!< in: table name charset */
+ bool tmp_table)
{
char* ref;
char db_name[MAX_DATABASE_NAME_LEN];
@@ -3294,9 +3295,12 @@ dict_get_referenced_table(
to_cs = system_charset_info;
}
- table_name_len = strconvert(from_cs, table_name, table_name_len, to_cs,
- tbl_name, MAX_TABLE_NAME_LEN, &errors);
- table_name = tbl_name;
+ if (!tmp_table)
+ {
+ table_name_len = strconvert(from_cs, table_name, table_name_len, to_cs,
+ tbl_name, MAX_TABLE_NAME_LEN, &errors);
+ table_name = tbl_name;
+ }
if (database_name) {
to_cs = &my_charset_filename;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index d4220d0ac5f..edaf9204012 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -12197,10 +12197,11 @@ create_table_info_t::create_foreign_keys()
dict_table_t* table_to_alter;
mem_heap_t* heap = mem_heap_create(10000);
ulint highest_id_so_far;
+ DBUG_ASSERT(!m_create_info->tmp_name);
char* n = dict_get_referenced_table(
name, LEX_STRING_WITH_LEN(m_form->s->db),
LEX_STRING_WITH_LEN(m_form->s->table_name),
- &table_to_alter, heap, cs);
+ &table_to_alter, heap, cs, false);
/* Starting from 4.0.18 and 4.1.2, we generate foreign key id's
in the format databasename/tablename_ibfk_[number], where
@@ -12391,7 +12392,8 @@ create_table_info_t::create_foreign_keys()
foreign->referenced_table_name = dict_get_referenced_table(
name, LEX_STRING_WITH_LEN(fk->ref_db),
LEX_STRING_WITH_LEN(fk->ref_table),
- &foreign->referenced_table, foreign->heap, cs);
+ &foreign->referenced_table, foreign->heap, cs,
+ m_create_info->tmp_name != NULL);
if (!foreign->referenced_table_name) {
return (DB_OUT_OF_MEMORY);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 5a03ad49875..318021c7d97 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -3057,7 +3057,7 @@ innobase_get_foreign_key_info(
LEX_STRING_WITH_LEN(fk_key->ref_db),
LEX_STRING_WITH_LEN(fk_key->ref_table),
&referenced_table,
- add_fk[num_fk]->heap, cs);
+ add_fk[num_fk]->heap, cs, false);
/* Test the case when referenced_table failed to
open, if trx->check_foreigns is not set, we should
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 505fe76b008..fddbe89e2f4 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -69,7 +69,8 @@ dict_get_referenced_table(
ulint table_name_len, /*!< in: table name length */
dict_table_t** table, /*!< out: table object or NULL */
mem_heap_t* heap, /*!< in: heap memory */
- CHARSET_INFO* from_cs); /*!< in: table name charset */
+ CHARSET_INFO* from_cs, /*!< in: table name charset */
+ bool tmp_table);
/*********************************************************************//**
Frees a foreign key struct. */
void
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 746d1a850b2..d88a67074d1 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2736,7 +2736,6 @@ row_rename_table_for_mysql(
if (err != DB_SUCCESS) {
// Assume the caller guarantees destination name doesn't exist.
- ut_ad(err != DB_DUPLICATE_KEY);
goto rollback_and_exit;
}
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 6ee0dd5af79..c359df68be9 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2208,7 +2208,7 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
(file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK) &&
(!share->have_versioning || !share->now_transactional ||
- file->used_tables->use_count == 1))
+ (file->used_tables && file->used_tables->use_count == 1)))
{
/**
@todo for a single-row INSERT SELECT, we will go into repair, which
diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc
index d5efcbafd86..59b1fc12def 100644
--- a/storage/maria/ha_s3.cc
+++ b/storage/maria/ha_s3.cc
@@ -1030,7 +1030,8 @@ static int ha_s3_init(void *p)
s3_hton->show_status= 0;
s3_hton->prepare_for_backup= 0;
s3_hton->end_backup= 0;
- s3_hton->flags= ((s3_slave_ignore_updates ? HTON_IGNORE_UPDATES : 0) |
+ s3_hton->flags= HTON_EXPENSIVE_RENAME |
+ ((s3_slave_ignore_updates ? HTON_IGNORE_UPDATES : 0) |
(s3_replicate_alter_as_create_select ?
HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE : 0));
/* Copy global arguments to s3_access_key and s3_secret_key */