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