~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_create.cc

  • Committer: Brian Aker
  • Date: 2009-03-25 18:24:15 UTC
  • mto: This revision was merged to the branch mainline in revision 963.
  • Revision ID: brian@tangent.org-20090325182415-opf2720c1hidtfgk
Cut down on shutdown loop of plugins (cutting stuff out in order to simplify
old lock system).

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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* Create a MyISAM table */
17
17
 
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;
 
18
#include "myisamdef.h"
 
19
#include <mysys/my_tree.h>
 
20
#include <mysys/my_bit.h>
 
21
 
 
22
#include <drizzled/util/test.h>
31
23
 
32
24
/*
33
25
  Old options is used when recreating database, from myisamchk
39
31
              MI_CREATE_INFO *ci,uint32_t flags)
40
32
{
41
33
  register uint32_t i, j;
42
 
  int dfile= 0, file= 0;
 
34
  File dfile= 0, file= 0;
43
35
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
44
36
  myf create_flag;
45
37
  uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
58
50
  HA_KEYSEG *keyseg,tmp_keyseg;
59
51
  MI_COLUMNDEF *rec;
60
52
  ulong *rec_per_key_part;
61
 
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
53
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
62
54
  MI_CREATE_INFO tmp_create_info;
63
55
 
64
56
  if (!ci)
69
61
 
70
62
  if (keys + uniques > MI_MAX_KEY || columns == 0)
71
63
  {
72
 
    return(errno=HA_WRONG_CREATE_OPTION);
 
64
    return(my_errno=HA_WRONG_CREATE_OPTION);
73
65
  }
74
66
  errpos= 0;
75
67
  options= 0;
80
72
    if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
81
73
      options=ci->old_options &
82
74
        (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
83
 
         HA_OPTION_READ_ONLY_DATA |
84
 
         HA_OPTION_TMP_TABLE );
 
75
         HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
 
76
         HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
85
77
    else
86
78
      options=ci->old_options &
87
 
        (HA_OPTION_TMP_TABLE );
 
79
        (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
88
80
  }
89
81
 
90
82
  if (ci->reloc_rows > ci->max_rows)
92
84
 
93
85
  if (!(rec_per_key_part=
94
86
        (ulong*) malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long))))
95
 
    return(errno);
 
87
    return(my_errno);
96
88
  memset(rec_per_key_part, 0, (keys + uniques)*MI_MAX_KEY_SEG*sizeof(long));
97
89
 
98
90
        /* Start by checking fields and field-types used */
169
161
 
170
162
  if (packed || (flags & HA_PACK_RECORD))
171
163
    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;
172
167
  if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
173
168
    min_pack_length+= varchar_length;
174
169
  if (flags & HA_CREATE_TMP_TABLE)
176
171
    options|= HA_OPTION_TMP_TABLE;
177
172
    create_mode|= O_EXCL;
178
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;
179
183
 
180
184
  packed=(packed+7)/8;
181
185
  if (pack_reclength != INT32_MAX)
182
186
    pack_reclength+= reclength+packed +
183
187
      test(test_all_bits(options,
184
 
                         uint32_t(HA_PACK_RECORD)));
 
188
                         uint32_t(HA_OPTION_CHECKSUM | HA_PACK_RECORD)));
185
189
  min_pack_length+=packed;
186
190
 
187
191
  if (!ci->data_file_length && ci->max_rows)
236
240
      /* Test if prefix compression */
237
241
      if (keydef->flag & HA_PACK_KEY)
238
242
      {
 
243
        /* Can't use space_compression on number keys */
 
244
        if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
 
245
            keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
 
246
          keydef->seg[0].flag&= ~HA_SPACE_PACK;
 
247
 
239
248
        /* Only use HA_PACK_KEY when first segment is a variable length key */
240
249
        if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
241
250
                                     HA_VAR_LENGTH_PART)))
