summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc71
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++;
}