Commit 9715539e authored by Ramil Kalimullin's avatar Ramil Kalimullin

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.


mysql-test/r/myisam.result:
  Fix for bug#51304: checksum table gives different results 
  for same data when using bit fields
    - test result.
mysql-test/t/myisam.test:
  Fix for bug#51304: checksum table gives different results 
  for same data when using bit fields
    - test case.
sql/sql_table.cc:
  Fix for bug#51304: checksum table gives different results 
  for same data when using bit fields
    - convert BIT fields to strings calculating its checksums
  as some bits may be saved among NULL bits in the record buffer.
parent 723e67b9
...@@ -2339,4 +2339,21 @@ CHECK TABLE t1; ...@@ -2339,4 +2339,21 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1; 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 End of 5.1 tests
...@@ -1587,5 +1587,20 @@ REPLACE INTO t1 VALUES ...@@ -1587,5 +1587,20 @@ REPLACE INTO t1 VALUES
CHECK TABLE t1; CHECK TABLE t1;
DROP 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, ...@@ -7934,22 +7934,28 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
for (uint i= 0; i < t->s->fields; i++ ) for (uint i= 0; i < t->s->fields; i++ )
{ {
Field *f= t->field[i]; Field *f= t->field[i];
enum_field_types field_type= f->type();
/* /*
BLOB and VARCHAR have pointers in their field, we must convert BLOB and VARCHAR have pointers in their field, we must convert
to string; GEOMETRY is implemented on top of BLOB. to string; GEOMETRY is implemented on top of BLOB.
*/ BIT may store its data among NULL bits, convert as well.
if ((field_type == MYSQL_TYPE_BLOB) || */
(field_type == MYSQL_TYPE_VARCHAR) || switch (f->type()) {
(field_type == MYSQL_TYPE_GEOMETRY)) case MYSQL_TYPE_BLOB:
{ case MYSQL_TYPE_VARCHAR:
String tmp; case MYSQL_TYPE_GEOMETRY:
f->val_str(&tmp); case MYSQL_TYPE_BIT:
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length()); {
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; crc+= row_crc;
......
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