Commit 0f50a8a7 authored by unknown's avatar unknown
Browse files

Fixed bug #20108.

Any default value for a enum fields over UCS2 charsets was corrupted
when we put it into the frm file, as it had been overwritten by its
HEX representation.
To fix it now we save a copy of structure that represents the enum
type and when putting the default values we use this copy. 


mysql-test/r/ctype_ucs.result:
  Added a test case for bug #20108.
mysql-test/t/ctype_ucs.test:
  Added a test case for bug #20108.
parent 903fc561
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -747,6 +747,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
export_set(5, name, upper(name), ",", 5)
test1,TEST1,test1,TEST1,TEST1
'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
CREATE TABLE t1 (
status enum('active','passive') collate latin1_general_ci 
NOT NULL default 'passive'
);
SHOW CREATE TABLE t1;
Table	Create Table
t1	CREATE TABLE `t1` (
  `status` enum('active','passive') character set latin1 collate latin1_general_ci NOT NULL default 'passive'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t1 ADD a int NOT NULL AFTER status;
CREATE TABLE t2 (
status enum('active','passive') collate ucs2_turkish_ci 
NOT NULL default 'passive'
);
SHOW CREATE TABLE t2;
Table	Create Table
t2	CREATE TABLE `t2` (
  `status` enum('active','passive') character set ucs2 collate ucs2_turkish_ci NOT NULL default 'passive'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t2 ADD a int NOT NULL AFTER status;
DROP TABLE t1,t2;
select password(name) from bug20536;
password(name)
????????????????????
+21 −0
Original line number Diff line number Diff line
@@ -482,6 +482,27 @@ select make_set(3, name, upper(name)) from bug20536;
select export_set(5, name, upper(name)) from bug20536;
select export_set(5, name, upper(name), ",", 5) from bug20536;

#
# Bug #20108: corrupted default enum value for a ucs2 field              
#

CREATE TABLE t1 (
  status enum('active','passive') collate latin1_general_ci 
    NOT NULL default 'passive'
);
SHOW CREATE TABLE t1;
ALTER TABLE t1 ADD a int NOT NULL AFTER status; 

CREATE TABLE t2 (
  status enum('active','passive') collate ucs2_turkish_ci 
    NOT NULL default 'passive'
);
SHOW CREATE TABLE t2;
ALTER TABLE t2 ADD a int NOT NULL AFTER status; 

DROP TABLE t1,t2;


# Some broken functions:  add these tests just to document current behavior.

# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
+2 −0
Original line number Diff line number Diff line
@@ -1192,6 +1192,8 @@ class create_field :public Sql_alloc {
  uint decimals,flags,pack_length;
  Field::utype unireg_check;
  TYPELIB *interval;			// Which interval to use
  TYPELIB *save_interval;               // Temporary copy for the above
                                        // Used only for UCS2 intervals
  List<String> interval_list;
  CHARSET_INFO *charset;
  Field::geometry_type geom_type;
+32 −7
Original line number Diff line number Diff line
@@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name,
    goto err3;

  {
    /* Unescape all UCS2 intervals: were escaped in pack_headers */
    /* 
      Restore all UCS2 intervals.
      HEX representation of them is not needed anymore.
    */
    List_iterator<create_field> it(create_fields);
    create_field *field;
    while ((field=it++))
    {
      if (field->interval && field->charset->mbminlen > 1)
        unhex_type2(field->interval);
      if (field->save_interval)
      {
        field->interval= field->save_interval;
        field->save_interval= 0;
      }
    }
  }
  DBUG_RETURN(0);
@@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
      reclength=(uint) (field->offset+ data_offset + length);
    n_length+= (ulong) strlen(field->field_name)+1;
    field->interval_id=0;
    field->save_interval= 0;
    if (field->interval)
    {
      uint old_int_count=int_count;

      if (field->charset->mbminlen > 1)
      {
        /* Escape UCS2 intervals using HEX notation */
        /* 
          Escape UCS2 intervals using HEX notation to avoid
          problems with delimiters between enum elements.
          As the original representation is still needed in 
          the function make_empty_rec to create a record of
          filled with default values it is saved in save_interval
          The HEX representation is created from this copy.
        */
        field->save_interval= field->interval;
        field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB));
        *field->interval= *field->save_interval; 
        field->interval->type_names= 
          (const char **) sql_alloc(sizeof(char*) * 
				    (field->interval->count+1));
        field->interval->type_names[field->interval->count]= 0;
        field->interval->type_lengths=
          (uint *) sql_alloc(sizeof(uint) * field->interval->count);
 
        for (uint pos= 0; pos < field->interval->count; pos++)
        {
          char *dst;
          uint length= field->interval->type_lengths[pos], hex_length;
          const char *src= field->interval->type_names[pos];
          uint length= field->save_interval->type_lengths[pos], hex_length;
          const char *src= field->save_interval->type_names[pos];
          const char *srcend= src + length;
          hex_length= length * 2;
          field->interval->type_lengths[pos]= hex_length;
@@ -715,6 +739,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
			       field->charset,
			       field->geom_type,
			       field->unireg_check,
			       field->save_interval ? field->save_interval :
                               field->interval, 
			       field->field_name,
			       &table);