Fix for bug#51304: checksum table gives different results
for same data when using bit fields Problem: checksum for BIT fields may be computed incorrectly in some cases due to its storage peculiarity. Fix: convert a BIT field to a string then calculate its checksum.
This commit is contained in:
parent
51d54a7eca
commit
c1de4070ca
@ -2339,4 +2339,21 @@ CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#51304: checksum table gives different results
|
||||
# for same data when using bit fields
|
||||
#
|
||||
CREATE TABLE t1(a INT, b BIT(1));
|
||||
INSERT INTO t1 VALUES(1, 0), (2, 1);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
CHECKSUM TABLE t1 EXTENDED;
|
||||
Table Checksum
|
||||
test.t1 3775188275
|
||||
CHECKSUM TABLE t2 EXTENDED;
|
||||
Table Checksum
|
||||
test.t2 3775188275
|
||||
CHECKSUM TABLE t3 EXTENDED;
|
||||
Table Checksum
|
||||
test.t3 3775188275
|
||||
DROP TABLE t1, t2, t3;
|
||||
End of 5.1 tests
|
||||
|
@ -1587,5 +1587,20 @@ REPLACE INTO t1 VALUES
|
||||
CHECK TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
--echo #
|
||||
--echo # Bug#51304: checksum table gives different results
|
||||
--echo # for same data when using bit fields
|
||||
--echo #
|
||||
CREATE TABLE t1(a INT, b BIT(1));
|
||||
INSERT INTO t1 VALUES(1, 0), (2, 1);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
--copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/t3.frm
|
||||
--copy_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/test/t3.MYD
|
||||
--copy_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/t3.MYI
|
||||
CHECKSUM TABLE t1 EXTENDED;
|
||||
CHECKSUM TABLE t2 EXTENDED;
|
||||
CHECKSUM TABLE t3 EXTENDED;
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -7934,22 +7934,28 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
||||
for (uint i= 0; i < t->s->fields; i++ )
|
||||
{
|
||||
Field *f= t->field[i];
|
||||
enum_field_types field_type= f->type();
|
||||
/*
|
||||
BLOB and VARCHAR have pointers in their field, we must convert
|
||||
to string; GEOMETRY is implemented on top of BLOB.
|
||||
*/
|
||||
if ((field_type == MYSQL_TYPE_BLOB) ||
|
||||
(field_type == MYSQL_TYPE_VARCHAR) ||
|
||||
(field_type == MYSQL_TYPE_GEOMETRY))
|
||||
{
|
||||
String tmp;
|
||||
f->val_str(&tmp);
|
||||
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
|
||||
|
||||
/*
|
||||
BLOB and VARCHAR have pointers in their field, we must convert
|
||||
to string; GEOMETRY is implemented on top of BLOB.
|
||||
BIT may store its data among NULL bits, convert as well.
|
||||
*/
|
||||
switch (f->type()) {
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
case MYSQL_TYPE_BIT:
|
||||
{
|
||||
String tmp;
|
||||
f->val_str(&tmp);
|
||||
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
|
||||
tmp.length());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
row_crc= my_checksum(row_crc, f->ptr, f->pack_length());
|
||||
break;
|
||||
}
|
||||
else
|
||||
row_crc= my_checksum(row_crc, f->ptr,
|
||||
f->pack_length());
|
||||
}
|
||||
|
||||
crc+= row_crc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user