summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc88
1 files changed, 69 insertions, 19 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 514ea865e8c..0e66ff9da94 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -517,7 +517,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
int error, table_type;
bool error_given;
File file;
- uchar head[288], *disk_buff;
+ uchar head[64], *disk_buff;
char path[FN_REFLEN];
MEM_ROOT **root_ptr, *old_root;
DBUG_ENTER("open_table_def");
@@ -660,6 +660,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos;
+ uchar forminfo[288];
uchar *record;
uchar *disk_buff, *strpos, *null_flags, *null_pos;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
@@ -682,6 +683,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
goto err; /* purecov: inspected */
+ mysql_file_seek(file,pos,MY_SEEK_SET,MYF(0));
+ if (mysql_file_read(file, forminfo,288,MYF(MY_NABP)))
+ goto err;
share->frm_version= head[2];
/*
Check if .frm file created by MySQL 5.0. In this case we want to
@@ -827,6 +831,20 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
keynames=(char*) key_part;
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
+ //reading index comments
+ for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
+ {
+ if (keyinfo->flags & HA_USES_COMMENT)
+ {
+ keyinfo->comment.length= uint2korr(strpos);
+ keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
+ keyinfo->comment.length);
+ strpos+= 2 + keyinfo->comment.length;
+ }
+ DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) ==
+ (keyinfo->comment.length > 0));
+ }
+
share->reclength = uint2korr((head+16));
if (*(head+26) == 1)
share->system= 1; /* one-record-database */
@@ -1007,6 +1025,25 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
}
}
}
+ if (forminfo[46] == (uchar)255)
+ {
+ //reading long table comment
+ if (next_chunk + 2 > buff_end)
+ {
+ DBUG_PRINT("error",
+ ("long table comment is not defined in .frm"));
+ my_free(buff, MYF(0));
+ goto err;
+ }
+ share->comment.length = uint2korr(next_chunk);
+ if (! (share->comment.str= strmake_root(&share->mem_root,
+ (char*)next_chunk + 2, share->comment.length)))
+ {
+ my_free(buff, MYF(0));
+ goto err;
+ }
+ next_chunk+= 2 + share->comment.length;
+ }
my_free(buff, MYF(0));
}
share->key_block_size= uint2korr(head+62);
@@ -1023,29 +1060,30 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
record_offset, MYF(MY_NABP)))
goto err; /* purecov: inspected */
- mysql_file_seek(file, pos, MY_SEEK_SET, MYF(0));
- if (mysql_file_read(file, head, 288, MYF(MY_NABP)))
- goto err;
+ mysql_file_seek(file, pos+288, MY_SEEK_SET, MYF(0));
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
- crypted->decode((char*) head+256,288-256);
- if (sint2korr(head+284) != 0) // Should be 0
+ crypted->decode((char*) forminfo+256,288-256);
+ if (sint2korr(forminfo+284) != 0) // Should be 0
goto err; // Wrong password
}
#endif
- share->fields= uint2korr(head+258);
- pos= uint2korr(head+260); /* Length of all screens */
- n_length= uint2korr(head+268);
- interval_count= uint2korr(head+270);
- interval_parts= uint2korr(head+272);
- int_length= uint2korr(head+274);
- share->null_fields= uint2korr(head+282);
- com_length= uint2korr(head+284);
- share->comment.length= (int) (head[46]);
- share->comment.str= strmake_root(&share->mem_root, (char*) head+47,
- share->comment.length);
+ share->fields= uint2korr(forminfo+258);
+ pos= uint2korr(forminfo+260); /* Length of all screens */
+ n_length= uint2korr(forminfo+268);
+ interval_count= uint2korr(forminfo+270);
+ interval_parts= uint2korr(forminfo+272);
+ int_length= uint2korr(forminfo+274);
+ share->null_fields= uint2korr(forminfo+282);
+ com_length= uint2korr(forminfo+284);
+ if (forminfo[46] != (uchar)255)
+ {
+ share->comment.length= (int) (forminfo[46]);
+ share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
+ share->comment.length);
+ }
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length));
@@ -2437,12 +2475,14 @@ void append_unescaped(String *res, const char *pos, uint length)
File create_frm(THD *thd, const char *name, const char *db,
const char *table, uint reclength, uchar *fileinfo,
- HA_CREATE_INFO *create_info, uint keys)
+ HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
{
register File file;
ulong length;
uchar fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
+ ulong key_comment_total_bytes= 0;
+ uint i;
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
@@ -2479,7 +2519,17 @@ File create_frm(THD *thd, const char *name, const char *db,
1 byte for the NAMES_SEP_CHAR (after the last name)
9 extra bytes (padding for safety? alignment?)
*/
- key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16;
+ for (i= 0; i < keys; i++)
+ {
+ DBUG_ASSERT(test(key_info[i].flags & HA_USES_COMMENT) ==
+ (key_info[i].comment.length > 0));
+ if (key_info[i].flags & HA_USES_COMMENT)
+ key_comment_total_bytes += 2 + key_info[i].comment.length;
+ }
+
+ key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16
+ + key_comment_total_bytes;
+
length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
create_info->extra_size));
int4store(fileinfo+10,length);