当前位置:Gxlcms > 数据库问题 > mysql_create_frm

mysql_create_frm

时间:2021-07-01 10:21:17 帮助过:3人阅读

mysql_create_frm(THD *thd, const char *file_name, const char *db, const char *table, HA_CREATE_INFO *create_info, List<Create_field> &create_fields, uint keys, KEY *key_info, handler *db_file) { LEX_STRING str_db_type; uint reclength, info_length, screens, key_info_length, maxlength, tmp_len, i; ulong key_buff_length; File file; ulong filepos, data_offset; uchar fileinfo[64],forminfo[288],*keybuff; uchar *screen_buff; char buff[128]; Pack_header_error_handler pack_header_error_handler; int error; const uint format_section_header_size= 8; uint format_section_length; uint tablespace_length= 0; DBUG_ENTER("mysql_create_frm"); DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0))) DBUG_RETURN(1); DBUG_ASSERT(db_file != NULL); /* If fixed row records, we need one bit to check for deleted rows */ if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) create_info->null_bits++; data_offset= (create_info->null_bits + 7) / 8; thd->push_internal_handler(&pack_header_error_handler); error= pack_header(forminfo, ha_legacy_type(create_info->db_type), create_fields,info_length, screens, create_info->table_options, data_offset, db_file); thd->pop_internal_handler(); if (error) { my_free(screen_buff); } reclength=uint2korr(forminfo+266); /* Calculate extra data segment length */ str_db_type.str= (char *) ha_resolve_storage_engine_name(create_info->db_type); str_db_type.length= strlen(str_db_type.str); /* str_db_type */ create_info->extra_size= (2 + str_db_type.length + 2 + create_info->connect_string.length); create_info->extra_size+= 6; /* If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes, store the comment in an extra segment (up to TABLE_COMMENT_MAXLEN bytes). Pre 6.0, the limit was 60 characters, with no extra segment-handling. */ if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN) { forminfo[46]=255; create_info->extra_size+= 2 + create_info->comment.length; } else{ strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; } if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo, create_info, keys, key_info)) < 0) { my_free(screen_buff); DBUG_RETURN(1); } key_buff_length= uint4korr(fileinfo+47); keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); key_info_length= pack_keys(keybuff, keys, key_info, data_offset); /* Ensure that there are no forms in this newly created form file. Even if the form file exists, create_frm must truncate it to ensure one form per form file. */ DBUG_ASSERT(uint2korr(fileinfo+8) == 0); if (!(filepos= make_new_entry(file, fileinfo, NULL, ""))) goto err; maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); int2store(forminfo+2,maxlength); int4store(fileinfo+10,(ulong) (filepos+maxlength)); fileinfo[26]= (uchar) test((create_info->max_rows == 1) && (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); int2store(fileinfo+59,db_file->extra_rec_buf_length()); if (mysql_file_pwrite(file, fileinfo, 64, 0L, MYF_RW) || mysql_file_pwrite(file, keybuff, key_info_length, (ulong) uint2korr(fileinfo+6), MYF_RW)) goto err; mysql_file_seek(file, (ulong) uint2korr(fileinfo+6) + (ulong) key_buff_length, MY_SEEK_SET, MYF(0)); if (make_empty_rec(thd,file,ha_legacy_type(create_info->db_type), create_info->table_options, create_fields,reclength, data_offset, db_file)) goto err; int2store(buff, create_info->connect_string.length); if (mysql_file_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) || mysql_file_write(file, (const uchar*)create_info->connect_string.str, create_info->connect_string.length, MYF(MY_NABP))) goto err; int2store(buff, str_db_type.length); if (mysql_file_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) || mysql_file_write(file, (const uchar*)str_db_type.str, str_db_type.length, MYF(MY_NABP))) goto err; { bzero((uchar*) buff, 6); if (mysql_file_write(file, (uchar*) buff, 6, MYF_RW)) goto err; } for (i= 0; i < keys; i++) { if (key_info[i].parser_name) { if (mysql_file_write(file, (const uchar*)key_info[i].parser_name->str, key_info[i].parser_name->length + 1, MYF(MY_NABP))) goto err; } } if (forminfo[46] == (uchar)255) { uchar comment_length_buff[2]; int2store(comment_length_buff,create_info->comment.length); if (mysql_file_write(file, comment_length_buff, 2, MYF(MY_NABP)) || mysql_file_write(file, (uchar*) create_info->comment.str, create_info->comment.length, MYF(MY_NABP))) goto err; } /* "Format section" with additional table and column properties */ mysql_file_seek(file, filepos, MY_SEEK_SET, MYF(0)); if (mysql_file_write(file, forminfo, 288, MYF_RW) || mysql_file_write(file, screen_buff, info_length, MYF_RW) || pack_fields(file, create_fields, data_offset)) goto err; my_free(screen_buff); my_free(keybuff); if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) && (mysql_file_sync(file, MYF(MY_WME)) || my_sync_dir_by_file(file_name, MYF(MY_WME)))) goto err2; if (mysql_file_close(file, MYF(MY_WME))) goto err3; err: my_free(screen_buff); my_free(keybuff); err2: (void) mysql_file_close(file, MYF(MY_WME)); err3: mysql_file_delete(key_file_frm, file_name, MYF(0)); DBUG_RETURN(1); } /* mysql_create_frm */

 

    /* Pack keyinfo and keynames to keybuff for save in form-file. */

