~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_create.cc

  • Committer: Monty Taylor
  • Date: 2010-10-15 17:18:02 UTC
  • mto: (1859.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1860.
  • Revision ID: mordred@inaugust.com-20101015171802-qhk6zyfhrkvprr1n
Added support for registering regular sys_var instances via module::Context.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/* Create a MyISAM table */
17
17
 
18
 
#include "myisamdef.h"
19
 
#include <mysys/my_tree.h>
20
 
#include <mysys/queues.h>
21
 
#include <mysys/my_bit.h>
22
 
 
 
18
#include "myisam_priv.h"
 
19
#include "drizzled/internal/my_bit.h"
 
20
#include "drizzled/internal/my_sys.h"
 
21
 
 
22
#include "drizzled/util/test.h"
 
23
#include "drizzled/global_charset_info.h"
 
24
#include "drizzled/error.h"
 
25
 
 
26
#include <cassert>
 
27
#include <algorithm>
 
28
 
 
29
using namespace std;
 
30
using namespace drizzled;
23
31
 
24
32
/*
25
33
  Old options is used when recreating database, from myisamchk
26
34
*/
27
35
 
28
 
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
29
 
              uint columns, MI_COLUMNDEF *recinfo,
30
 
              uint uniques, MI_UNIQUEDEF *uniquedefs,
31
 
              MI_CREATE_INFO *ci,uint flags)
 
36
int mi_create(const char *name,uint32_t keys,MI_KEYDEF *keydefs,
 
37
              uint32_t columns, MI_COLUMNDEF *recinfo,
 
38
              uint32_t uniques, MI_UNIQUEDEF *uniquedefs,
 
39
              MI_CREATE_INFO *ci,uint32_t flags)
32
40
{
33
 
  register uint i, j;
34
 
  File dfile= 0, file= 0;
 
41
  register uint32_t i, j;
 
42
  int dfile= 0, file= 0;
35
43
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
36
44
  myf create_flag;
37
 
  uint fields,length,max_key_length,packed,pointer,real_length_diff,
 
45
  uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
38
46
       key_length,info_length,key_segs,options,min_key_length_skip,
39
47
       base_pos,long_varchar_count,varchar_length,
40
48
       max_key_block_length,unique_key_parts,fulltext_keys,offset;
41
 
  uint aligned_key_start, block_length;
 
49
  uint32_t aligned_key_start, block_length;
42
50
  ulong reclength, real_reclength,min_pack_length;
43
51
  char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
44
52
  ulong pack_reclength;
50
58
  HA_KEYSEG *keyseg,tmp_keyseg;
51
59
  MI_COLUMNDEF *rec;
52
60
  ulong *rec_per_key_part;
53
 
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
61
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
54
62
  MI_CREATE_INFO tmp_create_info;
55
63
 
56
64
  if (!ci)
61
69
 
62
70
  if (keys + uniques > MI_MAX_KEY || columns == 0)
63
71
  {
64
 
    return(my_errno=HA_WRONG_CREATE_OPTION);
 
72
    return(errno=HA_WRONG_CREATE_OPTION);
65
73
  }
66
74
  errpos= 0;
67
75
  options= 0;
72
80
    if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
73
81
      options=ci->old_options &
74
82
        (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);
 
83
         HA_OPTION_READ_ONLY_DATA |
 
84
         HA_OPTION_TMP_TABLE );
77
85
    else
78
86
      options=ci->old_options &
79
 
        (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
 
87
        (HA_OPTION_TMP_TABLE );
80
88
  }
81
89
 
82
90
  if (ci->reloc_rows > ci->max_rows)
83
91
    ci->reloc_rows=ci->max_rows;                /* Check if wrong parameter */
84
92
 
85
93
  if (!(rec_per_key_part=
86
 
        (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
87
 
                           MYF(MY_WME | MY_ZEROFILL))))
88
 
    return(my_errno);
 
94
        (ulong*) malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long))))
 
95
    return(errno);
 
96
  memset(rec_per_key_part, 0, (keys + uniques)*MI_MAX_KEY_SEG*sizeof(long));
89
97
 
90
98
        /* Start by checking fields and field-types used */
91
99
 
161
169
 
162
170
  if (packed || (flags & HA_PACK_RECORD))
163
171
    options|=HA_OPTION_PACK_RECORD;     /* Must use packed records */
164
 
  /* We can't use checksum with static length rows */
165
 
  if (!(options & HA_OPTION_PACK_RECORD))
166
 
    options&= ~HA_OPTION_CHECKSUM;
167
172
  if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
168
173
    min_pack_length+= varchar_length;
169
174
  if (flags & HA_CREATE_TMP_TABLE)
170
175
  {
171
176
    options|= HA_OPTION_TMP_TABLE;
172
 
    create_mode|= O_EXCL | O_NOFOLLOW;
173
 
  }
