diff options
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r-- | sql/unireg.cc | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/sql/unireg.cc b/sql/unireg.cc index a080de489e9..c55d6db3c85 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -83,7 +82,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, uchar fileinfo[64],forminfo[288],*keybuff; TYPELIB formnames; uchar *screen_buff; - char buff[32]; + char buff[128]; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; #endif @@ -176,7 +175,6 @@ bool mysql_create_frm(THD *thd, const char *file_name, create_info->comment.length, 60); if (tmp_len < create_info->comment.length) { - char buff[128]; (void) my_snprintf(buff, sizeof(buff), "Too long comment for table '%s'", table); if ((thd->variables.sql_mode & @@ -552,11 +550,11 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, create_field *field; while ((field=it++)) { - uint tmp_len= system_charset_info->cset->charpos(system_charset_info, field->comment.str, field->comment.str + - field->comment.length, 255); + field->comment.length, + 255); if (tmp_len < field->comment.length) { char buff[128]; @@ -586,7 +584,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE as auto-update field. */ - if (field->sql_type == FIELD_TYPE_TIMESTAMP && + if (field->sql_type == MYSQL_TYPE_TIMESTAMP && MTYP_TYPENR(field->unireg_check) != Field::NONE && !time_stamp_pos) time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1; @@ -625,8 +623,9 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, for (uint pos= 0; pos < field->interval->count; pos++) { char *dst; - uint length= field->save_interval->type_lengths[pos], hex_length; const char *src= field->save_interval->type_names[pos]; + uint hex_length; + length= field->save_interval->type_lengths[pos]; hex_length= length * 2; field->interval->type_lengths[pos]= hex_length; field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1); @@ -745,7 +744,7 @@ static bool pack_fields(File file, List<create_field> &create_fields, int2store(buff+10,field->unireg_check); buff[12]= (uchar) field->interval_id; buff[13]= (uchar) field->sql_type; - if (field->sql_type == FIELD_TYPE_GEOMETRY) + if (field->sql_type == MYSQL_TYPE_GEOMETRY) { buff[14]= (uchar) field->geom_type; #ifndef HAVE_SPATIAL @@ -791,29 +790,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)) @@ -897,7 +915,10 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, field->interval, field->field_name); if (!regfield) + { + error= 1; goto err; // End of memory + } /* save_in_field() will access regfield->table->in_use */ regfield->init(&table); @@ -908,13 +929,13 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, null_count++; } - if (field->sql_type == FIELD_TYPE_BIT && !f_bit_as_char(field->pack_flag)) + if (field->sql_type == MYSQL_TYPE_BIT && !f_bit_as_char(field->pack_flag)) null_count+= field->length & 7; type= (Field::utype) MTYP_TYPENR(field->unireg_check); if (field->def && - (regfield->real_type() != FIELD_TYPE_YEAR || + (regfield->real_type() != MYSQL_TYPE_YEAR || field->def->val_int() != 0)) { if (field->def->save_in_field(regfield, 1)) @@ -925,7 +946,7 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, goto err; } } - else if (regfield->real_type() == FIELD_TYPE_ENUM && + else if (regfield->real_type() == MYSQL_TYPE_ENUM && (field->flags & NOT_NULL_FLAG)) { regfield->set_notnull(); |