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)
41
File UNINIT_VAR(dfile),file;
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);
80
bzero((uchar*) &share,sizeof(share));
82
if (flags & HA_DONT_TOUCH_DATA)
84
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
85
options=ci->old_options &
86
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
87
HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
88
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
90
options=ci->old_options &
91
(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
94
if (ci->reloc_rows > ci->max_rows)
95
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
97
if (!(rec_per_key_part=
98
(ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
99
MYF(MY_WME | MY_ZEROFILL))))
100
DBUG_RETURN(my_errno);
102
/* Start by checking fields and field-types used */
104
reclength=varchar_length=long_varchar_count=packed=
105
min_pack_length=pack_reclength=0;
106
for (rec=recinfo, fields=0 ;
110
reclength+=rec->length;
111
if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
115
if (type == FIELD_BLOB)
118
if (pack_reclength != INT_MAX32)
120
if (rec->length == 4+portable_sizeof_char_ptr)
121
pack_reclength= INT_MAX32;
123
pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
126
else if (type == FIELD_SKIP_PRESPACE ||
127
type == FIELD_SKIP_ENDSPACE)
129
if (pack_reclength != INT_MAX32)
130
pack_reclength+= rec->length > 255 ? 2 : 1;
133
else if (type == FIELD_VARCHAR)
135
varchar_length+= rec->length-1; /* Used for min_pack_length */
139
/* We must test for 257 as length includes pack-length */
140
if (test(rec->length >= 257))
142
long_varchar_count++;
143
pack_reclength+= 2; /* May be packed on 3 bytes */
146
else if (type != FIELD_SKIP_ZERO)
148
min_pack_length+=rec->length;
149
packed--; /* Not a pack record type */
152
else /* FIELD_NORMAL */
153
min_pack_length+=rec->length;
155
if ((packed & 7) == 1)
156
{ /* Bad packing, try to remove a zero-field */
157
while (rec != recinfo)
160
if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
163
NOTE1: here we change a field type FIELD_SKIP_ZERO ->
166
rec->type=(int) FIELD_NORMAL;
174
if (packed || (flags & HA_PACK_RECORD))
175
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
176
/* We can't use checksum with static length rows */
177
if (!(options & HA_OPTION_PACK_RECORD))
178
options&= ~HA_OPTION_CHECKSUM;
179
if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
180
min_pack_length+= varchar_length;
181
if (flags & HA_CREATE_TMP_TABLE)
183
options|= HA_OPTION_TMP_TABLE;
184
create_mode|= O_EXCL | O_NOFOLLOW;
186
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
188
options|= HA_OPTION_CHECKSUM;
191
if (flags & HA_CREATE_DELAY_KEY_WRITE)
192
options|= HA_OPTION_DELAY_KEY_WRITE;
193
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
194
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
197
if (pack_reclength != INT_MAX32)
198
pack_reclength+= reclength+packed +
199
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD));
200
min_pack_length+=packed;
202
if (!ci->data_file_length && ci->max_rows)
204
if (pack_reclength == INT_MAX32 ||
205
(~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
206
ci->data_file_length= ~(ulonglong) 0;
208
ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
210
else if (!ci->max_rows)
211
ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
212
((options & HA_OPTION_PACK_RECORD) ?
215
if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
216
pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size);
218
pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size);
219
if (!(max_rows=(ulonglong) ci->max_rows))
220
max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);
223
real_reclength=reclength;
224
if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
226
if (reclength <= pointer)
227
reclength=pointer+1; /* reserve place for delete link */
230
reclength+= long_varchar_count; /* We need space for varchar! */
232
max_key_length=0; tot_length=0 ; key_segs=0;
234
max_key_block_length=0;
235
share.state.rec_per_key_part=rec_per_key_part;
236
share.state.key_root=key_root;
237
share.state.key_del=key_del;
240
max_key_block_length= myisam_block_size;
241
max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
244
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
247
share.state.key_root[i]= HA_OFFSET_ERROR;
248
min_key_length_skip=length=real_length_diff=0;
250
if (keydef->flag & HA_SPATIAL)
253
/* BAR TODO to support 3D and more dimensions in the future */
254
uint sp_segs=SPDIMS*2;
255
keydef->flag=HA_SPATIAL;
257
if (flags & HA_DONT_TOUCH_DATA)
260
called by myisamchk - i.e. table structure was taken from
261
MYI file and SPATIAL key *does have* additional sp_segs keysegs.
262
keydef->seg here points right at the GEOMETRY segment,
263
so we only need to decrease keydef->keysegs.
264
(see recreate_table() in mi_check.c)
266
keydef->keysegs-=sp_segs-1;
269
for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
272
if (keyseg->type != HA_KEYTYPE_BINARY &&
273
keyseg->type != HA_KEYTYPE_VARBINARY1 &&
274
keyseg->type != HA_KEYTYPE_VARBINARY2)
276
my_errno=HA_WRONG_CREATE_OPTION;
280
keydef->keysegs+=sp_segs;
281
key_length+=SPLEN*sp_segs;
282
length++; /* At least one length byte */
283
min_key_length_skip+=SPLEN*2*SPDIMS;
285
my_errno= HA_ERR_UNSUPPORTED;
287
#endif /*HAVE_SPATIAL*/
289
else if (keydef->flag & HA_FULLTEXT)
291
keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
292
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
294
for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
297
if (keyseg->type != HA_KEYTYPE_TEXT &&
298
keyseg->type != HA_KEYTYPE_VARTEXT1 &&
299
keyseg->type != HA_KEYTYPE_VARTEXT2)
301
my_errno=HA_WRONG_CREATE_OPTION;
304
if (!(keyseg->flag & HA_BLOB_PART) &&
305
(keyseg->type == HA_KEYTYPE_VARTEXT1 ||
306
keyseg->type == HA_KEYTYPE_VARTEXT2))
308
/* Make a flag that this is a VARCHAR */
309
keyseg->flag|= HA_VAR_LENGTH_PART;
310
/* Store in bit_start number of bytes used to pack the length */
311
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1)?
317
key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN;
318
length++; /* At least one length byte */
319
min_key_length_skip+=HA_FT_MAXBYTELEN;
320
real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT;
324
/* Test if prefix compression */
325
if (keydef->flag & HA_PACK_KEY)
327
/* Can't use space_compression on number keys */
328
if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
329
keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
330
keydef->seg[0].flag&= ~HA_SPACE_PACK;
332
/* Only use HA_PACK_KEY when first segment is a variable length key */
333
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
334
HA_VAR_LENGTH_PART)))
336
/* pack relative to previous key */
337
keydef->flag&= ~HA_PACK_KEY;
338
keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
342
keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */
343
keydef->flag|=HA_VAR_LENGTH_KEY;
344
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
347
if (keydef->flag & HA_BINARY_PACK_KEY)
348
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
350
if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment)
351
share.base.auto_key=i+1;
352
for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
354
/* numbers are stored with high by first to make compression easier */
355
switch (keyseg->type) {
356
case HA_KEYTYPE_SHORT_INT:
357
case HA_KEYTYPE_LONG_INT:
358
case HA_KEYTYPE_FLOAT:
359
case HA_KEYTYPE_DOUBLE:
360
case HA_KEYTYPE_USHORT_INT:
361
case HA_KEYTYPE_ULONG_INT:
362
case HA_KEYTYPE_LONGLONG:
363
case HA_KEYTYPE_ULONGLONG:
364
case HA_KEYTYPE_INT24:
365
case HA_KEYTYPE_UINT24:
366
case HA_KEYTYPE_INT8:
367
keyseg->flag|= HA_SWAP_KEY;
369
case HA_KEYTYPE_VARTEXT1:
370
case HA_KEYTYPE_VARTEXT2:
371
case HA_KEYTYPE_VARBINARY1:
372
case HA_KEYTYPE_VARBINARY2:
373
if (!(keyseg->flag & HA_BLOB_PART))
375
/* Make a flag that this is a VARCHAR */
376
keyseg->flag|= HA_VAR_LENGTH_PART;
377
/* Store in bit_start number of bytes used to pack the length */
378
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
379
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
386
if (keyseg->flag & HA_SPACE_PACK)
388
DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART));
389
keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
390
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
391
length++; /* At least one length byte */
392
min_key_length_skip+=keyseg->length;
393
if (keyseg->length >= 255)
394
{ /* prefix may be 3 bytes */
395
min_key_length_skip+=2;
399
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
401
DBUG_ASSERT(!test_all_bits(keyseg->flag,
402
(HA_VAR_LENGTH_PART | HA_BLOB_PART)));
403
keydef->flag|=HA_VAR_LENGTH_KEY;
404
length++; /* At least one length byte */
405
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
406
min_key_length_skip+=keyseg->length;
407
if (keyseg->length >= 255)
408
{ /* prefix may be 3 bytes */
409
min_key_length_skip+=2;
413
key_length+= keyseg->length;
414
if (keyseg->null_bit)
417
options|=HA_OPTION_PACK_KEYS;
418
keyseg->flag|=HA_NULL_PART;
419
keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY;
422
} /* if HA_FULLTEXT */
423
key_segs+=keydef->keysegs;
424
if (keydef->keysegs > MI_MAX_KEY_SEG)
426
my_errno=HA_WRONG_CREATE_OPTION;
430
key_segs may be 0 in the case when we only want to be able to
431
add on row into the table. This can happen with some DISTINCT queries
434
if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME &&
436
share.state.rec_per_key_part[key_segs-1]=1L;
438
/* Get block length for key, if defined by user */
439
block_length= (keydef->block_length ?
440
my_round_up_to_next_power(keydef->block_length) :
442
block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
443
block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
445
keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
446
pointer,MI_MAX_KEYPTR_SIZE,
448
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
449
length >= MI_MAX_KEY_BUFF)
451
my_errno=HA_WRONG_CREATE_OPTION;
454
set_if_bigger(max_key_block_length,keydef->block_length);
455
keydef->keylength= (uint16) key_length;
456
keydef->minlength= (uint16) (length-min_key_length_skip);
457
keydef->maxlength= (uint16) length;
459
if (length > max_key_length)
460
max_key_length= length;
461
tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
463
(ulong) keydef->block_length;
465
for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
466
key_del[i]=HA_OFFSET_ERROR;
469
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
470
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
472
uniquedef->key=keys+i;
473
unique_key_parts+=uniquedef->keysegs;
474
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
475
tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/
476
((MI_UNIQUE_HASH_LENGTH + pointer)*2)))*
477
(ulong) myisam_block_size;
479
keys+=uniques; /* Each unique has 1 key */
480
key_segs+=uniques; /* Each unique has 1 key seg */
482
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
483
max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
484
MI_STATE_KEYBLOCK_SIZE+
485
key_segs*MI_STATE_KEYSEG_SIZE);
486
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
487
keys * MI_KEYDEF_SIZE+
488
uniques * MI_UNIQUEDEF_SIZE +
489
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
490
columns*MI_COLUMNDEF_SIZE);
491
DBUG_PRINT("info", ("info_length: %u", info_length));
492
/* There are only 16 bits for the total header length. */
493
if (info_length > 65535)
495
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
496
"indexes and/or unique constraints.",
497
MYF(0), name + dirname_length(name));
498
my_errno= HA_WRONG_CREATE_OPTION;
502
bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
503
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
504
HA_OPTION_COMPRESS_RECORD |
505
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
506
mi_int2store(share.state.header.options,ci->old_options);
507
mi_int2store(share.state.header.header_length,info_length);
508
mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE);
509
mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE);
510
mi_int2store(share.state.header.base_pos,base_pos);
511
share.state.header.language= (ci->language ?
512
ci->language : default_charset_info->number);
513
share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
515
share.state.dellink = HA_OFFSET_ERROR;
516
share.state.process= (ulong) getpid();
517
share.state.unique= (ulong) 0;
518
share.state.update_count=(ulong) 0;
519
share.state.version= (ulong) time((time_t*) 0);
520
share.state.sortkey= (ushort) ~0;
521
share.state.auto_increment=ci->auto_increment;
522
share.options=options;
523
share.base.rec_reflength=pointer;
524
/* Get estimate for index file length (this may be wrong for FT keys) */
525
tmp= (tot_length + max_key_block_length * keys *
526
MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH;
528
use maximum of key_file_length we calculated and key_file_length value we
529
got from MYI file header (see also myisampack.c:save_state)
531
share.base.key_reflength=
532
mi_get_pointer_length(max(ci->key_file_length,tmp),3);
533
share.base.keys= share.state.header.keys= keys;
534
share.state.header.uniques= uniques;
535
share.state.header.fulltext_keys= fulltext_keys;
536
mi_int2store(share.state.header.key_parts,key_segs);
537
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
539
mi_set_all_keys_active(share.state.key_map, keys);
540
aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
541
max_key_block_length :
544
share.base.keystart= share.state.state.key_file_length=
545
MY_ALIGN(info_length, aligned_key_start);
546
share.base.max_key_block_length=max_key_block_length;
547
share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
548
share.base.records=ci->max_rows;
549
share.base.reloc= ci->reloc_rows;
550
share.base.reclength=real_reclength;
551
share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
552
share.base.max_pack_length=pack_reclength;
553
share.base.min_pack_length=min_pack_length;
554
share.base.pack_bits=packed;
555
share.base.fields=fields;
556
share.base.pack_fields=packed;
558
share.base.raid_type=ci->raid_type;
559
share.base.raid_chunks=ci->raid_chunks;
560
share.base.raid_chunksize=ci->raid_chunksize;
563
/* max_data_file_length and max_key_file_length are recalculated on open */
564
if (options & HA_OPTION_TMP_TABLE)
565
share.base.max_data_file_length=(my_off_t) ci->data_file_length;
567
share.base.min_block_length=
568
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
569
! share.base.blobs) ?
570
max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
571
MI_EXTEND_BLOCK_LENGTH;
572
if (! (flags & HA_DONT_TOUCH_DATA))
573
share.state.create_time= (long) time((time_t*) 0);
575
pthread_mutex_lock(&THR_LOCK_myisam);
578
NOTE: For test_if_reopen() we need a real path name. Hence we need
579
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
581
if (ci->index_file_name)
583
char *iext= strrchr(ci->index_file_name, '.');
584
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
585
if (options & HA_OPTION_TMP_TABLE)
588
/* chop off the table name, tempory tables use generated name */
589
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
591
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
592
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
593
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
597
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
598
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
599
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
601
fn_format(linkname, name, "", MI_NAME_IEXT,
602
MY_UNPACK_FILENAME|MY_APPEND_EXT);
603
linkname_ptr=linkname;
605
Don't create the table if the link or file exists to ensure that one
606
doesn't accidently destroy another table.
612
char *iext= strrchr(name, '.');
613
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
614
fn_format(filename, name, "", MI_NAME_IEXT,
615
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
616
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
618
/* Replace the current file */
619
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
623
If a MRG_MyISAM table is in use, the mapped MyISAM tables are open,
624
but no entry is made in the table cache for them.
625
A TRUNCATE command checks for the table in the cache only and could
626
be fooled to believe, the table is not open.
627
Pull the emergency brake in this situation. (Bug #8306)
629
NOTE: The filename is compared against unique_file_name of every
630
open table. Hence we need a real path here.
632
if (test_if_reopen(filename))
634
my_printf_error(0, "MyISAM table '%s' is in use "
635
"(most likely by a MERGE table). Try FLUSH TABLES.",
636
MYF(0), name + dirname_length(name));
637
my_errno= HA_ERR_TABLE_EXIST;
641
if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
642
MYF(MY_WME | create_flag))) < 0)
646
if (!(flags & HA_DONT_TOUCH_DATA))
649
if (share.base.raid_type)
651
(void) fn_format(filename, name, "", MI_NAME_DEXT,
652
MY_UNPACK_FILENAME | MY_APPEND_EXT);
653
if ((dfile=my_raid_create(filename, 0, create_mode,
654
share.base.raid_type,
655
share.base.raid_chunks,
656
share.base.raid_chunksize,
657
MYF(MY_WME | MY_RAID))) < 0)
663
if (ci->data_file_name)
665
char *dext= strrchr(ci->data_file_name, '.');
666
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
668
if (options & HA_OPTION_TMP_TABLE)
671
/* chop off the table name, tempory tables use generated name */
672
if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
674
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
675
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
679
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
681
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
684
fn_format(linkname, name, "",MI_NAME_DEXT,
685
MY_UNPACK_FILENAME | MY_APPEND_EXT);
686
linkname_ptr=linkname;
691
fn_format(filename,name,"", MI_NAME_DEXT,
692
MY_UNPACK_FILENAME | MY_APPEND_EXT);
694
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
697
my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
698
MYF(MY_WME | create_flag))) < 0)
704
DBUG_PRINT("info", ("write state info and base info"));
705
if (mi_state_info_write(file, &share.state, 2) ||
706
mi_base_info_write(file, &share.base))
709
if ((uint) my_tell(file,MYF(0)) != base_pos+ MI_BASE_INFO_SIZE)
711
uint pos=(uint) my_tell(file,MYF(0));
712
DBUG_PRINT("warning",("base_length: %d != used_length: %d",
713
base_pos+ MI_BASE_INFO_SIZE, pos));
717
/* Write key and keyseg definitions */
718
DBUG_PRINT("info", ("write key and keyseg definitions"));
719
for (i=0 ; i < share.base.keys - uniques; i++)
721
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
723
if (mi_keydef_write(file, &keydefs[i]))
725
for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++)
726
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
729
for (j=0 ; j < sp_segs ; j++)
733
sseg.language= 7; /* Binary */
742
sseg.flag= HA_SWAP_KEY;
743
if (mi_keyseg_write(file, &sseg))
748
/* Create extra keys for unique definitions */
749
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
750
bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
751
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
752
for (i=0; i < uniques ; i++)
754
tmp_keydef.keysegs=1;
755
tmp_keydef.flag= HA_UNIQUE_CHECK;
756
tmp_keydef.block_length= (uint16)myisam_block_size;
757
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
758
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
759
tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
760
tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
761
tmp_keyseg.start= offset;
762
offset+= MI_UNIQUE_HASH_LENGTH;
763
if (mi_keydef_write(file,&tmp_keydef) ||
764
mi_keyseg_write(file,(&tmp_keyseg)))
768
/* Save unique definition */
769
DBUG_PRINT("info", ("write unique definitions"));
770
for (i=0 ; i < share.state.header.uniques ; i++)
772
HA_KEYSEG *keyseg_end;
773
keyseg= uniquedefs[i].seg;
774
if (mi_uniquedef_write(file, &uniquedefs[i]))
776
for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs;
780
switch (keyseg->type) {
781
case HA_KEYTYPE_VARTEXT1:
782
case HA_KEYTYPE_VARTEXT2:
783
case HA_KEYTYPE_VARBINARY1:
784
case HA_KEYTYPE_VARBINARY2:
785
if (!(keyseg->flag & HA_BLOB_PART))
787
keyseg->flag|= HA_VAR_LENGTH_PART;
788
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
789
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
796
if (mi_keyseg_write(file, keyseg))
800
DBUG_PRINT("info", ("write field definitions"));
801
for (i=0 ; i < share.base.fields ; i++)
802
if (mi_recinfo_write(file, &recinfo[i]))
806
if ((uint) my_tell(file,MYF(0)) != info_length)
808
uint pos= (uint) my_tell(file,MYF(0));
809
DBUG_PRINT("warning",("info_length: %d != used_length: %d",
815
DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
816
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
819
if (! (flags & HA_DONT_TOUCH_DATA))
822
if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0)))
826
if (my_close(dfile,MYF(0)))
830
pthread_mutex_unlock(&THR_LOCK_myisam);
831
if (my_close(file,MYF(0)))
833
my_free((char*) rec_per_key_part,MYF(0));
837
pthread_mutex_unlock(&THR_LOCK_myisam);
841
VOID(my_close(dfile,MYF(0)));
844
/* QQ: T�nu should add a call to my_raid_delete() here */
845
if (! (flags & HA_DONT_TOUCH_DATA))
846
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
847
MY_UNPACK_FILENAME | MY_APPEND_EXT),
851
VOID(my_close(file,MYF(0)));
852
if (! (flags & HA_DONT_TOUCH_DATA))
853
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
854
MY_UNPACK_FILENAME | MY_APPEND_EXT),
857
my_free((char*) rec_per_key_part, MYF(0));
858
DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
862
uint mi_get_pointer_length(ulonglong file_length, uint def)
864
DBUG_ASSERT(def >= 2 && def <= 7);
865
if (file_length) /* If not default */
867
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
868
if (file_length >= ULL(1) << 56)
872
if (file_length >= ULL(1) << 48)
874
else if (file_length >= ULL(1) << 40)
876
else if (file_length >= ULL(1) << 32)
878
else if (file_length >= ULL(1) << 24)
880
else if (file_length >= ULL(1) << 16)