~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_create.c

  • Committer: Toru Maesaka
  • Date: 2008-07-17 05:59:20 UTC
  • mto: (202.1.1 toru)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: dev@torum.net-20080717055920-10okif50x6nh7b1d
forgot to bzr-add new files in the previous push

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* Create a MyISAM table */
17
17
 
18
18
#include "myisamdef.h"
19
 
#include <mysys/my_tree.h>
20
 
#include <mysys/queues.h>
21
 
#include <mysys/my_bit.h>
 
19
#include <m_ctype.h>
 
20
#include <my_tree.h>
 
21
#include <queues.h>
 
22
#include <mysql/plugin.h>
 
23
#include <my_bit.h>
22
24
 
 
25
#include <m_ctype.h>
23
26
 
24
27
/*
25
28
  Old options is used when recreating database, from myisamchk
26
29
*/
27
30
 
28
 
int mi_create(const char *name,uint32_t keys,MI_KEYDEF *keydefs,
29
 
              uint32_t columns, MI_COLUMNDEF *recinfo,
30
 
              uint32_t uniques, MI_UNIQUEDEF *uniquedefs,
31
 
              MI_CREATE_INFO *ci,uint32_t flags)
 
31
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
 
32
              uint columns, MI_COLUMNDEF *recinfo,
 
33
              uint uniques, MI_UNIQUEDEF *uniquedefs,
 
34
              MI_CREATE_INFO *ci,uint flags)
32
35
{
33
 
  register uint32_t i, j;
34
 
  File dfile= 0, file= 0;
 
36
  register uint i, j;
 
37
  File dfile= 0, file;
35
38
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
36
39
  myf create_flag;
37
 
  uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
 
40
  uint fields,length,max_key_length,packed,pointer,real_length_diff,
38
41
       key_length,info_length,key_segs,options,min_key_length_skip,
39
42
       base_pos,long_varchar_count,varchar_length,
40
43
       max_key_block_length,unique_key_parts,fulltext_keys,offset;
41
 
  uint32_t aligned_key_start, block_length;
 
44
  uint aligned_key_start, block_length;
42
45
  ulong reclength, real_reclength,min_pack_length;
43
46
  char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
44
47
  ulong pack_reclength;
52
55
  ulong *rec_per_key_part;
53
56
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
54
57
  MI_CREATE_INFO tmp_create_info;
 
58
  DBUG_ENTER("mi_create");
 
59
  DBUG_PRINT("enter", ("keys: %u  columns: %u  uniques: %u  flags: %u",
 
60
                      keys, columns, uniques, flags));
55
61
 
56
62
  if (!ci)
57
63
  {
58
 
    memset(&tmp_create_info, 0, sizeof(tmp_create_info));
 
64
    bzero((char*) &tmp_create_info,sizeof(tmp_create_info));
59
65
    ci=&tmp_create_info;
60
66
  }
61
67
 
62
68
  if (keys + uniques > MI_MAX_KEY || columns == 0)
63
69
  {
64
 
    return(my_errno=HA_WRONG_CREATE_OPTION);
 
70
    DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
65
71
  }
66
72
  errpos= 0;
67
73
  options= 0;
68
 
  memset(&share, 0, sizeof(share));
 
74
  bzero((uchar*) &share,sizeof(share));
69
75
 
70
76
  if (flags & HA_DONT_TOUCH_DATA)
71
77
  {
85
91
  if (!(rec_per_key_part=
86
92
        (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
87
93
                           MYF(MY_WME | MY_ZEROFILL))))
88
 
    return(my_errno);
 
94
    DBUG_RETURN(my_errno);
89
95
 
90
96
        /* Start by checking fields and field-types used */
91
97
 
300
306
        }
301
307
        if (keyseg->flag & HA_SPACE_PACK)
302
308
        {
303
 
          assert(!(keyseg->flag & HA_VAR_LENGTH_PART));
 
309
          DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART));
304
310
          keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
305
311
          options|=HA_OPTION_PACK_KEYS;         /* Using packed keys */
306
312
          length++;                             /* At least one length byte */
313
319
        }
314
320
        if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