static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
                      ulong data_offset)
{
  uint key_parts,length;
  uchar *pos, *keyname_pos;
  KEY *key,*end;
  KEY_PART_INFO *key_part,*key_part_end;
  DBUG_ENTER("pack_keys");

  pos=keybuff+6;
  key_parts=0;
  for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++)
  {
    int2store(pos, (key->flags ^ HA_NOSAME));
    int2store(pos+2,key->key_length);
    pos[4]= (uchar) key->key_parts;
    pos[5]= (uchar) key->algorithm;
    int2store(pos+6, key->block_size);
    pos+=8;
    key_parts+=key->key_parts;
    DBUG_PRINT("loop", ("flags: %lu  key_parts: %d at 0x%lx",
                        key->flags, key->key_parts,
                        (long) key->key_part));
    for (key_part=key->key_part,key_part_end=key_part+key->key_parts ;
     key_part != key_part_end ;
     key_part++)

    {
      uint offset;
      DBUG_PRINT("loop",("field: %d  startpos: %lu  length: %d",
             key_part->fieldnr, key_part->offset + data_offset,
                         key_part->length));
      int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED);
      offset= (uint) (key_part->offset+data_offset+1);
      int2store(pos+2, offset);
      pos[4]=0;                    // Sort order
      int2store(pos+5,key_part->key_type);
      int2store(pos+7,key_part->length);
      pos+=9;
    }
  }
    /* Save keynames */
  keyname_pos=pos;
  *pos++=(uchar) NAMES_SEP_CHAR;
  for (key=keyinfo ; key != end ; key++)
  {
    uchar *tmp=(uchar*) strmov((char*) pos,key->name);
    *tmp++= (uchar) NAMES_SEP_CHAR;
    *tmp=0;
    pos=tmp;
  }
  *(pos++)=0;
  for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++)
  {
    if (key->flags & HA_USES_COMMENT)
    {
      int2store(pos, key->comment.length);
      uchar *tmp= (uchar*)strnmov((char*) pos+2,key->comment.str,
                                  key->comment.length);
      pos= tmp;
    }
  }

  if (key_count > 127 || key_parts > 127)
  {
    keybuff[0]= (key_count & 0x7f) | 0x80;
    keybuff[1]= key_count >> 7;
    int2store(keybuff+2,key_parts);
  }
  else
  {
    keybuff[0]=(uchar) key_count;
    keybuff[1]=(uchar) key_parts;
    keybuff[2]= keybuff[3]= 0;
  }
  length=(uint) (pos-keyname_pos);
  int2store(keybuff+4,length);
  DBUG_RETURN((uint) (pos-keybuff));
} /* pack_keys */

 

 

    /* Save fields, fieldnames and intervals */

