~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/myisam/mi_create.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
  File dfile,file;
42
42
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
43
43
  myf create_flag;
44
 
  uint fields,length,max_key_length,packed,pointer,real_length_diff,
 
44
  uint fields,length,max_key_length,packed,pack_bytes,pointer,real_length_diff,
45
45
       key_length,info_length,key_segs,options,min_key_length_skip,
46
46
       base_pos,long_varchar_count,varchar_length,
47
47
       max_key_block_length,unique_key_parts,fulltext_keys,offset;
48
 
  uint aligned_key_start, block_length;
 
48
  uint aligned_key_start, block_length, res;
49
49
  ulong reclength, real_reclength,min_pack_length;
50
50
  char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
51
51
  ulong pack_reclength;
57
57
  HA_KEYSEG *keyseg,tmp_keyseg;
58
58
  MI_COLUMNDEF *rec;
59
59
  ulong *rec_per_key_part;
60
 
  my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
60
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
61
61
  MI_CREATE_INFO tmp_create_info;
62
62
  DBUG_ENTER("mi_create");
63
63
  DBUG_PRINT("enter", ("keys: %u  columns: %u  uniques: %u  flags: %u",
95
95
    ci->reloc_rows=ci->max_rows;                /* Check if wrong parameter */
96
96
 
97
97
  if (!(rec_per_key_part=
98
 
        (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
 
98
        (ulong*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(long),
99
99
                           MYF(MY_WME | MY_ZEROFILL))))
100
100
    DBUG_RETURN(my_errno);
101
101
 
108
108
       rec++,fields++)
109
109
  {
110
110
    reclength+=rec->length;
 
111
    if (rec->null_bit)
 
112
      options|= HA_OPTION_NULL_FIELDS;
 
113
 
111
114
    if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
112
115
        type != FIELD_CHECK)
113
116
    {
117
120
        share.base.blobs++;
118
121
        if (pack_reclength != INT_MAX32)
119
122
        {
120
 
          if (rec->length == 4+mi_portable_sizeof_char_ptr)
 
123
          if (rec->length == 4+portable_sizeof_char_ptr)
121
124
            pack_reclength= INT_MAX32;
122
125
          else
123
 
            pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */
 
126
            pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
124
127
        }
125
128
      }
126
129
      else if (type == FIELD_SKIP_PRESPACE ||
142
145
          long_varchar_count++;
143
146
          pack_reclength+= 2;                   /* May be packed on 3 bytes */
144
147
        }
 
148
        options|= HA_OPTION_NULL_FIELDS;        /* Use of mi_checksum() */
145
149
      }
146
150
      else if (type != FIELD_SKIP_ZERO)
147
151
      {
181
185
  if (flags & HA_CREATE_TMP_TABLE)
182
186
  {
183
187
    options|= HA_OPTION_TMP_TABLE;
184
 
    create_mode|= O_EXCL | O_NOFOLLOW;
 
188
    create_mode|= O_NOFOLLOW;
185
189
  }
186
190
  if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
187
191
  {
193
197
  if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
194
198
    options|= HA_OPTION_RELIES_ON_SQL_LAYER;
195
199
 
196
 
  packed=(packed+7)/8;
 
200
  pack_bytes= (packed+7)/8;
197
201
  if (pack_reclength != INT_MAX32)
198
202
    pack_reclength+= reclength+packed +
199
203
      test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
200
 
  min_pack_length+=packed;
 
204
  min_pack_length+= pack_bytes;
201
205
 
202
206
  if (!ci->data_file_length && ci->max_rows)
203
207
  {
274
278
            keyseg->type != HA_KEYTYPE_VARBINARY2)
275
279
        {
276
280
          my_errno=HA_WRONG_CREATE_OPTION;
277
 
          goto err;
 
281
          goto err_no_lock;
278
282
        }
279
283
      }
280
284
      keydef->keysegs+=sp_segs;
283
287
      min_key_length_skip+=SPLEN*2*SPDIMS;
284
288
#else
285
289
      my_errno= HA_ERR_UNSUPPORTED;
286
 
      goto err;
 
290
      goto err_no_lock;
287
291
#endif /*HAVE_SPATIAL*/
288
292
    }
289
293
    else if (keydef->flag & HA_FULLTEXT)
299
303
            keyseg->type != HA_KEYTYPE_VARTEXT2)
300
304
        {
301
305
          my_errno=HA_WRONG_CREATE_OPTION;
302
 
          goto err;
 
306
          goto err_no_lock;
303
307
        }
304
308
        if (!(keyseg->flag & HA_BLOB_PART) &&
305
309
            (keyseg->type == HA_KEYTYPE_VARTEXT1 ||
421
425
      }
422
426
    } /* if HA_FULLTEXT */
423
427
    key_segs+=keydef->keysegs;
424
 
    if (keydef->keysegs > MI_MAX_KEY_SEG)
 
428
    if (keydef->keysegs > HA_MAX_KEY_SEG)
425
429
    {
426
430
      my_errno=HA_WRONG_CREATE_OPTION;
427
 
      goto err;
 
431
      goto err_no_lock;
428
432
    }
429
433
    /*
430
434
      key_segs may be 0 in the case when we only want to be able to
436
440
      share.state.rec_per_key_part[key_segs-1]=1L;
437
441
    length+=key_length;
438
442
    /* Get block length for key, if defined by user */
