Commit 2ba7c517 authored by unknown's avatar unknown
Browse files

Bug#7302: UCS2 data in ENUM field get truncated when new column is added

parent c6b6977b
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -581,3 +581,14 @@ x,y 0078002C0079
z	007A
x,y,z,,,	0078002C0079002C007A002C00E4002C00F6002C00FC
drop table t1;
create table t1(a enum('a','b','c')) default character set ucs2;
insert into t1 values('a'),('b'),('c');
alter table t1 add b char(1);
show warnings;
Level	Code	Message
select * from t1 order by a;
a	b
a	NULL
b	NULL
c	NULL
drop table t1;
+10 −0
Original line number Diff line number Diff line
@@ -374,3 +374,13 @@ insert into t1 values ('x,y');
insert into t1 values ('x,y,z,,,');
select a, hex(a) from t1 order by a;
drop table t1;

#
# Bug#7302 UCS2 data in ENUM fields get truncated when new column is added
#
create table t1(a enum('a','b','c')) default character set ucs2;
insert into t1 values('a'),('b'),('c');
alter table t1 add b char(1);
show warnings;
select * from t1 order by a;
drop table t1;
+1 −0
Original line number Diff line number Diff line
@@ -815,6 +815,7 @@ ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
		   char **err_pos, uint *err_len, bool *set_warning);
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
void unhex_type2(TYPELIB *lib);
uint check_word(TYPELIB *lib, const char *val, const char *end,
		const char **end_of_word);

+37 −0
Original line number Diff line number Diff line
@@ -169,6 +169,43 @@ uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs)
} /* find_type */


/*
  Un-hex all elements in a typelib

  SYNOPSIS
   unhex_type2()
   interval       TYPELIB (struct of pointer to values + lengths + count)

  NOTES

  RETURN
    N/A
*/

void unhex_type2(TYPELIB *interval)
{
  for (uint pos= 0; pos < interval->count; pos++)
  {
    char *from, *to;
    for (from= to= (char*) interval->type_names[pos]; *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;
    }
    interval->type_lengths[pos] /= 2;
  }
}


/*
  Check if the first word in a string is one of the ones in TYPELIB

+1 −19
Original line number Diff line number Diff line
@@ -490,25 +490,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
    {
      /* Unescape UCS2 intervals from HEX notation */
      TYPELIB *interval= outparam->intervals + interval_nr - 1;
      for (uint pos= 0; pos < interval->count; pos++)
      {
        char *from, *to;
        for (from= to= (char*) interval->type_names[pos]; *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;
        }
        interval->type_lengths[pos] /= 2;
      }
      unhex_type2(interval);
    }
    
    *field_ptr=reg_field=
Loading