Commit f5547706 authored by Jan Lindström's avatar Jan Lindström

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.
parent 99f6a266
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;
......@@ -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;
--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;
......@@ -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;
......@@ -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<uchar *>(ut_malloc_nokey(tmp_length));
ut_ad(str_length <= tmp_length);
memcpy(tmp_str, str, str_length);
......
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