~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_create.cc

  • Committer: Monty Taylor
  • Date: 2009-08-17 18:46:08 UTC
  • mto: (1182.1.1 staging)
  • mto: This revision was merged to the branch mainline in revision 1183.
  • Revision ID: mordred@inaugust.com-20090817184608-0b2emowpjr9m6le7
"Fixed" the deadlock test. I'd still like someone to look at what's going on here.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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>
 
18
#include "myisamdef.h"
 
19
#include <mysys/my_tree.h>
 
20
#include <mysys/my_bit.h>
 
21
 
 
22
#include <drizzled/util/test.h>
 
23
 
27
24
#include <algorithm>
28
25
 
29
26
using namespace std;
30
 
using namespace drizzled;
31
27
 
32
28
/*
33
29
  Old options is used when recreating database, from myisamchk
39
35
              MI_CREATE_INFO *ci,uint32_t flags)
40
36
{
41
37
  register uint32_t i, j;
42
 
  int dfile= 0, file= 0;
 
38
  File dfile= 0, file= 0;
43
39
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
44
40
  myf create_flag;
45
41
  uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
58
54
  HA_KEYSEG *keyseg,tmp_keyseg;
59
55
  MI_COLUMNDEF *rec;
60
56
  ulong *rec_per_key_part;
61
 
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
57
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
62
58
  MI_CREATE_INFO tmp_create_info;
63
59
 
64
60
  if (!ci)
69
65
 
70
66
  if (keys + uniques > MI_MAX_KEY || columns == 0)
71
67
  {
72
 
    return(errno=HA_WRONG_CREATE_OPTION);
 
68
    return(my_errno=HA_WRONG_CREATE_OPTION);
73
69
  }
74
70
  errpos= 0;
75
71
  options= 0;
80
76
    if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
81
77
      options=ci->old_options &
82
78
        (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
83
 
         HA_OPTION_READ_ONLY_DATA |
84
 
         HA_OPTION_TMP_TABLE );
 
79
         HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
 
80
         HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
85
81
    else
86
82
      options=ci->old_options &
87
 
        (HA_OPTION_TMP_TABLE );
 
83
        (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
88
84
  }
89
85
 
90
86
  if (ci->reloc_rows > ci->max_rows)
92
88
 
93
89
  if (!(rec_per_key_part=
94
90
        (ulong*) malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long))))
95
 
    return(errno);
 
91
    return(my_errno);
96
92
  memset(rec_per_key_part, 0, (keys + uniques)*MI_MAX_KEY_SEG*sizeof(long));
97
93
 
98
94
        /* Start by checking fields and field-types used */
169
165
 
170
166
  if (packed || (flags & HA_PACK_RECORD))
171
167
    options|=HA_OPTION_PACK_RECORD;     /* Must use packed records */
 
168
  /* We can't use checksum with static length rows */
 
169
  if (!(options & HA_OPTION_PACK_RECORD))
 
170
    options&= ~HA_OPTION_CHECKSUM;
172
171
  if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
173
172
    min_pack_length+= varchar_length;
174
173
  if (flags & HA_CREATE_TMP_TABLE)
176
175
    options|= HA_OPTION_TMP_TABLE;
177
176
    create_mode|= O_EXCL;
178
177
  }
 
178
  if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
 
179
  {
 
180
    options|= HA_OPTION_CHECKSUM;
 
181
    min_pack_length++;
 
182
  }
 
183
  if (flags & HA_CREATE_DELAY_KEY_WRITE)
 
184
    options|= HA_OPTION_DELAY_KEY_WRITE;
 
185
  if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
 
186
    options|= HA_OPTION_RELIES_ON_SQL_LAYER;
179
187
 
180
188
  packed=(packed+7)/8;
181
189
  if (pack_reclength != INT32_MAX)
182
190
    pack_reclength+= reclength+packed +
183
191
      test(test_all_bits(options,
184
 
                         uint32_t(HA_PACK_RECORD)));
 
192
                         uint32_t(HA_OPTION_CHECKSUM | HA_PACK_RECORD)));
185
193
  min_pack_length+=packed;
186
194
 
187
195
  if (!ci->data_file_length && ci->max_rows)
236
244
      /* Test if prefix compression */
237
245
      if (keydef->flag & HA_PACK_KEY)