315
321
        {
316
 
          assert(!test_all_bits(keyseg->flag,
 
322
          DBUG_ASSERT(!test_all_bits(keyseg->flag,
317
323
                                    (HA_VAR_LENGTH_PART | HA_BLOB_PART)));
318
324
          keydef->flag|=HA_VAR_LENGTH_KEY;
319
325
          length++;                             /* At least one length byte */
354
360
    block_length= (keydef->block_length ? 
355
361
                   my_round_up_to_next_power(keydef->block_length) :
356
362
                   myisam_block_size);
357
 
    block_length= cmax(block_length, MI_MIN_KEY_BLOCK_LENGTH);
358
 
    block_length= cmin(block_length, MI_MAX_KEY_BLOCK_LENGTH);
 
363
    block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
 
364
    block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
359
365
 
360
 
    keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
 
366
    keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
361
367
                                                 pointer,MI_MAX_KEYPTR_SIZE,
362
368
                                                 block_length);
363
369
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
367
373
      goto err;
368
374
    }
369
375
    set_if_bigger(max_key_block_length,keydef->block_length);
370
 
    keydef->keylength= (uint16_t) key_length;
371
 
    keydef->minlength= (uint16_t) (length-min_key_length_skip);
372
 
    keydef->maxlength= (uint16_t) length;
 
376
    keydef->keylength= (uint16) key_length;
 
377
    keydef->minlength= (uint16) (length-min_key_length_skip);
 
378
    keydef->maxlength= (uint16) length;
373
379
 
374
380
    if (length > max_key_length)
375
381
      max_key_length= length;
403
409
                               uniques * MI_UNIQUEDEF_SIZE +
404
410
                               (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
405
411
                               columns*MI_COLUMNDEF_SIZE);
 
412
  DBUG_PRINT("info", ("info_length: %u", info_length));
406
413
  /* There are only 16 bits for the total header length. */
407
414
  if (info_length > 65535)
408
415
  {
413
420
    goto err;
414
421
  }
415
422
 
416
 
  memcpy(share.state.header.file_version,myisam_file_magic,4);
 
423
  bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
417
424
  ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
418
425
                        HA_OPTION_COMPRESS_RECORD |
419
426
                        HA_OPTION_TEMP_COMPRESS_RECORD: 0);
431
438
  share.state.unique=   (ulong) 0;
432
439
  share.state.update_count=(ulong) 0;
433
440
  share.state.version=  (ulong) time((time_t*) 0);
434
 
  share.state.sortkey=  UINT16_MAX;
 
441
  share.state.sortkey=  (ushort) ~0;
435
442
  share.state.auto_increment=ci->auto_increment;
436
443
  share.options=options;
437
444
  share.base.rec_reflength=pointer;
443
450
    got from MYI file header (see also myisampack.c:save_state)
444
451
  */
445
452
  share.base.key_reflength=
446
 
    mi_get_pointer_length(cmax(ci->key_file_length,tmp),3);
 
453
    mi_get_pointer_length(max(ci->key_file_length,tmp),3);
447
454
  share.base.keys= share.state.header.keys= keys;
448
455
  share.state.header.uniques= uniques;
449
456
  share.state.header.fulltext_keys= fulltext_keys;
476
483
  share.base.min_block_length=
477
484
    (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
478
485
     ! share.base.blobs) ?
479
 
    cmax(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
 
486
    max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
480
487
    MI_EXTEND_BLOCK_LENGTH;
481
488
  if (! (flags & HA_DONT_TOUCH_DATA))
482
489
    share.state.create_time= (long) time((time_t*) 0);
596
603
    errpos=3;
597
604
  }
598
605
 
 
606
  DBUG_PRINT("info", ("write state info and base info"));
599
607
  if (mi_state_info_write(file, &share.state, 2) ||
600
608
      mi_base_info_write(file, &share.base))
601
609
    goto err;
 
610
#ifndef DBUG_OFF
 
611
  if ((uint) my_tell(file,MYF(0)) != base_pos+ MI_BASE_INFO_SIZE)
 
612
  {
 
613
    uint pos=(uint) my_tell(file,MYF(0));
 
614
    DBUG_PRINT("warning",("base_length: %d  != used_length: %d",
 
615
                          base_pos+ MI_BASE_INFO_SIZE, pos));
 
616
  }
 
617
#endif
602
618
 
603
619
  /* Write key and keyseg definitions */
 
620
  DBUG_PRINT("info", ("write key and keyseg definitions"));
