diff options
author | unknown <tnurnberg@mysql.com/sin.azundris.com> | 2007-01-12 11:06:38 +0100 |
---|---|---|
committer | unknown <tnurnberg@mysql.com/sin.azundris.com> | 2007-01-12 11:06:38 +0100 |
commit | cf0857d08c94d705b21dd014573eb19c6c4beca5 (patch) | |
tree | 2a6537cfb59459e1428a4f2b576e337cff6c429a /sql/unireg.cc | |
parent | 84e8991666227a538f38d99548ab27f21a38fbf2 (diff) | |
download | mariadb-git-cf0857d08c94d705b21dd014573eb19c6c4beca5.tar.gz |
Bug#24660: "enum" field type definition problem
ENUMs weren't allowed to have character 0xff, a perfectly good
character in some locales. This was circumvented by mapping 0xff in
ENUMs to ',', thereby prevent actual commas from being used. Now if
0xff makes an appearance, we find a character not used in the enum and
use that as a separator. If no such character exists, we throw an
error.
Any solution would have broken some sort of existing behaviour. This
solution should serve both fractions (those with 0xff and those with
',' in their enums), but WILL REQUIRE A DUMP/RESTORE CYCLE FROM THOSE
WITH 0xff IN THEIR ENUMS. :-/ That is, mysqldump with their current
server, and restore when upgrading to one with this patch.
mysql-test/r/type_enum.result:
Bug#24660: "enum" field type definition problem
Show that enums can now contain NAMES_SEP_CHAR (0xff, which is a perfectly respectable
char in some locales), or ',', or both.
mysql-test/t/type_enum.test:
Bug#24660: "enum" field type definition problem
Show that enums can now contain NAMES_SEP_CHAR (0xff, which is a perfectly respectable
char in some locales), or ',', or both.
sql/table.cc:
Bug#24660: "enum" field type definition problem
Revert fix for Bug#20922.
sql/unireg.cc:
Bug#24660: "enum" field type definition problem
Use a field-separator for ENUM-values that is not part of those values. If impossible,
throw error.
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r-- | sql/unireg.cc | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/sql/unireg.cc b/sql/unireg.cc index 2699cafa7b7..b1c29c885d9 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -788,29 +788,48 @@ static bool pack_fields(File file, List<create_field> &create_fields, { if (field->interval_id > int_count) { - int_count=field->interval_id; - tmp.append(NAMES_SEP_CHAR); - for (const char **pos=field->interval->type_names ; *pos ; pos++) - { - char *val= (char*) *pos; - uint str_len= strlen(val); - /* - Note, hack: in old frm NAMES_SEP_CHAR is used to separate - names in the interval (ENUM/SET). To allow names to contain - NAMES_SEP_CHAR, we replace it with a comma before writing frm. - Backward conversion is done during frm file opening, - See table.cc, openfrm() function - */ - for (uint cnt= 0 ; cnt < str_len ; cnt++) + unsigned char sep= 0; + unsigned char occ[256]; + uint i; + unsigned char *val= NULL; + + bzero(occ, sizeof(occ)); + + for (i=0; (val= (unsigned char*) field->interval->type_names[i]); i++) + for (uint j = 0; j < field->interval->type_lengths[i]; j++) + occ[(unsigned int) (val[j])]= 1; + + if (!occ[(unsigned char)NAMES_SEP_CHAR]) + sep= (unsigned char) NAMES_SEP_CHAR; + else if (!occ[(unsigned int)',']) + sep= ','; + else + { + for (uint i=1; i<256; i++) + { + if(!occ[i]) + { + sep= i; + break; + } + } + + if(!sep) /* disaster, enum uses all characters, none left as separator */ { - char c= val[cnt]; - if (c == NAMES_SEP_CHAR) - val[cnt]= ','; + my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS), + MYF(0)); + DBUG_RETURN(1); } - tmp.append(*pos); - tmp.append(NAMES_SEP_CHAR); - } - tmp.append('\0'); // End of intervall + } + + int_count= field->interval_id; + tmp.append(sep); + for (const char **pos=field->interval->type_names ; *pos ; pos++) + { + tmp.append(*pos); + tmp.append(sep); + } + tmp.append('\0'); // End of intervall } } if (my_write(file,(byte*) tmp.ptr(),tmp.length(),MYF_RW)) |