Commit f74d805e authored by kaa@polly.(none)'s avatar kaa@polly.(none)
Browse files

Backport of the 5.0 patch to 4.1

Bug#28878: InnoDB tables with UTF8 character set and indexes cause  wrong result for DML
When making key reference buffers over CHAR fields whitespace (0x20) must be used to fill in the remaining space in the field's buffer. This is what Field_string::store() does. Fixed Field_string::get_key_image() to do the same.
parent e7851316
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -182,4 +182,40 @@ t1.a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
DROP TABLE t1;
CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8;
INSERT INTO t1 VALUES ('uk'),('bg');
SELECT * FROM t1 WHERE a = 'uk';
a
uk
DELETE FROM t1 WHERE a = 'uk';
SELECT * FROM t1 WHERE a = 'uk';
a
UPDATE t1 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t1 WHERE a = 'uk';
a
CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB;
INSERT INTO t2 VALUES ('uk'),('bg');
SELECT * FROM t2 WHERE a = 'uk';
a
uk
DELETE FROM t2 WHERE a = 'uk';
SELECT * FROM t2 WHERE a = 'uk';
a
INSERT INTO t2 VALUES ('uk');
UPDATE t2 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t2 WHERE a = 'uk';
a
CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM;
INSERT INTO t3 VALUES ('uk'),('bg');
SELECT * FROM t3 WHERE a = 'uk';
a
uk
DELETE FROM t3 WHERE a = 'uk';
SELECT * FROM t3 WHERE a = 'uk';
a
INSERT INTO t3 VALUES ('uk');
UPDATE t3 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t3 WHERE a = 'uk';
a
DROP TABLE t1,t2,t3;
End of 4.1 tests
+32 −0
Original line number Diff line number Diff line
@@ -216,4 +216,36 @@ t1.a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';

DROP TABLE t1;

#
# Bug #28878: InnoDB tables with UTF8 character set and indexes cause wrong result for DML
#

CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8;
INSERT INTO t1 VALUES ('uk'),('bg');
SELECT * FROM t1 WHERE a = 'uk';
DELETE FROM t1 WHERE a = 'uk';
SELECT * FROM t1 WHERE a = 'uk';
UPDATE t1 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t1 WHERE a = 'uk';

CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB;
INSERT INTO t2 VALUES ('uk'),('bg');
SELECT * FROM t2 WHERE a = 'uk';
DELETE FROM t2 WHERE a = 'uk';
SELECT * FROM t2 WHERE a = 'uk';
INSERT INTO t2 VALUES ('uk');
UPDATE t2 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t2 WHERE a = 'uk';

CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM;
INSERT INTO t3 VALUES ('uk'),('bg');
SELECT * FROM t3 WHERE a = 'uk';
DELETE FROM t3 WHERE a = 'uk';
SELECT * FROM t3 WHERE a = 'uk';
INSERT INTO t3 VALUES ('uk');
UPDATE t3 SET a = 'us' WHERE a = 'uk';
SELECT * FROM t3 WHERE a = 'uk';

DROP TABLE t1,t2,t3;

--echo End of 4.1 tests
+2 −1
Original line number Diff line number Diff line
@@ -5211,7 +5211,8 @@ uint Field_string::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
                          length / field_charset->mbmaxlen);
  memcpy(buff, ptr, bytes);
  if (bytes < length)
    bzero(buff + bytes, length - bytes);
    field_charset->cset->fill(field_charset, buff + bytes, length - bytes,
                              ' ');
  return bytes;
}