238
246
      {
 
247
        /* Can't use space_compression on number keys */
 
248
        if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
 
249
            keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
 
250
          keydef->seg[0].flag&= ~HA_SPACE_PACK;
 
251
 
239
252
        /* Only use HA_PACK_KEY when first segment is a variable length key */
240
253
        if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
241
254
                                     HA_VAR_LENGTH_PART)))
260
273
      {
261
274
        /* numbers are stored with high by first to make compression easier */
262
275
        switch (keyseg->type) {
 
276
        case HA_KEYTYPE_SHORT_INT:
263
277
        case HA_KEYTYPE_LONG_INT:
 
278
        case HA_KEYTYPE_FLOAT:
264
279
        case HA_KEYTYPE_DOUBLE:
 
280
        case HA_KEYTYPE_USHORT_INT:
265
281
        case HA_KEYTYPE_ULONG_INT:
266
282
        case HA_KEYTYPE_LONGLONG:
267
283
        case HA_KEYTYPE_ULONGLONG:
 
284
        case HA_KEYTYPE_INT24:
268
285
        case HA_KEYTYPE_UINT24:
 
286
        case HA_KEYTYPE_INT8:
269
287
          keyseg->flag|= HA_SWAP_KEY;
270
288
          break;
271
289
        case HA_KEYTYPE_VARTEXT1:
325
343
    key_segs+=keydef->keysegs;
326
344
    if (keydef->keysegs > MI_MAX_KEY_SEG)
327
345
    {
328
 
      errno=HA_WRONG_CREATE_OPTION;
 
346
      my_errno=HA_WRONG_CREATE_OPTION;
329
347
      goto err;
330
348
    }
331
349
    /*
350
368
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
351
369
        length >= MI_MAX_KEY_BUFF)
352
370
    {
353
 
      errno=HA_WRONG_CREATE_OPTION;
 
371
      my_errno=HA_WRONG_CREATE_OPTION;
354
372
      goto err;
355
373
    }
356
374
    set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
395
413
  {
396
414
    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
397
415
                    "indexes and/or unique constraints.",
398
 
                    MYF(0), name + internal::dirname_length(name));
399
 
    errno= HA_WRONG_CREATE_OPTION;
 
416
                    MYF(0), name + dirname_length(name));
 
417
    my_errno= HA_WRONG_CREATE_OPTION;
400
418
    goto err;
401
419
  }
402
420
 
449
467
  share.base.records=ci->max_rows;
450
468
  share.base.reloc=  ci->reloc_rows;
451
469
  share.base.reclength=real_reclength;
452
 
  share.base.pack_reclength=reclength;
 
470
  share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
453
471
  share.base.max_pack_length=pack_reclength;
454
472
  share.base.min_pack_length=min_pack_length;
455
473
  share.base.pack_bits=packed;
458
476
 
459
477
  /* max_data_file_length and max_key_file_length are recalculated on open */
460
478
  if (options & HA_OPTION_TMP_TABLE)
461
 
    share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
 
479
    share.base.max_data_file_length=(my_off_t) ci->data_file_length;
462
480
 
463
481
  share.base.min_block_length=
464
482
    (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
472
490
 
473
491
  /*
474
492
    NOTE: For test_if_reopen() we need a real path name. Hence we need
475
 
    MY_RETURN_REAL_PATH for every internal::fn_format(filename, ...).
 
493
    MY_RETURN_REAL_PATH for every fn_format(filename, ...).
476
494
  */
477
495
  if (ci->index_file_name)
478
496
  {
484
502
      /* chop off the table name, tempory tables use generated name */
485
503
      if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
486
504
        *path= '\0';
487
 
      internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
 
505
      fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
488
506
                MY_REPLACE_DIR | MY_UNPACK_FILENAME |
489
507
                MY_RETURN_REAL_PATH | MY_APPEND_EXT);
490
508
    }
491
509
    else
492
510
    {
493
 
      internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
 
511
      fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
494
512
                MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
495
513
                (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
496
514
    }
497
 
    internal::fn_format(linkname, name, "", MI_NAME_IEXT,
 
515
    fn_format(linkname, name, "", MI_NAME_IEXT,
498
516
              MY_UNPACK_FILENAME|MY_APPEND_EXT);
499
517
    linkname_ptr=linkname;
500
518
    /*
507
525
  {
508
526
    char *iext= strrchr((char *)name, '.');
509
527
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
510
 
    internal::fn_format(filename, name, "", MI_NAME_IEXT,
 
528
    fn_format(filename, name, "", MI_NAME_IEXT,
511
529
              MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
512
530
              (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
513
531
    linkname_ptr=0;
529
547
  {
530
548
    my_printf_error(0, "MyISAM table '%s' is in use "
531
549
                    "(most likely by a MERGE table). Try FLUSH TABLES.",
532
 
                    MYF(0), name + internal::dirname_length(name));
533
 
    errno= HA_ERR_TABLE_EXIST;
 
550
                    MYF(0), name + dirname_length(name));
 
551
    my_errno= HA_ERR_TABLE_EXIST;
534
552
    goto err;
535
553
  }
536
554
 
537
 
  if ((file= internal::my_create_with_symlink(linkname_ptr,
538
 
                                              filename,
539
 
                                              0,
540
 
                                              create_mode,
541
 
                                              MYF(MY_WME | create_flag))) < 0)
 
555
  if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
 
556
                                    MYF(MY_WME | create_flag))) < 0)
542
557
    goto err;
543
558
  errpos=1;
544
559
 
556
571
          /* chop off the table name, tempory tables use generated name */
557
572
          if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
558
573
            *path= '\0';
559
 
          internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
 
574
          fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
560
575
                    MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
561
576
        }
562
577
        else
563
578
        {
564
 
          internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
 
579
          fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
565
580
                    MY_UNPACK_FILENAME |
566
581
                    (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
567
582
        }
568
583
 
569
 
        internal::fn_format(linkname, name, "",MI_NAME_DEXT,
 
584
        fn_format(linkname, name, "",MI_NAME_DEXT,
570
585
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
571
586
        linkname_ptr=linkname;
572
587
        create_flag=0;
573
588
      }
574
589
      else
575
590
      {
576
 
        internal::fn_format(filename,name,"", MI_NAME_DEXT,
 
591
        fn_format(filename,name,"", MI_NAME_DEXT,
577
592
                  MY_UNPACK_FILENAME | MY_APPEND_EXT);
578
593
        linkname_ptr=0;
579
594
        create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
580
595
      }
581
 
      if ((dfile= internal::my_create_with_symlink(linkname_ptr,
582
 
                                                   filename, 0, create_mode,
583
 
                                                   MYF(MY_WME | create_flag))) < 0)
 
596
      if ((dfile=
 
597
           my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
 
598
                                  MYF(MY_WME | create_flag))) < 0)
584
599
        goto err;
585
600
    }
586
601
    errpos=3;
667
682
      goto err;
668
683
#endif
669
684
    errpos=2;
670
 
    if (internal::my_close(dfile,MYF(0)))
 
685
    if (my_close(dfile,MYF(0)))
671
686
      goto err;
672
687
  }
673
688
  errpos=0;
674
689
  pthread_mutex_unlock(&THR_LOCK_myisam);
675
 
  if (internal::my_close(file,MYF(0)))
 
690
  if (my_close(file,MYF(0)))
676
691
    goto err;
677
692
  free((char*) rec_per_key_part);
678
693
  return(0);
679
694
 
680
695
err:
681
696
  pthread_mutex_unlock(&THR_LOCK_myisam);
682
 
  save_errno=errno;
 
697
  save_errno=my_errno;
683
698
  switch (errpos) {
684
699
  case 3:
685
 
    internal::my_close(dfile,MYF(0));
 
700
    my_close(dfile,MYF(0));
686
701
    /* fall through */
687
702
  case 2:
688
703
  if (! (flags & HA_DONT_TOUCH_DATA))
689
 
    internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
 
704
    my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
690
705
                                     MY_UNPACK_FILENAME | MY_APPEND_EXT),
691
706
                           MYF(0));
692
707
    /* fall through */
693
708
  case 1:
694
 
    internal::my_close(file,MYF(0));
 
709
    my_close(file,MYF(0));
695
710
    if (! (flags & HA_DONT_TOUCH_DATA))
696
 
      internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
 
711
      my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
697
712
                                       MY_UNPACK_FILENAME | MY_APPEND_EXT),
698
713
                             MYF(0));
699
714
  }
700
715
  free((char*) rec_per_key_part);
701
 
  return(errno=save_errno);             /* return the fatal errno */
 
716
  return(my_errno=save_errno);          /* return the fatal errno */
702
717
}
703
718
 
704
719