static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, File file) { int error, errarg= 0; uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; uint key_info_length, com_length, null_bit_pos; uint extra_rec_buf_length; uint i,j; bool use_hash; char *keynames, *names, *comment_pos; uchar forminfo[288]; uchar *record; uchar *disk_buff, *strpos, *null_flags, *null_pos; ulong pos, record_offset, *rec_per_key, rec_buff_length; handler *handler_file= 0; KEY *keyinfo; KEY_PART_INFO *key_part; SQL_CRYPT *crypted=0; Field **field_ptr, *reg_field; const char **interval_array; enum legacy_db_type legacy_db_type; my_bitmap_map *bitmaps; uchar *extra_segment_buff= 0; const uint format_section_header_size= 8; uchar *format_section_fields= 0; DBUG_ENTER("open_binary_frm"); new_field_pack_flag= head[27]; new_frm_ver= (head[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; disk_buff= 0; error= 3; /* Position of the form in the form file. */ if (!(pos= get_form_pos(file, head))) goto err; /* purecov: inspected */ mysql_file_seek(file,pos,MY_SEEK_SET,MYF(0)); if (mysql_file_read(file, forminfo,288,MYF(MY_NABP))) goto err; share->frm_version= head[2]; /* Check if .frm file created by MySQL 5.0. In this case we want to display CHAR fields as CHAR and not as VARCHAR. We do it this way as we want to keep the old frm version to enable MySQL 4.1 to read these files. */ if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5) share->frm_version= FRM_VER_TRUE_VARCHAR; legacy_db_type= (enum legacy_db_type) (uint) *(head+3); DBUG_ASSERT(share->db_plugin == NULL); share->db_create_options= db_create_options= uint2korr(head+30); share->db_options_in_use= share->db_create_options; share->mysql_version= uint4korr(head+51); share->null_field_first= 0; share->max_rows= uint4korr(head+18); share->min_rows= uint4korr(head+22); /* Read keyinformation */ key_info_length= (uint) uint2korr(head+28); mysql_file_seek(file, (ulong) uint2korr(head+6), MY_SEEK_SET, MYF(0)); /** *disk_buff已经被分配了内存,大小为key_info_length */ if (read_string(file,(uchar**) &disk_buff,key_info_length)) goto err; /* purecov: inspected */ if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); share->key_parts= key_parts= uint2korr(disk_buff+2); } else { share->keys= keys= disk_buff[0]; share->key_parts= key_parts= disk_buff[1]; } n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,n_length + uint2korr(disk_buff+4)))) goto err; bzero((char*) keyinfo,n_length); /** *share->key_info代表keyinfo这段内存起始地址 *keyinfo的类型为KEY*,故keyinfo++,意味着数组递增 * */ share->key_info= keyinfo; key_part= reinterpret_cast<KEY_PART_INFO*>(keyinfo+keys); strpos=disk_buff+6; if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, sizeof(ulong)*key_parts))) goto err; for (i=0 ; i < keys ; i++, keyinfo++) { keyinfo->table= 0; // Updated in open_frm if (new_frm_ver >= 3) { keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; //索引长度,索引中列的个数 keyinfo->key_length= (uint) uint2korr(strpos+2); keyinfo->key_parts= (uint) strpos[4]; keyinfo->algorithm= (enum ha_key_alg) strpos[5]; keyinfo->block_size= uint2korr(strpos+6); strpos+=8; } keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->key_parts ; j-- ; key_part++) { *rec_per_key++=0; key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK); key_part->offset= (uint) uint2korr(strpos+2)-1; key_part->key_type= (uint) uint2korr(strpos+5); } } keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; //reading index comments for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++) { if (keyinfo->flags & HA_USES_COMMENT) { keyinfo->comment.length= uint2korr(strpos); keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2, keyinfo->comment.length); strpos+= 2 + keyinfo->comment.length; } } share->key_block_size= uint2korr(head+62); share->fields= uint2korr(forminfo+258); pos= uint2korr(forminfo+260); /* Length of all screens */ n_length= uint2korr(forminfo+268); share->null_fields= uint2korr(forminfo+282); com_length= uint2korr(forminfo+284); if (!(field_ptr = (Field **) alloc_root(&share->mem_root, (uint) ((share->fields+1)*sizeof(Field*)+ interval_count*sizeof(TYPELIB)+ (share->fields+interval_parts+ keys+3)*sizeof(char *)+ (n_length+int_length+com_length))))) goto err; /* purecov: inspected */ /** *field_ptr也是刚分配内存的起始地址,赋值给share->field */ share->field= field_ptr; read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(uchar**) &disk_buff,read_length)) goto err; /* purecov: inspected */ strpos= disk_buff+pos; if (keynames) fix_type_pointers(&interval_array, &share->keynames, 1, &keynames); /* Allocate handler */ if (!(handler_file= get_new_handler(share, thd->mem_root, share->db_type()))) goto err; record= share->default_values-1; /* Fieldstart = 1 */ if (share->null_field_first) { null_flags= null_pos= (uchar*) record+1; null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1; /* null_bytes below is only correct under the condition that there are no bit fields. Correct values is set below after the table struct is initialized */ share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8; } for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++) { uint pack_flag, interval_nr, unireg_type, recpos, field_length; enum_field_types field_type; CHARSET_INFO *charset=NULL; Field::geometry_type geom_type= Field::GEOM_GEOMETRY; LEX_STRING comment; if (new_frm_ver >= 3) { /* new frm file in 4.1 */ field_length= uint2korr(strpos+3); recpos= uint3korr(strpos+5); pack_flag= uint2korr(strpos+8); unireg_type= (uint) strpos[10]; interval_nr= (uint) strpos[12]; uint comment_length=uint2korr(strpos+15); field_type=(enum_field_types) (uint) strpos[13]; } /** *这里的field_ptr其实是个FIELD*的对象 */ *field_ptr= reg_field= make_field(share, record+recpos, (uint32) field_length, null_pos, null_bit_pos, pack_flag, field_type, charset, geom_type, (Field::utype) MTYP_TYPENR(unireg_type), (interval_nr ? share->intervals+interval_nr-1 : (TYPELIB*) 0), share->fieldnames.type_names[i]); }//循环结束 *field_ptr=0; // End marker /* Fix key->name and key_part->field */ if (key_parts) { uint primary_key=(uint) (find_type(primary_key_name, &share->keynames, FIND_TYPE_NO_PREFIX) - 1); longlong ha_option= handler_file->ha_table_flags(); keyinfo= share->key_info; key_part= keyinfo->key_part; /** *share->keys本身是个结构体数组, *里面每一个key,设置其name, *key中的key_part也是个结构体数组,其中的filednr为share->filed该数组中的下标 * */ for (uint key=0 ; key < share->keys ; key++,keyinfo++) { uint usable_parts= 0; keyinfo->name=(char*) share->keynames.type_names[key]; for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) { Field *field; key_part->fieldnr= (uint16) find_field(share->field,share->default_values,(uint) key_part->offset,(uint) key_part->length); field= key_part->field= share->field[key_part->fieldnr-1]; key_part->type= field->key_type(); if (field->null_ptr) { key_part->null_offset=(uint) ((uchar*) field->null_ptr - share->default_values); key_part->null_bit= field->null_bit; key_part->store_length+=HA_KEY_NULL_LENGTH; keyinfo->flags|=HA_NULL_PART_KEY; keyinfo->extra_length+= HA_KEY_NULL_LENGTH; keyinfo->key_length+= HA_KEY_NULL_LENGTH; } } share->total_key_length+= keyinfo->key_length; } } /* the correct null_bytes can now be set, since bitfields have been taken into account */ share->null_bytes= (null_pos - (uchar*) null_flags + (null_bit_pos + 7) / 8); share->last_null_bit_pos= null_bit_pos; share->db_low_byte_first= handler_file->low_byte_first(); share->column_bitmap_size= bitmap_buffer_size(share->fields); if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root, share->column_bitmap_size))) goto err; bitmap_init(&share->all_set, bitmaps, share->fields, FALSE); bitmap_set_all(&share->all_set); delete handler_file; #ifndef DBUG_OFF if (use_hash) (void) my_hash_check(&share->name_hash); #endif my_free(extra_segment_buff); DBUG_RETURN (0); err: share->error= error; share->open_errno= my_errno; share->errarg= errarg; my_free(disk_buff); my_free(extra_segment_buff); delete crypted; delete handler_file; my_hash_free(&share->name_hash); if (share->ha_data_destroy) { share->ha_data_destroy(share->ha_data); share->ha_data_destroy= NULL; } #ifdef WITH_PARTITION_STORAGE_ENGINE if (share->ha_part_data_destroy) { share->ha_part_data_destroy(share->ha_part_data); share->ha_data_destroy= NULL; } #endif /* WITH_PARTITION_STORAGE_ENGINE */ open_table_error(share, error, share->open_errno, errarg); DBUG_RETURN(error); } /* open_binary_frm */
时间: 2024-10-08 17:25:06