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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
/* Create a MyISAM table */
18
#include "myisam_priv.h"
19
#include "drizzled/internal/my_bit.h"
20
#include "drizzled/internal/my_sys.h"
22
#include "drizzled/util/test.h"
23
#include "drizzled/global_charset_info.h"
24
#include "drizzled/error.h"
30
using namespace drizzled;
33
Old options is used when recreating database, from myisamchk
36
int mi_create(const char *name,uint32_t keys,MI_KEYDEF *keydefs,
37
uint32_t columns, MI_COLUMNDEF *recinfo,
38
uint32_t uniques, MI_UNIQUEDEF *uniquedefs,
39
MI_CREATE_INFO *ci,uint32_t flags)
41
register uint32_t i, j;
42
int dfile= 0, file= 0;
43
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
45
uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
46
key_length,info_length,key_segs,options,min_key_length_skip,
47
base_pos,long_varchar_count,varchar_length,
48
max_key_block_length,unique_key_parts,fulltext_keys,offset;
49
uint32_t aligned_key_start, block_length;
50
ulong reclength, real_reclength,min_pack_length;
51
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
53
uint64_t tot_length,max_rows, tmp;
54
enum en_fieldtype type;
56
MI_KEYDEF *keydef,tmp_keydef;
57
MI_UNIQUEDEF *uniquedef;
58
HA_KEYSEG *keyseg,tmp_keyseg;
60
ulong *rec_per_key_part;
61
internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
62
MI_CREATE_INFO tmp_create_info;
66
memset(&tmp_create_info, 0, sizeof(tmp_create_info));
70
if (keys + uniques > MI_MAX_KEY || columns == 0)
72
return(errno=HA_WRONG_CREATE_OPTION);
76
memset(&share, 0, sizeof(share));
78
if (flags & HA_DONT_TOUCH_DATA)
80
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
81
options=ci->old_options &
82
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
83
HA_OPTION_READ_ONLY_DATA |
84
HA_OPTION_TMP_TABLE );
86
options=ci->old_options &
87
(HA_OPTION_TMP_TABLE );
90
if (ci->reloc_rows > ci->max_rows)
91
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
93
if (!(rec_per_key_part=
94
(ulong*) malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long))))
96
memset(rec_per_key_part, 0, (keys + uniques)*MI_MAX_KEY_SEG*sizeof(long));
98
/* Start by checking fields and field-types used */
100
reclength=varchar_length=long_varchar_count=packed=
101
min_pack_length=pack_reclength=0;
102
for (rec=recinfo, fields=0 ;
106
reclength+=rec->length;
107
if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
111
if (type == FIELD_BLOB)
114
if (pack_reclength != INT32_MAX)
116
if (rec->length == 4+portable_sizeof_char_ptr)
117
pack_reclength= INT32_MAX;
119
pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
122
else if (type == FIELD_SKIP_PRESPACE ||
123
type == FIELD_SKIP_ENDSPACE)
125
if (pack_reclength != INT32_MAX)
126
pack_reclength+= rec->length > 255 ? 2 : 1;
129
else if (type == FIELD_VARCHAR)
131
varchar_length+= rec->length-1; /* Used for min_pack_length */
135
/* We must test for 257 as length includes pack-length */
136
if (test(rec->length >= 257))
138
long_varchar_count++;
139
pack_reclength+= 2; /* May be packed on 3 bytes */
142
else if (type != FIELD_SKIP_ZERO)
144
min_pack_length+=rec->length;
145
packed--; /* Not a pack record type */
148
else /* FIELD_NORMAL */
149
min_pack_length+=rec->length;
151
if ((packed & 7) == 1)
152
{ /* Bad packing, try to remove a zero-field */
153
while (rec != recinfo)
156
if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
159
NOTE1: here we change a field type FIELD_SKIP_ZERO ->
162
rec->type=(int) FIELD_NORMAL;
170
if (packed || (flags & HA_PACK_RECORD))
171
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
172
if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
173
min_pack_length+= varchar_length;
174
if (flags & HA_CREATE_TMP_TABLE)
176
options|= HA_OPTION_TMP_TABLE;
177
create_mode|= O_EXCL;
181
if (pack_reclength != INT32_MAX)
182
pack_reclength+= reclength+packed +
183
test(test_all_bits(options,
184
uint32_t(HA_PACK_RECORD)));
185
min_pack_length+=packed;
187
if (!ci->data_file_length && ci->max_rows)
189
if (pack_reclength == INT32_MAX ||
190
(~(uint64_t) 0)/ci->max_rows < (uint64_t) pack_reclength)
191
ci->data_file_length= ~(uint64_t) 0;
193
ci->data_file_length=(uint64_t) ci->max_rows*pack_reclength;
195
else if (!ci->max_rows)
196
ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
197
((options & HA_OPTION_PACK_RECORD) ?
200
if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
201
pointer=mi_get_pointer_length(ci->data_file_length, data_pointer_size);
203
pointer=mi_get_pointer_length(ci->max_rows, data_pointer_size);
204
if (!(max_rows=(uint64_t) ci->max_rows))
205
max_rows= ((((uint64_t) 1 << (pointer*8)) -1) / min_pack_length);
208
real_reclength=reclength;
209
if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
211
if (reclength <= pointer)
212
reclength=pointer+1; /* reserve place for delete link */
215
reclength+= long_varchar_count; /* We need space for varchar! */
217
max_key_length=0; tot_length=0 ; key_segs=0;
219
max_key_block_length=0;
220
share.state.rec_per_key_part=rec_per_key_part;
221
share.state.key_root=key_root;
222
share.state.key_del=key_del;
225
max_key_block_length= myisam_block_size;
226
max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
229
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
232
share.state.key_root[i]= HA_OFFSET_ERROR;
233
min_key_length_skip=length=real_length_diff=0;
236
/* Test if prefix compression */
237
if (keydef->flag & HA_PACK_KEY)
239
/* Only use HA_PACK_KEY when first segment is a variable length key */
240
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
241
HA_VAR_LENGTH_PART)))
243
/* pack relative to previous key */
244
keydef->flag&= ~HA_PACK_KEY;
245
keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
249
keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */
250
keydef->flag|=HA_VAR_LENGTH_KEY;
251
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
254
if (keydef->flag & HA_BINARY_PACK_KEY)
255
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
257
if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment)
258
share.base.auto_key=i+1;
259
for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
261
/* numbers are stored with high by first to make compression easier */
262
switch (keyseg->type) {
263
case HA_KEYTYPE_LONG_INT:
264
case HA_KEYTYPE_DOUBLE:
265
case HA_KEYTYPE_ULONG_INT:
266
case HA_KEYTYPE_LONGLONG:
267
case HA_KEYTYPE_ULONGLONG:
268
keyseg->flag|= HA_SWAP_KEY;
270
case HA_KEYTYPE_VARTEXT1:
271
case HA_KEYTYPE_VARTEXT2:
272
case HA_KEYTYPE_VARBINARY1:
273
case HA_KEYTYPE_VARBINARY2:
274
if (!(keyseg->flag & HA_BLOB_PART))
276
/* Make a flag that this is a VARCHAR */
277
keyseg->flag|= HA_VAR_LENGTH_PART;
278
/* Store in bit_start number of bytes used to pack the length */
279
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
280
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
287
if (keyseg->flag & HA_SPACE_PACK)
289
assert(!(keyseg->flag & HA_VAR_LENGTH_PART));
290
keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
291
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
292
length++; /* At least one length byte */
293
min_key_length_skip+=keyseg->length;
294
if (keyseg->length >= 255)
295
{ /* prefix may be 3 bytes */
296
min_key_length_skip+=2;
300
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
302
assert(!test_all_bits(keyseg->flag,
303
(HA_VAR_LENGTH_PART | HA_BLOB_PART)));
304
keydef->flag|=HA_VAR_LENGTH_KEY;
305
length++; /* At least one length byte */
306
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
307
min_key_length_skip+=keyseg->length;
308
if (keyseg->length >= 255)
309
{ /* prefix may be 3 bytes */
310
min_key_length_skip+=2;
314
key_length+= keyseg->length;
315
if (keyseg->null_bit)
318
options|=HA_OPTION_PACK_KEYS;
319
keyseg->flag|=HA_NULL_PART;
320
keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY;
323
} /* if HA_FULLTEXT */
324
key_segs+=keydef->keysegs;
325
if (keydef->keysegs > MI_MAX_KEY_SEG)
327
errno=HA_WRONG_CREATE_OPTION;
331
key_segs may be 0 in the case when we only want to be able to
332
add on row into the table. This can happen with some DISTINCT queries
335
if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME &&
337
share.state.rec_per_key_part[key_segs-1]=1L;
339
/* Get block length for key, if defined by user */
340
block_length= (keydef->block_length ?
341
my_round_up_to_next_power(keydef->block_length) :
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);
346
keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
347
pointer,MI_MAX_KEYPTR_SIZE,
349
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
350
length >= MI_MAX_KEY_BUFF)
352
errno=HA_WRONG_CREATE_OPTION;
355
set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
356
keydef->keylength= (uint16_t) key_length;
357
keydef->minlength= (uint16_t) (length-min_key_length_skip);
358
keydef->maxlength= (uint16_t) length;
360
if (length > max_key_length)
361
max_key_length= length;
362
tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
364
(ulong) keydef->block_length;
366
for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
367
key_del[i]=HA_OFFSET_ERROR;
370
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
371
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
373
uniquedef->key=keys+i;
374
unique_key_parts+=uniquedef->keysegs;
375
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
376
tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/
377
((MI_UNIQUE_HASH_LENGTH + pointer)*2)))*
378
(ulong) myisam_block_size;
380
keys+=uniques; /* Each unique has 1 key */
381
key_segs+=uniques; /* Each unique has 1 key seg */
383
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
384
max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
385
MI_STATE_KEYBLOCK_SIZE+
386
key_segs*MI_STATE_KEYSEG_SIZE);
387
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
388
keys * MI_KEYDEF_SIZE+
389
uniques * MI_UNIQUEDEF_SIZE +
390
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
391
columns*MI_COLUMNDEF_SIZE);
392
/* There are only 16 bits for the total header length. */
393
if (info_length > 65535)
395
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
396
"indexes and/or unique constraints.",
397
MYF(0), name + internal::dirname_length(name));
398
errno= HA_WRONG_CREATE_OPTION;
402
memmove(share.state.header.file_version,myisam_file_magic,4);
403
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
404
HA_OPTION_COMPRESS_RECORD |
405
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
406
mi_int2store(share.state.header.options,ci->old_options);
407
mi_int2store(share.state.header.header_length,info_length);
408
mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE);
409
mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE);
410
mi_int2store(share.state.header.base_pos,base_pos);
411
share.state.header.language= (ci->language ?
412
ci->language : default_charset_info->number);
413
share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
415
share.state.dellink = HA_OFFSET_ERROR;
416
share.state.process= (ulong) getpid();
417
share.state.unique= (ulong) 0;
418
share.state.update_count=(ulong) 0;
419
share.state.version= (ulong) time((time_t*) 0);
420
share.state.sortkey= UINT16_MAX;
421
share.state.auto_increment=ci->auto_increment;
422
share.options=options;
423
share.base.rec_reflength=pointer;
424
/* Get estimate for index file length (this may be wrong for FT keys) */
425
tmp= (tot_length + max_key_block_length * keys *
426
MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH;
428
use maximum of key_file_length we calculated and key_file_length value we
429
got from MYI file header (see also myisampack.c:save_state)
431
share.base.key_reflength=
432
mi_get_pointer_length(max(ci->key_file_length,tmp),3);
433
share.base.keys= share.state.header.keys= keys;
434
share.state.header.uniques= uniques;
435
share.state.header.fulltext_keys= fulltext_keys;
436
mi_int2store(share.state.header.key_parts,key_segs);
437
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
439
mi_set_all_keys_active(share.state.key_map, keys);
440
aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
441
max_key_block_length :
444
share.base.keystart= share.state.state.key_file_length=
445
MY_ALIGN(info_length, aligned_key_start);
446
share.base.max_key_block_length=max_key_block_length;
447
share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
448
share.base.records=ci->max_rows;
449
share.base.reloc= ci->reloc_rows;
450
share.base.reclength=real_reclength;
451
share.base.pack_reclength=reclength;
452
share.base.max_pack_length=pack_reclength;
453
share.base.min_pack_length=min_pack_length;
454
share.base.pack_bits=packed;
455
share.base.fields=fields;
456
share.base.pack_fields=packed;
458
/* max_data_file_length and max_key_file_length are recalculated on open */
459
if (options & HA_OPTION_TMP_TABLE)
460
share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
462
share.base.min_block_length=
463
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
464
! share.base.blobs) ?
465
max(share.base.pack_reclength,(ulong)MI_MIN_BLOCK_LENGTH) :
466
MI_EXTEND_BLOCK_LENGTH;
467
if (! (flags & HA_DONT_TOUCH_DATA))
468
share.state.create_time= (long) time((time_t*) 0);
470
THR_LOCK_myisam.lock();
473
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, ...).
476
if (ci->index_file_name)
478
char *iext= strrchr((char *)ci->index_file_name, '.');
479
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
480
if (options & HA_OPTION_TMP_TABLE)
483
/* chop off the table name, tempory tables use generated name */
484
if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
486
internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
487
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
488
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
492
internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
493
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
494
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
496
internal::fn_format(linkname, name, "", MI_NAME_IEXT,
497
MY_UNPACK_FILENAME|MY_APPEND_EXT);
498
linkname_ptr=linkname;
500
Don't create the table if the link or file exists to ensure that one
501
doesn't accidently destroy another table.
507
char *iext= strrchr((char *)name, '.');
508
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
509
internal::fn_format(filename, name, "", MI_NAME_IEXT,
510
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
511
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
513
/* Replace the current file */
514
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
518
If a MRG_MyISAM table is in use, the mapped MyISAM tables are open,
519
but no entry is made in the table cache for them.
520
A TRUNCATE command checks for the table in the cache only and could
521
be fooled to believe, the table is not open.
522
Pull the emergency brake in this situation. (Bug #8306)
524
NOTE: The filename is compared against unique_file_name of every
525
open table. Hence we need a real path here.
527
if (test_if_reopen(filename))
529
my_printf_error(0, "MyISAM table '%s' is in use "
530
"(most likely by a MERGE table). Try FLUSH TABLES.",
531
MYF(0), name + internal::dirname_length(name));
532
errno= HA_ERR_TABLE_EXIST;
536
if ((file= internal::my_create_with_symlink(linkname_ptr,
540
MYF(MY_WME | create_flag))) < 0)
544
if (!(flags & HA_DONT_TOUCH_DATA))
547
if (ci->data_file_name)
549
char *dext= strrchr((char *)ci->data_file_name, '.');
550
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
552
if (options & HA_OPTION_TMP_TABLE)
555
/* chop off the table name, tempory tables use generated name */
556
if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
558
internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
559
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
563
internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
565
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
568
internal::fn_format(linkname, name, "",MI_NAME_DEXT,
569
MY_UNPACK_FILENAME | MY_APPEND_EXT);
570
linkname_ptr=linkname;
575
internal::fn_format(filename,name,"", MI_NAME_DEXT,
576
MY_UNPACK_FILENAME | MY_APPEND_EXT);
578
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
580
if ((dfile= internal::my_create_with_symlink(linkname_ptr,
581
filename, 0, create_mode,
582
MYF(MY_WME | create_flag))) < 0)
588
if (mi_state_info_write(file, &share.state, 2) ||
589
mi_base_info_write(file, &share.base))
592
/* Write key and keyseg definitions */
593
for (i=0 ; i < share.base.keys - uniques; i++)
597
if (mi_keydef_write(file, &keydefs[i]))
599
for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++)
600
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
603
/* Create extra keys for unique definitions */
604
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
605
memset(&tmp_keydef, 0, sizeof(tmp_keydef));
606
memset(&tmp_keyseg, 0, sizeof(tmp_keyseg));
607
for (i=0; i < uniques ; i++)
609
tmp_keydef.keysegs=1;
610
tmp_keydef.flag= HA_UNIQUE_CHECK;
611
tmp_keydef.block_length= (uint16_t)myisam_block_size;
612
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
613
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
614
tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
615
tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
616
tmp_keyseg.start= offset;
617
offset+= MI_UNIQUE_HASH_LENGTH;
618
if (mi_keydef_write(file,&tmp_keydef) ||
619
mi_keyseg_write(file,(&tmp_keyseg)))
623
/* Save unique definition */
624
for (i=0 ; i < share.state.header.uniques ; i++)
626
HA_KEYSEG *keyseg_end;
627
keyseg= uniquedefs[i].seg;
628
if (mi_uniquedef_write(file, &uniquedefs[i]))
630
for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs;
634
switch (keyseg->type) {
635
case HA_KEYTYPE_VARTEXT1:
636
case HA_KEYTYPE_VARTEXT2:
637
case HA_KEYTYPE_VARBINARY1:
638
case HA_KEYTYPE_VARBINARY2:
639
if (!(keyseg->flag & HA_BLOB_PART))
641
keyseg->flag|= HA_VAR_LENGTH_PART;
642
keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
643
keyseg->type == HA_KEYTYPE_VARBINARY1) ?
650
if (mi_keyseg_write(file, keyseg))
654
for (i=0 ; i < share.base.fields ; i++)
655
if (mi_recinfo_write(file, &recinfo[i]))
659
if (ftruncate(file, (off_t) share.base.keystart))
662
if (! (flags & HA_DONT_TOUCH_DATA))
665
if (ftruncate(dfile,share.base.min_pack_length*ci->reloc_rows,))
669
if (internal::my_close(dfile,MYF(0)))
673
THR_LOCK_myisam.unlock();
674
if (internal::my_close(file,MYF(0)))
676
free((char*) rec_per_key_part);
680
THR_LOCK_myisam.unlock();
684
internal::my_close(dfile,MYF(0));
687
if (! (flags & HA_DONT_TOUCH_DATA))
688
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
689
MY_UNPACK_FILENAME | MY_APPEND_EXT),
693
internal::my_close(file,MYF(0));
694
if (! (flags & HA_DONT_TOUCH_DATA))
695
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
696
MY_UNPACK_FILENAME | MY_APPEND_EXT),
699
free((char*) rec_per_key_part);
700
return(errno=save_errno); /* return the fatal errno */
704
uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def)
706
assert(def >= 2 && def <= 7);
707
if (file_length) /* If not default */
709
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
710
if (file_length >= 1ULL << 56)
714
if (file_length >= 1ULL << 48)
716
else if (file_length >= 1ULL << 40)
718
else if (file_length >= 1ULL << 32)
720
else if (file_length >= 1ULL << 24)
722
else if (file_length >= 1ULL << 16)