summaryrefslogtreecommitdiff
path: root/sql/unireg.cc
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2010-02-20 13:07:32 +0300
committerAlexander Nozdrin <alik@sun.com>2010-02-20 13:07:32 +0300
commit7c10a8981ce3f5eff59e0f3a73e4f0ad176f8c90 (patch)
treec7e57caf2dddf80f1b45617e4a1bac400e4e880a /sql/unireg.cc
parent7ba05466208a5d32d7518152a84754892cf435e9 (diff)
downloadmariadb-git-7c10a8981ce3f5eff59e0f3a73e4f0ad176f8c90.tar.gz
Patch for WL#3736: Extended Table, Column and Index Comments.
The task is to (a) add a comment on indexes and (b) increase the maximum length of column, table and the new index comments. The patch committed on behalf of Yoshinori Matsunobu (Yoshinori.Matsunobu@Sun.COM).
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r--sql/unireg.cc129
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;
}