static bool pack_fields(File file, List<Create_field> &create_fields,
                        ulong data_offset)
{
  reg2 uint i;
  uint int_count, comment_length=0;
  uchar buff[MAX_FIELD_WIDTH];
  Create_field *field;
  DBUG_ENTER("pack_fields");

    /* Write field info */

  List_iterator<Create_field> it(create_fields);

  int_count=0;
  while ((field=it++))
  {
    uint recpos;
    buff[0]= (uchar) field->row;
    buff[1]= (uchar) field->col;
    buff[2]= (uchar) field->sc_length;
    int2store(buff+3, field->length);
    /* The +1 is here becasue the col offset in .frm file have offset 1 */
    recpos= field->offset+1 + (uint) data_offset;
    int3store(buff+5,recpos);
    int2store(buff+8,field->pack_flag);
    DBUG_ASSERT(field->unireg_check < 256);
    buff[10]= (uchar) field->unireg_check;
    buff[12]= (uchar) field->interval_id;
    buff[13]= (uchar) field->sql_type; 
    if (field->sql_type == MYSQL_TYPE_GEOMETRY)
    {
      buff[11]= 0;
      buff[14]= (uchar) field->geom_type;
#ifndef HAVE_SPATIAL
      DBUG_ASSERT(0);                           // Should newer happen
#endif
    }
    else if (field->charset) 
    {
      buff[11]= (uchar) (field->charset->number >> 8);
      buff[14]= (uchar) field->charset->number;
    }
    else
    {
      buff[11]= buff[14]= 0;            // Numerical
    }
    int2store(buff+15, field->comment.length);
    comment_length+= field->comment.length;
    set_if_bigger(int_count,field->interval_id);
    if (mysql_file_write(file, buff, FCOMP, MYF_RW))
      DBUG_RETURN(1);
  }

    /* Write fieldnames */
  buff[0]=(uchar) NAMES_SEP_CHAR;
  if (mysql_file_write(file, buff, 1, MYF_RW))
    DBUG_RETURN(1);
  i=0;
  it.rewind();
  while ((field=it++))
  {
    char *pos= strmov((char*) buff,field->field_name);
    *pos++=NAMES_SEP_CHAR;
    if (i == create_fields.elements-1)
      *pos++=0;
    if (mysql_file_write(file, buff, (size_t) (pos-(char*) buff), MYF_RW))
      DBUG_RETURN(1);
    i++;
  }

    /* Write intervals */
  if (int_count)
  {
    String tmp((char*) buff,sizeof(buff), &my_charset_bin);
    tmp.length(0);
    it.rewind();
    int_count=0;
    while ((field=it++))
    {
      if (field->interval_id > int_count)
      {
        unsigned char  sep= 0;
        unsigned char  occ[256];
        uint           i;
        unsigned char *val= NULL;

        bzero(occ, sizeof(occ));

        for (i=0; (val= (unsigned char*) field->interval->type_names[i]); i++)
          for (uint j = 0; j < field->interval->type_lengths[i]; j++)
            occ[(unsigned int) (val[j])]= 1;

        if (!occ[(unsigned char)NAMES_SEP_CHAR])
          sep= (unsigned char) NAMES_SEP_CHAR;
        else if (!occ[(unsigned int),])
          sep= ,;
        else
        {
          for (uint i=1; i<256; i++)
          {
            if(!occ[i])
            {
              sep= i;
              break;
            }
          }

          if(!sep)    /* disaster, enum uses all characters, none left as separator */
          {
            my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
                       MYF(0));
            DBUG_RETURN(1);
          }
        }

        int_count= field->interval_id;
        tmp.append(sep);
        for (const char **pos=field->interval->type_names ; *pos ; pos++)
        {
          tmp.append(*pos);
          tmp.append(sep);
        }
        tmp.append(\0);                      // End of intervall
      }
    }
    if (mysql_file_write(file, (uchar*) tmp.ptr(), tmp.length(), MYF_RW))
      DBUG_RETURN(1);
  }
  if (comment_length)
  {
    it.rewind();
    int_count=0;
    while ((field=it++))
    {
      if (field->comment.length)
        if (mysql_file_write(file, (uchar*) field->comment.str,
                             field->comment.length, MYF_RW))
      DBUG_RETURN(1);
    }
  }
  DBUG_RETURN(0);
}

 

mysql_create_frm

标签:

人气教程排行