Skip to content

Commit

Permalink
Issue facebook#110: SQL command checksum returns inconsistent result
Browse files Browse the repository at this point in the history
Summary:
When unpacking NULL values, we set the null-bit of the field to one.
Besides that, also set the field value to the default value (like
InnoDB does).
CHECKSUM TABLE depends on this as it includes field *value* in checksum
calculations even when the field has NULL value (this is despite the fact
that NULL-bits are also included in checksum calculation).

Differential Revision: https://reviews.facebook.net/D51525
  • Loading branch information
spetrunia authored and inikep committed Mar 28, 2023
1 parent a622775 commit 1b42fcb
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
67 changes: 67 additions & 0 deletions mysql-test/suite/rocksdb/r/checksum_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,70 @@ Table Checksum
test.t1 4259194219
test.t2 0
DROP TABLE t1, t2;
#
# Issue #110: SQL command checksum returns inconsistent result
#
create table t1 (pk int primary key, col1 varchar(10)) engine=rocksdb;
insert into t1 values (2,'fooo');
insert into t1 values (1,NULL);
checksum table t1;
Table Checksum
test.t1 1303411884
checksum table t1;
Table Checksum
test.t1 1303411884
select * from t1 where pk=2;
pk col1
2 fooo
checksum table t1;
Table Checksum
test.t1 1303411884
checksum table t1;
Table Checksum
test.t1 1303411884
flush tables;
checksum table t1;
Table Checksum
test.t1 1303411884
checksum table t1;
Table Checksum
test.t1 1303411884
drop table t1;
#
# The following test is about making sure MyRocks CHECKSUM TABLE
# values are the same as with InnoDB.
# If you see checksum values changed, make sure their counterparts
# in suite/innodb/r/checksum-matches-myrocks.result match.
#
create table t1 (pk int primary key, col1 varchar(10)) engine=rocksdb;
insert into t1 values (2,'fooo');
insert into t1 values (1,NULL);
checksum table t1;
Table Checksum
test.t1 1303411884
drop table t1;
create table t1 (
pk bigint unsigned primary key,
col1 varchar(10),
col2 tinyint,
col3 double
) engine=rocksdb;
checksum table t1;
Table Checksum
test.t1 0
insert into t1 values (1, NULL, NULL, NULL);
insert into t1 values (2, 'foo', NULL, NULL);
checksum table t1;
Table Checksum
test.t1 3633741545
insert into t1 values (3, NULL, 123, NULL);
insert into t1 values (4, NULL, NULL, 2.78);
checksum table t1;
Table Checksum
test.t1 390004011
insert into t1 values (5, 'xxxYYYzzzT', NULL, 2.78);
insert into t1 values (6, '', NULL, 2.78);
checksum table t1;
Table Checksum
test.t1 3183101003
drop table t1;
52 changes: 52 additions & 0 deletions mysql-test/suite/rocksdb/t/checksum_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,56 @@ CHECKSUM TABLE t1, t2 EXTENDED;

DROP TABLE t1, t2;

--echo #
--echo # Issue #110: SQL command checksum returns inconsistent result
--echo #
create table t1 (pk int primary key, col1 varchar(10)) engine=rocksdb;
insert into t1 values (2,'fooo');
insert into t1 values (1,NULL);
checksum table t1;
checksum table t1;
select * from t1 where pk=2;
checksum table t1;
checksum table t1;
flush tables;
checksum table t1;
checksum table t1;

drop table t1;

--echo #
--echo # The following test is about making sure MyRocks CHECKSUM TABLE
--echo # values are the same as with InnoDB.
--echo # If you see checksum values changed, make sure their counterparts
--echo # in suite/innodb/r/checksum-matches-myrocks.result match.
--echo #

create table t1 (pk int primary key, col1 varchar(10)) engine=rocksdb;
insert into t1 values (2,'fooo');
insert into t1 values (1,NULL);
checksum table t1;
drop table t1;

create table t1 (
pk bigint unsigned primary key,
col1 varchar(10),
col2 tinyint,
col3 double
) engine=rocksdb;

checksum table t1;

insert into t1 values (1, NULL, NULL, NULL);
insert into t1 values (2, 'foo', NULL, NULL);
checksum table t1;

insert into t1 values (3, NULL, 123, NULL);
insert into t1 values (4, NULL, NULL, 2.78);
checksum table t1;

insert into t1 values (5, 'xxxYYYzzzT', NULL, 2.78);
insert into t1 values (6, '', NULL, 2.78);
checksum table t1;

drop table t1;

11 changes: 11 additions & 0 deletions storage/rocksdb/ha_rocksdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2853,7 +2853,18 @@ int ha_rocksdb::convert_record_from_storage_format(const rocksdb::Slice *key,
int isNull = field_enc[i].maybe_null() &&
(null_bytes[field_enc[i].null_offset] & field_enc[i].null_mask) != 0;
if (isNull)
{
/* This sets the NULL-bit of this record */
field->set_null(ptr_diff);
/*
Besides that, set the field value to default value. CHECKSUM TABLE
depends on this.
*/
uint field_offset= field->ptr - table->record[0];
memcpy(buf + field_offset,
table->s->default_values + field_offset,
field->pack_length());
}
else
field->set_notnull(ptr_diff);

Expand Down
6 changes: 6 additions & 0 deletions storage/rocksdb/rdb_datadic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,13 @@ int RDBSE_KEYDEF::unpack_record(const ha_rocksdb *handler, TABLE *table,
return 1;
if (*nullp == 0)
{
/* Set the NULL-bit of this field */
field->set_null(ptr_diff);
/* Also set the field to its default value */
uint field_offset= field->ptr - table->record[0];
memcpy(buf + field_offset,
table->s->default_values + field_offset,
field->pack_length());
continue;
}
else if (*nullp == 1)
Expand Down

0 comments on commit 1b42fcb

Please sign in to comment.