1374
1457
parse_table_proto(session, table, share);
1376
/* end of proto code... now to get some scraps from FRM */
1378
if ((file= open(path.c_str(), O_RDONLY)) < 0)
1381
We don't try to open 5.0 unencoded name, if
1382
- non-encoded name contains '@' signs,
1383
because '@' can be misinterpreted.
1384
It is not clear if '@' is escape character in 5.1,
1385
or a normal character in 5.0.
1387
- non-encoded db or table name contain "#mysql50#" prefix.
1388
This kind of tables must have been opened only by the
1391
if (strchr(share->table_name.str, '@') ||
1392
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
1393
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1394
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
1395
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
1398
/* Try unencoded 5.0 name */
1400
char unpacked_path[FN_REFLEN];
1402
path.append(drizzle_data_home);
1404
path.append(share->db.str);
1406
path.append(share->table_name.str);
1407
path.append(reg_ext);
1408
length= unpack_filename(unpacked_path, path.c_str()) - reg_ext_length;
1410
The following is a safety test and should never fail
1411
as the old file name should never be longer than the new one.
1413
assert(length <= share->normalized_path.length);
1415
If the old and the new names have the same length,
1416
then table name does not have tricky characters,
1417
so no need to check the old file name.
1419
if (length == share->normalized_path.length ||
1420
((file= open(unpacked_path, O_RDONLY)) < 0))
1423
/* Unencoded 5.0 table name found */
1424
unpacked_path[length]= '\0'; // Remove .frm extension
1425
strcpy(share->normalized_path.str, unpacked_path);
1426
share->normalized_path.length= length;
1430
if (my_read(file, head, 64, MYF(MY_NABP)))
1433
if (head[0] == (unsigned char) 254 && head[1] == 1)
1435
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
1436
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
1442
error= 6; // Unkown .frm version
1449
/* No handling of text based files yet */
1450
if (table_type == 1)
1452
root_ptr= current_mem_root_ptr();
1453
old_root= *root_ptr;
1454
*root_ptr= &share->mem_root;
1455
error= open_binary_frm(session, share, head, file);
1456
*root_ptr= old_root;
1462
1459
share->table_category= get_table_category(& share->db, & share->table_name);
1465
1462
session->status_var.opened_shares++;
1468
my_close(file, MYF(MY_WME));
1471
1465
if (error && !error_given)
1482
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
1485
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
1488
int error, errarg= 0;
1489
uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
1490
uint32_t interval_count, interval_parts, read_length, int_length;
1491
uint32_t db_create_options, keys, key_parts, n_length;
1492
uint32_t key_info_length, com_length;
1493
uint32_t vcol_screen_length;
1495
unsigned char forminfo[288];
1496
char *names, *comment_pos, *vcol_screen_pos;
1497
unsigned char *record;
1498
unsigned char *disk_buff, *strpos;
1499
ulong pos, record_offset, rec_buff_length;
1500
handler *handler_file= 0;
1502
KEY_PART_INFO *key_part;
1503
Field **field_ptr, *reg_field;
1504
const char **interval_array;
1505
my_bitmap_map *bitmaps;
1506
unsigned char *buff= 0;
1507
unsigned char *field_extra_info= 0;
1509
new_field_pack_flag= head[27];
1510
new_frm_ver= (head[2] - FRM_VER);
1511
assert(new_frm_ver >= 2); /* If this fails, we're on old FRM */
1512
field_pack_length= 17;
1516
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
1517
goto err; /* purecov: inspected */
1518
lseek(file,pos,SEEK_SET);
1519
if (my_read(file,forminfo,288,MYF(MY_NABP)))
1522
share->db_create_options= db_create_options= uint2korr(head+30);
1523
share->db_options_in_use= share->db_create_options;
1527
/* Read keyinformation */
1528
key_info_length= (uint32_t) uint2korr(head+28);
1529
lseek(file,(ulong) uint2korr(head+6),SEEK_SET);
1530
if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
1531
goto err; /* purecov: inspected */
1532
if (disk_buff[0] & 0x80)
1534
/*share->keys=*/ keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
1535
/*share->key_parts=*/ key_parts= uint2korr(disk_buff+2);
1539
/*share->keys= */keys= disk_buff[0];
1540
/*share->key_parts=*/ key_parts= disk_buff[1];
1543
/* the magic uint2korr(disk_buff+4) is the key names size */
1545
keyinfo= share->key_info;
1546
key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
1549
for (i=0 ; i < keys ; i++, keyinfo++)
1551
if (new_frm_ver >= 3)
1556
for (j=keyinfo->key_parts ; j-- ; key_part++)
1558
if (new_frm_ver >= 1)
1564
abort(); // Old FRM version, we abort as we should never see it.
1569
// keynames=(char*) key_part;
1570
// strpos+= (strcpy(keynames, (char*)strpos)+strlen((char*)strpos)-keynames)+1;
1572
//reading index comments
1573
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
1575
if (keyinfo->flags & HA_USES_COMMENT)
1577
// keyinfo->comment.length= uint2korr(strpos);
1578
// keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
1579
// keyinfo->comment.length);
1580
strpos+= 2 + uint2korr(strpos);//keyinfo->comment.length;
1582
// assert(test(keyinfo->flags & HA_USES_COMMENT) ==
1583
// (keyinfo->comment.length > 0));
1586
assert(share->reclength == uint2korr((head+16)));
1588
record_offset= (ulong) (uint2korr(head+6)+
1589
((uint2korr(head+14) == 0xffff ?
1590
uint4korr(head+47) : uint2korr(head+14))));
1592
if ((n_length= uint4korr(head+55)))
1594
/* Read extra data segment */
1595
unsigned char *next_chunk, *buff_end;
1596
if (!(next_chunk= buff= (unsigned char*) malloc(n_length)))
1598
if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
1603
uint32_t connect_str_length= uint2korr(buff);
1604
next_chunk+= connect_str_length + 2;
1606
buff_end= buff + n_length;
1607
if (next_chunk + 2 < buff_end)
1609
uint32_t str_db_type_length= uint2korr(next_chunk);
1610
next_chunk+= str_db_type_length + 2;
1612
if (share->mysql_version >= 50110)
1614
/* New auto_partitioned indicator introduced in 5.1.11 */
1617
if (forminfo[46] == (unsigned char)255)
1619
//reading long table comment
1620
if (next_chunk + 2 > buff_end)
1625
uint32_t comment_str_length= uint2korr(next_chunk);
1626
next_chunk+= 2 + comment_str_length;
1628
assert(next_chunk <= buff_end);
1629
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
1632
New frm format in mysql_version 5.2.5 (originally in
1633
mysql-5.1.22-ndb-6.2.5)
1634
New column properties added:
1635
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
1636
TABLESPACE name is now stored in frm
1638
if (next_chunk >= buff_end)
1640
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
1647
const uint32_t format_section_header_size= 8;
1648
uint32_t format_section_len= uint2korr(next_chunk+0);
1649
uint32_t flags= uint4korr(next_chunk+2);
1653
const char *tablespace= (const char*)next_chunk + format_section_header_size;
1654
uint32_t tablespace_len= strlen(tablespace);
1656
field_extra_info= next_chunk + format_section_header_size + tablespace_len + 1;
1657
next_chunk+= format_section_len;
1660
assert (next_chunk <= buff_end);
1661
if (next_chunk > buff_end)
1668
/* head+59 was extra_rec_buf_length */
1669
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
1671
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
1673
goto err; /* purecov: inspected */
1675
if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
1676
goto err; /* purecov: inspected */
1678
assert(memcmp(share->default_values, record, share->reclength)==0);
1680
lseek(file,pos+288,SEEK_SET);
1682
// share->fields= uint2korr(forminfo+258);
1683
pos= uint2korr(forminfo+260); /* Length of all screens */
1684
n_length= uint2korr(forminfo+268);
1685
interval_count= uint2korr(forminfo+270);
1686
interval_parts= uint2korr(forminfo+272);
1687
int_length= uint2korr(forminfo+274);
1688
share->null_fields= uint2korr(forminfo+282);
1689
com_length= uint2korr(forminfo+284);
1690
vcol_screen_length= uint2korr(forminfo+286);
1691
// share->vfields= 0;
1692
// share->stored_fields= share->fields;
1695
/* WTF is with the share->fields+1 here... */
1696
if (!(field_ptr = (Field **)
1697
alloc_root(&share->mem_root,
1698
(uint32_t) ((share->fields+1)*sizeof(Field*)+
1699
interval_count*sizeof(TYPELIB)+
1700
(share->fields+interval_parts+
1701
keys+3)*sizeof(char *)+
1702
(n_length+int_length+
1703
vcol_screen_length)))))
1704
goto err; /* purecov: inspected */
1706
// share->field= field_ptr;
1707
read_length=(uint32_t) (share->fields * field_pack_length +
1708
pos+ (uint32_t) (n_length+int_length+com_length+
1709
vcol_screen_length));
1710
if (read_string(file,(unsigned char**) &disk_buff,read_length))
1711
goto err; /* purecov: inspected */
1712
strpos= disk_buff+pos;
1714
// share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
1715
interval_array= (const char **) ((field_ptr+share->fields+1)+interval_count);
1716
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
1718
memcpy(names, strpos+(share->fields*field_pack_length),
1719
(uint32_t) (n_length+int_length));
1720
comment_pos= (char *)(disk_buff+read_length-com_length-vcol_screen_length);
1721
vcol_screen_pos= names+(n_length+int_length);
1722
memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length,
1723
vcol_screen_length);
1725
// fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
1726
assert(share->fieldnames.count == share->fields);
1729
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);*/
1731
/* Allocate handler */
1732
if (!(handler_file= get_new_handler(share, session->mem_root,
1736
record= share->default_values-1; /* Fieldstart = 1 */
1738
/* Sanity checks: */
1739
assert(share->fields>=share->stored_fields);
1740
assert(share->reclength>=share->stored_rec_length);
1747
if (share->found_next_number_field)
1749
reg_field= *share->found_next_number_field;
1750
if ((int) (share->next_number_index= (uint32_t)
1751
find_ref_key(share->key_info, share->keys,
1752
share->default_values, reg_field,
1753
&share->next_number_key_offset,
1754
&share->next_number_keypart)) < 0)
1756
/* Wrong field definition */
1761
reg_field->flags |= AUTO_INCREMENT_FLAG;
1764
if (share->blob_fields)
1769
/* Store offsets to blob fields to find them fast */
1770
if (!(share->blob_field= save=
1771
(uint*) alloc_root(&share->mem_root,
1772
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1774
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1776
if ((*ptr)->flags & BLOB_FLAG)
1782
the correct null_bytes can now be set, since bitfields have been taken
1786
share->db_low_byte_first= handler_file->low_byte_first();
1787
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1789
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1790
share->column_bitmap_size)))
1792
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1793
bitmap_set_all(&share->all_set);
1795
delete handler_file;
1803
share->error= error;
1804
share->open_errno= my_errno;
1805
share->errarg= errarg;
1808
delete handler_file;
1809
hash_free(&share->name_hash);
1811
open_table_error(share, error, share->open_errno, errarg);
1813
} /* open_binary_frm */
1817
1475
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1818
1476
This routine is used for error handling purposes.