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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
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;
18
#include "myisamdef.h"
19
#include <mysys/my_tree.h>
20
#include <mysys/my_bit.h>
22
#include <drizzled/util/test.h>
33
25
Old options is used when recreating database, from myisamchk
39
31
MI_CREATE_INFO *ci,uint32_t flags)
41
33
register uint32_t i, j;
42
int dfile= 0, file= 0;
34
File dfile= 0, file= 0;
43
35
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
45
37
uint32_t fields,length,max_key_length,packed,pointer,real_length_diff,
58
50
HA_KEYSEG *keyseg,tmp_keyseg;
60
52
ulong *rec_per_key_part;
61
internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
53
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
62
54
MI_CREATE_INFO tmp_create_info;
80
72
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
81
73
options=ci->old_options &
82
74
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
83
HA_OPTION_READ_ONLY_DATA |
84
HA_OPTION_TMP_TABLE );
75
HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
76
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
86
78
options=ci->old_options &
87
(HA_OPTION_TMP_TABLE );
79
(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
90
82
if (ci->reloc_rows > ci->max_rows)
170
162
if (packed || (flags & HA_PACK_RECORD))
171
163
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;
172
167
if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
173
168
min_pack_length+= varchar_length;
174
169
if (flags & HA_CREATE_TMP_TABLE)
176
171
options|= HA_OPTION_TMP_TABLE;
177
172
create_mode|= O_EXCL;
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;
180
184
packed=(packed+7)/8;
181
185
if (pack_reclength != INT32_MAX)
182
186
pack_reclength+= reclength+packed +
183
187
test(test_all_bits(options,
184
uint32_t(HA_PACK_RECORD)));
188
uint32_t(HA_OPTION_CHECKSUM | HA_PACK_RECORD)));
185
189
min_pack_length+=packed;
187
191
if (!ci->data_file_length && ci->max_rows)
236
240
/* Test if prefix compression */
237
241
if (keydef->flag & HA_PACK_KEY)
243
/* Can't use space_compression on number keys */
244
if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
245
keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
246
keydef->seg[0].flag&= ~HA_SPACE_PACK;
239
248
/* Only use HA_PACK_KEY when first segment is a variable length key */
240
249
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
241
250
HA_VAR_LENGTH_PART)))
261
270
/* numbers are stored with high by first to make compression easier */
262
271
switch (keyseg->type) {
272
case HA_KEYTYPE_SHORT_INT:
263
273
case HA_KEYTYPE_LONG_INT:
274
case HA_KEYTYPE_FLOAT:
264
275
case HA_KEYTYPE_DOUBLE:
276
case HA_KEYTYPE_USHORT_INT:
265
277
case HA_KEYTYPE_ULONG_INT:
266
278
case HA_KEYTYPE_LONGLONG:
267
279
case HA_KEYTYPE_ULONGLONG:
280
case HA_KEYTYPE_INT24:
281
case HA_KEYTYPE_UINT24:
282
case HA_KEYTYPE_INT8:
268
283
keyseg->flag|= HA_SWAP_KEY;
270
285
case HA_KEYTYPE_VARTEXT1:
340
355
block_length= (keydef->block_length ?
341
356
my_round_up_to_next_power(keydef->block_length) :
342
357
myisam_block_size);
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);
358
block_length= cmax(block_length, MI_MIN_KEY_BLOCK_LENGTH);
359
block_length= cmin(block_length, MI_MAX_KEY_BLOCK_LENGTH);
346
361
keydef->block_length= (uint16_t) MI_BLOCK_SIZE(length-real_length_diff,
347
362
pointer,MI_MAX_KEYPTR_SIZE,
349
364
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
350
365
length >= MI_MAX_KEY_BUFF)
352
errno=HA_WRONG_CREATE_OPTION;
367
my_errno=HA_WRONG_CREATE_OPTION;
355
370
set_if_bigger(max_key_block_length,(uint32_t)keydef->block_length);
395
410
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
396
411
"indexes and/or unique constraints.",
397
MYF(0), name + internal::dirname_length(name));
398
errno= HA_WRONG_CREATE_OPTION;
412
MYF(0), name + dirname_length(name));
413
my_errno= HA_WRONG_CREATE_OPTION;
429
444
got from MYI file header (see also myisampack.c:save_state)
431
446
share.base.key_reflength=
432
mi_get_pointer_length(max(ci->key_file_length,tmp),3);
447
mi_get_pointer_length(cmax(ci->key_file_length,tmp),3);
433
448
share.base.keys= share.state.header.keys= keys;
434
449
share.state.header.uniques= uniques;
435
450
share.state.header.fulltext_keys= fulltext_keys;
448
463
share.base.records=ci->max_rows;
449
464
share.base.reloc= ci->reloc_rows;
450
465
share.base.reclength=real_reclength;
451
share.base.pack_reclength=reclength;
466
share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
452
467
share.base.max_pack_length=pack_reclength;
453
468
share.base.min_pack_length=min_pack_length;
454
469
share.base.pack_bits=packed;
458
473
/* max_data_file_length and max_key_file_length are recalculated on open */
459
474
if (options & HA_OPTION_TMP_TABLE)
460
share.base.max_data_file_length=(internal::my_off_t) ci->data_file_length;
475
share.base.max_data_file_length=(my_off_t) ci->data_file_length;
462
477
share.base.min_block_length=
463
478
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
464
479
! share.base.blobs) ?
465
max(share.base.pack_reclength,(ulong)MI_MIN_BLOCK_LENGTH) :
480
cmax(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
466
481
MI_EXTEND_BLOCK_LENGTH;
467
482
if (! (flags & HA_DONT_TOUCH_DATA))
468
483
share.state.create_time= (long) time((time_t*) 0);
470
THR_LOCK_myisam.lock();
485
pthread_mutex_lock(&THR_LOCK_myisam);
473
488
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, ...).
489
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
476
491
if (ci->index_file_name)
483
498
/* chop off the table name, tempory tables use generated name */
484
499
if ((path= strrchr((char *)ci->index_file_name, FN_LIBCHAR)))
486
internal::fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
501
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
487
502
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
488
503
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
492
internal::fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
507
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
493
508
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
494
509
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
496
internal::fn_format(linkname, name, "", MI_NAME_IEXT,
511
fn_format(linkname, name, "", MI_NAME_IEXT,
497
512
MY_UNPACK_FILENAME|MY_APPEND_EXT);
498
513
linkname_ptr=linkname;
507
522
char *iext= strrchr((char *)name, '.');
508
523
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
509
internal::fn_format(filename, name, "", MI_NAME_IEXT,
524
fn_format(filename, name, "", MI_NAME_IEXT,
510
525
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
511
526
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
529
544
my_printf_error(0, "MyISAM table '%s' is in use "
530
545
"(most likely by a MERGE table). Try FLUSH TABLES.",
531
MYF(0), name + internal::dirname_length(name));
532
errno= HA_ERR_TABLE_EXIST;
546
MYF(0), name + dirname_length(name));
547
my_errno= HA_ERR_TABLE_EXIST;
536
if ((file= internal::my_create_with_symlink(linkname_ptr,
540
MYF(MY_WME | create_flag))) < 0)
551
if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
552
MYF(MY_WME | create_flag))) < 0)
555
567
/* chop off the table name, tempory tables use generated name */
556
568
if ((path= strrchr((char *)ci->data_file_name, FN_LIBCHAR)))
558
internal::fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
570
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
559
571
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
563
internal::fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
575
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
564
576
MY_UNPACK_FILENAME |
565
577
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
568
internal::fn_format(linkname, name, "",MI_NAME_DEXT,
580
fn_format(linkname, name, "",MI_NAME_DEXT,
569
581
MY_UNPACK_FILENAME | MY_APPEND_EXT);
570
582
linkname_ptr=linkname;
575
internal::fn_format(filename,name,"", MI_NAME_DEXT,
587
fn_format(filename,name,"", MI_NAME_DEXT,
576
588
MY_UNPACK_FILENAME | MY_APPEND_EXT);
578
590
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)
593
my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
594
MYF(MY_WME | create_flag))) < 0)
669
if (internal::my_close(dfile,MYF(0)))
681
if (my_close(dfile,MYF(0)))
673
THR_LOCK_myisam.unlock();
674
if (internal::my_close(file,MYF(0)))
685
pthread_mutex_unlock(&THR_LOCK_myisam);
686
if (my_close(file,MYF(0)))
676
688
free((char*) rec_per_key_part);
680
THR_LOCK_myisam.unlock();
692
pthread_mutex_unlock(&THR_LOCK_myisam);
682
694
switch (errpos) {
684
internal::my_close(dfile,MYF(0));
696
my_close(dfile,MYF(0));
685
697
/* fall through */
687
699
if (! (flags & HA_DONT_TOUCH_DATA))
688
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_DEXT,
700
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
689
701
MY_UNPACK_FILENAME | MY_APPEND_EXT),
691
703
/* fall through */
693
internal::my_close(file,MYF(0));
705
my_close(file,MYF(0));
694
706
if (! (flags & HA_DONT_TOUCH_DATA))
695
internal::my_delete_with_symlink(internal::fn_format(filename,name,"",MI_NAME_IEXT,
707
my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
696
708
MY_UNPACK_FILENAME | MY_APPEND_EXT),
699
711
free((char*) rec_per_key_part);
700
return(errno=save_errno); /* return the fatal errno */
712
return(my_errno=save_errno); /* return the fatal errno */