12
12
You should have received a copy of the GNU General Public License
13
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 */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
16
/* Create a MyISAM table */
18
#include "myisamdef.h"
19
#include <mysys/my_tree.h>
20
#include <mysys/queues.h>
21
#include <mysys/my_bit.h>
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;
25
33
Old options is used when recreating database, from myisamchk
28
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
29
uint columns, MI_COLUMNDEF *recinfo,
30
uint uniques, MI_UNIQUEDEF *uniquedefs,
31
MI_CREATE_INFO *ci,uint flags)
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)
34
File dfile= 0, file= 0;
41
register uint32_t i, j;
42
int dfile= 0, file= 0;
35
43
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
37
uint fields,length,max_key_length,packed,pointer,real_length_diff,
45
uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
38
46
key_length,info_length,key_segs,options,min_key_length_skip,
39
47
base_pos,long_varchar_count,varchar_length,
40
48
max_key_block_length,unique_key_parts,fulltext_keys,offset;
41
uint aligned_key_start, block_length;
49
uint32_t aligned_key_start, block_length;
42
50
ulong reclength, real_reclength,min_pack_length;
43
51
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
44
52
ulong pack_reclength;
72
80
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
73
81
options=ci->old_options &
74
82
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
75
HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
76
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
83
HA_OPTION_READ_ONLY_DATA |
84
HA_OPTION_TMP_TABLE );
78
86
options=ci->old_options &
79
(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
87
(HA_OPTION_TMP_TABLE );
82
90
if (ci->reloc_rows > ci->max_rows)
83
91
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
85
93
if (!(rec_per_key_part=
86
(ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
87
MYF(MY_WME | MY_ZEROFILL))))
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));
90
98
/* Start by checking fields and field-types used */
162
170
if (packed || (flags & HA_PACK_RECORD))
163
171
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
164
/* We can't use checksum with static length rows */
165
if (!(options & HA_OPTION_PACK_RECORD))
166
options&= ~HA_OPTION_CHECKSUM;
167
172
if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
168
173
min_pack_length+= varchar_length;
169
174
if (flags & HA_CREATE_TMP_TABLE)
171
176
options|= HA_OPTION_TMP_TABLE;
172
create_mode|= O_EXCL | O_NOFOLLOW;
174
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
176
options|= HA_OPTION_CHECKSUM;
179
if (flags & HA_CREATE_DELAY_KEY_WRITE)
180
options|= HA_OPTION_DELAY_KEY_WRITE;
181
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
182
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
177
create_mode|= O_EXCL;
184
180
packed=(packed+7)/8;
185
181
if (pack_reclength != INT32_MAX)
186
182
pack_reclength+= reclength+packed +
187
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
183
test(test_all_bits(options,
184
uint32_t(HA_PACK_RECORD)));
188
185
min_pack_length+=packed;
190
187
if (!ci->data_file_length && ci->max_rows)
203
200
if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
204
pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size);
201
pointer=mi_get_pointer_length(ci->data_file_length, data_pointer_size);
206
pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size);
203
pointer=mi_get_pointer_length(ci->max_rows, data_pointer_size);
207
204
if (!(max_rows=(uint64_t) ci->max_rows))
208
205
max_rows= ((((uint64_t) 1 << (pointer*8)) -1) / min_pack_length);
269
261
/* numbers are stored with high by first to make compression easier */
270
262
switch (keyseg->type) {
271
case HA_KEYTYPE_SHORT_INT:
272
263
case HA_KEYTYPE_LONG_INT:
273
case HA_KEYTYPE_FLOAT:
274
264
case HA_KEYTYPE_DOUBLE:
275
case HA_KEYTYPE_USHORT_INT:
276
265
case HA_KEYTYPE_ULONG_INT:
277
266
case HA_KEYTYPE_LONGLONG:
278
267
case HA_KEYTYPE_ULONGLONG:
279
case HA_KEYTYPE_INT24:
280
case HA_KEYTYPE_UINT24:
281
case HA_KEYTYPE_INT8:
282
268
keyseg->flag|= HA_SWAP_KEY;
284
270
case HA_KEYTYPE_VARTEXT1:
351
337
share.state.rec_per_key_part[key_segs-1]=1L;
352
338
length+=key_length;
353
339
/* Get block length for key, if defined by user */
354
block_length= (keydef->block_length ?
340
block_length= (keydef->block_length ?
355
341
my_round_up_to_next_power(keydef->block_length) :
356
342
myisam_block_size);
357
block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
358
block_length= min(block_length, MI_MAX_KEY_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);
360
346
keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
361
347
pointer,MI_MAX_KEYPTR_SIZE,
363
349
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
364
350
length >= MI_MAX_KEY_BUFF)
366
my_errno=HA_WRONG_CREATE_OPTION;
352
errno=HA_WRONG_CREATE_OPTION;
369
set_if_bigger(max_key_block_length,keydef->block_length);
355
set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
370
356
keydef->keylength= (uint16_t) key_length;
371
357
keydef->minlength= (uint16_t) (length-min_key_length_skip);
372
358
keydef->maxlength= (uint16_t) length;
409
395
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
410
396
"indexes and/or unique constraints.",
411
MYF(0), name + dirname_length(name));
412
my_errno= HA_WRONG_CREATE_OPTION;
397
MYF(0), name + internal::dirname_length(name));
398
errno= HA_WRONG_CREATE_OPTION;
416
memcpy(share.state.header.file_version,myisam_file_magic,4);
402
memmove(share.state.header.file_version,myisam_file_magic,4);
417
403
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
418
404
HA_OPTION_COMPRESS_RECORD |
419
405
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
472
458
/* max_data_file_length and max_key_file_length are recalculated on open */
473
459
if (options & HA_OPTION_TMP_TABLE)
474
share.base.max_data_file_length=(my_off_t) ci->data_file_length;
460
share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
476
462
share.base.min_block_length=
477
463
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
478
464
! share.base.blobs) ?
479
max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
465
max(share.base.pack_reclength,(ulong)MI_MIN_BLOCK_LENGTH) :
480
466
MI_EXTEND_BLOCK_LENGTH;
481
467
if (! (flags & HA_DONT_TOUCH_DATA))
482
468
share.state.create_time= (long) time((time_t*) 0);
484
pthread_mutex_lock(&THR_LOCK_myisam);
470
THR_LOCK_myisam.lock();
487
473
NOTE: For test_if_reopen() we need a real path name. Hence we need
488
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
474
MY_RETURN_REAL_PATH for every internal::fn_format(filename, ...).
490
476
if (ci->index_file_name)
492
char *iext= strrchr(ci->index_file_name, '.');
478
char *iext= strrchr((char *)ci->index_file_name, '.');
493
479
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
494
480
if (options & HA_OPTION_TMP_TABLE)
497
483
/* chop off the table name, tempory tables use generated name */
498
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
484
if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
500
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
486
internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
501
487
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
502
488
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
506
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
492
internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
507
493
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
508
494
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
510
fn_format(linkname, name, "", MI_NAME_IEXT,
496
internal::fn_format(linkname, name, "", MI_NAME_IEXT,
511
497
MY_UNPACK_FILENAME|MY_APPEND_EXT);
512
498
linkname_ptr=linkname;
521
char *iext= strrchr(name, '.');
507
char *iext= strrchr((char *)name, '.');
522
508
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
523
fn_format(filename, name, "", MI_NAME_IEXT,
509
internal::fn_format(filename, name, "", MI_NAME_IEXT,
524
510
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
525
511
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
543
529
my_printf_error(0, "MyISAM table '%s' is in use "
544
530
"(most likely by a MERGE table). Try FLUSH TABLES.",
545
MYF(0), name + dirname_length(name));
546
my_errno= HA_ERR_TABLE_EXIST;
531
MYF(0), name + internal::dirname_length(name));
532
errno= HA_ERR_TABLE_EXIST;
550
if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
551
MYF(MY_WME | create_flag))) < 0)
536
if ((file= internal::my_create_with_symlink(linkname_ptr,
540
MYF(MY_WME | create_flag))) < 0)
558
547
if (ci->data_file_name)
560
char *dext= strrchr(ci->data_file_name, '.');
549
char *dext= strrchr((char *)ci->data_file_name, '.');
561
550
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
563
552
if (options & HA_OPTION_TMP_TABLE)
566
555
/* chop off the table name, tempory tables use generated name */
567
if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
556
if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
569
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
558
internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
570
559
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
574
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
563
internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
575
564
MY_UNPACK_FILENAME |
576
565
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
579
fn_format(linkname, name, "",MI_NAME_DEXT,
568
internal::fn_format(linkname, name, "",MI_NAME_DEXT,
580
569
MY_UNPACK_FILENAME | MY_APPEND_EXT);
581
570
linkname_ptr=linkname;
586
fn_format(filename,name,"", MI_NAME_DEXT,
575
internal::fn_format(filename,name,"", MI_NAME_DEXT,
587
576
MY_UNPACK_FILENAME | MY_APPEND_EXT);
589
578
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
592
my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
593
MYF(MY_WME | create_flag))) < 0)
580
if ((dfile= internal::my_create_with_symlink(linkname_ptr,
581
filename, 0, create_mode,
582
MYF(MY_WME | create_flag))) < 0)
680
if (my_close(dfile,MYF(0)))
669
if (internal::my_close(dfile,MYF(0)))
684
pthread_mutex_unlock(&THR_LOCK_myisam);
685
if (my_close(file,MYF(0)))
673
THR_LOCK_myisam.unlock();
674
if (internal::my_close(file,MYF(0)))
687
my_free((char*) rec_per_key_part,MYF(0));
676
free((char*) rec_per_key_part);
691
pthread_mutex_unlock(&THR_LOCK_myisam);
680
THR_LOCK_myisam.unlock();
693
682
switch (errpos) {
695
VOID(my_close(dfile,MYF(0)));
684
internal::my_close(dfile,MYF(0));
696
685
/* fall through */
698
/* QQ: T�nu should add a call to my_raid_delete() here */
699
687
if (! (flags & HA_DONT_TOUCH_DATA))
700
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
688
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
701
689
MY_UNPACK_FILENAME | MY_APPEND_EXT),
703
691
/* fall through */
705
VOID(my_close(file,MYF(0)));
693
internal::my_close(file,MYF(0));
706
694
if (! (flags & HA_DONT_TOUCH_DATA))
707
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
695
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
708
696
MY_UNPACK_FILENAME | MY_APPEND_EXT),
711
my_free((char*) rec_per_key_part, MYF(0));
712
return(my_errno=save_errno); /* return the fatal errno */
699
free((char*) rec_per_key_part);
700
return(errno=save_errno); /* return the fatal errno */
716
uint mi_get_pointer_length(uint64_t file_length, uint def)
704
uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def)
718
706
assert(def >= 2 && def <= 7);
719
707
if (file_length) /* If not default */