174
 
  if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
175
 
  {
176
 
    options|= HA_OPTION_CHECKSUM;
177
 
    min_pack_length++;
178
 
  }
179
 
  if (flags & HA_CREATE_DELAY_KEY_WRITE)
180
 
    options|= HA_OPTION_DELAY_KEY_WRITE;
181
 
  if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
182
 
    options|= HA_OPTION_RELIES_ON_SQL_LAYER;
 
177
    create_mode|= O_EXCL;
 
178
  }
183
179
 
184
180
  packed=(packed+7)/8;
185
181
  if (pack_reclength != INT32_MAX)
186
182
    pack_reclength+= reclength+packed +
187
 
      test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
 
183
      test(test_all_bits(options,
 
184
                         uint32_t(HA_PACK_RECORD)));
188
185
  min_pack_length+=packed;
189
186
 
190
187
  if (!ci->data_file_length && ci->max_rows)
201
198
                                          3 : 0)));
202
199
 
203
200
  if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
204
 
    pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size);
 
201
    pointer=mi_get_pointer_length(ci->data_file_length, data_pointer_size);
205
202
  else
206
 
    pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size);
 
203
    pointer=mi_get_pointer_length(ci->max_rows, data_pointer_size);
207
204
  if (!(max_rows=(uint64_t) ci->max_rows))
208
205
    max_rows= ((((uint64_t) 1 << (pointer*8)) -1) / min_pack_length);
209
206
 
239
236
      /* Test if prefix compression */
240
237
      if (keydef->flag & HA_PACK_KEY)
241
238
      {
242
 
        /* Can't use space_compression on number keys */
243
 
        if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
244
 
            keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
245
 
          keydef->seg[0].flag&= ~HA_SPACE_PACK;
246
 
 
247
239
        /* Only use HA_PACK_KEY when first segment is a variable length key */
248
240
        if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
249
241
                                     HA_VAR_LENGTH_PART)))
268
260
      {
269
261
        /* numbers are stored with high by first to make compression easier */
270
262
        switch (keyseg->type) {
271
 
        case HA_KEYTYPE_SHORT_INT:
272
263
        case HA_KEYTYPE_LONG_INT:
273
 
        case HA_KEYTYPE_FLOAT:
274
264
        case HA_KEYTYPE_DOUBLE:
275
 
        case HA_KEYTYPE_USHORT_INT:
276
265
        case HA_KEYTYPE_ULONG_INT:
277
266
        case HA_KEYTYPE_LONGLONG:
278
267
        case HA_KEYTYPE_ULONGLONG:
279
 
        case HA_KEYTYPE_INT24:
280
 
        case HA_KEYTYPE_UINT24:
281
 
        case HA_KEYTYPE_INT8:
282
268
          keyseg->flag|= HA_SWAP_KEY;
283
269
          break;
284
270
        case HA_KEYTYPE_VARTEXT1:
338
324
    key_segs+=keydef->keysegs;
339
325
    if (keydef->keysegs > MI_MAX_KEY_SEG)
340
326
    {
341
 
      my_errno=HA_WRONG_CREATE_OPTION;
 
327
      errno=HA_WRONG_CREATE_OPTION;
342
328
      goto err;
343
329
    }
344
330
    /*
351
337
      share.state.rec_per_key_part[key_segs-1]=1L;
352
338
    length+=key_length;
353
339
    /* Get block length for key, if defined by user */
354
 
    block_length= (keydef->block_length ? 
 
340
    block_length= (keydef->block_length ?
355
341
                   my_round_up_to_next_power(keydef->block_length) :
356
342
                   myisam_block_size);
357
 
    block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
358
 
    block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
 
343
    block_length= max(block_length, (uint32_t)MI_MIN_KEY_BLOCK_LENGTH);
 
344
    block_length= min(block_length, (uint32_t)MI_MAX_KEY_BLOCK_LENGTH);
359
345
 
360
346
    keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
361
347
                                                 pointer,MI_MAX_KEYPTR_SIZE,
363
349
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
364
350
        length >= MI_MAX_KEY_BUFF)
365
351
    {
366
 
      my_errno=HA_WRONG_CREATE_OPTION;
 
352
      errno=HA_WRONG_CREATE_OPTION;
367
353
      goto err;
368
354
    }
369
 
    set_if_bigger(max_key_block_length,keydef->block_length);
 
355
    set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
370
356
    keydef->keylength= (uint16_t) key_length;
371
357
    keydef->minlength= (uint16_t) (length-min_key_length_skip);
372
358
    keydef->maxlength= (uint16_t) length;
408
394
  {
409
395
    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
410
396
                    "indexes and/or unique constraints.",
411
 
                    MYF(0), name + dirname_length(name));
412
 
    my_errno= HA_WRONG_CREATE_OPTION;
 
397
                    MYF(0), name + internal::dirname_length(name));
 
398
    errno= HA_WRONG_CREATE_OPTION;
413
399
    goto err;
414
400
  }
