2464
/* Create a .frm file */
2466
File create_frm(Session *session, const char *name, const char *db,
2467
const char *table, uint32_t reclength, unsigned char *fileinfo,
2468
HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
2472
unsigned char fill[IO_SIZE];
2473
int create_flags= O_RDWR | O_TRUNC;
2474
ulong key_comment_total_bytes= 0;
2477
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2478
create_flags|= O_EXCL;
2480
/* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */
2481
if (create_info->max_rows > UINT32_MAX)
2482
create_info->max_rows= UINT32_MAX;
2483
if (create_info->min_rows > UINT32_MAX)
2484
create_info->min_rows= UINT32_MAX;
2486
if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
2488
uint32_t key_length, tmp_key_length;
2490
memset(fileinfo, 0, 64);
2492
fileinfo[0]=(unsigned char) 254;
2494
fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
2496
fileinfo[3]= (unsigned char) ha_legacy_type(
2497
ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
2499
int2store(fileinfo+6,IO_SIZE); /* Next block starts here */
2500
for (i= 0; i < keys; i++)
2502
assert(test(key_info[i].flags & HA_USES_COMMENT) ==
2503
(key_info[i].comment.length > 0));
2504
if (key_info[i].flags & HA_USES_COMMENT)
2505
key_comment_total_bytes += 2 + key_info[i].comment.length;
2508
Keep in sync with pack_keys() in unireg.cc
2510
8 bytes for the key header
2511
9 bytes for each key-part (MAX_REF_PARTS)
2512
NAME_LEN bytes for the name
2513
1 byte for the NAMES_SEP_CHAR (before the name)
2515
6 bytes for the header
2516
1 byte for the NAMES_SEP_CHAR (after the last name)
2517
9 extra bytes (padding for safety? alignment?)
2520
key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
2521
key_comment_total_bytes);
2522
length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
2523
create_info->extra_size));
2524
int4store(fileinfo+10,length);
2525
tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
2526
int2store(fileinfo+14,tmp_key_length);
2527
int2store(fileinfo+16,reclength);
2528
int4store(fileinfo+18,create_info->max_rows);
2529
int4store(fileinfo+22,create_info->min_rows);
2530
/* fileinfo[26] is set in mysql_create_frm() */
2531
fileinfo[27]=2; // Use long pack-fields
2532
/* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
2533
create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
2534
int2store(fileinfo+30,create_info->table_options);
2535
fileinfo[32]=0; // No filename anymore
2536
fileinfo[33]=5; // Mark for 5.0 frm file
2537
int4store(fileinfo+34,create_info->avg_row_length);
2538
fileinfo[38]= (create_info->default_table_charset ?
2539
create_info->default_table_charset->number : 0);
2540
fileinfo[39]= (unsigned char) create_info->page_checksum;
2541
fileinfo[40]= (unsigned char) create_info->row_type;
2542
/* Next few bytes were for RAID support */
2545
int4store(fileinfo+43,create_info->block_size);
2550
int4store(fileinfo+47, key_length);
2551
tmp= DRIZZLE_VERSION_ID; // Store to avoid warning from int4store
2552
int4store(fileinfo+51, tmp);
2553
int4store(fileinfo+55, create_info->extra_size);
2555
59-60 is reserved for extra_rec_buf_length (always 0),
2556
61 for default_part_db_type
2558
int2store(fileinfo+62, create_info->key_block_size);
2559
memset(fill, 0, IO_SIZE);
2560
for (; length > IO_SIZE ; length-= IO_SIZE)
2562
if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
2564
my_close(file,MYF(0));
2565
my_delete(name,MYF(0));
2572
if (my_errno == ENOENT)
2573
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2575
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2581
2470
Set up column usage bitmaps for a temporary table