diff options
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r-- | sql/unireg.cc | 129 |
1 files changed, 88 insertions, 41 deletions
diff --git a/sql/unireg.cc b/sql/unireg.cc index b20e759efbb..c7d2f2f5b5b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -188,27 +188,6 @@ bool mysql_create_frm(THD *thd, const char *file_name, if (key_info[i].parser_name) create_info->extra_size+= key_info[i].parser_name->length + 1; } - - if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo, - create_info, keys)) < 0) - { - my_free(screen_buff, MYF(0)); - DBUG_RETURN(1); - } - - key_buff_length= uint4korr(fileinfo+47); - keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); - key_info_length= pack_keys(keybuff, keys, key_info, data_offset); - (void) get_form_pos(file,fileinfo,&formnames); - if (!(filepos=make_new_entry(file,fileinfo,&formnames,""))) - goto err; - maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); - int2store(forminfo+2,maxlength); - int4store(fileinfo+10,(ulong) (filepos+maxlength)); - fileinfo[26]= (uchar) test((create_info->max_rows == 1) && - (create_info->min_rows == 1) && (keys == 0)); - int2store(fileinfo+28,key_info_length); - /* This gives us the byte-position of the character at (character-position, not byte-position) TABLE_COMMENT_MAXLEN. @@ -222,33 +201,78 @@ bool mysql_create_frm(THD *thd, const char *file_name, string), the string is too long. For additional credit, realise that UTF-8 has 1-3 bytes before 6.0, - and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the - inlined COMMENT supposedly does not exceed 60 character plus - terminator, vulgo, 181 bytes. + and 1-4 bytes in 6.0 (6.0 also has UTF-32). */ - tmp_len= system_charset_info->cset->charpos(system_charset_info, create_info->comment.str, create_info->comment.str + - create_info->comment.length, 60); + create_info->comment.length, + TABLE_COMMENT_MAXLEN); + if (tmp_len < create_info->comment.length) { + char *real_table_name= (char*) table; + List_iterator<Create_field> it(create_fields); + Create_field *field; + while ((field=it++)) + { + if (field->field && field->field->table && + (real_table_name= field->field->table->s->table_name.str)) + break; + } if ((thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), table, tmp_len); - goto err; + my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), + real_table_name, (uint) TABLE_COMMENT_MAXLEN); + my_free(screen_buff,MYF(0)); + DBUG_RETURN(1); } - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_TABLE_COMMENT, - ER(ER_TOO_LONG_TABLE_COMMENT), - table, tmp_len); + char warn_buff[MYSQL_ERRMSG_SIZE]; + my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT), + real_table_name, (uint) TABLE_COMMENT_MAXLEN); + /* do not push duplicate warnings */ + if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_TABLE_COMMENT, warn_buff); create_info->comment.length= tmp_len; } + /* + If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes, + store the comment in an extra segment (up to TABLE_COMMENT_MAXLEN bytes). + Pre 6.0, the limit was 60 characters, with no extra segment-handling. + */ + if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN) + { + forminfo[46]=255; + create_info->extra_size+= 2 + create_info->comment.length; + } + else{ + strmake((char*) forminfo+47, create_info->comment.str ? + create_info->comment.str : "", create_info->comment.length); + forminfo[46]=(uchar) create_info->comment.length; + } + + if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo, + create_info, keys, key_info)) < 0) + { + my_free(screen_buff, MYF(0)); + DBUG_RETURN(1); + } + + key_buff_length= uint4korr(fileinfo+47); + keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); + key_info_length= pack_keys(keybuff, keys, key_info, data_offset); + (void) get_form_pos(file,fileinfo,&formnames); + if (!(filepos=make_new_entry(file,fileinfo,&formnames,""))) + goto err; + maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); + int2store(forminfo+2,maxlength); + int4store(fileinfo+10,(ulong) (filepos+maxlength)); + fileinfo[26]= (uchar) test((create_info->max_rows == 1) && + (create_info->min_rows == 1) && (keys == 0)); + int2store(fileinfo+28,key_info_length); - strmake((char*) forminfo+47, create_info->comment.str ? - create_info->comment.str : "", create_info->comment.length); - forminfo[46]=(uchar) create_info->comment.length; #ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) { @@ -309,6 +333,15 @@ bool mysql_create_frm(THD *thd, const char *file_name, goto err; } } + if (forminfo[46] == (uchar)255) + { + uchar comment_length_buff[2]; + int2store(comment_length_buff,create_info->comment.length); + if (mysql_file_write(file, comment_length_buff, 2, MYF(MY_NABP)) || + mysql_file_write(file, (uchar*) create_info->comment.str, + create_info->comment.length, MYF(MY_NABP))) + goto err; + } mysql_file_seek(file, filepos, MY_SEEK_SET, MYF(0)); if (mysql_file_write(file, forminfo, 288, MYF_RW) || @@ -561,6 +594,16 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, pos=tmp; } *(pos++)=0; + for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++) + { + if (key->flags & HA_USES_COMMENT) + { + int2store(pos, key->comment.length); + uchar *tmp= (uchar*)strnmov((char*) pos+2,key->comment.str, + key->comment.length); + pos= tmp; + } + } if (key_count > 127 || key_parts > 127) { @@ -614,19 +657,23 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, field->comment.str, field->comment.str + field->comment.length, - 255); + COLUMN_COMMENT_MAXLEN); if (tmp_len < field->comment.length) { if ((current_thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, tmp_len); + my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), + field->field_name, (uint) COLUMN_COMMENT_MAXLEN); DBUG_RETURN(1); } - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_FIELD_COMMENT, - ER(ER_TOO_LONG_FIELD_COMMENT), - field->field_name, tmp_len); + char warn_buff[MYSQL_ERRMSG_SIZE]; + my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_FIELD_COMMENT), + field->field_name, (uint) COLUMN_COMMENT_MAXLEN); + /* do not push duplicate warnings */ + if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_FIELD_COMMENT, warn_buff); field->comment.length= tmp_len; } |