1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

WL#5370 Keep forward-compatibility when changing

'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour
BUG#55474, BUG#55499, BUG#55598, BUG#55616 and BUG#55777 are fixed
in this patch too.

This is the 5.1 part.
It implements:
- if the table exists, binlog two events: CREATE TABLE IF NOT EXISTS
  and INSERT ... SELECT

- Insert nothing and binlog nothing on master if the existing object
  is a view. It only generates a warning that table already exists.
This commit is contained in:
2010-08-18 12:56:06 +08:00
parent 12f7d57d42
commit b766a51f41
15 changed files with 1191 additions and 27 deletions

View File

@@ -0,0 +1,235 @@
--echo
--echo
connection master;
if ($is_temporary)
{
--let $_temporary=TEMPORARY
}
CREATE TABLE t2(c1 INT, c2 char(10));
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
--echo
--echo # The original query should be binlogged if the table does not exist.
--echo # ------------------------------------------------------------------
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
SELECT 'abc' AS c3, 1 AS c4;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # The statement should be binlogged as two events. one is
--echo # 'CREATE $_temporary TABLE IF NOT EXISTS ..', another one is
--echo # 'INSERT ... SELECT'.
--echo # ------------------------------------------------------------------
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
SELECT 'abc', 2;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # Verify if it can be binlogged with right database name when the table
--echo # is not in the default database
--echo
--disable_warnings
DROP DATABASE IF EXISTS db1;
--enable_warnings
CREATE DATABASE db1;
USE db1;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS test.t1
SELECT 'abc', 20;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
USE test;
DROP DATABASE db1;
--echo
--echo # It should be binlogged as 'REPLACE ... SELECT'
--echo # if the original statement has option REPLACE
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
REPLACE SELECT '123', 2;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # It should be binlogged as 'INSERT IGNORE... SELECT'
--echo # if the original statement has option IGNORE
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
IGNORE SELECT '123', 2;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # Nothing should be binlogged if error happens and no any row is inserted
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--error ER_DUP_ENTRY
eval CREATE $_temporary TABLE IF NOT EXISTS t1
SELECT '123', 2;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # Verify it can binlog well when there are some braces('(')
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
(SELECT '123', 3) UNION (SELECT '123', 4);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
eval CREATE $_temporary TABLE IF NOT EXISTS t1
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
if (!$is_temporary)
{
--echo
--echo # Throw a warning that table already exists and don't insert anything
--echo
CREATE VIEW t3 AS SELECT * FROM t2;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
CREATE TABLE IF NOT EXISTS t3
SELECT '123', 2;
source include/show_binlog_events.inc;
DROP VIEW t3;
}
--echo
--echo # The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
--echo
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
eval CREATE PROCEDURE p1(IN a INT)
CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', a;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
call p1(500);
call p1(600);
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
DROP PROCEDURE p1;
--echo
--echo # The statement can be binlogged correctly when it is in a prepared statement
--echo
eval PREPARE stm FROM "CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', ?";
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
SET @a= 700;
EXECUTE stm USING @a;
SET @a= 800;
EXECUTE stm USING @a;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
--echo
--echo # The statement can be binlogged correctly when it is in a conditional comment
--echo
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo # The whole statement in a conditional comment
eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1
SELECT 'abc', 900*/;
source include/show_binlog_events.inc;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # There is an long comment before SELECT
eval /*!CREATE $_temporary /*blabla*/ TABLE IF NOT EXISTS t1
SELECT 'abc', 901*/;
source include/show_binlog_events.inc;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # Conditional comment starts just from SELECT
eval CREATE $_temporary TABLE IF NOT EXISTS t1
/*!SELECT 'abc',*/ 902;
source include/show_binlog_events.inc;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # Only SELECT keyword is in the conditional comment
eval CREATE $_temporary TABLE IF NOT EXISTS t1
/*!SELECT*/ /*!'abc',*/ 904;
source include/show_binlog_events.inc;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # Conditional comment is after SELECT keyword
eval CREATE $_temporary TABLE IF NOT EXISTS t1
SELECT /*!'abc',*/ 903;
source include/show_binlog_events.inc;
let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # Conditional comment ends just before SELECT keyword
eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1
*/SELECT 'abc', 905;
source include/show_binlog_events.inc;
if (!$is_temporary)
{
let $diff_table= test.t1;
source include/rpl_diff_tables.inc;
}
DROP TABLE t2;
eval DROP $_temporary TABLE t1;

