1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
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 */
16
/* Create a MyISAM table */
22
#if defined(MSDOS) || defined(__WIN__)
26
#include <process.h> /* Prototype for getpid */
32
Old options is used when recreating database, from myisamchk
35
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
36
uint columns, MI_COLUMNDEF *recinfo,
37
uint uniques, MI_UNIQUEDEF *uniquedefs,
38
MI_CREATE_INFO *ci,uint flags)
42
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
44
uint fields,length,max_key_length,packed,pointer,real_length_diff,
45
key_length,info_length,key_segs,options,min_key_length_skip,
46
base_pos,long_varchar_count,varchar_length,
47
max_key_block_length,unique_key_parts,fulltext_keys,offset;
48
uint aligned_key_start, block_length;
49
ulong reclength, real_reclength,min_pack_length;
50
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
52
ulonglong tot_length,max_rows, tmp;
53
enum en_fieldtype type;
55
MI_KEYDEF *keydef,tmp_keydef;
56
MI_UNIQUEDEF *uniquedef;
57
HA_KEYSEG *keyseg,tmp_keyseg;
59
ulong *rec_per_key_part;
60
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
61
MI_CREATE_INFO tmp_create_info;
62
DBUG_ENTER("mi_create");
63
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
64
keys, columns, uniques, flags));
68
bzero((char*) &tmp_create_info,sizeof(tmp_create_info));
72
if (keys + uniques > MI_MAX_KEY || columns == 0)
74
DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
78
bzero((uchar*) &share,sizeof(share));
80
if (flags & HA_DONT_TOUCH_DATA)
82
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
83
options=ci->old_options &
84
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
85
HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
86
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
88
options=ci->old_options &
89
(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
92
if (ci->reloc_rows > ci->max_rows)
93
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
95
if (!(rec_per_key_part=
96
(ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
97
MYF(MY_WME | MY_ZEROFILL))))
98
DBUG_RETURN(my_errno);
100
/* Start by checking fields and field-types used */
102
reclength=varchar_length=long_varchar_count=packed=
103
min_pack_length=pack_reclength=0;
104
for (rec=recinfo, fields=0 ;
108
reclength+=rec->length;
109
if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
113
if (type == FIELD_BLOB)
116
if (pack_reclength != INT_MAX32)
118
if (rec->length == 4+portable_sizeof_char_ptr)
119
pack_reclength= INT_MAX32;
121
pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
124
else if (type == FIELD_SKIP_PRESPACE ||
125
type == FIELD_SKIP_ENDSPACE)
127
if (pack_reclength != INT_MAX32)
128
pack_reclength+= rec->length > 255 ? 2 : 1;
131
else if (type == FIELD_VARCHAR)
133
varchar_length+= rec->length-1; /* Used for min_pack_length */
137
/* We must test for 257 as length includes pack-length */
138
if (test(rec->length >= 257))
140
long_varchar_count++;
141
pack_reclength+= 2; /* May be packed on 3 bytes */
144
else if (type != FIELD_SKIP_ZERO)
146
min_pack_length+=rec->length;
147
packed--; /* Not a pack record type */
150
else /* FIELD_NORMAL */
151
min_pack_length+=rec->length;
153
if ((packed & 7) == 1)
154
{ /* Bad packing, try to remove a zero-field */
155
while (rec != recinfo)
158
if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
161
NOTE1: here we change a field type FIELD_SKIP_ZERO ->
164
rec->type=(int) FIELD_NORMAL;
172
if (packed || (flags & HA_PACK_RECORD))
173
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
174
/* We can't use checksum with static length rows */
175
if (!(options & HA_OPTION_PACK_RECORD))
176
options&= ~HA_OPTION_CHECKSUM;
177
if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
178
min_pack_length+= varchar_length;
179
if (flags & HA_CREATE_TMP_TABLE)
181
options|= HA_OPTION_TMP_TABLE;
182
create_mode|= O_EXCL | O_NOFOLLOW;
184
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
186
options|= HA_OPTION_CHECKSUM;
189
if (flags & HA_CREATE_DELAY_KEY_WRITE)
190
options|= HA_OPTION_DELAY_KEY_WRITE;
191
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
192
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
195
if (pack_reclength != INT_MAX32)
196
pack_reclength+= reclength+packed +
197
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
198
min_pack_length+=packed;
200
if (!ci->data_file_length && ci->max_rows)
202
if (pack_reclength == INT_MAX32 ||
203
(~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
204
ci->data_file_length= ~(ulonglong) 0;
206
ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
208
else if (!ci->max_rows)
209
ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
210
((options & HA_OPTION_PACK_RECORD) ?
213
if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
214
pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size);
216
pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size);
217
if (!(max_rows=(ulonglong) ci->max_rows))
218
max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);
221
real_reclength=reclength;
222
if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
224
if (reclength <= pointer)
225
reclength=pointer+1; /* reserve place for delete link */
228
reclength+= long_varchar_count; /* We need space for varchar! */
230
max_key_length=0; tot_length=0 ; key_segs=0;
232
max_key_block_length=0;
233
share.state.rec_per_key_part=rec_per_key_part;
234
share.state.key_root=key_root;
235
share.state.key_del=key_del;
238
max_key_block_length= myisam_block_size;
239
max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
242
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
245
share.state.key_root[i]= HA_OFFSET_ERROR;
246
min_key_length_skip=length=real_length_diff=0;
248
if (keydef->flag & HA_SPATIAL)
251
/* BAR TODO to support 3D and more dimensions in the future */
252
uint sp_segs=SPDIMS*2;
253
keydef->flag=HA_SPATIAL;
255
if (flags & HA_DONT_TOUCH_DATA)
258
called by myisamchk - i.e. table structure was taken from
259
MYI file and SPATIAL key *does have* additional sp_segs keysegs.
260
keydef->seg here points right at the GEOMETRY segment,
261
so we only need to decrease keydef->keysegs.
262
(see recreate_table() in mi_check.c)
264
keydef->keysegs-=sp_segs-1;
267
for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
270
if (keyseg->type != HA_KEYTYPE_BINARY &&
271
keyseg->type != HA_KEYTYPE_VARBINARY1 &&
272
keyseg->type != HA_KEYTYPE_VARBINARY2)
274
my_errno=HA_WRONG_CREATE_OPTION;
278
keydef->keysegs+=sp_segs;
279
key_length+=SPLEN*sp_segs;
280
length++; /* At least one length byte */
281
min_key_length_skip+=SPLEN*2*SPDIMS;
283
my_errno= HA_ERR_UNSUPPORTED;
285
#endif /*HAVE_SPATIAL*/
287
else if (keydef->flag & HA_FULLTEXT)
289
keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
290
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
292
for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
295
if (keyseg->type != HA_KEYTYPE_TEXT &&
296
keyseg->type != HA_KEYTYPE_VARTEXT1 &&
297
keyseg->type != HA_KEYTYPE_VARTEXT2)
299
my_errno=HA_WRONG_CREATE_OPTION;
302
if (!(keyseg->flag & HA_BLOB_PART) &&
303
(keyseg->type == HA_KEYTYPE_VARTEXT1 ||
304
keyseg->type == HA_KEYTYPE_VARTEXT2))
306
/* Make a flag that this is a VARCHAR */
307
keyseg->flag|= HA_VAR_LENGTH_PART;
308
/* Store in bit_start number of bytes used to pack the length */
309
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1)?
315
key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN;
316
length++; /* At least one length byte */
317
min_key_length_skip+=HA_FT_MAXBYTELEN;
318
real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT;
322
/* Test if prefix compression */
323
if (keydef->flag & HA_PACK_KEY)
325
/* Can't use space_compression on number keys */
326
if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
327
keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
328
keydef->seg[0].flag&= ~HA_SPACE_PACK;
330
/* Only use HA_PACK_KEY when first segment is a variable length key */
331
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
332
HA_VAR_LENGTH_PART)))
334
/* pack relative to previous key */
335
keydef->flag&= ~HA_PACK_KEY;
336
keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
340
keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */
341
keydef->flag|=HA_VAR_LENGTH_KEY;
342
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
345
if (keydef->flag & HA_BINARY_PACK_KEY)
346
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
348
if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment)
349
share.base.auto_key=i+1;
350
for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
352
/* numbers are stored with high by first to make compression easier */
353
switch (keyseg->type) {
354
case HA_KEYTYPE_SHORT_INT:
355
case HA_KEYTYPE_LONG_INT:
356
case HA_KEYTYPE_FLOAT:
357
case HA_KEYTYPE_DOUBLE:
358
case HA_KEYTYPE_USHORT_INT:
359
case HA_KEYTYPE_ULONG_INT:
360
case HA_KEYTYPE_LONGLONG:
361
case HA_KEYTYPE_ULONGLONG:
362
case HA_KEYTYPE_INT24:
363
case HA_KEYTYPE_UINT24:
364
case HA_KEYTYPE_INT8:
365
keyseg->flag|= HA_SWAP_KEY;
367
case HA_KEYTYPE_VARTEXT1:
368
case HA_KEYTYPE_VARTEXT2:
369
case HA_KEYTYPE_VARBINARY1:
370
case HA_KEYTYPE_VARBINARY2:
371
if (!(keyseg->flag & HA_BLOB_PART))
373
/* Make a flag that this is a VARCHAR */
374
keyseg->flag|= HA_VAR_LENGTH_PART;
375
/* Store in bit_start number of bytes used to pack the length */
376
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
377
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
384
if (keyseg->flag & HA_SPACE_PACK)
386
DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART));
387
keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
388
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
389
length++; /* At least one length byte */
390
min_key_length_skip+=keyseg->length;
391
if (keyseg->length >= 255)
392
{ /* prefix may be 3 bytes */
393
min_key_length_skip+=2;
397
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
399
DBUG_ASSERT(!test_all_bits(keyseg->flag,
400
(HA_VAR_LENGTH_PART | HA_BLOB_PART)));
401
keydef->flag|=HA_VAR_LENGTH_KEY;
402
length++; /* At least one length byte */
403
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
404
min_key_length_skip+=keyseg->length;
405
if (keyseg->length >= 255)
406
{ /* prefix may be 3 bytes */
407
min_key_length_skip+=2;
411
key_length+= keyseg->length;
412
if (keyseg->null_bit)
415
options|=HA_OPTION_PACK_KEYS;
416
keyseg->flag|=HA_NULL_PART;
417
keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY;
420
} /* if HA_FULLTEXT */
421
key_segs+=keydef->keysegs;
422
if (keydef->keysegs > MI_MAX_KEY_SEG)
424
my_errno=HA_WRONG_CREATE_OPTION;
428
key_segs may be 0 in the case when we only want to be able to
429
add on row into the table. This can happen with some DISTINCT queries
432
if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME &&
434
share.state.rec_per_key_part[key_segs-1]=1L;
436
/* Get block length for key, if defined by user */
437
block_length= (keydef->block_length ?
438
my_round_up_to_next_power(keydef->block_length) :
440
block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
441
block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
443
keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
444
pointer,MI_MAX_KEYPTR_SIZE,
446
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
447
length >= MI_MAX_KEY_BUFF)
449
my_errno=HA_WRONG_CREATE_OPTION;
452
set_if_bigger(max_key_block_length,keydef->block_length);
453
keydef->keylength= (uint16) key_length;
454
keydef->minlength= (uint16) (length-min_key_length_skip);
455
keydef->maxlength= (uint16) length;
457
if (length > max_key_length)
458
max_key_length= length;
459
tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
461
(ulong) keydef->block_length;
463
for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
464
key_del[i]=HA_OFFSET_ERROR;
467
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
468
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
470
uniquedef->key=keys+i;
471
unique_key_parts+=uniquedef->keysegs;
472
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
473
tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/
474
((MI_UNIQUE_HASH_LENGTH + pointer)*2)))*
475
(ulong) myisam_block_size;
477
keys+=uniques; /* Each unique has 1 key */
478
key_segs+=uniques; /* Each unique has 1 key seg */
480
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
481
max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
482
MI_STATE_KEYBLOCK_SIZE+
483
key_segs*MI_STATE_KEYSEG_SIZE);
484
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
485
keys * MI_KEYDEF_SIZE+
486
uniques * MI_UNIQUEDEF_SIZE +
487
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
488
columns*MI_COLUMNDEF_SIZE);
489
DBUG_PRINT("info", ("info_length: %u", info_length));
490
/* There are only 16 bits for the total header length. */
491
if (info_length > 65535)
493
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
494
"indexes and/or unique constraints.",
495
MYF(0), name + dirname_length(name));
496
my_errno= HA_WRONG_CREATE_OPTION;
500
bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
501
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
502
HA_OPTION_COMPRESS_RECORD |
503
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
504
mi_int2store(share.state.header.options,ci->old_options);
505
mi_int2store(share.state.header.header_length,info_length);
506
mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE);
507
mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE);
508
mi_int2store(share.state.header.base_pos,base_pos);
509
share.state.header.language= (ci->language ?
510
ci->language : default_charset_info->number);
511
share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
513
share.state.dellink = HA_OFFSET_ERROR;
514
share.state.process= (ulong) getpid();
515
share.state.unique= (ulong) 0;
516
share.state.update_count=(ulong) 0;
517
share.state.version= (ulong) time((time_t*) 0);
518
share.state.sortkey= (ushort) ~0;
519
share.state.auto_increment=ci->auto_increment;
520
share.options=options;
521
share.base.rec_reflength=pointer;
522
/* Get estimate for index file length (this may be wrong for FT keys) */
523
tmp= (tot_length + max_key_block_length * keys *
524
MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH;
526
use maximum of key_file_length we calculated and key_file_length value we
527
got from MYI file header (see also myisampack.c:save_state)
529
share.base.key_reflength=
530
mi_get_pointer_length(max(ci->key_file_length,tmp),3);
531
share.base.keys= share.state.header.keys= keys;
532
share.state.header.uniques= uniques;
533
share.state.header.fulltext_keys= fulltext_keys;
534
mi_int2store(share.state.header.key_parts,key_segs);
535
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
537
mi_set_all_keys_active(share.state.key_map, keys);
538
aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
539
max_key_block_length :
542
share.base.keystart= share.state.state.key_file_length=
543
MY_ALIGN(info_length, aligned_key_start);
544
share.base.max_key_block_length=max_key_block_length;
545
share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
546
share.base.records=ci->max_rows;
547
share.base.reloc= ci->reloc_rows;
548
share.base.reclength=real_reclength;
549
share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
550
share.base.max_pack_length=pack_reclength;
551
share.base.min_pack_length=min_pack_length;
552
share.base.pack_bits=packed;
553
share.base.fields=fields;
554
share.base.pack_fields=packed;
556
share.base.raid_type=ci->raid_type;
557
share.base.raid_chunks=ci->raid_chunks;
558
share.base.raid_chunksize=ci->raid_chunksize;
561
/* max_data_file_length and max_key_file_length are recalculated on open */
562
if (options & HA_OPTION_TMP_TABLE)
563
share.base.max_data_file_length=(my_off_t) ci->data_file_length;
565
share.base.min_block_length=
566
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
567
! share.base.blobs) ?
568
max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
569
MI_EXTEND_BLOCK_LENGTH;
570
if (! (flags & HA_DONT_TOUCH_DATA))
571
share.state.create_time= (long) time((time_t*) 0);
573
pthread_mutex_lock(&THR_LOCK_myisam);
576
NOTE: For test_if_reopen() we need a real path name. Hence we need
577
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
579
if (ci->index_file_name)
581
char *iext= strrchr(ci->index_file_name, '.');
582
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
583
if (options & HA_OPTION_TMP_TABLE)
586
/* chop off the table name, tempory tables use generated name */
587
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
589
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
590
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
591
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
595
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
596
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
597
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
599
fn_format(linkname, name, "", MI_NAME_IEXT,
600
MY_UNPACK_FILENAME|MY_APPEND_EXT);
601
linkname_ptr=linkname;
603
Don't create the table if the link or file exists to ensure that one
604
doesn't accidently destroy another table.
610
char *iext= strrchr(name, '.');
611
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
612
fn_format(filename, name, "", MI_NAME_IEXT,
613
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
614
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
616
/* Replace the current file */
617
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
621
If a MRG_MyISAM table is in use, the mapped MyISAM tables are open,
622
but no entry is made in the table cache for them.
623
A TRUNCATE command checks for the table in the cache only and could
624
be fooled to believe, the table is not open.
625
Pull the emergency brake in this situation. (Bug #8306)
627
NOTE: The filename is compared against unique_file_name of every
628
open table. Hence we need a real path here.
630
if (test_if_reopen(filename))
632
my_printf_error(0, "MyISAM table '%s' is in use "
633
"(most likely by a MERGE table). Try FLUSH TABLES.",
634
MYF(0), name + dirname_length(name));
635
my_errno= HA_ERR_TABLE_EXIST;
639
if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
640
MYF(MY_WME | create_flag))) < 0)
644
if (!(flags & HA_DONT_TOUCH_DATA))
647
if (share.base.raid_type)
649
(void) fn_format(filename, name, "", MI_NAME_DEXT,
650
MY_UNPACK_FILENAME | MY_APPEND_EXT);
651
if ((dfile=my_raid_create(filename, 0, create_mode,
652
share.base.raid_type,
653
share.base.raid_chunks,
654
share.base.raid_chunksize,
655
MYF(MY_WME | MY_RAID))) < 0)
661
if (ci->data_file_name)
663
char *dext= strrchr(ci->data_file_name, '.');
664
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
666
if (options & HA_OPTION_TMP_TABLE)
669
/* chop off the table name, tempory tables use generated name */
670
if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
672
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
673
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
677
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
679
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
682
fn_format(linkname, name, "",MI_NAME_DEXT,
683
MY_UNPACK_FILENAME | MY_APPEND_EXT);
684
linkname_ptr=linkname;
689
fn_format(filename,name,"", MI_NAME_DEXT,
690
MY_UNPACK_FILENAME | MY_APPEND_EXT);
692
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
695
my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
696
MYF(MY_WME | create_flag))) < 0)
702
DBUG_PRINT("info", ("write state info and base info"));
703
if (mi_state_info_write(file, &share.state, 2) ||
704
mi_base_info_write(file, &share.base))
707
if ((uint) my_tell(file,MYF(0)) != base_pos+ MI_BASE_INFO_SIZE)
709
uint pos=(uint) my_tell(file,MYF(0));
710
DBUG_PRINT("warning",("base_length: %d != used_length: %d",
711
base_pos+ MI_BASE_INFO_SIZE, pos));
715
/* Write key and keyseg definitions */
716
DBUG_PRINT("info", ("write key and keyseg definitions"));
717
for (i=0 ; i < share.base.keys - uniques; i++)
719
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
721
if (mi_keydef_write(file, &keydefs[i]))
723
for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++)
724
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
727
for (j=0 ; j < sp_segs ; j++)
731
sseg.language= 7; /* Binary */
740
sseg.flag= HA_SWAP_KEY;
741
if (mi_keyseg_write(file, &sseg))
746
/* Create extra keys for unique definitions */
747
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
748
bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
749
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
750
for (i=0; i < uniques ; i++)
752
tmp_keydef.keysegs=1;
753
tmp_keydef.flag= HA_UNIQUE_CHECK;
754
tmp_keydef.block_length= (uint16)myisam_block_size;
755
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
756
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
757
tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
758
tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
759
tmp_keyseg.start= offset;
760
offset+= MI_UNIQUE_HASH_LENGTH;
761
if (mi_keydef_write(file,&tmp_keydef) ||
762
mi_keyseg_write(file,(&tmp_keyseg)))
766
/* Save unique definition */
767
DBUG_PRINT("info", ("write unique definitions"));
768
for (i=0 ; i < share.state.header.uniques ; i++)
770
HA_KEYSEG *keyseg_end;
771
keyseg= uniquedefs[i].seg;
772
if (mi_uniquedef_write(file, &uniquedefs[i]))
774
for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs;
778
switch (keyseg->type) {
779
case HA_KEYTYPE_VARTEXT1:
780
case HA_KEYTYPE_VARTEXT2:
781
case HA_KEYTYPE_VARBINARY1:
782
case HA_KEYTYPE_VARBINARY2:
783
if (!(keyseg->flag & HA_BLOB_PART))
785
keyseg->flag|= HA_VAR_LENGTH_PART;
786
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
787
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
794
if (mi_keyseg_write(file, keyseg))
798
DBUG_PRINT("info", ("write field definitions"));
799
for (i=0 ; i < share.base.fields ; i++)
800
if (mi_recinfo_write(file, &recinfo[i]))
804
if ((uint) my_tell(file,MYF(0)) != info_length)
806
uint pos= (uint) my_tell(file,MYF(0));
807
DBUG_PRINT("warning",("info_length: %d != used_length: %d",
813
DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
814
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
817
if (! (flags & HA_DONT_TOUCH_DATA))
820
if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0)))
824
if (my_close(dfile,MYF(0)))
828
pthread_mutex_unlock(&THR_LOCK_myisam);
829
if (my_close(file,MYF(0)))
831
my_free((char*) rec_per_key_part,MYF(0));
835
pthread_mutex_unlock(&THR_LOCK_myisam);
839
VOID(my_close(dfile,MYF(0)));
842
/* QQ: T�nu should add a call to my_raid_delete() here */
843
if (! (flags & HA_DONT_TOUCH_DATA))
844
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
845
MY_UNPACK_FILENAME | MY_APPEND_EXT),
849
VOID(my_close(file,MYF(0)));
850
if (! (flags & HA_DONT_TOUCH_DATA))
851
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
852
MY_UNPACK_FILENAME | MY_APPEND_EXT),
855
my_free((char*) rec_per_key_part, MYF(0));
856
DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
860
uint mi_get_pointer_length(ulonglong file_length, uint def)
862
DBUG_ASSERT(def >= 2 && def <= 7);
863
if (file_length) /* If not default */
865
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
866
if (file_length >= ULL(1) << 56)
870
if (file_length >= ULL(1) << 48)
872
else if (file_length >= ULL(1) << 40)
874
else if (file_length >= ULL(1) << 32)
876
else if (file_length >= ULL(1) << 24)
878
else if (file_length >= ULL(1) << 16)