Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.4
-
None
Description
I apply this patch:
--- a/storage/innobase/rem/rem0cmp.cc
|
+++ b/storage/innobase/rem/rem0cmp.cc
|
@@ -326,8 +326,11 @@ static int cmp_whole_field(ulint mtype, ulint prtype, |
DBUG_ASSERT(is_strnncoll_compatible(prtype & DATA_MYSQL_TYPE_MASK));
|
if (CHARSET_INFO *cs= get_charset(dtype_get_charset_coll(prtype), |
MYF(MY_WME)))
|
+ {
|
+ DBUG_ASSERT(a_length == b_length || cs->mbminlen != cs->mbmaxlen);
|
return cs->coll->strnncollsp_nchars(cs, a, a_length, b, b_length, |
std::max(a_length, b_length)); |
+ }
|
}
|
The idea of the assert is to prove that InnoDB for the CHAR(N) data type:
- performs trailing space compression for variable length encodings (e.g. utf8)
- does not perform trailing space compression for fixed length encodings (e.g. latin1)
Then I run this script:
drop table if exists t2,t1; |
create table t1 (a int primary key,s1 varchar(2) character set latin1 collate latin1_bin not null unique) engine=innodb; |
create table t2 (s1 char(2) character set latin1 collate latin1_bin not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb; |
insert into t1 values(1,0x4100),(2,0x41); |
insert into t2 values(0x41); |
the server crashes on the new assert when doing the insert into t2.
Tracing in gdb show that the lengths are different indeed:
(gdb) p a_length
|
$1 = 2
|
(gdb) p b_length
|
$2 = 1
|
If I change the collation from latin1_bin to latin1_german1_ci:
drop table if exists t2,t1; |
create table t1 (a int primary key,s1 varchar(2) character set latin1 collate latin1_german1_ci not null unique) engine=innodb; |
create table t2 (s1 char(2) character set latin1 collate latin1_german1_ci not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb; |
insert into t1 values(1,0x4100),(2,0x41); |
insert into t2 values(0x41); |
it does not crash.
Tracing the same place shows that lengths are equal:
(gdb) p a_length
|
$3 = 2
|
(gdb) p b_length
|
$4 = 2
|
This looks suspicious. The two collations should work symmetrically in this context.
- latin1_bin behaviour does not seem to be expected
- latin1_german1_ci seems to work fine