415
401
 
416
 
  memcpy(share.state.header.file_version,myisam_file_magic,4);
 
402
  memmove(share.state.header.file_version,myisam_file_magic,4);
417
403
  ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
418
404
                        HA_OPTION_COMPRESS_RECORD |
419
405
                        HA_OPTION_TEMP_COMPRESS_RECORD: 0);
431
417
  share.state.unique=   (ulong) 0;
432
418
  share.state.update_count=(ulong) 0;
433
419
  share.state.version=  (ulong) time((time_t*) 0);
434
 
  share.state.sortkey=  (ushort) ~0;
 
420
  share.state.sortkey=  UINT16_MAX;
435
421
  share.state.auto_increment=ci->auto_increment;
436
422
  share.options=options;
437
423
  share.base.rec_reflength=pointer;
462
448
  share.base.records=ci->max_rows;
463
449
  share.base.reloc=  ci->reloc_rows;
464
450
  share.base.reclength=real_reclength;
465
 
  share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
 
451
  share.base.pack_reclength=reclength;
466
452
  share.base.max_pack_length=pack_reclength;
467
453
  share.base.min_pack_length=min_pack_length;
468
454
  share.base.pack_bits=packed;
471
457
 
472
458
  /* max_data_file_length and max_key_file_length are recalculated on open */
473
459
  if (options & HA_OPTION_TMP_TABLE)
474
 
    share.base.max_data_file_length=(my_off_t) ci->data_file_length;
 
460
    share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
475
461
 
476
462
  share.base.min_block_length=
477
463
    (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
478
464
     ! share.base.blobs) ?
479
 
    max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
 
465
    max(share.base.pack_reclength,(ulong)MI_MIN_BLOCK_LENGTH) :
480
466
    MI_EXTEND_BLOCK_LENGTH;
481
467
  if (! (flags & HA_DONT_TOUCH_DATA))
482
468
    share.state.create_time= (long) time((time_t*) 0);
483
469
 
484
 
  pthread_mutex_lock(&THR_LOCK_myisam);
 
470
  THR_LOCK_myisam.lock();
485
471
 
486
472
  /*
487
473
    NOTE: For test_if_reopen() we need a real path name. Hence we need
488
 
    MY_RETURN_REAL_PATH for every fn_format(filename, ...).
 
474
    MY_RETURN_REAL_PATH for every internal::fn_format(filename, ...).
489
475
  */
490
476
  if (ci->index_file_name)
491
477
  {
492
 
    char *iext= strrchr(ci->index_file_name, '.');
 
478
    char *iext= strrchr((char *)ci->index_file_name, '.');
493
479
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
494
480
    if (options & HA_OPTION_TMP_TABLE)
495
481
    {
496
482
      char *path;
497
483
      /* chop off the table name, tempory tables use generated name */
498
 
      if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
 
484
      if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
499
485
        *path= '\0';
500
 
      fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
 
486
      internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
501
487
                MY_REPLACE_DIR | MY_UNPACK_FILENAME |
502
488
                MY_RETURN_REAL_PATH | MY_APPEND_EXT);
503
489
    }
504
490
    else
