Commit 7d244411 authored by Martin Hansson's avatar Martin Hansson

Bug#43737: Select query return bad result

      
A bug in the initialization of key segment information made it point
to the wrong bit, since a bit index was used when its int value
was needed. This lead to misinterpretation of bit columns
read from MyISAM record format when a NULL bit pushed them over
a byte boundary.
Fixed by using the int value of the bit instead.
parent 4edc43b7
...@@ -2226,4 +2226,30 @@ Key Start Len Index Type ...@@ -2226,4 +2226,30 @@ Key Start Len Index Type
1 2 30 multip. varchar 1 2 30 multip. varchar
2 33 30 multip. char NULL 2 33 30 multip. char NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
c INT,
d bit(1),
e INT,
f VARCHAR(1),
g BIT(1),
h BIT(1),
KEY (h, d, e, g)
);
INSERT INTO t1 VALUES
( 3, 1, 1, 'a', 0, 0 ),
( 3, 1, 5, 'a', 0, 0 ),
( 10, 1, 2, 'a', 0, 1 ),
( 10, 1, 3, 'a', 0, 1 ),
( 10, 1, 4, 'a', 0, 1 );
SELECT f FROM t1 WHERE d = 1 AND e = 2 AND g = 0 AND h = 1;
f
a
SELECT h+0, d + 0, e, g + 0 FROM t1;
h+0 d + 0 e g + 0
0 1 1 0
0 1 5 0
1 1 2 0
1 1 3 0
1 1 4 0
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -1478,5 +1478,30 @@ let $MYSQLD_DATADIR= `select @@datadir`; ...@@ -1478,5 +1478,30 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--exec $MYISAMCHK -d $MYSQLD_DATADIR/test/t1 --exec $MYISAMCHK -d $MYSQLD_DATADIR/test/t1
DROP TABLE t1; DROP TABLE t1;
#
# Bug#43737: Select query return bad result
#
CREATE TABLE t1 (
c INT,
d bit(1),
e INT,
f VARCHAR(1),
g BIT(1),
h BIT(1),
KEY (h, d, e, g)
);
INSERT INTO t1 VALUES
( 3, 1, 1, 'a', 0, 0 ),
( 3, 1, 5, 'a', 0, 0 ),
( 10, 1, 2, 'a', 0, 1 ),
( 10, 1, 3, 'a', 0, 1 ),
( 10, 1, 4, 'a', 0, 1 );
SELECT f FROM t1 WHERE d = 1 AND e = 2 AND g = 0 AND h = 1;
SELECT h+0, d + 0, e, g + 0 FROM t1;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -1160,7 +1160,8 @@ uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg) ...@@ -1160,7 +1160,8 @@ uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
keyseg->null_pos = mi_uint4korr(ptr); ptr +=4; keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
keyseg->charset=0; /* Will be filled in later */ keyseg->charset=0; /* Will be filled in later */
if (keyseg->null_bit) if (keyseg->null_bit)
keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7)); /* We adjust bit_pos if null_bit is last in the byte */
keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == (1 << 7)));
else else
{ {
keyseg->bit_pos= (uint16)keyseg->null_pos; keyseg->bit_pos= (uint16)keyseg->null_pos;
......
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