Bug #7066 "ctype_ucs" fails on SGI IRIX
Submitted: 7 Dec 2004 10:36 Modified: 7 Dec 2004 13:14
Reporter: Lenz Grimmer Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:4.1.8-pre OS:SGI IRIX 6.5
Assigned to: Alexander Barkov CPU Architecture:Any

[7 Dec 2004 10:36] Lenz Grimmer
Description:
When running the test suite on SGI IRIX, the "ctype_ucs" test fails with the following diff (some of the special chars might be mangled):

TEST                            RESULT
-------------------------------------------------------
ctype_ucs                      [ fail ]

Errors are (from /usr/people/mysqldev/octane2/test/mysql-debug-4.1.8-sgi-irix6.5-mips/mysql-test/var/log/mysqltest-time) :
/usr/people/mysqldev/octane2/test/mysql-debug-4.1.8-sgi-irix6.5-mips/bin/mysqltest: At line 377: Result length mismatch
(the last lines may be the most important ones)
Below are the diffs between actual and expected results:
-------------------------------------------------------
*** r/ctype_ucs.result  Tue Dec  7 06:00:39 2004
--- r/ctype_ucs.reject  Tue Dec  7 13:33:33 2004
***************
*** 530,583 ****
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` enum('x','y','z') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('x');
  insert into t1 values ('y');
  insert into t1 values ('z');
  select a, hex(a) from t1 order by a;
  a     hex(a)
! x     0078
! y     0079
! z     007A
  alter table t1 change a a enum('x','y','z','d','e','ä','ö','ü') character set ucs2;
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` enum('x','y','z','d','e','ä','ö','ü') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('D');
  insert into t1 values ('E ');
  insert into t1 values ('Ä');
  insert into t1 values ('Ö');
  insert into t1 values ('Ü');
  select a, hex(a) from t1 order by a;
  a     hex(a)
! x     0078
! y     0079
! z     007A
! d     0064
! e     0065
! ä     00E4
! ö     00F6
! ü     00FC
  drop table t1;
  create table t1 (a set ('x','y','z','ä','ö','ü') character set ucs2);
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` set('x','y','z','ä','ö','ü') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('x');
  insert into t1 values ('y');
  insert into t1 values ('z');
  insert into t1 values ('x,y');
  insert into t1 values ('x,y,z,Ä,Ö,Ü');
  select a, hex(a) from t1 order by a;
  a     hex(a)
! x     0078
! y     0079
! x,y   0078002C0079
! z     007A
! x,y,z,ä,ö,ü   0078002C0079002C007A002C00E4002C00F6002C00FC
  drop table t1;
--- 530,605 ----
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` enum('?','?','ª') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('x');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('y');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('z');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  select a, hex(a) from t1 order by a;
  a     hex(a)
!
!
!
  alter table t1 change a a enum('x','y','z','d','e','ä','ö','ü') character set ucs2;
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` enum('?','?','ª','D','U','D','f','Ì') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('D');
  insert into t1 values ('E ');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('Ä');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('Ö');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('Ü');
  select a, hex(a) from t1 order by a;
  a     hex(a)
!
!
!
!
!
!
! D     0044
! U     0055
  drop table t1;
  create table t1 (a set ('x','y','z','ä','ö','ü') character set ucs2);
  show create table t1;
  Table Create Table
  t1    CREATE TABLE `t1` (
!   `a` set('?','?','ª','D','f','Ì') character set ucs2 default NULL
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
  insert into t1 values ('x');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('y');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('z');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('x,y');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  insert into t1 values ('x,y,z,Ä,Ö,Ü');
+ Warnings:
+ Warning       1265    Data truncated for column 'a' at row 1
  select a, hex(a) from t1 order by a;
  a     hex(a)
!
!
!
!
!
  drop table t1;
-------------------------------------------------------

How to repeat:
Run the ctype_ucs test and observe the diff.
[7 Dec 2004 13:05] Alexander Barkov
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

Fixed in 4.1.8.
[7 Dec 2004 13:14] Alexander Barkov
The reason of the problem seems to be a bug in IRIX compiler.

This is the fix:

-          *to++= (char) (hexchar_to_int(*from++) << 4) + 
-                         hexchar_to_int(*from++);
+          /*
+            Note, hexchar_to_int(*from++) doesn't work
+            one some compilers, e.g. IRIX. Looks like a compiler
+            bug in inline functions in combination with arguments
+            that have a side effect. So, let's use from[0] and from[1]
+            and increment 'from' by two later.
+          */
+
+          *to++= (char) (hexchar_to_int(from[0]) << 4) +
+                         hexchar_to_int(from[1]);
+          from+= 2;

And this is the function declaration:

inline int hexchar_to_int(char c)
{
  if (c <= '9' && c >= '0')
    return c-'0';
  c|=32;
  if (c <= 'f' && c >= 'a')
    return c-'a'+10;
  return -1;
}