mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Extension of .frm file (not yet ready for push)
This commit is contained in:
136
sql/table.cc
136
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;
|
||||
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;
|
||||
uchar *null_pos, *comment_pos;
|
||||
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=default_charset_info;
|
||||
null_field_first=1;
|
||||
}
|
||||
outparam->db_record_offset=1;
|
||||
@ -153,10 +156,22 @@ 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;
|
||||
@ -167,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);
|
||||
@ -193,26 +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++);
|
||||
/* Temporary fix to get spatial index to work */
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_RTREE)
|
||||
keyinfo->flags|= HA_SPATIAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set key types to BTREE, BAR TODO: how to be with HASH/RBTREE? */
|
||||
keyinfo=outparam->key_info;
|
||||
for (i=0 ; i < keys ; i++, keyinfo++)
|
||||
keyinfo->algorithm= HA_KEY_ALG_BTREE;
|
||||
}
|
||||
outparam->reclength = uint2korr((head+16));
|
||||
if (*(head+26) == 1)
|
||||
outparam->system=1; /* one-record-database */
|
||||
@ -280,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,
|
||||
@ -291,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));
|
||||
if (read_string(file,(gptr*) &disk_buff,read_length))
|
||||
goto err_not_open; /* purecov: inspected */
|
||||
if (crypted)
|
||||
@ -306,13 +302,14 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
crypted=0;
|
||||
}
|
||||
strpos= disk_buff+pos;
|
||||
comment_pos=disk_buff+read_length-com_length;
|
||||
|
||||
outparam->intervals= (TYPELIB*) (field_ptr+outparam->fields+1);
|
||||
int_array= (const char **) (outparam->intervals+interval_count);
|
||||
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));
|
||||
|
||||
fix_type_pointers(&int_array,&outparam->fieldnames,1,&names);
|
||||
@ -346,43 +343,55 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
(hash_get_key) get_field_name,0,
|
||||
HASH_CASE_INSENSITIVE);
|
||||
|
||||
// BAR: dirty hack while waiting for new FRM
|
||||
// BAR: take a charset information from table name
|
||||
{
|
||||
const char* csname=strstr(alias,"_cs_");
|
||||
if(!csname ||
|
||||
!(outparam->table_charset=get_charset_by_name(csname+4,MYF(MY_WME))))
|
||||
outparam->table_charset=default_charset_info;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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())
|
||||
{
|
||||
// BAR: dirty hack while waiting for new FRM
|
||||
// BAR: take a charset information from field name
|
||||
|
||||
Field_str* str_field=(Field_str*)reg_field;
|
||||
const char* csname=strstr(str_field->field_name,"_cs_");
|
||||
CHARSET_INFO *fcs;
|
||||
if (!csname || (!(fcs=get_charset_by_name(csname+4,MYF(MY_WME)))))
|
||||
fcs=outparam->table_charset;
|
||||
str_field->set_charset(fcs);
|
||||
}
|
||||
((Field_str*) reg_field)->set_charset(charset);
|
||||
if (!(reg_field->flags & NOT_NULL_FLAG))
|
||||
{
|
||||
if ((null_bit<<=1) == 256)
|
||||
@ -956,9 +965,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' */
|
||||
@ -986,6 +1000,7 @@ void append_unescaped(String *res,const char *pos)
|
||||
break;
|
||||
}
|
||||
}
|
||||
res->append('\'');
|
||||
}
|
||||
|
||||
/* Create a .frm file */
|
||||
@ -1009,7 +1024,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 */
|
||||
@ -1025,6 +1040,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->number;
|
||||
fileinfo[40]= (uchar) create_info->row_type;
|
||||
fileinfo[41]= (uchar) create_info->raid_type;
|
||||
fileinfo[42]= (uchar) create_info->raid_chunks;
|
||||
|
Reference in New Issue
Block a user