260
269
      {
261
270
        /* numbers are stored with high by first to make compression easier */
262
271
        switch (keyseg->type) {
 
272
        case HA_KEYTYPE_SHORT_INT:
263
273
        case HA_KEYTYPE_LONG_INT:
 
274
        case HA_KEYTYPE_FLOAT:
264
275
        case HA_KEYTYPE_DOUBLE:
 
276
        case HA_KEYTYPE_USHORT_INT:
265
277
        case HA_KEYTYPE_ULONG_INT:
266
278
        case HA_KEYTYPE_LONGLONG:
267
279
        case HA_KEYTYPE_ULONGLONG:
 
280
        case HA_KEYTYPE_INT24:
 
281
        case HA_KEYTYPE_UINT24:
 
282
        case HA_KEYTYPE_INT8:
268
283
          keyseg->flag|= HA_SWAP_KEY;
269
284
          break;
270
285
        case HA_KEYTYPE_VARTEXT1:
324
339
    key_segs+=keydef->keysegs;
325
340
    if (keydef->keysegs > MI_MAX_KEY_SEG)
326
341
    {
327
 
      errno=HA_WRONG_CREATE_OPTION;
 
342
      my_errno=HA_WRONG_CREATE_OPTION;
328
343
      goto err;
329
344
    }
330
345
    /*
340
355
    block_length= (keydef->block_length ?
341
356
                   my_round_up_to_next_power(keydef->block_length) :
342
357
                   myisam_block_size);
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);
 
358
    block_length= cmax(block_length, MI_MIN_KEY_BLOCK_LENGTH);
 
359
    block_length= cmin(block_length, MI_MAX_KEY_BLOCK_LENGTH);
345
360
 
346
361
    keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
347
362
                                                 pointer,MI_MAX_KEYPTR_SIZE,
349
364
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
350
365
        length >= MI_MAX_KEY_BUFF)
351
366
    {
352
 
      errno=HA_WRONG_CREATE_OPTION;
 
367
      my_errno=HA_WRONG_CREATE_OPTION;
353
368
      goto err;
354
369
    }
355
370
    set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
394
409
  {
395
410
    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
396
411
                    "indexes and/or unique constraints.",
397
 
                    MYF(0), name + internal::dirname_length(name));
398
 
    errno= HA_WRONG_CREATE_OPTION;
 
412
                    MYF(0), name + dirname_length(name));
 
413
    my_errno= HA_WRONG_CREATE_OPTION;
399
414
    goto err;
400
415
  }
401
416
 
429
444
    got from MYI file header (see also myisampack.c:save_state)
430
445
  */
431
446
  share.base.key_reflength=
432
 
    mi_get_pointer_length(max(ci->key_file_length,tmp),3);
 
447
    mi_get_pointer_length(cmax(ci->key_file_length,tmp),3);
433
448
  share.base.keys= share.state.header.keys= keys;
434
449
  share.state.header.uniques= uniques;
435
450
  share.state.header.fulltext_keys= fulltext_keys;
448
463
  share.base.records=ci->max_rows;
449
464
  share.base.reloc=  ci->reloc_rows;
450
465
  share.base.reclength=real_reclength;
451
 
  share.base.pack_reclength=reclength;
 
466
  share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
452
467
  share.base.max_pack_length=pack_reclength;
453
468
  share.base.min_pack_length=min_pack_length;
454
469
  share.base.pack_bits=packed;
457
472
 
458
473
  /* max_data_file_length and max_key_file_length are recalculated on open */
459
474
  if (options & HA_OPTION_TMP_TABLE)
460
 
    share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
 
475
    share.base.max_data_file_length=(my_off_t) ci->data_file_length;
461
476
 
462
477
  share.base.min_block_length=
463
478
    (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
464
479
     ! share.base.blobs) ?
465
 
    max(share.base.pack_reclength,(ulong)MI_MIN_BLOCK_LENGTH) :
 
480
    cmax(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
466
481
    MI_EXTEND_BLOCK_LENGTH;
467
482
  if (! (flags & HA_DONT_TOUCH_DATA))
468
483
    share.state.create_time= (long) time((time_t*) 0);
469
484
 
470
 
  THR_LOCK_myisam.lock();
 
485
  pthread_mutex_lock(&THR_LOCK_myisam);
471
486
 
472
487
  /*
473
488
    NOTE: For test_if_reopen() we need a real path name. Hence we need
474
 
    MY_RETURN_REAL_PATH for every internal::fn_format(filename, ...).
 
489
    MY_RETURN_REAL_PATH for every fn_format(filename, ...).
475
490
  */
476
491
  if (ci->index_file_name)
477
492
  {
483
498
      /* chop off the table name, tempory tables use generated name */
484
499
      if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
485
500
        *path= '\0';
486
 
      internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
 
501
      fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
487
502
                MY_REPLACE_DIR | MY_UNPACK_FILENAME |
488
503
                MY_RETURN_REAL_PATH | MY_APPEND_EXT);
489
504
    }
490
505
    else
491
506
    {
492
 
      internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
 
507
      fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
493
508
                MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
494
509
                (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
495
510
    }
496
 
    internal::fn_format(linkname, name, "", MI_NAME_IEXT,
 
511
    fn_format(linkname, name, "", MI_NAME_IEXT,
497
512
              MY_UNPACK_FILENAME|MY_APPEND_EXT);
498
513
    linkname_ptr=linkname;
499
514
    /*
506
521
  {
507
522
    char *iext= strrchr((char *)name, '.');
508
523
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
509
 
    internal::fn_format(filename, name, "", MI_NAME_IEXT,
 
524
    fn_format(filename, name, "", MI_NAME_IEXT,
510
525
              MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
511
526
              (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
512
527
    linkname_ptr=0;
528
543
  {
529
544
    my_printf_error(0, "MyISAM table '%s' is in use "
530
545
                    "(most likely by a MERGE table). Try FLUSH TABLES.",
531
 
                    MYF(0), name + internal::dirname_length(name));
532
 
    errno= HA_ERR_TABLE_EXIST;
 
546
                    MYF(0), name + dirname_length(name));
 
547
    my_errno= HA_ERR_TABLE_EXIST;
533
548
    goto err;
534
549
  }
535
550
 
536
 
  if ((file= internal::my_create_with_symlink(linkname_ptr,
537
 
                                              filename,
538
 
                                              0,
539
 
                                              create_mode,
540
 
                                              MYF(MY_WME | create_flag))) < 0)
 
551
  if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
 
552
                                    MYF(MY_WME | create_flag))) < 0)
541
553
    goto err;
542
554
  errpos=1;
543
555
 
555
567
          /* chop off the table name, tempory tables use generated name */
556
568
          if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
557
569
            *path= '\0';
558
 
          internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
 
570
          fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
559
571
                    MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
560
572
        }
561
573
        else
562
574
        {
563
 
          internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
 
575
          fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
564
576
                    MY_UNPACK_FILENAME |
565
577
                    (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
566
578
        }
567
579
 
568
 
        internal::fn_format(linkname, name, "",MI_NAME_DEXT,
 
580
        fn_format(linkname, name, "",MI_NAME_DEXT,
569
581
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
570
582
        linkname_ptr=linkname;
571
583
        create_flag=0;
572
584
      }
573
585
      else
574
586
      {
575
 
        internal::fn_format(filename,name,"", MI_NAME_DEXT,
 
587
        fn_format(filename,name,"", MI_NAME_DEXT,
576
588
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
577
589
        linkname_ptr=0;
578
590
        create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
579
591
      }
580
 
      if ((dfile= internal::my_create_with_symlink(linkname_ptr,
581
 
                                                   filename, 0, create_mode,
582
 
                                                   MYF(MY_WME | create_flag))) < 0)
 
592
      if ((dfile=
 
593
           my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
 
594
                                  MYF(MY_WME | create_flag))) < 0)
583
595
        goto err;
584
596
    }
585
597
    errpos=3;
666
678
      goto err;
667
679
#endif
668
680
    errpos=2;
669
 
    if (internal::my_close(dfile,MYF(0)))
 
681
    if (my_close(dfile,MYF(0)))
670
682
      goto err;
671
683
  }
672
684
  errpos=0;
673
 
  THR_LOCK_myisam.unlock();
674
 
  if (internal::my_close(file,MYF(0)))
 
685
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
686
  if (my_close(file,MYF(0)))
675
687
    goto err;
676
688
  free((char*) rec_per_key_part);
677
689
  return(0);
678
690
 
679
691
err:
680
 
  THR_LOCK_myisam.unlock();
681
 
  save_errno=errno;
 
692
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
693
  save_errno=my_errno;
682
694
  switch (errpos) {
683
695
  case 3:
684
 
    internal::my_close(dfile,MYF(0));
 
696
    my_close(dfile,MYF(0));
685
697
    /* fall through */
686
698
  case 2:
687
699
  if (! (flags & HA_DONT_TOUCH_DATA))
688
 
    internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
 
700
    my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
689
701
                                     MY_UNPACK_FILENAME | MY_APPEND_EXT),
690
702
                           MYF(0));
691
703
    /* fall through */
692
704
  case 1:
693
 
    internal::my_close(file,MYF(0));
 
705
    my_close(file,MYF(0));
694
706
    if (! (flags & HA_DONT_TOUCH_DATA))
695
 
      internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
 
707
      my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
696
708
                                       MY_UNPACK_FILENAME | MY_APPEND_EXT),
697
709
                             MYF(0));
698
710
  }
699
711
  free((char*) rec_per_key_part);
700
 
  return(errno=save_errno);             /* return the fatal errno */
 
712
  return(my_errno=save_errno);          /* return the fatal errno */
701
713
}
702
714
 
703
715