summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2004-12-21 17:12:27 +0400
committerunknown <bar@mysql.com>2004-12-21 17:12:27 +0400
commit2ba7c517a48a670cad22c1282f6a74903db80e99 (patch)
tree08f36b11c00064e38be98e5ac2f6e7587f8d8a13 /sql
parentc6b6977b9ee65258eef6f55a17fea8c68dcf1a0d (diff)
downloadmariadb-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.h1
-rw-r--r--sql/strfunc.cc37
-rw-r--r--sql/table.cc20
-rw-r--r--sql/unireg.cc11
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: