#At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-43789/mysql-6.0-rpl/ based on revid:alfranio.correia@stripped
2839 Alfranio Correia 2009-04-05
BUG#43789 different master/slave table defs cause crash: text/varchar null
vs not null
The replication was generating corrupted data, warning messages on
Valgrind and aborting on debug mode while replicating a "null" to
"not null" field. Specifically the unpack_row routine, was considering
the slave's table definition and trying to retrieve a field value, where
there was nothing to be retrieved, ignoring the fact that the value was
defined as "null" by the master.
To fix the problem, we throw an error if the slave's table definition
does not accept nulls and proceed with the execution otherwise.
added:
mysql-test/suite/rpl/r/rpl_not_null.result
mysql-test/suite/rpl/t/rpl_not_null.test
modified:
sql/rpl_record.cc
sql/log_event.cc
sql/log_event_old.cc
added:
mysql-test/suite/rpl/r/rpl_not_null.result
mysql-test/suite/rpl/t/rpl_not_null.test
modified:
sql/log_event.cc
sql/log_event_old.cc
sql/rpl_record.cc
=== added file 'mysql-test/suite/rpl/r/rpl_not_null.result'
--- a/mysql-test/suite/rpl/r/rpl_not_null.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_not_null.result 2009-04-05 12:13:10 +0000
@@ -0,0 +1,512 @@
+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;
+################################################################################
+# NULL ---> NULL
+################################################################################
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, 4);
+INSERT INTO t1(a) VALUES (5);
+INSERT INTO t2(a,b) VALUES (1, null);
+INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t2(a) VALUES (3);
+INSERT INTO t3(a,b) VALUES (1, null);
+INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t3(a) VALUES (3);
+INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t4(a,b) VALUES (3, null);
+INSERT INTO t4(a,c) VALUES (4, 4);
+INSERT INTO t4(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+TABLES t2 and t3 must be different.
+SELECT * FROM t3;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+SELECT * FROM t3;
+a b c
+1 NULL 500
+2 1111-11-11 500
+3 0000-00-00 500
+SELECT * FROM t4;
+a b c
+1 NULL 1
+2 1111-11-11 2
+3 NULL NULL
+4 NULL 4
+5 NULL NULL
+SELECT * FROM t4;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+4 0000-00-00
+5 0000-00-00
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+UPDATE t1 set b= NULL, c= 300 where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+************* CLEANING *************
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+PRIMARY KEY(`a`)) ENGINE=MYISAM DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, 4);
+INSERT INTO t1(a) VALUES (5);
+INSERT INTO t2(a,b) VALUES (1, null);
+INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t2(a) VALUES (3);
+INSERT INTO t3(a,b) VALUES (1, null);
+INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t3(a) VALUES (3);
+INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t4(a,b) VALUES (3, null);
+INSERT INTO t4(a,c) VALUES (4, 4);
+INSERT INTO t4(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+TABLES t2 and t3 must be different.
+SELECT * FROM t3;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+SELECT * FROM t3;
+a b c
+1 NULL 500
+2 1111-11-11 500
+3 0000-00-00 500
+SELECT * FROM t4;
+a b c
+1 NULL 1
+2 1111-11-11 2
+3 NULL NULL
+4 NULL 4
+5 NULL NULL
+SELECT * FROM t4;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+4 0000-00-00
+5 0000-00-00
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+UPDATE t1 set b= NULL, c= 300 where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+************* CLEANING *************
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= INNODB;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= INNODB;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, b'01');
+INSERT INTO t1(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be different.
+SELECT a,b+0,c+0 FROM t1;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+SELECT a,b+0,c+0 FROM t1;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 1 1
+5 1 NULL
+************* EXECUTION WITH UPDATES AND REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+UPDATE t1 set b= NULL, c= b'00' where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+************* SHOWING THE RESULT SETS WITH UPDATES AND REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= MYISAM;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= MYISAM;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, b'01');
+INSERT INTO t1(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be different.
+SELECT a,b+0,c+0 FROM t1;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+SELECT a,b+0,c+0 FROM t1;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 1 1
+5 1 NULL
+************* EXECUTION WITH UPDATES AND REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+UPDATE t1 set b= NULL, c= b'00' where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+************* SHOWING THE RESULT SETS WITH UPDATES AND REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+################################################################################
+# NULL ---> NOT NULL
+################################################################################
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a) VALUES (1);
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+1 NULL
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+SELECT * FROM t2;
+a b c
+SELECT * FROM t3;
+a b
+SELECT * FROM t3;
+a b c
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a, b) VALUES (1, NULL);
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+1 NULL
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+SELECT * FROM t2;
+a b c
+SELECT * FROM t3;
+a b
+SELECT * FROM t3;
+a b c
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH UPDATES *************
+INSERT INTO t3(a, b) VALUES (1, 1);
+INSERT INTO t3(a, b) VALUES (2, 1);
+UPDATE t3 SET b = NULL where a= 1;
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+SELECT * FROM t2;
+a b c
+SELECT * FROM t3;
+a b
+1 NULL
+2 1
+SELECT * FROM t3;
+a b c
+1 1 500
+2 1 500
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS/REPLACES *************
+REPLACE INTO t3(a, b) VALUES (1, null);
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+SELECT * FROM t2;
+a b c
+SELECT * FROM t3;
+a b
+1 NULL
+SELECT * FROM t3;
+a b c
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH UPDATES/REPLACES *************
+INSERT INTO t3(a, b) VALUES (1, 1);
+REPLACE INTO t3(a, b) VALUES (1, null);
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+SELECT * FROM t2;
+a b c
+SELECT * FROM t3;
+a b
+1 NULL
+SELECT * FROM t3;
+a b c
+1 1 500
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+************* THIS SHOULD BE CHANGED AFTER FIXING BUG#38173 *************
+INSERT INTO t3(a, b) VALUES (1, 1);
+INSERT INTO t2(a, b) VALUES (1, 1);
+INSERT INTO t1(a, b) VALUES (1, 1);
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1;
+a b
+1 1
+SELECT * FROM t1;
+a b c
+SELECT * FROM t2;
+a b
+1 1
+SELECT * FROM t2;
+a b c
+1 1 NULL
+SELECT * FROM t3;
+a b
+1 1
+SELECT * FROM t3;
+a b c
+1 1 500
+**** Resetting master and slave ****
+include/stop_slave.inc
+RESET SLAVE;
+RESET MASTER;
+include/start_slave.inc
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
=== added file 'mysql-test/suite/rpl/t/rpl_not_null.test'
--- a/mysql-test/suite/rpl/t/rpl_not_null.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_not_null.test 2009-04-05 12:13:10 +0000
@@ -0,0 +1,302 @@
+#################################################################################
+# This test checks if the replication between "null" fields to either "null"
+# fields or "not null" fields works properly. In the first case, the execution
+# should work fine. In the second case, an error should be thrown.
+#################################################################################
+--source include/master-slave.inc
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--echo ################################################################################
+--echo # NULL ---> NULL
+--echo ################################################################################
+connection master;
+
+let $y=0;
+while (`select $y < 2`)
+{
+ if (`select $y=0`)
+ {
+ let $engine=INNODB;
+ }
+
+ if (`select $y=1`)
+ {
+ let $engine=MYISAM;
+ }
+
+ connection master;
+
+ SET SQL_LOG_BIN= 0;
+ eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+ `c` INT DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+ `c` INT DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+ SET SQL_LOG_BIN= 1;
+
+ connection slave;
+
+ eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+ `c` INT DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+ `c` INT DEFAULT 500,
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+ PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+ --echo ************* EXECUTION WITH INSERTS *************
+ connection master;
+ INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+ INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+ INSERT INTO t1(a,b) VALUES (3, null);
+ INSERT INTO t1(a,c) VALUES (4, 4);
+ INSERT INTO t1(a) VALUES (5);
+
+ INSERT INTO t2(a,b) VALUES (1, null);
+ INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+ INSERT INTO t2(a) VALUES (3);
+
+ INSERT INTO t3(a,b) VALUES (1, null);
+ INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+ INSERT INTO t3(a) VALUES (3);
+
+ INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+ INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+ INSERT INTO t4(a,b) VALUES (3, null);
+ INSERT INTO t4(a,c) VALUES (4, 4);
+ INSERT INTO t4(a) VALUES (5);
+
+ --echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
+ sync_slave_with_master;
+
+ --echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+ let $diff_table_1=master:test.t1;
+ let $diff_table_2=slave:test.t1;
+ source include/diff_tables.inc;
+
+ let $diff_table_1=master:test.t2;
+ let $diff_table_2=slave:test.t2;
+ source include/diff_tables.inc;
+
+ --echo TABLES t2 and t3 must be different.
+ connection master;
+ SELECT * FROM t3;
+ connection slave;
+ SELECT * FROM t3;
+ connection master;
+ SELECT * FROM t4;
+ connection slave;
+ SELECT * FROM t4;
+
+ --echo ************* EXECUTION WITH UPDATES and REPLACES *************
+ connection master;
+ DELETE FROM t1;
+ INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+ REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+ UPDATE t1 set b= NULL, c= 300 where a= 1;
+ REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+
+ --echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+ sync_slave_with_master;
+
+ --echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+ let $diff_table_1=master:test.t1;
+ let $diff_table_2=slave:test.t1;
+ source include/diff_tables.inc;
+
+ --echo ************* CLEANING *************
+ connection master;
+
+ DROP TABLE t1;
+ DROP TABLE t2;
+ DROP TABLE t3;
+ DROP TABLE t4;
+
+ sync_slave_with_master;
+
+ inc $y;
+}
+
+let $y=0;
+while (`select $y < 2`)
+{
+ if (`select $y=0`)
+ {
+ let $engine=INNODB;
+ }
+
+ if (`select $y=1`)
+ {
+ let $engine=MYISAM;
+ }
+
+ connection master;
+
+ SET SQL_LOG_BIN= 0;
+ eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+ PRIMARY KEY (`a`)) ENGINE= $engine;
+ SET SQL_LOG_BIN= 1;
+
+ connection slave;
+
+ eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+ PRIMARY KEY (`a`)) ENGINE= $engine;
+
+ --echo ************* EXECUTION WITH INSERTS *************
+ connection master;
+ INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+ INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+ INSERT INTO t1(a,b) VALUES (3, null);
+ INSERT INTO t1(a,c) VALUES (4, b'01');
+ INSERT INTO t1(a) VALUES (5);
+
+ --echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
+ --echo TABLES t1 and t2 must be different.
+ sync_slave_with_master;
+ connection master;
+ SELECT a,b+0,c+0 FROM t1;
+ connection slave;
+ SELECT a,b+0,c+0 FROM t1;
+
+ --echo ************* EXECUTION WITH UPDATES AND REPLACES *************
+ connection master;
+ DELETE FROM t1;
+ INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+ REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+ UPDATE t1 set b= NULL, c= b'00' where a= 1;
+ REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+
+ --echo ************* SHOWING THE RESULT SETS WITH UPDATES AND REPLACES *************
+ --echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+ sync_slave_with_master;
+ let $diff_table_1=master:test.t1;
+ let $diff_table_2=slave:test.t1;
+ source include/diff_tables.inc;
+
+ connection master;
+
+ DROP TABLE t1;
+
+ sync_slave_with_master;
+
+ inc $y;
+}
+
+--echo ################################################################################
+--echo # NULL ---> NOT NULL
+--echo ################################################################################
+let $y=0;
+while (`select $y < 6`)
+{
+ connection master;
+
+ SET SQL_LOG_BIN= 0;
+ CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+ CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+ CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+ SET SQL_LOG_BIN= 1;
+
+ connection slave;
+
+ CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+ `c` INT NOT NULL,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+ CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+ `c` INT,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+ CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+ `c` INT DEFAULT 500,
+ PRIMARY KEY(`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1;
+
+ if (`select $y=0`)
+ {
+ --echo ************* EXECUTION WITH INSERTS *************
+ connection master;
+ INSERT INTO t1(a) VALUES (1);
+ }
+
+ if (`select $y=1`)
+ {
+ --echo ************* EXECUTION WITH INSERTS *************
+ connection master;
+ INSERT INTO t1(a, b) VALUES (1, NULL);
+ }
+
+ if (`select $y=2`)
+ {
+ --echo ************* EXECUTION WITH UPDATES *************
+ connection master;
+ INSERT INTO t3(a, b) VALUES (1, 1);
+ INSERT INTO t3(a, b) VALUES (2, 1);
+ UPDATE t3 SET b = NULL where a= 1;
+ }
+
+ if (`select $y=3`)
+ {
+ --echo ************* EXECUTION WITH INSERTS/REPLACES *************
+ connection master;
+ REPLACE INTO t3(a, b) VALUES (1, null);
+ }
+
+ if (`select $y=4`)
+ {
+ --echo ************* EXECUTION WITH UPDATES/REPLACES *************
+ connection master;
+ INSERT INTO t3(a, b) VALUES (1, 1);
+ REPLACE INTO t3(a, b) VALUES (1, null);
+ }
+
+ if (`select $y=5`)
+ {
+ --echo ************* EXECUTION WITH INSERTS *************
+ --echo ************* THIS SHOULD BE CHANGED AFTER FIXING BUG#38173 *************
+ connection master;
+ INSERT INTO t3(a, b) VALUES (1, 1);
+ INSERT INTO t2(a, b) VALUES (1, 1);
+ INSERT INTO t1(a, b) VALUES (1, 1);
+ }
+
+ --echo ************* SHOWING THE RESULT SETS *************
+ connection slave;
+ --source include/wait_for_slave_sql_to_stop.inc
+ connection master;
+ SELECT * FROM t1;
+ connection slave;
+ SELECT * FROM t1;
+ connection master;
+ SELECT * FROM t2;
+ connection slave;
+ SELECT * FROM t2;
+ connection master;
+ SELECT * FROM t3;
+ connection slave;
+ SELECT * FROM t3;
+ --source include/reset_master_and_slave.inc
+
+ connection master;
+
+ DROP TABLE t1;
+ DROP TABLE t2;
+ DROP TABLE t3;
+
+ sync_slave_with_master;
+
+ inc $y;
+}
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2009-04-02 16:14:14 +0000
+++ b/sql/log_event.cc 2009-04-05 12:13:10 +0000
@@ -7398,7 +7398,7 @@ int Rows_log_event::do_apply_event(Relay
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
if (!m_curr_row_end && !error)
- unpack_current_row(rli, &m_cols);
+ error= unpack_current_row(rli, &m_cols);
// at this moment m_curr_row_end should be set
DBUG_ASSERT(error || m_curr_row_end != NULL);
@@ -8392,7 +8392,8 @@ Rows_log_event::write_row(const Relay_lo
DBUG_RETURN(error);
/* unpack row into table->record[0] */
- error= unpack_current_row(rli, &m_cols);
+ if ((error= unpack_current_row(rli, &m_cols)))
+ DBUG_RETURN(error);
// Temporary fix to find out why it fails [/Matz]
memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
@@ -9197,7 +9198,8 @@ Update_rows_log_event::do_exec_row(const
store_record(m_table,record[1]);
m_curr_row= m_curr_row_end;
- error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
+ if ((error= unpack_current_row(rli, &m_cols_ai))) // this also updates m_curr_row_end
+ return error;
/*
Now we have the right row to update. The old row (the one we're
=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc 2009-04-02 16:14:14 +0000
+++ b/sql/log_event_old.cc 2009-04-05 12:13:10 +0000
@@ -1718,7 +1718,7 @@ int Old_rows_log_event::do_apply_event(R
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
if (!m_curr_row_end && !error)
- unpack_current_row(rli);
+ error= unpack_current_row(rli);
// at this moment m_curr_row_end should be set
DBUG_ASSERT(error || m_curr_row_end != NULL);
@@ -2045,7 +2045,8 @@ Old_rows_log_event::write_row(const Rela
DBUG_RETURN(error);
/* unpack row into table->record[0] */
- error= unpack_current_row(rli); // TODO: how to handle errors?
+ if ((error= unpack_current_row(rli)))
+ DBUG_RETURN(error);
#ifndef DBUG_OFF
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@@ -2845,7 +2846,8 @@ Update_rows_log_event_old::do_exec_row(c
store_record(m_table,record[1]);
m_curr_row= m_curr_row_end;
- error= unpack_current_row(rli); // this also updates m_curr_row_end
+ if ((error= unpack_current_row(rli))) // this also updates m_curr_row_end
+ return error;
/*
Now we have the right row to update. The old row (the one we're
=== modified file 'sql/rpl_record.cc'
--- a/sql/rpl_record.cc 2009-03-05 21:13:37 +0000
+++ b/sql/rpl_record.cc 2009-04-05 12:13:10 +0000
@@ -265,12 +265,21 @@ unpack_row(Relay_log_info const *rli,
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT(pack_ptr != NULL);
- if ((null_bits & null_mask) && f->maybe_null())
+ if (null_bits & null_mask)
{
- DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
- null_mask, null_bits));
-
- f->set_null();
+ if (f->maybe_null())
+ {
+ DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
+ null_mask, null_bits));
+
+ f->set_null();
+ }
+ else
+ {
+ my_error(ER_BAD_NULL_ERROR, MYF(0), f->field_name);
+ error = HA_ERR_ROWS_EVENT_APPLY;
+ DBUG_RETURN(error);
+ }
}
else if (!unpack_blobs && f->unireg_check==Field::BLOB_FIELD)
{
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (alfranio.correia:2839) Bug#43789 | Alfranio Correia | 5 Apr |