From 6d924c8286237413f7347e07e4b4dfcfd5e3dff2 Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Tue, 5 Jul 2005 13:55:54 +0200 Subject: [PATCH] Bug#11401: Setting thd->lex so that engines (i.e., InnoDB) recognizes this as a LOAD DATA ... REPLACE INTO .. statement. --- mysql-test/r/rpl_innodb.result | 37 +++++++++++++++++++++ mysql-test/std_data/loaddata_pair.dat | 2 ++ mysql-test/t/rpl_innodb.test | 46 +++++++++++++++++++++++++++ sql/log_event.cc | 15 +++++++++ 4 files changed, 100 insertions(+) create mode 100644 mysql-test/r/rpl_innodb.result create mode 100644 mysql-test/std_data/loaddata_pair.dat create mode 100644 mysql-test/t/rpl_innodb.test diff --git a/mysql-test/r/rpl_innodb.result b/mysql-test/r/rpl_innodb.result new file mode 100644 index 00000000000..ebf1d79c4d0 --- /dev/null +++ b/mysql-test/r/rpl_innodb.result @@ -0,0 +1,37 @@ +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 t4 ( +id INT(5) unsigned NOT NULL auto_increment, +name varchar(15) NOT NULL default '', +number varchar(35) NOT NULL default 'default', +PRIMARY KEY (id), +UNIQUE KEY unique_rec (name,number) +) ENGINE=InnoDB; +LOAD DATA +INFILE '../../std_data/loaddata_pair.dat' +REPLACE INTO TABLE t4 +(name,number); +SELECT * FROM t4; +id name number +1 XXX 12345 +2 XXY 12345 +SELECT * FROM t4; +id name number +1 XXX 12345 +2 XXY 12345 +LOAD DATA +INFILE '../../std_data/loaddata_pair.dat' +REPLACE INTO TABLE t4 +(name,number); +SELECT * FROM t4; +id name number +3 XXX 12345 +4 XXY 12345 +SELECT * FROM t4; +id name number +3 XXX 12345 +4 XXY 12345 diff --git a/mysql-test/std_data/loaddata_pair.dat b/mysql-test/std_data/loaddata_pair.dat new file mode 100644 index 00000000000..5a4f6b57af8 --- /dev/null +++ b/mysql-test/std_data/loaddata_pair.dat @@ -0,0 +1,2 @@ +XXX 12345 +XXY 12345 diff --git a/mysql-test/t/rpl_innodb.test b/mysql-test/t/rpl_innodb.test new file mode 100644 index 00000000000..b171dced26e --- /dev/null +++ b/mysql-test/t/rpl_innodb.test @@ -0,0 +1,46 @@ +# File for specialities regarding replication from or to InnoDB +# tables. + +source include/master-slave.inc; +source include/have_innodb.inc; + +# +# Bug#11401: Load data infile 'REPLACE INTO' fails on slave. +# +connection master; +CREATE TABLE t4 ( + id INT(5) unsigned NOT NULL auto_increment, + name varchar(15) NOT NULL default '', + number varchar(35) NOT NULL default 'default', + PRIMARY KEY (id), + UNIQUE KEY unique_rec (name,number) +) ENGINE=InnoDB; + +--disable_warnings +LOAD DATA + INFILE '../../std_data/loaddata_pair.dat' + REPLACE INTO TABLE t4 + (name,number); +--enable_warnings +SELECT * FROM t4; + +sync_slave_with_master; +SELECT * FROM t4; + +connection master; +--disable_warnings +LOAD DATA + INFILE '../../std_data/loaddata_pair.dat' + REPLACE INTO TABLE t4 + (name,number); +--enable_warnings +SELECT * FROM t4; + +sync_slave_with_master; +SELECT * FROM t4; + +connection master; +--disable_query_log +DROP TABLE t4; +--enable_query_log +sync_slave_with_master; diff --git a/sql/log_event.cc b/sql/log_event.cc index a4319f63b83..cda385c911b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1809,11 +1809,25 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, "` <...>", NullS) - load_data_query); thd->query= load_data_query; } + + /* + We need to set thd->lex->sql_command and thd->lex->duplicates + since InnoDB tests these variables to decide if this is a LOAD + DATA ... REPLACE INTO ... statement even though mysql_parse() + is not called. This is not needed in 5.0 since there the LOAD + DATA ... statement is replicated using mysql_parse(), which + sets the thd->lex fields correctly. + */ + thd->lex->sql_command= SQLCOM_LOAD; if (sql_ex.opt_flags & REPLACE_FLAG) + { + thd->lex->duplicates= DUP_REPLACE; handle_dup= DUP_REPLACE; + } else if (sql_ex.opt_flags & IGNORE_FLAG) { ignore= 1; + thd->lex->duplicates= DUP_ERROR; handle_dup= DUP_ERROR; } else @@ -1831,6 +1845,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, If reading from net (a 3.23 master), mysql_load() will change this to IGNORE. */ + thd->lex->duplicates= DUP_ERROR; handle_dup= DUP_ERROR; }