505
491
    {
506
 
      fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
 
492
      internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
507
493
                MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
508
494
                (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
509
495
    }
510
 
    fn_format(linkname, name, "", MI_NAME_IEXT,
 
496
    internal::fn_format(linkname, name, "", MI_NAME_IEXT,
511
497
              MY_UNPACK_FILENAME|MY_APPEND_EXT);
512
498
    linkname_ptr=linkname;
513
499
    /*
518
504
  }
519
505
  else
520
506
  {
521
 
    char *iext= strrchr(name, '.');
 
507
    char *iext= strrchr((char *)name, '.');
522
508
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
523
 
    fn_format(filename, name, "", MI_NAME_IEXT,
 
509
    internal::fn_format(filename, name, "", MI_NAME_IEXT,
524
510
              MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
525
511
              (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
526
512
    linkname_ptr=0;
542
528
  {
543
529
    my_printf_error(0, "MyISAM table '%s' is in use "
544
530
                    "(most likely by a MERGE table). Try FLUSH TABLES.",
545
 
                    MYF(0), name + dirname_length(name));
546
 
    my_errno= HA_ERR_TABLE_EXIST;
 
531
                    MYF(0), name + internal::dirname_length(name));
 
532
    errno= HA_ERR_TABLE_EXIST;
547
533
    goto err;
548
534
  }
549
535
 
550
 
  if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
551
 
                                    MYF(MY_WME | create_flag))) < 0)
 
536
  if ((file= internal::my_create_with_symlink(linkname_ptr,
 
537
                                              filename,
 
538
                                              0,
 
539
                                              create_mode,
 
540
                                              MYF(MY_WME | create_flag))) < 0)
552
541
    goto err;
553
542
  errpos=1;
554
543
 
557
546
    {
558
547
      if (ci->data_file_name)
559
548
      {
560
 
        char *dext= strrchr(ci->data_file_name, '.');
 
549
        char *dext= strrchr((char *)ci->data_file_name, '.');
561
550
        int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
562
551
 
563
552
        if (options & HA_OPTION_TMP_TABLE)
564
553
        {
565
554
          char *path;
566
555
          /* chop off the table name, tempory tables use generated name */
567
 
          if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
 
556
          if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
568
557
            *path= '\0';
569
 
          fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
 
558
          internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
570
559
                    MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
571
560
        }
572
561
        else
573
562
        {
574
 
          fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
 
563
          internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
575
564
                    MY_UNPACK_FILENAME |
576
565
                    (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
577
566
        }
578
567
 
579
 
        fn_format(linkname, name, "",MI_NAME_DEXT,
 
568
        internal::fn_format(linkname, name, "",MI_NAME_DEXT,
580
569
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
581
570
        linkname_ptr=linkname;
582
571
        create_flag=0;
583
572
      }
584
573
      else
585
574
      {
586
 
        fn_format(filename,name,"", MI_NAME_DEXT,
 
575
        internal::fn_format(filename,name,"", MI_NAME_DEXT,
587
576
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
588
577
        linkname_ptr=0;
589
578
        create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
590
579
      }
591
 
      if ((dfile=
592
 
           my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
593
 
                                  MYF(MY_WME | create_flag))) < 0)
 
580
      if ((dfile= internal::my_create_with_symlink(linkname_ptr,
 
581
                                                   filename, 0, create_mode,
 
582
                                                   MYF(MY_WME | create_flag))) < 0)
594
583
        goto err;
595
584
    }
596
585
    errpos=3;
603
592
  /* Write key and keyseg definitions */
604
593
  for (i=0 ; i < share.base.keys - uniques; i++)
605
594
  {
606
 
    uint sp_segs= 0;
 
595
    uint32_t sp_segs= 0;
607
596
 
608
597
    if (mi_keydef_write(file, &keydefs[i]))
609
598
      goto err;
677
666
      goto err;
678
667
#endif
679
668
    errpos=2;
680
 
    if (my_close(dfile,MYF(0)))
 
669
    if (internal::my_close(dfile,MYF(0)))
681
670
      goto err;
682
671
  }
683
672
  errpos=0;
684
 
  pthread_mutex_unlock(&THR_LOCK_myisam);
685
 
  if (my_close(file,MYF(0)))
 
673
  THR_LOCK_myisam.unlock();
 
674
  if (internal::my_close(file,MYF(0)))
686
675
    goto err;
687
 
  my_free((char*) rec_per_key_part,MYF(0));
 
676
  free((char*) rec_per_key_part);
688
677
  return(0);
689
678
 
690
679
err:
691
 
  pthread_mutex_unlock(&THR_LOCK_myisam);
692
 
  save_errno=my_errno;
 
680
  THR_LOCK_myisam.unlock();
 
681
  save_errno=errno;
693
682
  switch (errpos) {
694
683
  case 3:
695
 
    VOID(my_close(dfile,MYF(0)));
 
684
    internal::my_close(dfile,MYF(0));
696
685
    /* fall through */
697
686
  case 2:
698
 
    /* QQ: T�nu should add a call to my_raid_delete() here */
699
687
  if (! (flags & HA_DONT_TOUCH_DATA))
700
 
    my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
 
688
    internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
701
689
                                     MY_UNPACK_FILENAME | MY_APPEND_EXT),
702
690
                           MYF(0));
703
691
    /* fall through */
704
692
  case 1:
705
 
    VOID(my_close(file,MYF(0)));
 
693
    internal::my_close(file,MYF(0));
706
694
    if (! (flags & HA_DONT_TOUCH_DATA))
707
 
      my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
 
695
      internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
708
696
                                       MY_UNPACK_FILENAME | MY_APPEND_EXT),
709
697
                             MYF(0));
710
698
  }
711
 
  my_free((char*) rec_per_key_part, MYF(0));
712
 
  return(my_errno=save_errno);          /* return the fatal errno */
 
699
  free((char*) rec_per_key_part);
 
700
  return(errno=save_errno);             /* return the fatal errno */
713
701
}
714
702
 
715
703
 
716
 
uint mi_get_pointer_length(uint64_t file_length, uint def)
 
704
uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def)
717
705
{
718
706
  assert(def >= 2 && def <= 7);
719
707
  if (file_length)                              /* If not default */