#At file:///home/lsoares/Workspace/mysql-server/bugfix/40045/6.0-rpl/ based on revid:serge.kozlov@stripped
2831 Luis Soares 2009-03-20
BUG#40045: Replication failure on RBR + no PK + UPDATE + integer key +
char with no key
Row based replication would break if updating a row and using a key
for searching for the correct row to update. This was observed when
using MyISAM storage engine on the slave. Since MyISAM does not
provide partial row fetch (HA_PARTIAL_COLUMN_READ) , the comparison
between the row fetched on the slave and the before image (BI)
replicated from master would fail. This happened because the BI (which
sometimes was only part of the row) would always be compared against a
complete row.
Furthermore, the read set mask was not being properly set when using
keys (not unique nor primary) which would lead to partial row matches,
thence changes might end up in the wrong row.
This patch addresses this by changing the record_compare function for
taking into consideration the fields set on the readset and the engine
used on the slave. Furthermore, it also changes the construction of
the read set on the master by forcing the setting of the appropriate
fields (the ones that uniquely identify the row).
@ mysql-test/extra/rpl_tests/rpl_row_record_find.test
Shared part of the test battery while testing with different engines.
@ mysql-test/suite/rpl/r/rpl_row_record_find.result
Result file.
@ mysql-test/suite/rpl/t/rpl_row_record_find.test
Test case that checks for different combinations of engines and
updates/deletes.
@ sql/log_event.cc
Changed the record_compare function to compare the entire record
when possible, or just the fields marked in the read_set otherwise.
@ sql/log_event_old.cc
Changed the record_compare function to compare the entire record
when possible, or just the fields marked in the read_set otherwise.
@ sql/records.cc
Added changes for forcing marking the correct read_set when binlogging.
added:
mysql-test/extra/rpl_tests/rpl_row_record_find.test
mysql-test/suite/rpl/r/rpl_row_record_find.result
mysql-test/suite/rpl/t/rpl_row_record_find.test
modified:
sql/log_event.cc
sql/log_event_old.cc
sql/records.cc
=== added file 'mysql-test/extra/rpl_tests/rpl_row_record_find.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_record_find.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_record_find.test 2009-03-20 13:17:10 +0000
@@ -0,0 +1,161 @@
+# USAGE:
+# Before including this file the following variables should be set:
+# * $master_engine
+# * slave_engine
+#
+# Example:
+#
+# let $master_engine= Falcon;
+# let $slave_engine= MyISAM;
+#
+# -- source extra/rpl_tests/rpl_row_record_find.test
+#
+
+
+connection master;
+
+--disable_warnings
+DROP TABLE IF EXISTS t;
+--enable_warnings
+
+sync_slave_with_master;
+connection master;
+
+let $i= 7;
+while($i)
+{
+ connection master;
+ SET SQL_LOG_BIN=0;
+
+ if (`SELECT $i=1`) {
+ --echo ******* TEST: No keys ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= $slave_engine;
+ }
+ if (`SELECT $i=2`)
+ {
+ --echo ******* TEST: One Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= $slave_engine;
+ }
+ if (`SELECT $i=3`)
+ {
+ --echo ****** TEST: One Composite Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= $slave_engine;
+ }
+ if (`SELECT $i=4`)
+ {
+ --echo ****** TEST: One Unique Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= $slave_engine;
+ }
+ if (`SELECT $i=5`)
+ {
+ --echo ****** TEST: One Composite Unique Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= $slave_engine;
+ }
+ if (`SELECT $i=6`)
+ {
+ --echo ****** TEST: One Primary Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= $slave_engine;
+ }
+ if (`SELECT $i=7`)
+ {
+ --echo ****** TEST: One Composite Primary Key ($master_engine -> $slave_engine)
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= $master_engine;
+ connection slave;
+ --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= $slave_engine;
+ }
+
+ connection master;
+ SET SQL_LOG_BIN=1;
+
+ connection master;
+ INSERT INTO t VALUES (1, '1', '3' );
+ INSERT INTO t VALUES (2, '2', '3' );
+ INSERT INTO t VALUES (3, '9', '9' );
+
+ sync_slave_with_master;
+
+ --echo ** WITHOUT KEY
+ connection master;
+ UPDATE t SET c3 = '4';
+
+ sync_slave_with_master;
+
+ let $diff_table_1=master:test.t;
+ let $diff_table_2=slave:test.t;
+ source include/diff_tables.inc;
+
+ if (`SELECT $i>1`)
+ {
+
+ if (`SELECT $i=2 or $i=4 or $i=6`)
+ {
+ --echo ** WITH FULL (primary / unique / normal) KEY
+ }
+
+ if (`SELECT $i=3 or $i=5 or $i=7`)
+ {
+ --echo ** WITH HALF (primary / unique / normal) KEY READ
+ }
+
+ connection master;
+ UPDATE t SET c3 = '5' WHERE c1 = 1;
+
+ sync_slave_with_master;
+
+ let $diff_table_1=master:test.t;
+ let $diff_table_2=slave:test.t;
+ source include/diff_tables.inc;
+ }
+
+ if (`SELECT $i=3 or $i=5 or $i=7`)
+ {
+ --echo ** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+
+ connection master;
+ UPDATE t SET c2 = '3' WHERE c2 = '2';
+
+ sync_slave_with_master;
+
+ let $diff_table_1=master:test.t;
+ let $diff_table_2=slave:test.t;
+ source include/diff_tables.inc;
+
+ --echo ** CHANGE PART OF KEY (with no key field in WHERE)
+ connection master;
+ UPDATE t SET c2 = '1' WHERE c3 = '9';
+
+ sync_slave_with_master;
+
+ let $diff_table_1=master:test.t;
+ let $diff_table_2=slave:test.t;
+ source include/diff_tables.inc;
+ }
+
+ connection master;
+ DELETE FROM t WHERE c1 = 1;
+ DELETE FROM t WHERE c1 = 2;
+ DELETE FROM t;
+
+ sync_slave_with_master;
+
+ let $diff_table_1=master:test.t;
+ let $diff_table_2=slave:test.t;
+ source include/diff_tables.inc;
+
+ DROP TABLE t;
+ sync_slave_with_master;
+
+ dec $i;
+}
=== added file 'mysql-test/suite/rpl/r/rpl_row_record_find.result'
--- a/mysql-test/suite/rpl/r/rpl_row_record_find.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_record_find.result 2009-03-20 13:17:10 +0000
@@ -0,0 +1,1080 @@
+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 t1 ( i1 int, c1 char(1), key ( i1 ));
+INSERT IGNORE INTO t1 VALUES (1, 'a');
+UPDATE t1 SET c1 = 'b' WHERE i1 = 1;
+DROP TABLE t1;
+CREATE TABLE table1_myisam ( `bit_key` bit, `int_key` int, key (`bit_key` ), key (`int_key` ));
+INSERT IGNORE INTO table1_myisam VALUES ('1', '-2146992385');
+Warnings:
+Warning 1264 Out of range value for column 'bit_key' at row 1
+UPDATE `table1_myisam` SET `bit_key` = 0 WHERE `bit_key` = 1;
+DROP TABLE table1_myisam;
+#################################################################
+# CASE 1: MyISAM - master, MyISAM - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (MyISAM -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 2: Falcon - master, Falcon - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (Falcon -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 3: Falcon - master, MyISAM - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (Falcon -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 4: InnoDB - master, MyISAM - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (InnoDB -> MyISAM)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 5: InnoDB - master, InnoDB - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (InnoDB -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 6: MyISAM - master, InnoDB - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (MyISAM -> Falcon)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= Falcon;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+#################################################################
+# CASE 7: MyISAM - master, InnoDB - slave
+#################################################################
+DROP TABLE IF EXISTS t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Primary Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Primary Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), primary key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Unique Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Unique Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), unique key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+****** TEST: One Composite Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1,c2)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique / normal) KEY READ
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+** WITH HALF (primary / unique /normal) KEY READ (changing itself)
+UPDATE t SET c2 = '3' WHERE c2 = '2';
+Comparing tables master:test.t and slave:test.t
+** CHANGE PART OF KEY (with no key field in WHERE)
+UPDATE t SET c2 = '1' WHERE c3 = '9';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: One Key (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1), key(c1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+** WITH FULL (primary / unique / normal) KEY
+UPDATE t SET c3 = '5' WHERE c1 = 1;
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
+SET SQL_LOG_BIN=0;
+******* TEST: No keys (MyISAM -> InnoDB)
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= MyISAM;;
+CREATE TABLE t (c1 int, c2 char(1), c3 char(1)) engine= InnoDB;;
+SET SQL_LOG_BIN=1;
+INSERT INTO t VALUES (1, '1', '3' );
+INSERT INTO t VALUES (2, '2', '3' );
+INSERT INTO t VALUES (3, '9', '9' );
+** WITHOUT KEY
+UPDATE t SET c3 = '4';
+Comparing tables master:test.t and slave:test.t
+DELETE FROM t WHERE c1 = 1;
+DELETE FROM t WHERE c1 = 2;
+DELETE FROM t;
+Comparing tables master:test.t and slave:test.t
+DROP TABLE t;
=== added file 'mysql-test/suite/rpl/t/rpl_row_record_find.test'
--- a/mysql-test/suite/rpl/t/rpl_row_record_find.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_record_find.test 2009-03-20 13:17:10 +0000
@@ -0,0 +1,127 @@
+#
+# BUG#40045: Replication failure on RBR + no PK + UPDATE + integer key + char
+# with no key
+#
+# BUG#40007: Replication failure with RBR + no PK + 2 indexed fields
+#
+# TEST DESCRIPTION
+# ================
+#
+# This test is structure in three cases. In all of them, roughly the same
+# update and delete operations are performed, but what changes are the keys
+# in the table:
+# no keys, one key, composite key (but only half is used in query),
+# unique key, primary key
+#
+# The three cases are distinct because the engine on both and master and
+# slave varies:
+#
+# CASE 1: MyISAM - master, MyISAM - slave
+# test without HA_PARTIAL_COLUMN_READ engine on master and on slave
+# CASE 2: Falcon - master, Falcon - slave
+# test with HA_PARTIAL_COLUMN_READ engine on master and on slave
+# CASE 3: Falcon - master, MyISAM - slave
+# test with HA_PARTIAL_COLUMN_READ engine on master but not on slave
+# CASE 4: InnoDB - master, MyISAM - slave
+# test with HA_PARTIAL_COLUMN_READ engine on master but not on slave
+# (InnoDB)
+# CASE 5: InnoDB - master, InnoDB - slave
+# test with HA_PARTIAL_COLUMN_READ engine on master and on slave
+# (InnoDB)
+# CASE 6: MyISAM - master, Falcon - slave
+# test without HA_PARTIAL_COLUMN_READ engine on master but with it on slave
+# (Falcon)
+# CASE 7: MyISAM - master, InnoDB - slave
+# test without HA_PARTIAL_COLUMN_READ engine on master but with it on slave
+# (InnoDB)
+#
+# NOTE: Before the battery of tests actually takes place, a sanity check is
+# performed with the test cases used to verify the BUGS.
+
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+source include/have_innodb.inc;
+source include/have_falcon.inc;
+
+### SANITY TESTS for BUG#40045 and BUG#40007
+
+# TEST CASE USED for verifying BUG#40045
+CREATE TABLE t1 ( i1 int, c1 char(1), key ( i1 ));
+INSERT IGNORE INTO t1 VALUES (1, 'a');
+UPDATE t1 SET c1 = 'b' WHERE i1 = 1;
+DROP TABLE t1;
+sync_slave_with_master;
+
+# TEST CASE USED for verifying BUG#40007
+connection master;
+CREATE TABLE table1_myisam ( `bit_key` bit, `int_key` int, key (`bit_key` ), key (`int_key` ));
+INSERT IGNORE INTO table1_myisam VALUES ('1', '-2146992385');
+UPDATE `table1_myisam` SET `bit_key` = 0 WHERE `bit_key` = 1;
+DROP TABLE table1_myisam;
+sync_slave_with_master;
+
+connection master;
+
+--echo #################################################################
+--echo # CASE 1: MyISAM - master, MyISAM - slave
+--echo #################################################################
+
+let $master_engine= MyISAM;
+let $slave_engine= MyISAM;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 2: Falcon - master, Falcon - slave
+--echo #################################################################
+
+let $master_engine= Falcon;
+let $slave_engine= Falcon;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 3: Falcon - master, MyISAM - slave
+--echo #################################################################
+
+let $master_engine= Falcon;
+let $slave_engine= MyISAM;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 4: InnoDB - master, MyISAM - slave
+--echo #################################################################
+
+let $master_engine= InnoDB;
+let $slave_engine= MyISAM;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 5: InnoDB - master, InnoDB - slave
+--echo #################################################################
+
+let $master_engine= InnoDB;
+let $slave_engine= InnoDB;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 6: MyISAM - master, InnoDB - slave
+--echo #################################################################
+
+let $master_engine= MyISAM;
+let $slave_engine= Falcon;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
+--echo #################################################################
+--echo # CASE 7: MyISAM - master, InnoDB - slave
+--echo #################################################################
+
+let $master_engine= MyISAM;
+let $slave_engine= InnoDB;
+
+-- source extra/rpl_tests/rpl_row_record_find.test
+
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2009-03-04 13:33:47 +0000
+++ b/sql/log_event.cc 2009-03-20 13:17:10 +0000
@@ -8611,7 +8611,7 @@ void Write_rows_log_event::print(FILE *f
Returns TRUE if different.
*/
-static bool record_compare(TABLE *table)
+static bool record_compare(TABLE *table, const MY_BITMAP *cols_in_readset)
{
/*
Need to set the X bit and the filler bits in both records since
@@ -8643,14 +8643,23 @@ static bool record_compare(TABLE *table)
}
}
- if (table->s->blob_fields + table->s->varchar_fields == 0)
+ /*
+ We can compare the record straight away if:
+ i) there are no blob and varchar fields
+ ii) all columns were read or the slave SE provides partial reads
+ */
+ if ((table->s->blob_fields + table->s->varchar_fields == 0) &&
+ (bitmap_is_set_all(cols_in_readset) ||
+ (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)))
{
result= cmp_record(table,record[1]);
goto record_compare_exit;
}
- /* Compare null bits */
- if (memcmp(table->null_flags,
+ /* Compare null bits only if all fields were read or slave SE has partial reads */
+ if ((bitmap_is_set_all(cols_in_readset) ||
+ (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)) &&
+ memcmp(table->null_flags,
table->null_flags+table->s->rec_buff_length,
table->s->null_bytes))
{
@@ -8661,10 +8670,14 @@ static bool record_compare(TABLE *table)
/* Compare updated fields */
for (Field **ptr=table->field ; *ptr ; ptr++)
{
- if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
- {
- result= TRUE;
- goto record_compare_exit;
+ /* compare field if it is set */
+ if (bitmap_is_set(cols_in_readset, (*ptr)->field_index))
+ {
+ if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
+ {
+ result= TRUE;
+ goto record_compare_exit;
+ }
}
}
@@ -8875,7 +8888,7 @@ int Rows_log_event::find_row(const Relay
*/
DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
- while (record_compare(table))
+ while (record_compare(table, &m_cols))
{
/*
We need to set the null bytes to ensure that the filler bit
@@ -8956,7 +8969,7 @@ int Rows_log_event::find_row(const Relay
goto err;
}
}
- while (restart_count < 2 && record_compare(table));
+ while (restart_count < 2 && record_compare(table, &m_cols));
/*
Note: above record_compare will take into accout all record fields
=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc 2008-12-10 14:30:52 +0000
+++ b/sql/log_event_old.cc 2009-03-20 13:17:10 +0000
@@ -313,7 +313,7 @@ last_uniq_key(TABLE *table, uint keyno)
Returns TRUE if different.
*/
-static bool record_compare(TABLE *table)
+static bool record_compare(TABLE *table, const MY_BITMAP *cols_in_readset)
{
/*
Need to set the X bit and the filler bits in both records since
@@ -342,16 +342,25 @@ static bool record_compare(TABLE *table)
}
}
- if (table->s->blob_fields + table->s->varchar_fields == 0)
+ /*
+ We can compare the record straight away if:
+ i) there are no blob and varchar fields
+ ii) all columns were read or the slave SE provides partial reads
+ */
+ if ((table->s->blob_fields + table->s->varchar_fields == 0) &&
+ (bitmap_is_set_all(cols_in_readset) ||
+ (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)))
{
result= cmp_record(table,record[1]);
goto record_compare_exit;
}
- /* Compare null bits */
- if (memcmp(table->null_flags,
- table->null_flags+table->s->rec_buff_length,
- table->s->null_bytes))
+ /* Compare null bits only if all fields were read or slave SE has partial reads */
+ if ((bitmap_is_set_all(cols_in_readset) ||
+ (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)) &&
+ memcmp(table->null_flags,
+ table->null_flags+table->s->rec_buff_length,
+ table->s->null_bytes))
{
result= TRUE; // Diff in NULL value
goto record_compare_exit;
@@ -360,10 +369,14 @@ static bool record_compare(TABLE *table)
/* Compare updated fields */
for (Field **ptr=table->field ; *ptr ; ptr++)
{
- if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
- {
- result= TRUE;
- goto record_compare_exit;
+ /* compare field if it is set */
+ if (bitmap_is_set(cols_in_readset, (*ptr)->field_index))
+ {
+ if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
+ {
+ result= TRUE;
+ goto record_compare_exit;
+ }
}
}
@@ -761,7 +774,7 @@ static int find_and_fetch_row(TABLE *tab
DBUG_RETURN(0);
}
- while (record_compare(table))
+ while (record_compare(table, table->read_set))
{
int error;
@@ -837,7 +850,7 @@ static int find_and_fetch_row(TABLE *tab
DBUG_RETURN(error);
}
}
- while (restart_count < 2 && record_compare(table));
+ while (restart_count < 2 && record_compare(table, table->read_set));
/*
Have to restart the scan to be able to fetch the next row.
@@ -2387,7 +2400,7 @@ int Old_rows_log_event::find_row(const R
*/
DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
- while (record_compare(table))
+ while (record_compare(table, &m_cols))
{
/*
We need to set the null bytes to ensure that the filler bit
@@ -2463,7 +2476,7 @@ int Old_rows_log_event::find_row(const R
DBUG_RETURN(error);
}
}
- while (restart_count < 2 && record_compare(table));
+ while (restart_count < 2 && record_compare(table, &m_cols));
/*
Note: above record_compare will take into accout all record fields
=== modified file 'sql/records.cc'
--- a/sql/records.cc 2008-08-11 12:40:09 +0000
+++ b/sql/records.cc 2009-03-20 13:17:10 +0000
@@ -67,6 +67,27 @@ void init_read_record_idx(READ_RECORD *i
info->record= table->record[0];
info->print_error= print_error;
+ /* sets read set needed for RBR */
+ if (thd->current_stmt_binlog_row_based && mysql_bin_log.is_open())
+ {
+ /*
+ If the handler has no cursor capabilites, or we have row-based
+ logging active for the current statement, we have to read either
+ the primary key, the hidden primary key or all columns to be
+ able to do an update
+ */
+ if (table->s->primary_key == MAX_KEY ||
+ !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
+ table->file->use_hidden_primary_key(); /* alias for use_all_columns() */
+ else
+ {
+ /* mark the primary key */
+ table->mark_columns_used_by_index_no_reset(table->s->primary_key,
+ table->read_set);
+ table->file->column_bitmaps_signal();
+ }
+ }
+
table->status=0; /* And it's always found */
if (!table->file->inited)
table->file->ha_index_init(idx, 1);
@@ -174,6 +195,27 @@ void init_read_record(READ_RECORD *info,
info->file= table->file;
info->forms= &info->table; /* Only one table */
+ /* sets read set needed for RBR */
+ if (thd->current_stmt_binlog_row_based && mysql_bin_log.is_open())
+ {
+ /*
+ If the handler has no cursor capabilites, or we have row-based
+ logging active for the current statement, we have to read either
+ the primary key, the hidden primary key or all columns to be
+ able to do an update
+ */
+ if (table->s->primary_key == MAX_KEY ||
+ !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
+ table->file->use_hidden_primary_key(); /* alias for use_all_columns() */
+ else
+ {
+ /* mark the primary key */
+ table->mark_columns_used_by_index_no_reset(table->s->primary_key,
+ table->read_set);
+ table->file->column_bitmaps_signal();
+ }
+ }
+
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
!table->sort.addon_field)
(void) table->file->extra(HA_EXTRA_MMAP);
Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20090320131710-f3rmlkii7ng550zi.bundle