diff options
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/sql/table.cc b/sql/table.cc index e0f5edbf262..d3b719c553d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -46,7 +46,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, reg2 uchar *strpos; int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, - interval_count,interval_parts,read_length,db_create_options; + interval_count,interval_parts,read_length,db_create_options; + uint key_info_length; ulong pos; char index_file[FN_REFLEN], *names,*keynames; uchar head[288],*disk_buff,new_field_pack_flag; @@ -127,11 +128,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->min_rows=uint4korr(head+22); /* Read keyinformation */ + key_info_length= (uint) uint2korr(head+28); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); - if (read_string(file,(gptr*) &disk_buff,(uint) uint2korr(head+28))) + if (read_string(file,(gptr*) &disk_buff,key_info_length)) goto err_not_open; /* purecov: inspected */ outparam->keys=keys= disk_buff[0]; - outparam->keys_in_use= set_bits(key_map, keys); + outparam->keys_for_keyread= outparam->keys_in_use= set_bits(key_map, keys); outparam->key_parts=key_parts=disk_buff[1]; n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); @@ -187,8 +189,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (keyinfo->flags & HA_NOSAME) set_if_bigger(outparam->max_unique_length,keyinfo->key_length); } + 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++); + } - (void) strmov(keynames= (char *) key_part,(char *) strpos); outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -259,7 +270,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->comment=strdup_root(&outparam->mem_root, (char*) head+47); - DBUG_PRINT("form",("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", interval_count,interval_parts, outparam->keys,n_length,int_length)); if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, @@ -359,14 +370,24 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames, 3)-1); - uint ha_option=outparam->file->option_flag(); + uint ha_option=outparam->file->table_flags(); keyinfo=outparam->key_info; key_part=keyinfo->key_part; for (uint key=0 ; key < outparam->keys ; key++,keyinfo++) { uint usable_parts=0; + ulong index_flags; keyinfo->name=(char*) outparam->keynames.type_names[key]; + /* Fix fulltext keys for old .frm files */ + if (outparam->key_info[key].flags & HA_FULLTEXT) + outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; + + /* This has to be done after the above fulltext correction */ + index_flags=outparam->file->index_flags(key); + if (!(index_flags & HA_KEY_READ_ONLY)) + outparam->keys_for_keyread&= ~((key_map) 1 << key); + if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) { /* @@ -424,7 +445,7 @@ 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 ((ha_option & HA_HAVE_KEY_READ_ONLY) && + if ((index_flags & HA_KEY_READ_ONLY) && field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { @@ -432,8 +453,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (!(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)) + if ((field->key_type() != HA_KEYTYPE_TEXT || + !(keyinfo->flags & HA_FULLTEXT)) && + !(index_flags & HA_WRONG_ASCII_ORDER)) field->part_of_sortkey|= ((key_map) 1 << key); } if (!(key_part->key_part_flag & HA_REVERSE_SORT) && @@ -443,15 +465,20 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (key == primary_key) { field->flags|= PRI_KEY_FLAG; + /* + If this field is part of the primary key and all keys contains + the primary key, then we can use any key to find this column + */ if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX) - field->part_of_key|= ((key_map) 1 << primary_key); + field->part_of_key= outparam->keys_in_use; } if (field->key_length() != key_part->length) { key_part->key_part_flag|= HA_PART_KEY; if (field->type() != FIELD_TYPE_BLOB) { // Create a new field - field=key_part->field=field->new_field(outparam); + field=key_part->field=field->new_field(&outparam->mem_root, + outparam); field->field_length=key_part->length; } } @@ -475,8 +502,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (outparam->keys_in_use & ((key_map) 1 << primary_key))) { outparam->primary_key=primary_key; - if (outparam->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX) - outparam->ref_primary_key= (key_map) 1 << primary_key; /* If we are using an integer as the primary key then allow the user to refer to it as '_rowid' @@ -504,6 +529,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, bfill(outparam->null_flags+outparam->rec_buff_length*2,null_length,255); } + if ((reg_field=outparam->found_next_number_field)) { if ((int) (outparam->next_number_index= (uint) @@ -757,7 +783,7 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, int2store(fileinfo+8,names+1); int2store(fileinfo+4,n_length+length); - VOID(my_chsize(file,newpos,MYF(MY_WME))); /* Append file with '\0' */ + VOID(my_chsize(file, newpos, 0, MYF(MY_WME)));/* Append file with '\0' */ DBUG_RETURN(newpos); } /* make_new_entry */ @@ -831,7 +857,7 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, *type_name= '\0'; /* End string */ ptr=type_name; } - ptr+=2; /* Skipp end mark and last 0 */ + ptr+=2; /* Skip end mark and last 0 */ } else ptr++; @@ -917,7 +943,7 @@ ulong next_io_size(register ulong pos) void append_unescaped(String *res,const char *pos) { - for ( ; *pos ; pos++) + for (; *pos ; pos++) { switch (*pos) { case 0: /* Must be escaped for 'mysql' */ @@ -1005,6 +1031,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) { + DBUG_ENTER("update_create_info_from_table"); create_info->max_rows=table->max_rows; create_info->min_rows=table->min_rows; create_info->table_options=table->db_create_options; @@ -1013,7 +1040,8 @@ 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; -} + DBUG_VOID_RETURN; +} int rename_file_ext(const char * from,const char * to,const char * ext) @@ -1061,7 +1089,8 @@ bool check_db_name(const char *name) } } #endif - if (*name == '/' || *name == FN_LIBCHAR || *name == FN_EXTCHAR) + if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR || + *name == FN_EXTCHAR) return 1; name++; } |