Commit 0ade82fe authored by Luis Soares's avatar Luis Soares

BUG 53893: automerged bug branch into mysql-5.1-bugteam latest.

parents 21634b92 8ce9f9b3
...@@ -24,3 +24,15 @@ INSERT INTO t VALUES (1,2,4); ...@@ -24,3 +24,15 @@ INSERT INTO t VALUES (1,2,4);
INSERT INTO t VALUES (4,3,4); INSERT INTO t VALUES (4,3,4);
DELETE FROM t; DELETE FROM t;
DROP TABLE t; DROP TABLE t;
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 (c1 INT NOT NULL, c2 INT NOT NULL, c3 INT, UNIQUE KEY(c1,c3), KEY(c2));
INSERT INTO t1(c1,c2) VALUES(1,1);
INSERT INTO t1(c1,c2) VALUES(1,2);
UPDATE t1 SET c1=1000 WHERE c2=2;
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
...@@ -71,3 +71,34 @@ DELETE FROM t; ...@@ -71,3 +71,34 @@ DELETE FROM t;
DROP TABLE t; DROP TABLE t;
-- sync_slave_with_master -- sync_slave_with_master
#
# BUG#53893: RBR: nullable unique key can lead to out-of-sync slave
#
#
# We insert two rows. Both with part of UNIQUE KEY set to null.
# Then we update the last row inserted. On master the correct
# row is updated. On the slave the wrong row would be updated
# because the engine would look it up by the NULL Unique KEY.
# As a consquence, the wrong row would be updated.
#
-- connection master
-- source include/master-slave-reset.inc
-- connection master
CREATE TABLE t1 (c1 INT NOT NULL, c2 INT NOT NULL, c3 INT, UNIQUE KEY(c1,c3), KEY(c2));
INSERT INTO t1(c1,c2) VALUES(1,1);
INSERT INTO t1(c1,c2) VALUES(1,2);
UPDATE t1 SET c1=1000 WHERE c2=2;
-- 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
...@@ -9015,8 +9015,38 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -9015,8 +9015,38 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
*/ */
if (table->key_info->flags & HA_NOSAME) if (table->key_info->flags & HA_NOSAME)
{ {
table->file->ha_index_end(); /* Unique does not have non nullable part */
goto ok; if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
{
table->file->ha_index_end();
goto ok;
}
else
{
KEY *keyinfo= table->key_info;
/*
Unique has nullable part. We need to check if there is any field in the
BI image that is null and part of UNNI.
*/
bool null_found= FALSE;
for (uint i=0, fieldnr= keyinfo->key_part[i].fieldnr - 1 ;
(i < keyinfo->key_parts) && !null_found ;
i++, fieldnr= keyinfo->key_part[i].fieldnr - 1)
{
Field **f= table->field+fieldnr;
if ((*f)->is_null())
null_found= TRUE;
}
if (!null_found)
{
table->file->ha_index_end();
goto ok;
}
/* else fall through to index scan */
}
} }
/* /*
......
...@@ -2428,8 +2428,38 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2428,8 +2428,38 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
*/ */
if (table->key_info->flags & HA_NOSAME) if (table->key_info->flags & HA_NOSAME)
{ {
table->file->ha_index_end(); /* Unique does not have non nullable part */
DBUG_RETURN(0); if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
{
table->file->ha_index_end();
DBUG_RETURN(0);
}
else
{
KEY *keyinfo= table->key_info;
/*
Unique has nullable part. We need to check if there is any field in the
BI image that is null and part of UNNI.
*/
bool null_found= FALSE;
for (uint i=0, fieldnr= keyinfo->key_part[i].fieldnr - 1 ;
(i < keyinfo->key_parts) && !null_found ;
i++, fieldnr= keyinfo->key_part[i].fieldnr - 1)
{
Field **f= table->field+fieldnr;
if ((*f)->is_null())
null_found= TRUE;
}
if (!null_found)
{
table->file->ha_index_end();
DBUG_RETURN(0);
}
/* else fall through to index scan */
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment