Commit 4017a533 authored by unknown's avatar unknown

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 73d1a44b
...@@ -747,6 +747,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536; ...@@ -747,6 +747,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
export_set(5, name, upper(name), ",", 5) export_set(5, name, upper(name), ",", 5)
test1,TEST1,test1,TEST1,TEST1 test1,TEST1,test1,TEST1,TEST1
'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2' '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; select password(name) from bug20536;
password(name) password(name)
???????????????????? ????????????????????
......
...@@ -482,6 +482,27 @@ select make_set(3, name, upper(name)) from bug20536; ...@@ -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)) from bug20536;
select export_set(5, name, upper(name), ",", 5) 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. # 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 # PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
......
...@@ -1192,6 +1192,8 @@ class create_field :public Sql_alloc { ...@@ -1192,6 +1192,8 @@ class create_field :public Sql_alloc {
uint decimals,flags,pack_length; uint decimals,flags,pack_length;
Field::utype unireg_check; Field::utype unireg_check;
TYPELIB *interval; // Which interval to use TYPELIB *interval; // Which interval to use
TYPELIB *save_interval; // Temporary copy for the above
// Used only for UCS2 intervals
List<String> interval_list; List<String> interval_list;
CHARSET_INFO *charset; CHARSET_INFO *charset;
Field::geometry_type geom_type; Field::geometry_type geom_type;
......
...@@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name, ...@@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name,
goto err3; 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); List_iterator<create_field> it(create_fields);
create_field *field; create_field *field;
while ((field=it++)) while ((field=it++))
{ {
if (field->interval && field->charset->mbminlen > 1) if (field->save_interval)
unhex_type2(field->interval); {
field->interval= field->save_interval;
field->save_interval= 0;
}
} }
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, ...@@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
reclength=(uint) (field->offset+ data_offset + length); reclength=(uint) (field->offset+ data_offset + length);
n_length+= (ulong) strlen(field->field_name)+1; n_length+= (ulong) strlen(field->field_name)+1;
field->interval_id=0; field->interval_id=0;
field->save_interval= 0;
if (field->interval) if (field->interval)
{ {
uint old_int_count=int_count; uint old_int_count=int_count;
if (field->charset->mbminlen > 1) 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++) for (uint pos= 0; pos < field->interval->count; pos++)
{ {
char *dst; char *dst;
uint length= field->interval->type_lengths[pos], hex_length; uint length= field->save_interval->type_lengths[pos], hex_length;
const char *src= field->interval->type_names[pos]; const char *src= field->save_interval->type_names[pos];
const char *srcend= src + length; const char *srcend= src + length;
hex_length= length * 2; hex_length= length * 2;
field->interval->type_lengths[pos]= hex_length; field->interval->type_lengths[pos]= hex_length;
...@@ -715,7 +739,8 @@ static bool make_empty_rec(File file,enum db_type table_type, ...@@ -715,7 +739,8 @@ static bool make_empty_rec(File file,enum db_type table_type,
field->charset, field->charset,
field->geom_type, field->geom_type,
field->unireg_check, field->unireg_check,
field->interval, field->save_interval ? field->save_interval :
field->interval,
field->field_name, field->field_name,
&table); &table);
......
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