View File

@@ -33,3 +33,4 @@ while (`SELECT "XX$_servers" <> "XX"`)
--source include/diff_tables.inc
connection $_slave;
}
connection $_master;

View File

@@ -1824,11 +1824,8 @@ Note 1050 Table 'v1' already exists
set @id=last_insert_id();
select * from t1;
id operation
1 CREATE TABLE ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... SELECT, inserting a new key
truncate t1_op_log;
create table if not exists v1 replace
select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
@@ -1836,13 +1833,8 @@ Warnings:
Note 1050 Table 'v1' already exists
select * from t1;
id operation
1 CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
Before DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
truncate t1;
truncate t1_op_log;
insert into v1 (id, operation)

View File

@@ -65,3 +65,12 @@ c1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
# Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes
# slave SQL thread abort
CREATE TABLE t1 ( i INT );
CREATE TABLE IF NOT EXISTS t1
AS SELECT SLEEP(3);
KILL QUERY master1;
DROP TABLE t1;

View File

@@ -19,4 +19,9 @@ master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `tmp2` (
`c1` int(11) DEFAULT NULL
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`tmp2` (`c1`) SELECT * FROM tmp
master-bin.000001 # Query # # COMMIT

View File

@@ -467,4 +467,10 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
DROP TEMPORARY TABLES t7;
DROP TABLES t4, t5;
DROP TABLES IF EXISTS bug48506_t4;
CREATE TABLE t1 SELECT 1;
CREATE TABLE IF NOT EXISTS t1 SELECT 1;
Warnings:
Note 1050 Table 't1' already exists
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
end of the tests

View File

@@ -0,0 +1,704 @@
# WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT
# EXISTS ... SELECT' behaviour
#
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t2(c1 INT, c2 char(10));
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
# The original query should be binlogged if the table does not exist.
# ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
SELECT 'abc' AS c3, 1 AS c4;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
SELECT 'abc' AS c3, 1 AS c4
Comparing tables master:test.t1 and slave:test.t1
# The statement should be binlogged as two events. one is
# 'CREATE TABLE IF NOT EXISTS ..', another one is
# 'INSERT ... SELECT'.
# ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS t1
SELECT 'abc', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# Verify if it can be binlogged with right database name when the table
# is not in the default database
DROP DATABASE IF EXISTS db1;
CREATE DATABASE db1;
USE db1;
CREATE TABLE IF NOT EXISTS test.t1
SELECT 'abc', 20;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `db1`; CREATE TABLE IF NOT EXISTS `test`.`t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
USE test;
DROP DATABASE db1;
# It should be binlogged as 'REPLACE ... SELECT'
# if the original statement has option REPLACE
CREATE TABLE IF NOT EXISTS t1
REPLACE SELECT '123', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# It should be binlogged as 'INSERT IGNORE... SELECT'
# if the original statement has option IGNORE
CREATE TABLE IF NOT EXISTS t1
IGNORE SELECT '123', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# Nothing should be binlogged if error happens and no any row is inserted
CREATE TABLE IF NOT EXISTS t1
SELECT '123', 2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
Comparing tables master:test.t1 and slave:test.t1
# Verify it can binlog well when there are some braces('(')
CREATE TABLE IF NOT EXISTS t1
(SELECT '123', 3) UNION (SELECT '123', 4);
Warnings:
Note 1050 Table 't1' already exists
CREATE TABLE IF NOT EXISTS t1
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
Warnings:
Note 1050 Table 't1' already exists
CREATE TABLE IF NOT EXISTS t1
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# Throw a warning that table already exists and don't insert anything
CREATE VIEW t3 AS SELECT * FROM t2;
CREATE TABLE IF NOT EXISTS t3
SELECT '123', 2;
Warnings:
Note 1050 Table 't3' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
DROP VIEW t3;
# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1(IN a INT)
CREATE TABLE IF NOT EXISTS t1 SELECT '123', a;
call p1(500);
Warnings:
Note 1050 Table 't1' already exists
call p1(600);
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600)
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
DROP PROCEDURE p1;
# The statement can be binlogged correctly when it is in a prepared statement
PREPARE stm FROM "CREATE TABLE IF NOT EXISTS t1 SELECT '123', ?";
SET @a= 700;
EXECUTE stm USING @a;
Warnings:
Note 1050 Table 't1' already exists
SET @a= 800;
EXECUTE stm USING @a;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# The statement can be binlogged correctly when it is in a conditional comment
# The whole statement in a conditional comment
/*!CREATE TABLE IF NOT EXISTS t1
SELECT 'abc', 900*/;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/
master-bin.000001 # Query # # COMMIT
# There is an long comment before SELECT
/*!CREATE /*blabla*/ TABLE IF NOT EXISTS t1
SELECT 'abc', 901*/;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/
master-bin.000001 # Query # # COMMIT
# Conditional comment starts just from SELECT
CREATE TABLE IF NOT EXISTS t1
/*!SELECT 'abc',*/ 902;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902
master-bin.000001 # Query # # COMMIT
# Only SELECT keyword is in the conditional comment
CREATE TABLE IF NOT EXISTS t1
/*!SELECT*/ /*!'abc',*/ 904;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904
master-bin.000001 # Query # # COMMIT
# Conditional comment is after SELECT keyword
CREATE TABLE IF NOT EXISTS t1
SELECT /*!'abc',*/ 903;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903
master-bin.000001 # Query # # COMMIT
# Conditional comment ends just before SELECT keyword
/*!CREATE TABLE IF NOT EXISTS t1
*/SELECT 'abc', 905;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE t2(c1 INT, c2 char(10));
INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc');
# The original query should be binlogged if the table does not exist.
# ------------------------------------------------------------------
CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
SELECT 'abc' AS c3, 1 AS c4;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY)
SELECT 'abc' AS c3, 1 AS c4
# The statement should be binlogged as two events. one is
# 'CREATE TEMPORARY TABLE IF NOT EXISTS ..', another one is
# 'INSERT ... SELECT'.
# ------------------------------------------------------------------
CREATE TEMPORARY TABLE IF NOT EXISTS t1
SELECT 'abc', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2
master-bin.000001 # Query # # COMMIT
# Verify if it can be binlogged with right database name when the table
# is not in the default database
DROP DATABASE IF EXISTS db1;
CREATE DATABASE db1;
USE db1;
CREATE TEMPORARY TABLE IF NOT EXISTS test.t1
SELECT 'abc', 20;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `db1`; CREATE TEMPORARY TABLE IF NOT EXISTS `test`.`t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20
master-bin.000001 # Query # # COMMIT
USE test;
DROP DATABASE db1;
# It should be binlogged as 'REPLACE ... SELECT'
# if the original statement has option REPLACE
CREATE TEMPORARY TABLE IF NOT EXISTS t1
REPLACE SELECT '123', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
master-bin.000001 # Query # # COMMIT
# It should be binlogged as 'INSERT IGNORE... SELECT'
# if the original statement has option IGNORE
CREATE TEMPORARY TABLE IF NOT EXISTS t1
IGNORE SELECT '123', 2;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2
master-bin.000001 # Query # # COMMIT
# Nothing should be binlogged if error happens and no any row is inserted
CREATE TEMPORARY TABLE IF NOT EXISTS t1
SELECT '123', 2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
# Verify it can binlog well when there are some braces('(')
CREATE TEMPORARY TABLE IF NOT EXISTS t1
(SELECT '123', 3) UNION (SELECT '123', 4);
Warnings:
Note 1050 Table 't1' already exists
CREATE TEMPORARY TABLE IF NOT EXISTS t1
REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4);
Warnings:
Note 1050 Table 't1' already exists
CREATE TEMPORARY TABLE IF NOT EXISTS t1
IGNORE (SELECT '123', 3) UNION (SELECT '123', 4);
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4)
master-bin.000001 # Query # # COMMIT
# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1(IN a INT)
CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', a;
call p1(500);
Warnings:
Note 1050 Table 't1' already exists
call p1(600);
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600)
master-bin.000001 # Query # # COMMIT
DROP PROCEDURE p1;
# The statement can be binlogged correctly when it is in a prepared statement
PREPARE stm FROM "CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', ?";
SET @a= 700;
EXECUTE stm USING @a;
Warnings:
Note 1050 Table 't1' already exists
SET @a= 800;
EXECUTE stm USING @a;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800
master-bin.000001 # Query # # COMMIT
# The statement can be binlogged correctly when it is in a conditional comment
# The whole statement in a conditional comment
/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1
SELECT 'abc', 900*/;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/
master-bin.000001 # Query # # COMMIT
# There is an long comment before SELECT
/*!CREATE TEMPORARY /*blabla*/ TABLE IF NOT EXISTS t1
SELECT 'abc', 901*/;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/
master-bin.000001 # Query # # COMMIT
# Conditional comment starts just from SELECT
CREATE TEMPORARY TABLE IF NOT EXISTS t1
/*!SELECT 'abc',*/ 902;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902
master-bin.000001 # Query # # COMMIT
# Only SELECT keyword is in the conditional comment
CREATE TEMPORARY TABLE IF NOT EXISTS t1
/*!SELECT*/ /*!'abc',*/ 904;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904
master-bin.000001 # Query # # COMMIT
# Conditional comment is after SELECT keyword
CREATE TEMPORARY TABLE IF NOT EXISTS t1
SELECT /*!'abc',*/ 903;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903
master-bin.000001 # Query # # COMMIT
# Conditional comment ends just before SELECT keyword
/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1
*/SELECT 'abc', 905;
Warnings:
Note 1050 Table 't1' already exists
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` char(10) DEFAULT NULL,
`c4` int(11) NOT NULL,
PRIMARY KEY (`c4`)
)
master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905
master-bin.000001 # Query # # COMMIT
DROP TABLE t2;
DROP TEMPORARY TABLE t1;

View File

@@ -119,5 +119,32 @@ SELECT * FROM t2;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
sync_slave_with_master;
--echo
--echo # Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes
--echo # slave SQL thread abort
--echo
--connection master1
let $con_id = `SELECT CONNECTION_ID()`;
CREATE TABLE t1 ( i INT );
send CREATE TABLE IF NOT EXISTS t1
AS SELECT SLEEP(3);
connection master;
let $wait_timeout = 3;
let $show_statement = SHOW PROCESSLIST;
let $field = State;
let $condition = = 'User sleep';
source include/wait_show_condition.inc;
--replace_result $con_id master1
eval KILL QUERY $con_id;
sync_slave_with_master;
connection master;
DROP TABLE t1;
source include/master-slave-end.inc;

View File

@@ -299,5 +299,18 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
DROP TEMPORARY TABLES t7;
DROP TABLES t4, t5;
DROP TABLES IF EXISTS bug48506_t4;
sync_slave_with_master;
#
# Bug#55598 RBR: CREATE TABLE IF NOT EXISTS and INSERT written to binary log
# twice
#
connection master;
CREATE TABLE t1 SELECT 1;
CREATE TABLE IF NOT EXISTS t1 SELECT 1;
let $diff_table=test.t1;
source include/rpl_diff_tables.inc;
DROP TABLE t1;
source include/master-slave-end.inc;
--echo end of the tests

View File

@@ -0,0 +1,14 @@
#
--echo # WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT
--echo # EXISTS ... SELECT' behaviour
--echo #
source include/master-slave.inc;
source include/have_binlog_format_statement.inc;
source extra/rpl_tests/rpl_stm_create_if_not_exists.test;
let $is_temporary=1;
source extra/rpl_tests/rpl_stm_create_if_not_exists.test;
source include/master-slave-end.inc;