mi_create.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:19k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* Create a MyISAM table */
  17. #include "fulltext.h"
  18. #if defined(MSDOS) || defined(__WIN__)
  19. #ifdef __WIN__
  20. #include <fcntl.h>
  21. #else
  22. #include <process.h> /* Prototype for getpid */
  23. #endif
  24. #endif
  25. #include <m_ctype.h>
  26. /*
  27. ** Old options is used when recreating database, from isamchk
  28. */
  29. int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
  30.       uint columns, MI_COLUMNDEF *recinfo,
  31.       uint uniques, MI_UNIQUEDEF *uniquedefs,
  32.       MI_CREATE_INFO *ci,uint flags)
  33. {
  34.   register uint i,j;
  35.   File dfile,file;
  36.   int errpos,save_errno;
  37.   uint fields,length,max_key_length,packed,pointer,
  38.        key_length,info_length,key_segs,options,min_key_length_skipp,
  39.        base_pos,varchar_count,long_varchar_count,varchar_length,
  40.        max_key_block_length,unique_key_parts,offset;
  41.   ulong reclength, real_reclength,min_pack_length;
  42.   char buff[FN_REFLEN];
  43.   ulong pack_reclength;
  44.   ulonglong tot_length,max_rows;
  45.   enum en_fieldtype type;
  46.   MYISAM_SHARE share;
  47.   MI_KEYDEF *keydef,tmp_keydef;
  48.   MI_UNIQUEDEF *uniquedef;
  49.   MI_KEYSEG *keyseg,tmp_keyseg;
  50.   MI_COLUMNDEF *rec;
  51.   ulong *rec_per_key_part;
  52.   my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
  53.   MI_CREATE_INFO tmp_create_info;
  54.   DBUG_ENTER("mi_create");
  55.   if (!ci)
  56.   {
  57.     bzero((char*) &tmp_create_info,sizeof(tmp_create_info));
  58.     ci=&tmp_create_info;
  59.   }
  60.   if (keys + uniques > MI_MAX_KEY)
  61.   {
  62.     DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
  63.   }
  64.   LINT_INIT(dfile);
  65.   LINT_INIT(file);
  66.   pthread_mutex_lock(&THR_LOCK_myisam);
  67.   errpos=0;
  68.   options=0;
  69.   bzero((byte*) &share,sizeof(share));
  70.   if (flags & HA_DONT_TOUCH_DATA)
  71.   {
  72.     if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
  73.       options=ci->old_options &
  74. (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
  75.  HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
  76.  HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
  77.     else
  78.       options=ci->old_options &
  79. (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
  80.   }
  81.   if (ci->reloc_rows > ci->max_rows)
  82.     ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
  83.   if (!(rec_per_key_part=
  84. (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
  85.    MYF(MY_WME | MY_ZEROFILL))))
  86.     DBUG_RETURN(my_errno);
  87. /* Start by checking fields and field-types used */
  88.   reclength=varchar_count=varchar_length=long_varchar_count=packed=
  89.     min_pack_length=pack_reclength=0;
  90.   for (rec=recinfo, fields=0 ;
  91.        fields != columns ;
  92.        rec++,fields++)
  93.   {
  94.     reclength+=rec->length;
  95.     if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
  96. type != FIELD_CHECK)
  97.     {
  98.       packed++;
  99.       if (type == FIELD_BLOB)
  100.       {
  101. share.base.blobs++;
  102. if (pack_reclength != INT_MAX32)
  103. {
  104.   if (rec->length == 4+mi_portable_sizeof_char_ptr)
  105.     pack_reclength= INT_MAX32;
  106.   else
  107.     pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */
  108. }
  109.       }
  110.       else if (type == FIELD_SKIPP_PRESPACE ||
  111.        type == FIELD_SKIPP_ENDSPACE)
  112.       {
  113. if (pack_reclength != INT_MAX32)
  114.   pack_reclength+= rec->length > 255 ? 2 : 1;
  115. min_pack_length++;
  116.       }
  117.       else if (type == FIELD_VARCHAR)
  118.       {
  119. varchar_count++;
  120. varchar_length+=rec->length-2;
  121. packed--;
  122. pack_reclength+=1;
  123. if (test(rec->length > 257))
  124. { /* May be packed on 3 bytes */
  125.   long_varchar_count++;
  126.   pack_reclength+=2;
  127. }
  128.       }
  129.       else if (type != FIELD_SKIPP_ZERO)
  130.       {
  131. min_pack_length+=rec->length;
  132. packed--; /* Not a pack record type */
  133.       }
  134.     }
  135.     else /* FIELD_NORMAL */
  136.       min_pack_length+=rec->length;
  137.   }
  138.   if ((packed & 7) == 1)
  139.   { /* Bad packing, try to remove a zero-field */
  140.     while (rec != recinfo)
  141.     {
  142.       rec--;
  143.       if (rec->type == (int) FIELD_SKIPP_ZERO && rec->length == 1)
  144.       {
  145. rec->type=(int) FIELD_NORMAL;
  146. packed--;
  147. min_pack_length++;
  148. break;
  149.       }
  150.     }
  151.   }
  152.   if (packed || (flags & HA_PACK_RECORD))
  153.     options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
  154.   if (options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
  155.     min_pack_length+=varchar_count; /* Min length to pack */
  156.   else
  157.   {
  158.     min_pack_length+=varchar_length+2*varchar_count;
  159.   }
  160.   if (flags & HA_CREATE_TMP_TABLE)
  161.     options|= HA_OPTION_TMP_TABLE;
  162.   if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
  163.   {
  164.     options|= HA_OPTION_CHECKSUM;
  165.     min_pack_length++;
  166.   }
  167.   if (flags & HA_CREATE_DELAY_KEY_WRITE)
  168.     options|= HA_OPTION_DELAY_KEY_WRITE;
  169.   packed=(packed+7)/8;
  170.   if (pack_reclength != INT_MAX32)
  171.     pack_reclength+= reclength+packed +
  172.       test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
  173.   min_pack_length+=packed;
  174.   if (!ci->data_file_length)
  175.   {
  176.     if (ci->max_rows == 0 || pack_reclength == INT_MAX32)
  177.       ci->data_file_length= INT_MAX32-1; /* Should be enough */
  178.     else if ((~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
  179.       ci->data_file_length= ~(ulonglong) 0;
  180.     else
  181.       ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
  182.   }
  183.   else if (!ci->max_rows)
  184.     ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
  185.  ((options & HA_OPTION_PACK_RECORD) ?
  186.   3 : 0)));
  187.   if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
  188.     pointer=mi_get_pointer_length(ci->data_file_length,4);
  189.   else
  190.     pointer=mi_get_pointer_length(ci->max_rows,4);
  191.   if (!(max_rows=(ulonglong) ci->max_rows))
  192.     max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);
  193.   real_reclength=reclength;
  194.   if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
  195.   {
  196.     if (reclength <= pointer)
  197.       reclength=pointer+1; /* reserve place for delete link */
  198.   }
  199.   else
  200.     reclength+=long_varchar_count; /* We need space for this! */
  201.   max_key_length=0; tot_length=0 ; key_segs=0;
  202.   max_key_block_length=0;
  203.   share.state.rec_per_key_part=rec_per_key_part;
  204.   share.state.key_root=key_root;
  205.   share.state.key_del=key_del;
  206.   if (uniques)
  207.   {
  208.     max_key_block_length= MI_KEY_BLOCK_LENGTH;
  209.     max_key_length= MI_UNIQUE_HASH_LENGTH;
  210.   }
  211.   for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
  212.   {
  213.     share.state.key_root[i]= HA_OFFSET_ERROR;
  214.     min_key_length_skipp=length=0;
  215.     key_length=pointer;
  216.     if (keydef->flag & HA_FULLTEXT)                                 /* SerG */
  217.     {
  218.       keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
  219.       options|=HA_OPTION_PACK_KEYS;             /* Using packed keys */
  220.       if (flags & HA_DONT_TOUCH_DATA)
  221.       {
  222.         /* called by myisamchk - i.e. table structure was taken from
  223.            MYI file and FULLTEXT key *do has* additional FT_SEGS keysegs.
  224.            We'd better delete them now
  225.         */
  226.         keydef->keysegs-=FT_SEGS;
  227.       }
  228.       for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
  229.    j++, keyseg++)
  230.       {
  231.         if (keyseg->type != HA_KEYTYPE_TEXT &&
  232.     keyseg->type != HA_KEYTYPE_VARTEXT)
  233.         {
  234.           my_errno=HA_WRONG_CREATE_OPTION;
  235.           goto err;
  236.         }
  237.       }
  238.       keydef->keysegs+=FT_SEGS;
  239.       key_length+= HA_FT_MAXLEN+HA_FT_WLEN;
  240. #ifdef EVAL_RUN
  241.       key_length++;
  242. #endif
  243.       length++;                              /* At least one length byte */
  244.       min_key_length_skipp+=HA_FT_MAXLEN;
  245. #if HA_FT_MAXLEN >= 255
  246.       min_key_length_skipp+=2;                  /* prefix may be 3 bytes */
  247.       length+=2;
  248. #endif
  249.     }
  250.     else
  251.     {
  252.       /* Test if prefix compression */
  253.       if (keydef->flag & HA_PACK_KEY)
  254.       {
  255. /* Can't use space_compression on number keys */
  256. if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
  257.     keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
  258.   keydef->seg[0].flag&= ~HA_SPACE_PACK;
  259. /* Only use HA_PACK_KEY if the first segment is a variable length key */
  260. if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
  261.      HA_VAR_LENGTH)))
  262. {
  263.   /* pack relative to previous key */
  264.   keydef->flag&= ~HA_PACK_KEY;
  265.   keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
  266. }
  267. else
  268. {
  269.   keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */
  270.   keydef->flag|=HA_VAR_LENGTH_KEY;
  271.   options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
  272. }
  273.       }
  274.       if (keydef->flag & HA_BINARY_PACK_KEY)
  275. options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
  276.       if (keydef->flag & HA_AUTO_KEY)
  277. share.base.auto_key=i+1;
  278.       for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
  279.       {
  280. /* numbers are stored with high by first to make compression easier */
  281. switch (keyseg->type) {
  282. case HA_KEYTYPE_SHORT_INT:
  283. case HA_KEYTYPE_LONG_INT:
  284. case HA_KEYTYPE_FLOAT:
  285. case HA_KEYTYPE_DOUBLE:
  286. case HA_KEYTYPE_USHORT_INT:
  287. case HA_KEYTYPE_ULONG_INT:
  288. case HA_KEYTYPE_LONGLONG:
  289. case HA_KEYTYPE_ULONGLONG:
  290. case HA_KEYTYPE_INT24:
  291. case HA_KEYTYPE_UINT24:
  292. case HA_KEYTYPE_INT8:
  293.   keyseg->flag|= HA_SWAP_KEY;
  294.   /* fall through */
  295. default:
  296.   break;
  297. }
  298. if (keyseg->flag & HA_SPACE_PACK)
  299. {
  300.   keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
  301.   options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
  302.   length++; /* At least one length byte */
  303.   min_key_length_skipp+=keyseg->length;
  304.   if (keyseg->length >= 255)
  305.   { /* prefix may be 3 bytes */
  306.     min_key_length_skipp+=2;
  307.     length+=2;
  308.   }
  309. }
  310. if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART))
  311. {
  312.   keydef->flag|=HA_VAR_LENGTH_KEY;
  313.   length++; /* At least one length byte */
  314.   options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
  315.   min_key_length_skipp+=keyseg->length;
  316.   if (keyseg->length >= 255)
  317.   { /* prefix may be 3 bytes */
  318.     min_key_length_skipp+=2;
  319.     length+=2;
  320.   }
  321. }
  322. key_length+= keyseg->length;
  323. if (keyseg->null_bit)
  324. {
  325.   key_length++;
  326.   options|=HA_OPTION_PACK_KEYS;
  327.   keyseg->flag|=HA_NULL_PART;
  328.   keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY;
  329. }
  330.       }
  331.     } /* if HA_FULLTEXT */
  332.     key_segs+=keydef->keysegs;
  333.     if (keydef->keysegs > MI_MAX_KEY_SEG)
  334.     {
  335.       my_errno=HA_WRONG_CREATE_OPTION;
  336.       goto err;
  337.     }
  338.     if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
  339.       share.state.rec_per_key_part[key_segs-1]=1L;
  340.     length+=key_length;
  341.     keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE);
  342.     if (keydef->block_length/MI_KEY_BLOCK_LENGTH > MI_MAX_KEY_BLOCK_SIZE)
  343.     {
  344.       my_errno=HA_WRONG_CREATE_OPTION;
  345.       goto err;
  346.     }
  347.     set_if_bigger(max_key_block_length,keydef->block_length);
  348.     keydef->keylength= (uint16) key_length;
  349.     keydef->minlength= (uint16) (length-min_key_length_skipp);
  350.     keydef->maxlength= (uint16) length;
  351.     if (length > max_key_length)
  352.       max_key_length= length;
  353.     tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
  354.     (length*2)))*
  355.       (ulong) keydef->block_length;
  356.   }
  357.   for (i=max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
  358.     key_del[i]=HA_OFFSET_ERROR;
  359.   unique_key_parts=0;
  360.   offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
  361.   for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
  362.   {
  363.     uniquedef->key=keys+i;
  364.     unique_key_parts+=uniquedef->keysegs;
  365.     share.state.key_root[keys+i]= HA_OFFSET_ERROR;
  366.   }
  367.   keys+=uniques; /* Each unique has 1 key */
  368.   key_segs+=uniques; /* Each unique has 1 key seg */
  369.   base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
  370.     max_key_block_length/MI_KEY_BLOCK_LENGTH*MI_STATE_KEYBLOCK_SIZE+
  371.     key_segs*MI_STATE_KEYSEG_SIZE);
  372.   info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
  373.        keys * MI_KEYDEF_SIZE+
  374.        uniques * MI_UNIQUEDEF_SIZE +
  375.        (key_segs + unique_key_parts)*MI_KEYSEG_SIZE+
  376.        columns*MI_COLUMNDEF_SIZE);
  377.   bmove(share.state.header.file_version,(byte*) myisam_file_magic,4);
  378.   ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
  379. HA_OPTION_COMPRESS_RECORD |
  380. HA_OPTION_TEMP_COMPRESS_RECORD: 0);
  381.   mi_int2store(share.state.header.options,ci->old_options);
  382.   mi_int2store(share.state.header.header_length,info_length);
  383.   mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE);
  384.   mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE);
  385.   mi_int2store(share.state.header.base_pos,base_pos);
  386.   share.state.header.language= (ci->language ?
  387. ci->language : MY_CHARSET_CURRENT);
  388.   share.state.header.max_block_size=max_key_block_length/MI_KEY_BLOCK_LENGTH;
  389.   share.state.dellink = HA_OFFSET_ERROR;
  390.   share.state.process= (ulong) getpid();
  391.   share.state.unique= (ulong) 0;
  392.   share.state.update_count=(ulong) 0;
  393.   share.state.version= (ulong) time((time_t*) 0);
  394.   share.state.sortkey=  (ushort) ~0;
  395.   share.state.auto_increment=ci->auto_increment;
  396.   share.options=options;
  397.   share.base.rec_reflength=pointer;
  398.   share.base.key_reflength=
  399.     mi_get_pointer_length((tot_length + max_key_block_length * keys *
  400.    MI_INDEX_BLOCK_MARGIN) / MI_KEY_BLOCK_LENGTH,
  401.   3);
  402.   share.base.keys= share.state.header.keys = keys;
  403.   share.state.header.uniques= uniques;
  404.   mi_int2store(share.state.header.key_parts,key_segs);
  405.   mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
  406.   share.state.key_map = ((ulonglong) 1 << keys)-1;
  407.   share.base.keystart = share.state.state.key_file_length=
  408.     MY_ALIGN(info_length, myisam_block_size);
  409.   share.base.max_key_block_length=max_key_block_length;
  410.   share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
  411.   share.base.records=ci->max_rows;
  412.   share.base.reloc=  ci->reloc_rows;
  413.   share.base.reclength=real_reclength;
  414.   share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);;
  415.   share.base.max_pack_length=pack_reclength;
  416.   share.base.min_pack_length=min_pack_length;
  417.   share.base.pack_bits=packed;
  418.   share.base.fields=fields;
  419.   share.base.pack_fields=packed;
  420. #ifdef USE_RAID
  421.   share.base.raid_type=ci->raid_type;
  422.   share.base.raid_chunks=ci->raid_chunks;
  423.   share.base.raid_chunksize=ci->raid_chunksize;
  424. #endif
  425.   /* max_data_file_length and max_key_file_length are recalculated on open */
  426.   if (options & HA_OPTION_TMP_TABLE)
  427.     share.base.max_data_file_length=(my_off_t) ci->data_file_length;
  428.   share.base.min_block_length=
  429.     (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
  430.      ! share.base.blobs) ?
  431.     max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
  432.     MI_EXTEND_BLOCK_LENGTH;
  433.   if (! (flags & HA_DONT_TOUCH_DATA))
  434.     share.state.create_time= (long) time((time_t*) 0);
  435.   if ((file = my_create(fn_format(buff,name,"",MI_NAME_IEXT,4),0,
  436. O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
  437.     goto err;
  438.   errpos=1;
  439.   VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
  440.   if (!(flags & HA_DONT_TOUCH_DATA))
  441.   {
  442. #ifdef USE_RAID
  443.     if (share.base.raid_type)
  444.     {
  445.       if ((dfile=my_raid_create(buff,0,O_RDWR | O_TRUNC,
  446. share.base.raid_type,
  447. share.base.raid_chunks,
  448. share.base.raid_chunksize,
  449. MYF(MY_WME | MY_RAID))) < 0)
  450. goto err;
  451.     }
  452.     else
  453. #endif
  454.     if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
  455.       goto err;
  456.     errpos=3;
  457.   }
  458.   if (mi_state_info_write(file, &share.state, 2) ||
  459.       mi_base_info_write(file, &share.base))
  460.     goto err;
  461. #ifndef DBUG_OFF
  462.   if ((uint) my_tell(file,MYF(0)) != base_pos+ MI_BASE_INFO_SIZE)
  463.   {
  464.     uint pos=(uint) my_tell(file,MYF(0));
  465.     DBUG_PRINT("warning",("base_length: %d  != used_length: %d",
  466.   base_pos+ MI_BASE_INFO_SIZE, pos));
  467.   }
  468. #endif
  469.   /* Write key and keyseg definitions */
  470.   for (i=0 ; i < share.base.keys - uniques; i++)
  471.   {
  472.     uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0;    /* SerG */
  473.     if (mi_keydef_write(file, &keydefs[i]))
  474.       goto err;
  475.     for (j=0 ; j < keydefs[i].keysegs-ft_segs ; j++)
  476.       if (mi_keyseg_write(file, &keydefs[i].seg[j]))
  477. goto err;
  478.     for (j=0 ; j < ft_segs ; j++)                                   /* SerG */
  479.     {
  480.       MI_KEYSEG seg=ft_keysegs[j];
  481.       seg.language= keydefs[i].seg[0].language;
  482.       if (mi_keyseg_write(file, &seg))
  483.         goto err;
  484.     }
  485.   }
  486.   /* Create extra keys for unique definitions */
  487.   offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
  488.   bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
  489.   bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
  490.   for (i=0; i < uniques ; i++)
  491.   {
  492.     tmp_keydef.keysegs=1;
  493.     tmp_keydef.flag= HA_UNIQUE_CHECK;
  494.     tmp_keydef.block_length= MI_KEY_BLOCK_LENGTH;
  495.     tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
  496.     tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
  497.     tmp_keyseg.type=  MI_UNIQUE_HASH_TYPE;
  498.     tmp_keyseg.length=  MI_UNIQUE_HASH_LENGTH;
  499.     tmp_keyseg.start= offset;
  500.     offset+= MI_UNIQUE_HASH_LENGTH;
  501.     if (mi_keydef_write(file,&tmp_keydef) ||
  502. mi_keyseg_write(file,(&tmp_keyseg)))
  503.       goto err;
  504.   }
  505.   /* Save unique definition */
  506.   for (i=0 ; i < share.state.header.uniques ; i++)
  507.   {
  508.     if (mi_uniquedef_write(file, &uniquedefs[i]))
  509.       goto err;
  510.     for (j=0 ; j < uniquedefs[i].keysegs ; j++)
  511.     {
  512.       if (mi_keyseg_write(file, &uniquedefs[i].seg[j]))
  513. goto err;
  514.     }
  515.   }
  516.   for (i=0 ; i < share.base.fields ; i++)
  517.     if (mi_recinfo_write(file, &recinfo[i]))
  518.       goto err;
  519. #ifndef DBUG_OFF
  520.   if ((uint) my_tell(file,MYF(0)) != info_length)
  521.   {
  522.     uint pos= (uint) my_tell(file,MYF(0));
  523.     DBUG_PRINT("warning",("info_length: %d  != used_length: %d",
  524.   info_length, pos));
  525.   }
  526. #endif
  527. /* Enlarge files */
  528.   if (my_chsize(file,(ulong) share.base.keystart,MYF(0)))
  529.     goto err;
  530.   if (! (flags & HA_DONT_TOUCH_DATA))
  531.   {
  532. #ifdef USE_RELOC
  533.     if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,MYF(0)))
  534.       goto err;
  535. #endif
  536.     errpos=2;
  537.     if (my_close(dfile,MYF(0)))
  538.       goto err;
  539.   }
  540.   errpos=0;
  541.   pthread_mutex_unlock(&THR_LOCK_myisam);
  542.   if (my_close(file,MYF(0)))
  543.     goto err;
  544.   my_free((char*) rec_per_key_part,MYF(0));
  545.   DBUG_RETURN(0);
  546. err:
  547.   pthread_mutex_unlock(&THR_LOCK_myisam);
  548.   save_errno=my_errno;
  549.   switch (errpos) {
  550.   case 3:
  551.     VOID(my_close(dfile,MYF(0)));
  552.     /* fall through */
  553.   case 2:
  554.   if (! (flags & HA_DONT_TOUCH_DATA))
  555.   {
  556.     /* QQ: T鮪u should add a call to my_raid_delete() here */
  557.     VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
  558.     my_delete(buff,MYF(0));
  559.   }
  560.     /* fall through */
  561.   case 1:
  562.     VOID(my_close(file,MYF(0)));
  563.     if (! (flags & HA_DONT_TOUCH_DATA))
  564.     {
  565.       VOID(fn_format(buff,name,"",MI_NAME_IEXT,2+4));
  566.       my_delete(buff,MYF(0));
  567.     }
  568.   }
  569.   my_free((char*) rec_per_key_part, MYF(0));
  570.   DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
  571. }
  572. uint mi_get_pointer_length(ulonglong file_length, uint def)
  573. {
  574.   if (file_length) /* If not default */
  575.   {
  576.     if (file_length >= (longlong) 1 << 56)
  577.       def=8;
  578.     if (file_length >= (longlong) 1 << 48)
  579.       def=7;
  580.     if (file_length >= (longlong) 1 << 40)
  581.       def=6;
  582.     else if (file_length >= (longlong) 1 << 32)
  583.       def=5;
  584.     else if (file_length >= (1L << 24))
  585.       def=4;
  586.     else if (file_length >= (1L << 16))
  587.       def=3;
  588.     else
  589.       def=2;
  590.   }
  591.   return def;
  592. }