summaryrefslogtreecommitdiff
path: root/sql/unireg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r--sql/unireg.cc89
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();