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
...@@ -9014,11 +9014,41 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -9014,11 +9014,41 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
chose the row to change only using a PK or an UNNI. chose the row to change only using a PK or an UNNI.
*/ */
if (table->key_info->flags & HA_NOSAME) if (table->key_info->flags & HA_NOSAME)
{
/* Unique does not have non nullable part */
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(); table->file->ha_index_end();
goto ok; goto ok;
} }
/* else fall through to index scan */
}
}
/* /*
In case key is not unique, we still have to iterate over records found In case key is not unique, we still have to iterate over records found
and find the one which is identical to the row given. A copy of the and find the one which is identical to the row given. A copy of the
......
...@@ -2427,11 +2427,41 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2427,11 +2427,41 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
chose the row to change only using a PK or an UNNI. chose the row to change only using a PK or an UNNI.
*/ */
if (table->key_info->flags & HA_NOSAME) if (table->key_info->flags & HA_NOSAME)
{
/* Unique does not have non nullable part */
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(); table->file->ha_index_end();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* else fall through to index scan */
}
}
/* /*
In case key is not unique, we still have to iterate over records found In case key is not unique, we still have to iterate over records found
and find the one which is identical to the row given. A copy of the and find the one which is identical to the row given. A copy of the
......
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