~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_create.c

  • Committer: Brian Aker
  • Date: 2008-07-16 01:30:24 UTC
  • Revision ID: brian@tangent.org-20080716013024-nmnogwdpa459jrch
First pass of cleanup

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