From f55477060c008dfef1f27768d5ce45d87f26af34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 1 Sep 2021 14:30:18 +0300 Subject: MDEV-26518 ; Galera incorrectly handles primary or unique keys with any multi-byte character set We need to set temporary buffer large enough to fit also multi-byte characters. --- .../suite/galera/r/galera_fk_multibyte.result | 33 ++++++++++++++++++++++ mysql-test/suite/galera/r/galera_fulltext.result | 28 ++++++++++++++++++ mysql-test/suite/galera/t/galera_fk_multibyte.test | 23 +++++++++++++++ mysql-test/suite/galera/t/galera_fulltext.test | 24 ++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 3 +- 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_fk_multibyte.result create mode 100644 mysql-test/suite/galera/t/galera_fk_multibyte.test diff --git a/mysql-test/suite/galera/r/galera_fk_multibyte.result b/mysql-test/suite/galera/r/galera_fk_multibyte.result new file mode 100644 index 00000000000..dfb3b86ff38 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_fk_multibyte.result @@ -0,0 +1,33 @@ +create table p (i varchar(100) primary key, j int) ENGINE=InnoDB DEFAULT CHARSET=utf8; +create table c1 (i int primary key auto_increment, j varchar(100), k int, key(j), constraint fk1 foreign key (j) references p(i)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +create table c2 (i int primary key auto_increment, j varchar(100), k int, key(j), constraint fk2 foreign key (j) references p(i)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into p values('sippo',1); +insert into c1 values(1,'sippo',1); +insert into c2 values(1,'sippo',1); +update c1 set k = 100 where j = 'sippo'; +insert into c1 values(2,'sippo',1); +select * from p; +i j +sippo 1 +select * from c1; +i j k +1 sippo 100 +2 sippo 1 +select * from c2; +i j k +1 sippo 1 +connection node_2; +select * from p; +i j +sippo 1 +select * from c1; +i j k +1 sippo 100 +2 sippo 1 +select * from c2; +i j k +1 sippo 1 +connection node_1; +drop table c1; +drop table c2; +drop table p; diff --git a/mysql-test/suite/galera/r/galera_fulltext.result b/mysql-test/suite/galera/r/galera_fulltext.result index af017083b4e..bb482b7f4f7 100644 --- a/mysql-test/suite/galera/r/galera_fulltext.result +++ b/mysql-test/suite/galera/r/galera_fulltext.result @@ -62,3 +62,31 @@ COUNT(*) 1 connection node_1; DROP TABLE t; +connection node_1; +SET @value=REPEAT (1,5001); +CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8; +INSERT IGNORE INTO t VALUES(@value); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT COUNT(*) FROM t; +COUNT(*) +1 +connection node_2; +SELECT COUNT(*) FROM t; +COUNT(*) +1 +connection node_1; +DROP TABLE t; +CREATE TABLE t (a VARCHAR(5000)) engine=innodb DEFAULT CHARSET=utf8; +INSERT IGNORE INTO t VALUES(@value); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT COUNT(*) FROM t; +COUNT(*) +1 +connection node_2; +SELECT COUNT(*) FROM t; +COUNT(*) +1 +connection node_1; +DROP TABLE t; diff --git a/mysql-test/suite/galera/t/galera_fk_multibyte.test b/mysql-test/suite/galera/t/galera_fk_multibyte.test new file mode 100644 index 00000000000..4bc03b6d84b --- /dev/null +++ b/mysql-test/suite/galera/t/galera_fk_multibyte.test @@ -0,0 +1,23 @@ +--source include/galera_cluster.inc + +create table p (i varchar(100) primary key, j int) ENGINE=InnoDB DEFAULT CHARSET=utf8; +create table c1 (i int primary key auto_increment, j varchar(100), k int, key(j), constraint fk1 foreign key (j) references p(i)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +create table c2 (i int primary key auto_increment, j varchar(100), k int, key(j), constraint fk2 foreign key (j) references p(i)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into p values('sippo',1); +insert into c1 values(1,'sippo',1); +insert into c2 values(1,'sippo',1); +update c1 set k = 100 where j = 'sippo'; +insert into c1 values(2,'sippo',1); +select * from p; +select * from c1; +select * from c2; + +--connection node_2 +select * from p; +select * from c1; +select * from c2; + +--connection node_1 +drop table c1; +drop table c2; +drop table p; diff --git a/mysql-test/suite/galera/t/galera_fulltext.test b/mysql-test/suite/galera/t/galera_fulltext.test index 19aa4f7a0a0..25f4f83b7b7 100644 --- a/mysql-test/suite/galera/t/galera_fulltext.test +++ b/mysql-test/suite/galera/t/galera_fulltext.test @@ -83,3 +83,27 @@ SELECT COUNT(*) FROM t; --connection node_1 DROP TABLE t; + +# +# Case 2: UTF-8 +# +--connection node_1 +SET @value=REPEAT (1,5001); +CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8; +INSERT IGNORE INTO t VALUES(@value); +SELECT COUNT(*) FROM t; + +--connection node_2 +SELECT COUNT(*) FROM t; + +--connection node_1 +DROP TABLE t; +CREATE TABLE t (a VARCHAR(5000)) engine=innodb DEFAULT CHARSET=utf8; +INSERT IGNORE INTO t VALUES(@value); +SELECT COUNT(*) FROM t; + +--connection node_2 +SELECT COUNT(*) FROM t; + +--connection node_1 +DROP TABLE t; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 00c9595aa87..c17bb219a72 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6750,7 +6750,8 @@ wsrep_innobase_mysql_sort( // Note that strnxfrm may change length of string tmp_length= charset->coll->strnxfrmlen(charset, str_length); - tmp_length= ut_max(str_length, tmp_length) + 1; + tmp_length= tmp_length * charset->mbmaxlen; + tmp_length= ut_max(str_length, tmp_length) + charset->mbmaxlen; tmp_str= static_cast(ut_malloc_nokey(tmp_length)); ut_ad(str_length <= tmp_length); memcpy(tmp_str, str, str_length); -- cgit v1.2.1