Commit ffe91b8d authored by Luis Soares's avatar Luis Soares

BUG 52868: automerged bzr bundle from bug report.

parents 2cd8fd18 2d1b72fc
#
# BUG#52868: Wrong handling of NULL value during update, replication out of sync
#
-- echo ## case #1 - last_null_bit_pos==0 in record_compare without X bit
-- source include/master-slave-reset.inc
-- connection master
-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
-- disable_warnings
UPDATE t1 SET c5 = 'a';
-- enable_warnings
-- 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
-- echo ## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
-- echo ## (1 column less and no varchar)
-- source include/master-slave-reset.inc
-- connection master
-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
-- disable_warnings
UPDATE t1 SET c5 = 'a';
-- enable_warnings
-- 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
-- echo ## case #2 - X bit is wrongly set.
-- source include/master-slave-reset.inc
-- connection master
-- eval CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=$engine DEFAULT CHARSET= latin1
INSERT INTO t1(c1) VALUES (10);
INSERT INTO t1(c1) VALUES (NULL);
UPDATE t1 SET c1= 0;
-- 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
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;
## case #1 - last_null_bit_pos==0 in record_compare without X bit
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 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
UPDATE t1 SET c5 = 'a';
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
## (1 column less and no varchar)
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 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
UPDATE t1 SET c5 = 'a';
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
## case #2 - X bit is wrongly set.
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, c2 varchar(1) default '') ENGINE=InnoDB DEFAULT CHARSET= latin1;
INSERT INTO t1(c1) VALUES (10);
INSERT INTO t1(c1) VALUES (NULL);
UPDATE t1 SET c1= 0;
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
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;
## case #1 - last_null_bit_pos==0 in record_compare without X bit
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 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
UPDATE t1 SET c5 = 'a';
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
## (1 column less and no varchar)
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 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
UPDATE t1 SET c5 = 'a';
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
## case #2 - X bit is wrongly set.
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, c2 varchar(1) default '') ENGINE=MyISAM DEFAULT CHARSET= latin1;
INSERT INTO t1(c1) VALUES (10);
INSERT INTO t1(c1) VALUES (NULL);
UPDATE t1 SET c1= 0;
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
## coverage purposes - Field_bits
## 1 X bit + 2 Null bits + 5 bits => last_null_bit_pos==0
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 bigint(20) DEFAULT 0, c2 bit(5)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1(c1,c2) VALUES (10, b'1');
INSERT INTO t1(c1,c2) VALUES (NULL, b'1');
UPDATE t1 SET c1= 0;
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
-- source include/have_innodb.inc
#
# BUG#52868 Wrong handling of NULL value during update, replication out of sync
#
-- let $engine= InnoDB
-- source extra/rpl_tests/rpl_record_compare.test
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
#
# BUG#52868 Wrong handling of NULL value during update, replication out of sync
#
-- let $engine= MyISAM
-- source extra/rpl_tests/rpl_record_compare.test
-- echo ## coverage purposes - Field_bits
-- echo ## 1 X bit + 2 Null bits + 5 bits => last_null_bit_pos==0
## Added here because AFAIK it's only MyISAM and NDB that use Field_bits
-- source include/master-slave-reset.inc
-- connection master
-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bit(5)) ENGINE=$engine DEFAULT CHARSET=latin1
INSERT INTO t1(c1,c2) VALUES (10, b'1');
INSERT INTO t1(c1,c2) VALUES (NULL, b'1');
UPDATE t1 SET c1= 0;
-- 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
...@@ -8774,11 +8774,28 @@ static bool record_compare(TABLE *table) ...@@ -8774,11 +8774,28 @@ static bool record_compare(TABLE *table)
{ {
for (int i = 0 ; i < 2 ; ++i) for (int i = 0 ; i < 2 ; ++i)
{ {
saved_x[i]= table->record[i][0]; /*
saved_filler[i]= table->record[i][table->s->null_bytes - 1]; If we have an X bit then we need to take care of it.
table->record[i][0]|= 1U; */
table->record[i][table->s->null_bytes - 1]|= if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
256U - (1U << table->s->last_null_bit_pos); {
saved_x[i]= table->record[i][0];
table->record[i][0]|= 1U;
}
/*
If (last_null_bit_pos == 0 && null_bytes > 1), then:
X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
Ie, the entire byte is used.
*/
if (table->s->last_null_bit_pos > 0)
{
saved_filler[i]= table->record[i][table->s->null_bytes - 1];
table->record[i][table->s->null_bytes - 1]|=
256U - (1U << table->s->last_null_bit_pos);
}
} }
} }
...@@ -8818,8 +8835,11 @@ static bool record_compare(TABLE *table) ...@@ -8818,8 +8835,11 @@ static bool record_compare(TABLE *table)
{ {
for (int i = 0 ; i < 2 ; ++i) for (int i = 0 ; i < 2 ; ++i)
{ {
table->record[i][0]= saved_x[i]; if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
table->record[i][table->s->null_bytes - 1]= saved_filler[i]; table->record[i][0]= saved_x[i];
if (table->s->last_null_bit_pos)
table->record[i][table->s->null_bytes - 1]= saved_filler[i];
} }
} }
......
...@@ -342,12 +342,29 @@ static bool record_compare(TABLE *table) ...@@ -342,12 +342,29 @@ static bool record_compare(TABLE *table)
if (table->s->null_bytes > 0) if (table->s->null_bytes > 0)
{ {
for (int i = 0 ; i < 2 ; ++i) for (int i = 0 ; i < 2 ; ++i)
{ {
saved_x[i]= table->record[i][0]; /*
saved_filler[i]= table->record[i][table->s->null_bytes - 1]; If we have an X bit then we need to take care of it.
table->record[i][0]|= 1U; */
table->record[i][table->s->null_bytes - 1]|= if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
256U - (1U << table->s->last_null_bit_pos); {
saved_x[i]= table->record[i][0];
table->record[i][0]|= 1U;
}
/*
If (last_null_bit_pos == 0 && null_bytes > 1), then:
X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
Ie, the entire byte is used.
*/
if (table->s->last_null_bit_pos > 0)
{
saved_filler[i]= table->record[i][table->s->null_bytes - 1];
table->record[i][table->s->null_bytes - 1]|=
256U - (1U << table->s->last_null_bit_pos);
}
} }
} }
...@@ -387,8 +404,11 @@ static bool record_compare(TABLE *table) ...@@ -387,8 +404,11 @@ static bool record_compare(TABLE *table)
{ {
for (int i = 0 ; i < 2 ; ++i) for (int i = 0 ; i < 2 ; ++i)
{ {
table->record[i][0]= saved_x[i]; if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
table->record[i][table->s->null_bytes - 1]= saved_filler[i]; table->record[i][0]= saved_x[i];
if (table->s->last_null_bit_pos > 0)
table->record[i][table->s->null_bytes - 1]= saved_filler[i];
} }
} }
......
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