604
621
  for (i=0 ; i < share.base.keys - uniques; i++)
605
622
  {
606
 
    uint32_t sp_segs= 0;
 
623
    uint sp_segs= 0;
607
624
 
608
625
    if (mi_keydef_write(file, &keydefs[i]))
609
626
      goto err;
613
630
  }
614
631
  /* Create extra keys for unique definitions */
615
632
  offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
616
 
  memset(&tmp_keydef, 0, sizeof(tmp_keydef));
617
 
  memset(&tmp_keyseg, 0, sizeof(tmp_keyseg));
 
633
  bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
 
634
  bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
618
635
  for (i=0; i < uniques ; i++)
619
636
  {
620
637
    tmp_keydef.keysegs=1;
621
638
    tmp_keydef.flag=            HA_UNIQUE_CHECK;
622
 
    tmp_keydef.block_length=    (uint16_t)myisam_block_size;
 
639
    tmp_keydef.block_length=    (uint16)myisam_block_size;
623
640
    tmp_keydef.keylength=       MI_UNIQUE_HASH_LENGTH + pointer;
624
641
    tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
625
642
    tmp_keyseg.type=            MI_UNIQUE_HASH_TYPE;
632
649
  }
633
650
 
634
651
  /* Save unique definition */
 
652
  DBUG_PRINT("info", ("write unique definitions"));
635
653
  for (i=0 ; i < share.state.header.uniques ; i++)
636
654
  {
637
655
    HA_KEYSEG *keyseg_end;
662
680
        goto err;
663
681
    }
664
682
  }
 
683
  DBUG_PRINT("info", ("write field definitions"));
665
684
  for (i=0 ; i < share.base.fields ; i++)
666
685
    if (mi_recinfo_write(file, &recinfo[i]))
667
686
      goto err;
668
687
 
 
688
#ifndef DBUG_OFF
 
689
  if ((uint) my_tell(file,MYF(0)) != info_length)
 
690
  {
 
691
    uint pos= (uint) my_tell(file,MYF(0));
 
692
    DBUG_PRINT("warning",("info_length: %d  != used_length: %d",
 
693
                          info_length, pos));
 
694
  }
 
695
#endif
 
696
 
669
697
        /* Enlarge files */
 
698
  DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
670
699
  if (ftruncate(file, (off_t) share.base.keystart))
671
700
    goto err;
672
701
 
684
713
  pthread_mutex_unlock(&THR_LOCK_myisam);
685
714
  if (my_close(file,MYF(0)))
686
715
    goto err;
687
 
  free((char*) rec_per_key_part);
688
 
  return(0);
 
716
  my_free((char*) rec_per_key_part,MYF(0));
 
717
  DBUG_RETURN(0);
689
718
 
690
719
err:
691
720
  pthread_mutex_unlock(&THR_LOCK_myisam);
692
721
  save_errno=my_errno;
693
722
  switch (errpos) {
694
723
  case 3:
695
 
    my_close(dfile,MYF(0));
 
724
    VOID(my_close(dfile,MYF(0)));
696
725
    /* fall through */
697
726
  case 2:
698
727
    /* QQ: T�nu should add a call to my_raid_delete() here */
702
731
                           MYF(0));
703
732
    /* fall through */
704
733
  case 1:
705
 
    my_close(file,MYF(0));
 
734
    VOID(my_close(file,MYF(0)));
706
735
    if (! (flags & HA_DONT_TOUCH_DATA))
707
736
      my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
708
737
                                       MY_UNPACK_FILENAME | MY_APPEND_EXT),
709
738
                             MYF(0));
710
739
  }
711
 
  free((char*) rec_per_key_part);
712
 
  return(my_errno=save_errno);          /* return the fatal errno */
 
740
  my_free((char*) rec_per_key_part, MYF(0));
 
741
  DBUG_RETURN(my_errno=save_errno);             /* return the fatal errno */
713
742
}
714
743
 
715
744
 
716
 
uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def)
 
745
uint mi_get_pointer_length(uint64_t file_length, uint def)
717
746
{
718
 
  assert(def >= 2 && def <= 7);
 
747
  DBUG_ASSERT(def >= 2 && def <= 7);
719
748
  if (file_length)                              /* If not default */
720
749
  {
721
750
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS