diff --git a/mysql-test/r/myisampack.result b/mysql-test/r/myisampack.result index 50d700ab7a2..dc7f3e396d1 100644 --- a/mysql-test/r/myisampack.result +++ b/mysql-test/r/myisampack.result @@ -54,3 +54,14 @@ test.t1 repair error Table 'test.t1' is read only Warnings: Error 1036 Table 't1' is read only drop table t1; +# +# BUG#41541 - Valgrind warnings on packed MyISAM table +# +CREATE TABLE t1(f1 VARCHAR(200), f2 TEXT); +INSERT INTO t1 VALUES ('foo', 'foo1'), ('bar', 'bar1'); +FLUSH TABLE t1; +# Compress the table using MYISAMPACK tool +SELECT COUNT(*) FROM t1; +COUNT(*) +1024 +DROP TABLE t1; diff --git a/mysql-test/t/myisampack.test b/mysql-test/t/myisampack.test index f554e7d0184..a88126f2d04 100644 --- a/mysql-test/t/myisampack.test +++ b/mysql-test/t/myisampack.test @@ -61,3 +61,23 @@ let $MYSQLD_DATADIR= `select @@datadir`; optimize table t1; repair table t1; drop table t1; + +--echo # +--echo # BUG#41541 - Valgrind warnings on packed MyISAM table +--echo # +CREATE TABLE t1(f1 VARCHAR(200), f2 TEXT); +INSERT INTO t1 VALUES ('foo', 'foo1'), ('bar', 'bar1'); +let $i=9; +--disable_query_log +while ($i) +{ + INSERT INTO t1 SELECT * FROM t1; + dec $i; +} +--enable_query_log +FLUSH TABLE t1; +--echo # Compress the table using MYISAMPACK tool +let $MYSQLD_DATADIR= `select @@datadir`; +--exec $MYISAMPACK $MYSQLD_DATADIR/test/t1 +SELECT COUNT(*) FROM t1; +DROP TABLE t1; diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index b5260e9c463..0f3c35235e9 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1431,6 +1431,32 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff) bit_buff->current_byte=0; return; } + else + { + uint len= 0; + uint i= 0; + /* + Check if the remaining buffer/record to read is less than the word size. + If so read byte by byte + + Note: if this branch becomes a bottleneck it can be removed, assuming + that the second memory segment allocates 7 extra bytes (see + _mi_read_pack_info()). + */ + len= bit_buff->end - bit_buff->pos; + if (len < (BITS_SAVED / 8)) + { + bit_buff->current_byte= 0; + for (i=0 ; i < len ; i++) + { + bit_buff->current_byte+= (((uint) ((uchar) bit_buff->pos[len - i - 1])) + << (8 * i)); + } + bit_buff->pos= bit_buff->end; + return; + } + } + #if BITS_SAVED == 64 bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) + (((uint) ((uchar) bit_buff->pos[6])) << 8) +