diff options
author | unknown <bar@mysql.com> | 2004-12-21 17:12:27 +0400 |
---|---|---|
committer | unknown <bar@mysql.com> | 2004-12-21 17:12:27 +0400 |
commit | 2ba7c517a48a670cad22c1282f6a74903db80e99 (patch) | |
tree | 08f36b11c00064e38be98e5ac2f6e7587f8d8a13 /sql | |
parent | c6b6977b9ee65258eef6f55a17fea8c68dcf1a0d (diff) | |
download | mariadb-git-2ba7c517a48a670cad22c1282f6a74903db80e99.tar.gz |
Bug#7302: UCS2 data in ENUM field get truncated when new column is added
Diffstat (limited to 'sql')
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/strfunc.cc | 37 | ||||
-rw-r--r-- | sql/table.cc | 20 | ||||
-rw-r--r-- | sql/unireg.cc | 11 |
4 files changed, 50 insertions, 19 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c90935f4cf9..c300ea2885e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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); diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 8ab6992a63a..3ad6b1155d1 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -170,6 +170,43 @@ uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs) /* + 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 SYNOPSIS diff --git a/sql/table.cc b/sql/table.cc index 992f6df0401..7adca2a5ab0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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= diff --git a/sql/unireg.cc b/sql/unireg.cc index 6d72c6af135..a550b06a466 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -174,6 +174,17 @@ bool mysql_create_frm(THD *thd, my_string file_name, goto err2; if (my_close(file,MYF(MY_WME))) goto err3; + + { + /* Unescape all UCS2 intervals: were escaped in pack_headers */ + List_iterator<create_field> it(create_fields); + create_field *field; + while ((field=it++)) + { + if (field->interval && field->charset->mbminlen > 1) + unhex_type2(field->interval); + } + } DBUG_RETURN(0); err: |