diff options
author | unknown <monty@hundin.mysql.fi> | 2002-10-16 19:30:24 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-10-16 19:30:24 +0300 |
commit | b3cb7b7f7742f691c9a14598e455b4ecb96f07e1 (patch) | |
tree | fd68b42f3c1b7e47b36b19209daf540c3a0c7a68 /sql/table.cc | |
parent | 6f38e3083f0d867af8d1499fba92c7eaae295726 (diff) | |
parent | aee5ef8516ce0599402ca8e8a6b72f3eca36739b (diff) | |
download | mariadb-git-b3cb7b7f7742f691c9a14598e455b4ecb96f07e1.tar.gz |
merge with 4.0.5
BitKeeper/etc/logging_ok:
auto-union
configure.in:
Auto merged
Docs/manual.texi:
Auto merged
myisam/mi_open.c:
Auto merged
mysql-test/r/null_key.result:
Auto merged
mysql-test/r/select.result:
Auto merged
sql/field.h:
Auto merged
sql/field_conv.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/log.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/table.cc:
Auto merged
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/sql/table.cc b/sql/table.cc index d3b719c553d..122cce160b6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -47,19 +47,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; - uint key_info_length; + uint key_info_length, com_length; ulong pos; - char index_file[FN_REFLEN], *names,*keynames; + char index_file[FN_REFLEN], *names, *keynames, *comment_pos; uchar head[288],*disk_buff,new_field_pack_flag; my_string record; const char **int_array; - bool new_frm_ver,use_hash, null_field_first; + bool use_hash, null_field_first; File file; Field **field_ptr,*reg_field; KEY *keyinfo; KEY_PART_INFO *key_part; uchar *null_pos; - uint null_bit; + uint null_bit, new_frm_ver, field_pack_length; SQL_CRYPT *crypted=0; DBUG_ENTER("openfrm"); DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam)); @@ -95,10 +95,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open; if (head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) goto err_not_open; /* purecov: inspected */ new_field_pack_flag=head[27]; - new_frm_ver= (head[2] == FRM_VER+1); + new_frm_ver= (head[2] - FRM_VER); + field_pack_length= new_frm_ver < 2 ? 11 : 15; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) @@ -116,6 +117,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->raid_type= head[41]; outparam->raid_chunks= head[42]; outparam->raid_chunksize= uint4korr(head+43); + if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0)))) + outparam->table_charset=NULL; // QQ display error message? null_field_first=1; } outparam->db_record_offset=1; @@ -153,9 +156,23 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (i=0 ; i < keys ; i++, keyinfo++) { - keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; - keyinfo->key_length= (uint) uint2korr(strpos+1); - keyinfo->key_parts= (uint) strpos[3]; strpos+=4; + if (new_frm_ver == 2) + { + keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+2); + keyinfo->key_parts= (uint) strpos[4]; + keyinfo->algorithm= (enum ha_key_alg) strpos[5]; + strpos+=8; + } + else + { + keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+1); + keyinfo->key_parts= (uint) strpos[3]; + keyinfo->algorithm= HA_KEY_ALG_UNDEF; + strpos+=4; + } + keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->key_parts ; j-- ; key_part++) @@ -165,7 +182,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, key_part->offset= (uint) uint2korr(strpos+2)-1; key_part->key_type= (uint) uint2korr(strpos+5); // key_part->field= (Field*) 0; // Will be fixed later - if (new_frm_ver) + if (new_frm_ver >= 1) { key_part->key_part_flag= *(strpos+4); key_part->length= (uint) uint2korr(strpos+7); @@ -191,15 +208,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; - /* Test if new 4.0 format */ - if ((uint) (strpos - disk_buff) < key_info_length) - { - /* Read key types */ - keyinfo=outparam->key_info; - for (i=0 ; i < keys ; i++, keyinfo++) - keyinfo->algorithm= (enum ha_key_alg) *(strpos++); - } - outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -267,10 +275,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_parts=uint2korr(head+272); int_length=uint2korr(head+274); outparam->null_fields=uint2korr(head+282); + com_length=uint2korr(head+284); outparam->comment=strdup_root(&outparam->mem_root, (char*) head+47); - DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_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, outparam->keys,n_length,int_length, com_length)); if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, @@ -278,12 +287,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_count*sizeof(TYPELIB)+ (outparam->fields+interval_parts+ keys+3)*sizeof(my_string)+ - (n_length+int_length))))) + (n_length+int_length+com_length))))) goto err_not_open; /* purecov: inspected */ outparam->field=field_ptr; - read_length=((uint) (outparam->fields*11)+pos+ - (uint) (n_length+int_length)); + read_length=(uint) (outparam->fields * field_pack_length + + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) goto err_not_open; /* purecov: inspected */ if (crypted) @@ -299,8 +308,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, names= (char*) (int_array+outparam->fields+interval_parts+keys+3); if (!interval_count) outparam->intervals=0; // For better debugging - memcpy((char*) names, strpos+(outparam->fields*11), + memcpy((char*) names, strpos+(outparam->fields*field_pack_length), (uint) (n_length+int_length)); + comment_pos=names+(n_length+int_length); + memcpy(comment_pos, disk_buff+read_length-com_length, com_length); fix_type_pointers(&int_array,&outparam->fieldnames,1,&names); fix_type_pointers(&int_array,outparam->intervals,interval_count, @@ -328,26 +339,60 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, use_hash= outparam->fields >= MAX_FIELDS_BEFORE_HASH; if (use_hash) use_hash= !hash_init(&outparam->name_hash, + system_charset_info, outparam->fields,0,0, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); - for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++) + for (i=0 ; i < outparam->fields; i++, strpos+=field_pack_length, field_ptr++) { uint pack_flag= uint2korr(strpos+6); uint interval_nr= (uint) strpos[10]; + enum_field_types field_type; + CHARSET_INFO *charset; + LEX_STRING comment; + if (new_frm_ver == 2) + { + /* new frm file in 4.1 */ + uint comment_length=uint2korr(strpos+13); + field_type=(enum_field_types) (uint) strpos[11]; + if (!(charset=get_charset((uint) strpos[12], MYF(0)))) + charset=outparam->table_charset?outparam->table_charset:default_charset_info; + if (!comment_length) + { + comment.str= (char*) ""; + comment.length=0; + } + else + { + comment.str= (char*) comment_pos; + comment.length= comment_length; + comment_pos+= comment_length; + } + } + else + { + /* old frm file */ + field_type= (enum_field_types) f_packtype(pack_flag); + charset=outparam->table_charset?outparam->table_charset:default_charset_info; + bzero((char*) &comment, sizeof(comment)); + } *field_ptr=reg_field= make_field(record+uint2korr(strpos+4), (uint32) strpos[3], // field_length null_pos,null_bit, pack_flag, + field_type, (Field::utype) MTYP_TYPENR((uint) strpos[8]), (interval_nr ? outparam->intervals+interval_nr-1 : (TYPELIB*) 0), outparam->fieldnames.type_names[i], outparam); + reg_field->comment=comment; + if (!reg_field->binary()) + ((Field_str*) reg_field)->set_charset(charset); if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) @@ -445,13 +490,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); if (i == 0) field->key_start|= ((key_map) 1 << key); - if ((index_flags & HA_KEY_READ_ONLY) && - field->key_length() == key_part->length && + if (field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { - if (field->key_type() != HA_KEYTYPE_TEXT || - (!(ha_option & HA_KEY_READ_WRONG_STR) && - !(keyinfo->flags & HA_FULLTEXT))) + if ((index_flags & HA_KEY_READ_ONLY) && + (field->key_type() != HA_KEYTYPE_TEXT || + (!(ha_option & HA_KEY_READ_WRONG_STR) && + !(keyinfo->flags & HA_FULLTEXT)))) field->part_of_key|= ((key_map) 1 << key); if ((field->key_type() != HA_KEYTYPE_TEXT || !(keyinfo->flags & HA_FULLTEXT)) && @@ -941,9 +986,14 @@ ulong next_io_size(register ulong pos) } /* next_io_size */ -void append_unescaped(String *res,const char *pos) + /* Store in String an SQL quoted string */ + +void append_unescaped(String *res,const char *pos, uint length) { - for (; *pos ; pos++) + const char *end= pos+length; + res->append('\''); + + for (; pos != end ; pos++) { switch (*pos) { case 0: /* Must be escaped for 'mysql' */ @@ -971,6 +1021,7 @@ void append_unescaped(String *res,const char *pos) break; } } + res->append('\''); } /* Create a .frm file */ @@ -994,7 +1045,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, if ((file=my_create(name,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { bzero((char*) fileinfo,64); - fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+1; // Header + fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+2; // Header fileinfo[3]= (uchar) ha_checktype(create_info->db_type); fileinfo[4]=1; int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ @@ -1010,6 +1061,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore int4store(fileinfo+34,create_info->avg_row_length); + fileinfo[38]= create_info->table_charset?create_info->table_charset->number:0; fileinfo[40]= (uchar) create_info->row_type; fileinfo[41]= (uchar) create_info->raid_type; fileinfo[42]= (uchar) create_info->raid_chunks; @@ -1040,6 +1092,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->raid_type=table->raid_type; create_info->raid_chunks=table->raid_chunks; create_info->raid_chunksize=table->raid_chunksize; + create_info->table_charset=table->table_charset; DBUG_VOID_RETURN; } @@ -1062,7 +1115,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) { Field *field=table->field[fieldnr]; char buff[MAX_FIELD_WIDTH]; - String str(buff,sizeof(buff)); + String str(buff,sizeof(buff),default_charset_info); field->val_str(&str,&str); uint length=str.length(); if (!length) @@ -1079,9 +1132,10 @@ bool check_db_name(const char *name) while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, name+MBMAXLEN); + int len=my_ismbchar(system_charset_info, name, + name+system_charset_info->mbmaxlen); if (len) { name += len; @@ -1094,7 +1148,7 @@ bool check_db_name(const char *name) return 1; name++; } - return (uint) (name - start) > NAME_LEN; + return (uint) (name - start) > NAME_LEN || name == start; } @@ -1112,9 +1166,9 @@ bool check_table_name(const char *name, uint length) while (name != end) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, end); + int len=my_ismbchar(system_charset_info, name, end); if (len) { name += len; @@ -1134,9 +1188,10 @@ bool check_column_name(const char *name) while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, name+MBMAXLEN); + int len=my_ismbchar(system_charset_info, name, + name+system_charset_info->mbmaxlen); if (len) { name += len; @@ -1168,7 +1223,7 @@ db_type get_table_type(const char *name) error=my_read(file,(byte*) head,4,MYF(MY_NABP)); my_close(file,MYF(0)); if (error || head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) DBUG_RETURN(DB_TYPE_UNKNOWN); DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3))); } |