439
 
    block_length= (keydef->block_length ? 
 
443
    block_length= (keydef->block_length ?
440
444
                   my_round_up_to_next_power(keydef->block_length) :
441
445
                   myisam_block_size);
442
446
    block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
446
450
                                                 pointer,MI_MAX_KEYPTR_SIZE,
447
451
                                                 block_length);
448
452
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
449
 
        length >= MI_MAX_KEY_BUFF)
 
453
        length >= HA_MAX_KEY_BUFF)
450
454
    {
451
455
      my_errno=HA_WRONG_CREATE_OPTION;
452
 
      goto err;
 
456
      goto err_no_lock;
453
457
    }
454
458
    set_if_bigger(max_key_block_length,keydef->block_length);
455
459
    keydef->keylength= (uint16) key_length;
496
500
                    "indexes and/or unique constraints.",
497
501
                    MYF(0), name + dirname_length(name));
498
502
    my_errno= HA_WRONG_CREATE_OPTION;
499
 
    goto err;
 
503
    goto err_no_lock;
500
504
  }
501
505
 
502
506
  bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
551
555
  share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
552
556
  share.base.max_pack_length=pack_reclength;
553
557
  share.base.min_pack_length=min_pack_length;
554
 
  share.base.pack_bits=packed;
 
558
  share.base.pack_bits= pack_bytes;
555
559
  share.base.fields=fields;
556
 
  share.base.pack_fields=packed;
 
560
  share.base.pack_fields= packed;
557
561
#ifdef USE_RAID
558
562
  share.base.raid_type=ci->raid_type;
559
563
  share.base.raid_chunks=ci->raid_chunks;
571
575
    MI_EXTEND_BLOCK_LENGTH;
572
576
  if (! (flags & HA_DONT_TOUCH_DATA))
573
577
    share.state.create_time= (long) time((time_t*) 0);
 
578
#ifdef THREAD
 
579
  /* This rwlock is used in mi_state_info_write(). */
 
580
  my_atomic_rwlock_init(&share.physical_logging_rwlock);
 
581
#endif
574
582
 
575
583
  pthread_mutex_lock(&THR_LOCK_myisam);
576
584
 
634
642
    my_printf_error(0, "MyISAM table '%s' is in use "
635
643
                    "(most likely by a MERGE table). Try FLUSH TABLES.",
636
644
                    MYF(0), name + dirname_length(name));
 
645
    my_errno= HA_ERR_TABLE_EXIST;
637
646
    goto err;
638
647
  }
 
648
  /*
 
649
    TRUNCATE TABLE does not work with physical logging. If we changed TRUNCATE
 
650
    to always use mi_delete_all_rows() (remove HTON_CAN_RECREATE from MyISAM)
 
651
    this would solve the problem.
 
652
 */
 
653
  DBUG_ASSERT((options & HA_OPTION_TMP_TABLE) || !mi_log_tables_physical ||
 
654
              !hash_search(mi_log_tables_physical, filename,
 
655
                           strlen(filename)));
639
656
 
640
657
  if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
641
658
                                    MYF(MY_WME | create_flag))) < 0)
701
718
  }
702
719
 
703
720
  DBUG_PRINT("info", ("write state info and base info"));
704
 
  if (mi_state_info_write(file, &share.state, 2) ||
 
721
  if (mi_state_info_write(&share, file, &share.state, 2) ||
705
722
      mi_base_info_write(file, &share.base))
706
723
    goto err;
707
724
#ifndef DBUG_OFF
827
844
  }
828
845
  errpos=0;
829
846
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
847
  res= 0;
830
848
  if (my_close(file,MYF(0)))
831
 
    goto err;
 
849
    res= my_errno;
 
850
#ifdef THREAD
 
851
  my_atomic_rwlock_destroy(&share.physical_logging_rwlock);
 
852
#endif
832
853
  my_free((char*) rec_per_key_part,MYF(0));
833
 
  DBUG_RETURN(0);
 
854
  DBUG_RETURN(res);
834
855
 
835
856
err:
836
857
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
858
err_no_lock:
 
859
 
837
860
  save_errno=my_errno;
838
861
  switch (errpos) {
839
862
  case 3:
840
 
    VOID(my_close(dfile,MYF(0)));
 
863
    (void) my_close(dfile,MYF(0));
841
864
    /* fall through */
842
865
  case 2:
843
866
    /* QQ: T�nu should add a call to my_raid_delete() here */
847
870
                           MYF(0));
848
871
    /* fall through */
849
872
  case 1:
850
 
    VOID(my_close(file,MYF(0)));
 
873
    (void) my_close(file,MYF(0));
851
874
    if (! (flags & HA_DONT_TOUCH_DATA))
852
875
      my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
853
876
                                       MY_UNPACK_FILENAME | MY_APPEND_EXT),
854
877
                             MYF(0));
855
878
  }
 
879
#ifdef THREAD
 
880
  my_atomic_rwlock_destroy(&share.physical_logging_rwlock);
 
881
#endif
856
882
  my_free((char*) rec_per_key_part, MYF(0));
857
883
  DBUG_RETURN(my_errno=save_errno);             /* return the fatal errno */
858
884
}