38 static void setup_key_functions(
MI_KEYDEF *keyinfo);
39 #define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
43 #define disk_pos_assert(pos, end_pos) \
46 my_errno=HA_ERR_CRASHED; \
56 MI_INFO *test_if_reopen(
char *filename)
60 for (pos=myisam_open_list ; pos ; pos=pos->next)
64 if (!strcmp(share->unique_file_name,filename) && share->last_version)
81 int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
82 uint
i,j,len,errpos,head_length,base_pos,
offset,info_length,keys,
83 key_parts,unique_key_parts,fulltext_keys,uniques;
84 uint internal_table= open_flags & HA_OPEN_INTERNAL_TABLE;
85 char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
87 uchar *disk_cache, *disk_pos, *end_pos;
88 MI_INFO info, *m_info, *old_info= NULL;
90 ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
91 my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
92 ulonglong max_key_file_length, max_data_file_length;
93 DBUG_ENTER(
"mi_open");
99 head_length=
sizeof(share_buff.state.header);
100 memset(&info, 0,
sizeof(info));
102 realpath_err= my_realpath(name_buff,
103 fn_format(org_name,name,
"",MI_NAME_IEXT,4),MYF(0));
104 if (my_is_symlink(org_name) &&
105 (realpath_err || (*myisam_test_invalid_symlink)(name_buff)))
107 my_errno= HA_WRONG_CREATE_OPTION;
114 old_info= test_if_reopen(name_buff);
120 memset(&share_buff, 0,
sizeof(share_buff));
121 share_buff.state.rec_per_key_part=rec_per_key_part;
122 share_buff.state.key_root=key_root;
123 share_buff.state.key_del=key_del;
124 share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
127 DBUG_EXECUTE_IF(
"myisam_pretend_crashed_table_on_open",
128 if (strstr(name,
"/t1"))
130 my_errno= HA_ERR_CRASHED;
135 (open_mode= O_RDWR) | O_SHARE, MYF(0))) < 0)
137 if ((errno != EROFS && errno != EACCES) ||
141 (open_mode= O_RDONLY) | O_SHARE, MYF(0))) < 0)
144 share->mode=open_mode;
146 if (
mysql_file_read(kfile, share->state.header.file_version, head_length,
149 my_errno= HA_ERR_NOT_A_TABLE;
152 if (memcmp((uchar*) share->state.header.file_version,
153 (uchar*) myisam_file_magic, 4))
155 DBUG_PRINT(
"error",(
"Wrong header in %s",name_buff));
156 DBUG_DUMP(
"error_dump", share->state.header.file_version,
158 my_errno=HA_ERR_NOT_A_TABLE;
161 share->options= mi_uint2korr(share->state.header.options);
163 ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
164 HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
165 HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
166 HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
167 HA_OPTION_RELIES_ON_SQL_LAYER))
169 DBUG_PRINT(
"error",(
"wrong options: 0x%lx", share->options));
170 my_errno=HA_ERR_OLD_FILE;
173 if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
174 ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
176 DBUG_PRINT(
"error", (
"table cannot be openned from non-sql layer"));
177 my_errno= HA_ERR_UNSUPPORTED;
181 if (!strcmp(name_buff, org_name) ||
182 my_readlink(index_name, org_name, MYF(0)) == -1)
183 (void) strmov(index_name, org_name);
184 *strrchr(org_name,
'.')=
'\0';
185 (void) fn_format(data_name,org_name,
"",MI_NAME_DEXT,
186 MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
188 info_length=mi_uint2korr(share->state.header.header_length);
189 base_pos=mi_uint2korr(share->state.header.base_pos);
190 if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
195 end_pos=disk_cache+info_length;
199 if (!(open_flags & HA_OPEN_TMP_TABLE))
201 if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
202 MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
203 0 : MY_DONT_WAIT))) &&
204 !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
210 my_errno=HA_ERR_CRASHED;
213 len=mi_uint2korr(share->state.header.state_info_length);
214 keys= (uint) share->state.header.keys;
215 uniques= (uint) share->state.header.uniques;
216 fulltext_keys= (uint) share->state.header.fulltext_keys;
217 key_parts= mi_uint2korr(share->state.header.key_parts);
218 unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
219 if (len != MI_STATE_INFO_SIZE)
221 DBUG_PRINT(
"warning",
222 (
"saved_state_info_length: %d state_info_length: %d",
223 len,MI_STATE_INFO_SIZE));
225 share->state_diff_length=len-MI_STATE_INFO_SIZE;
227 mi_state_info_read(disk_cache, &share->state);
228 len= mi_uint2korr(share->state.header.base_info_length);
229 if (len != MI_BASE_INFO_SIZE)
231 DBUG_PRINT(
"warning",(
"saved_base_info_length: %d base_info_length: %d",
232 len,MI_BASE_INFO_SIZE));
234 disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
235 share->state.state_length=base_pos;
237 if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
238 ((share->state.changed & STATE_CRASHED) ||
239 ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
240 (my_disable_locking && share->state.open_count))))
242 DBUG_PRINT(
"error",(
"Table is marked as crashed. open_flags: %u "
243 "changed: %u open_count: %u !locking: %d",
244 open_flags, share->state.changed,
245 share->state.open_count, my_disable_locking));
246 my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
247 HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
252 if (share->base.keystart > 65535 ||
253 share->base.rec_reflength > 8 || share->base.key_reflength > 7)
255 my_errno=HA_ERR_CRASHED;
259 key_parts+=fulltext_keys*FT_SEGS;
260 if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
261 key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
263 DBUG_PRINT(
"error",(
"Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
264 my_errno=HA_ERR_UNSUPPORTED;
269 max_data_file_length=
270 (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
271 (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
272 (mi_safe_mul(share->base.pack_reclength,
273 (ulonglong) 1 << (share->base.rec_reflength*8))-1);
275 mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
276 ((ulonglong) 1 << (share->base.key_reflength*8))-1);
277 #if SIZEOF_OFF_T == 4
278 set_if_smaller(max_data_file_length, INT_MAX32);
279 set_if_smaller(max_key_file_length, INT_MAX32);
281 share->base.max_data_file_length=(my_off_t) max_data_file_length;
282 share->base.max_key_file_length=(my_off_t) max_key_file_length;
284 if (share->options & HA_OPTION_COMPRESS_RECORD)
285 share->base.max_key_length+=2;
288 share->base.max_key_length+= share->base.key_reflength;
290 if (!my_multi_malloc(MY_WME,
291 &share,
sizeof(*share),
292 &share->state.rec_per_key_part,
sizeof(long)*key_parts,
296 (key_parts+unique_key_parts+keys+uniques) *
300 &share->blobs,
sizeof(
MI_BLOB)*share->base.blobs,
301 &share->unique_file_name,strlen(name_buff)+1,
302 &share->index_file_name,strlen(index_name)+1,
303 &share->data_file_name,strlen(data_name)+1,
304 &share->state.key_root,keys*
sizeof(my_off_t),
305 &share->state.key_del,
306 (share->state.header.max_block_size_index*
sizeof(my_off_t)),
313 memcpy((
char*) share->state.rec_per_key_part,
314 (
char*) rec_per_key_part,
sizeof(
long)*key_parts);
315 memcpy((
char*) share->state.key_root,
316 (
char*) key_root,
sizeof(my_off_t)*keys);
317 memcpy((
char*) share->state.key_del,
318 (
char*) key_del, (
sizeof(my_off_t) *
319 share->state.header.max_block_size_index));
320 strmov(share->unique_file_name, name_buff);
321 share->unique_name_length= strlen(name_buff);
322 strmov(share->index_file_name, index_name);
323 strmov(share->data_file_name, data_name);
325 share->blocksize= MY_MIN(IO_SIZE, myisam_block_size);
329 for (i=0 ; i < keys ; i++)
331 share->keyinfo[
i].share= share;
332 disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
333 disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
335 if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
337 set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
338 share->keyinfo[
i].seg=pos;
339 for (j=0 ; j < share->keyinfo[
i].keysegs; j++,pos++)
341 disk_pos=mi_keyseg_read(disk_pos, pos);
342 if (pos->flag & HA_BLOB_PART &&
343 ! (share->options & (HA_OPTION_COMPRESS_RECORD |
344 HA_OPTION_PACK_RECORD)))
346 my_errno= HA_ERR_CRASHED;
349 if (pos->type == HA_KEYTYPE_TEXT ||
350 pos->type == HA_KEYTYPE_VARTEXT1 ||
351 pos->type == HA_KEYTYPE_VARTEXT2)
354 pos->charset=default_charset_info;
355 else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
357 my_errno=HA_ERR_UNKNOWN_CHARSET;
361 else if (pos->type == HA_KEYTYPE_BINARY)
362 pos->charset= &my_charset_bin;
363 if (!(share->keyinfo[i].flag & HA_SPATIAL) &&
364 pos->start > share->base.reclength)
366 my_errno= HA_ERR_CRASHED;
370 if (share->keyinfo[i].flag & HA_SPATIAL)
373 uint sp_segs=SPDIMS*2;
374 share->keyinfo[
i].seg=pos-sp_segs;
375 share->keyinfo[
i].keysegs--;
377 my_errno=HA_ERR_UNSUPPORTED;
381 else if (share->keyinfo[i].flag & HA_FULLTEXT)
385 share->keyinfo[
i].seg=pos-FT_SEGS;
386 share->keyinfo[
i].keysegs-=FT_SEGS;
391 share->keyinfo[
i].seg=pos;
392 for (k=0; k < FT_SEGS; k++)
395 pos[0].language= pos[-1].language;
396 if (!(pos[0].charset= pos[-1].charset))
398 my_errno=HA_ERR_CRASHED;
404 if (!share->ft2_keyinfo.seg)
406 memcpy(& share->ft2_keyinfo, & share->keyinfo[i],
sizeof(
MI_KEYDEF));
407 share->ft2_keyinfo.keysegs=1;
408 share->ft2_keyinfo.flag=0;
409 share->ft2_keyinfo.keylength=
410 share->ft2_keyinfo.minlength=
411 share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
412 share->ft2_keyinfo.seg=pos-1;
413 share->ft2_keyinfo.end=pos;
414 setup_key_functions(& share->ft2_keyinfo);
416 share->keyinfo[
i].ftkey_nr= ftkey_nr++;
418 setup_key_functions(share->keyinfo+i);
419 share->keyinfo[
i].end=pos;
420 pos->type=HA_KEYTYPE_END;
421 pos->length=share->base.rec_reflength;
427 for (i=0 ; i < uniques ; i++)
429 disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
430 disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs *
431 HA_KEYSEG_SIZE, end_pos);
432 share->uniqueinfo[
i].seg=pos;
433 for (j=0 ; j < share->uniqueinfo[
i].keysegs; j++,pos++)
435 disk_pos=mi_keyseg_read(disk_pos, pos);
436 if (pos->type == HA_KEYTYPE_TEXT ||
437 pos->type == HA_KEYTYPE_VARTEXT1 ||
438 pos->type == HA_KEYTYPE_VARTEXT2)
441 pos->charset=default_charset_info;
442 else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
444 my_errno=HA_ERR_UNKNOWN_CHARSET;
449 share->uniqueinfo[
i].end=pos;
450 pos->type=HA_KEYTYPE_END;
455 share->ftkeys= ftkey_nr;
458 disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
459 for (i=j=offset=0 ; i < share->base.fields ; i++)
461 disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
462 share->rec[
i].pack_type=0;
463 share->rec[
i].huff_tree=0;
465 if (share->rec[i].type == (
int) FIELD_BLOB)
467 share->blobs[j].pack_length=
468 share->rec[
i].length-portable_sizeof_char_ptr;
469 share->blobs[j].offset=
offset;
472 offset+=share->rec[
i].length;
474 share->rec[
i].type=(int) FIELD_LAST;
475 if (offset > share->base.reclength)
478 my_errno= HA_ERR_CRASHED;
485 (void) my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
489 if (mi_open_datafile(&info, share, name, -1))
494 share->this_process=(ulong) getpid();
495 share->last_process= share->state.process;
496 share->base.key_parts=key_parts;
497 share->base.all_key_parts=key_parts+unique_key_parts;
498 if (!(share->last_version=share->state.version))
499 share->last_version=1;
500 share->rec_reflength=share->base.rec_reflength;
501 share->base.margin_key_file_length=(share->base.max_key_file_length -
502 (keys ? MI_INDEX_BLOCK_MARGIN *
503 share->blocksize * keys : 0));
504 share->blocksize= MY_MIN(IO_SIZE, myisam_block_size);
505 share->data_file_type=STATIC_RECORD;
506 if (share->options & HA_OPTION_COMPRESS_RECORD)
508 share->data_file_type = COMPRESSED_RECORD;
509 share->options|= HA_OPTION_READ_ONLY_DATA;
511 if (_mi_read_pack_info(&info,
513 test(!(share->options &
514 (HA_OPTION_PACK_RECORD |
515 HA_OPTION_TEMP_COMPRESS_RECORD)))))
518 else if (share->options & HA_OPTION_PACK_RECORD)
519 share->data_file_type = DYNAMIC_RECORD;
520 my_afree(disk_cache);
521 mi_setup_functions(share);
522 share->is_log_table= FALSE;
523 thr_lock_init(&share->lock);
525 &share->intern_lock, MY_MUTEX_INIT_FAST);
526 for (i=0; i<keys; i++)
528 &share->key_root_lock[i]);
530 if (!thr_lock_inited)
533 myisam_concurrent_insert=0;
535 else if (myisam_concurrent_insert)
537 share->concurrent_insert=
538 ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
539 HA_OPTION_COMPRESS_RECORD |
540 HA_OPTION_TEMP_COMPRESS_RECORD)) ||
541 (open_flags & HA_OPEN_TMP_TABLE) ||
543 if (share->concurrent_insert)
545 share->lock.get_status=mi_get_status;
546 share->lock.copy_status=mi_copy_status;
547 share->lock.update_status=mi_update_status;
548 share->lock.restore_status= mi_restore_status;
549 share->lock.check_status=mi_check_status;
555 if (open_flags & HA_OPEN_MMAP)
558 mi_extra(&info, HA_EXTRA_MMAP, 0);
564 if (mode == O_RDWR && share->mode == O_RDONLY)
569 if (mi_open_datafile(&info, share, name, old_info->dfile))
572 have_rtree= old_info->rtree_recursion_state != NULL;
576 if (!my_multi_malloc(MY_WME,
578 &info.blobs,
sizeof(
MI_BLOB)*share->base.blobs,
579 &info.buff,(share->base.max_key_block_length*2+
580 share->base.max_key_length),
581 &info.lastkey,share->base.max_key_length*3+1,
582 &info.first_mbr_key, share->base.max_key_length,
583 &info.filename,strlen(name)+1,
584 &info.rtree_recursion_state,have_rtree ? 1024 : 0,
590 info.rtree_recursion_state= NULL;
592 strmov(info.filename,name);
593 memcpy(info.blobs,share->blobs,
sizeof(
MI_BLOB)*share->base.blobs);
594 info.lastkey2=info.lastkey+share->base.max_key_length;
597 info.lastpos= HA_OFFSET_ERROR;
598 info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
599 info.opt_flag=READ_CHECK_USED;
600 info.this_unique= (ulong) info.dfile;
601 if (share->data_file_type == COMPRESSED_RECORD)
602 info.this_unique= share->state.unique;
604 info.last_unique= share->state.unique;
605 info.last_loop= share->state.update_count;
606 if (mode == O_RDONLY)
607 share->options|=HA_OPTION_READ_ONLY_DATA;
608 info.lock_type=F_UNLCK;
615 info.read_record=share->read_record;
617 share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
618 if (share->options & HA_OPTION_READ_ONLY_DATA)
620 info.lock_type=F_RDLCK;
624 if ((open_flags & HA_OPEN_TMP_TABLE) ||
625 (share->options & HA_OPTION_TMP_TABLE))
627 share->temporary=share->delay_key_write=1;
628 share->write_flag=MYF(MY_NABP);
631 info.lock_type=F_WRLCK;
633 if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
634 (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
635 myisam_delay_key_write)
636 share->delay_key_write=1;
637 info.state= &share->state.state;
643 if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
645 memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
648 thr_lock_data_init(&share->lock,&m_info->lock,(
void*) m_info);
652 m_info->open_list.data= (
void*) m_info;
653 myisam_open_list= list_add(myisam_open_list, &m_info->open_list);
657 memset(info.buff, 0, share->base.max_key_block_length * 2);
659 if (myisam_log_file >= 0)
661 intern_filename(name_buff,share->index_file_name);
662 _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
667 save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
668 if ((save_errno == HA_ERR_CRASHED) ||
669 (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
670 (save_errno == HA_ERR_CRASHED_ON_REPAIR))
671 mi_report_error(save_errno, name);
686 (void) my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE));
689 my_afree(disk_cache);
705 uchar *mi_alloc_rec_buff(
MI_INFO *info, ulong length, uchar **
buf)
708 uint32 UNINIT_VAR(old_length);
709 LINT_INIT(old_length);
711 if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
713 uchar *newptr = *
buf;
716 if (length == (ulong) -1)
718 if (info->s->options & HA_OPTION_COMPRESS_RECORD)
719 length= MY_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
721 length= info->s->base.pack_reclength;
722 length= MY_MAX(length, info->s->base.max_key_length);
724 if (newptr && length == old_length)
728 extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
729 ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
730 MI_REC_BUFF_OFFSET : 0);
732 newptr-= MI_REC_BUFF_OFFSET;
733 if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
734 MYF(MY_ALLOW_ZERO_PTR))))
736 *((uint32 *) newptr)= (uint32) length;
737 *buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
743 ulonglong mi_safe_mul(ulonglong a, ulonglong b)
745 ulonglong max_val= ~ (ulonglong) 0;
747 if (!a || max_val / a < b)
756 if (share->options & HA_OPTION_COMPRESS_RECORD)
758 share->read_record=_mi_read_pack_record;
759 share->read_rnd=_mi_read_rnd_pack_record;
760 if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
761 share->calc_checksum=0;
762 else if (share->options & HA_OPTION_PACK_RECORD)
763 share->calc_checksum= mi_checksum;
765 share->calc_checksum= mi_static_checksum;
767 else if (share->options & HA_OPTION_PACK_RECORD)
769 share->read_record=_mi_read_dynamic_record;
770 share->read_rnd=_mi_read_rnd_dynamic_record;
771 share->delete_record=_mi_delete_dynamic_record;
772 share->compare_record=_mi_cmp_dynamic_record;
773 share->compare_unique=_mi_cmp_dynamic_unique;
774 share->calc_checksum= mi_checksum;
777 share->base.pack_reclength+= share->base.pack_bits;
778 if (share->base.blobs)
780 share->update_record=_mi_update_blob_record;
781 share->write_record=_mi_write_blob_record;
785 share->write_record=_mi_write_dynamic_record;
786 share->update_record=_mi_update_dynamic_record;
791 share->read_record=_mi_read_static_record;
792 share->read_rnd=_mi_read_rnd_static_record;
793 share->delete_record=_mi_delete_static_record;
794 share->compare_record=_mi_cmp_static_record;
795 share->update_record=_mi_update_static_record;
796 share->write_record=_mi_write_static_record;
797 share->compare_unique=_mi_cmp_static_unique;
798 share->calc_checksum= mi_static_checksum;
800 share->file_read= mi_nommap_pread;
801 share->file_write= mi_nommap_pwrite;
802 if (!(share->options & HA_OPTION_CHECKSUM))
803 share->calc_checksum=0;
808 static void setup_key_functions(
register MI_KEYDEF *keyinfo)
810 if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
812 #ifdef HAVE_RTREE_KEYS
813 keyinfo->ck_insert = rtree_insert;
814 keyinfo->ck_delete = rtree_delete;
821 keyinfo->ck_insert = _mi_ck_write;
822 keyinfo->ck_delete = _mi_ck_delete;
824 if (keyinfo->flag & HA_BINARY_PACK_KEY)
826 keyinfo->bin_search=_mi_seq_search;
827 keyinfo->get_key=_mi_get_binary_pack_key;
828 keyinfo->pack_key=_mi_calc_bin_pack_key_length;
829 keyinfo->store_key=_mi_store_bin_pack_key;
831 else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
833 keyinfo->get_key= _mi_get_pack_key;
834 if (keyinfo->seg[0].flag & HA_PACK_KEY)
844 if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
845 (keyinfo->seg->flag & HA_NULL_PART) ||
846 (keyinfo->seg->charset->mbminlen > 1))
847 keyinfo->bin_search=_mi_seq_search;
849 keyinfo->bin_search=_mi_prefix_search;
850 keyinfo->pack_key=_mi_calc_var_pack_key_length;
851 keyinfo->store_key=_mi_store_var_pack_key;
855 keyinfo->bin_search=_mi_seq_search;
856 keyinfo->pack_key=_mi_calc_var_key_length;
857 keyinfo->store_key=_mi_store_static_key;
862 keyinfo->bin_search=_mi_bin_search;
863 keyinfo->get_key=_mi_get_static_key;
864 keyinfo->pack_key=_mi_calc_static_key_length;
865 keyinfo->store_key=_mi_store_static_key;
877 uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
879 uint
i, keys= (uint) state->header.keys,
880 key_blocks=state->header.max_block_size_index;
881 DBUG_ENTER(
"mi_state_info_write");
883 memcpy(ptr, &state->header,
sizeof(state->header));
884 ptr+=
sizeof(state->header);
887 mi_int2store(ptr,state->open_count); ptr +=2;
888 *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
889 mi_rowstore(ptr,state->state.records); ptr +=8;
890 mi_rowstore(ptr,state->state.del); ptr +=8;
891 mi_rowstore(ptr,state->split); ptr +=8;
892 mi_sizestore(ptr,state->dellink); ptr +=8;
893 mi_sizestore(ptr,state->state.key_file_length); ptr +=8;
894 mi_sizestore(ptr,state->state.data_file_length); ptr +=8;
895 mi_sizestore(ptr,state->state.empty); ptr +=8;
896 mi_sizestore(ptr,state->state.key_empty); ptr +=8;
897 mi_int8store(ptr,state->auto_increment); ptr +=8;
898 mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
899 mi_int4store(ptr,state->process); ptr +=4;
900 mi_int4store(ptr,state->unique); ptr +=4;
901 mi_int4store(ptr,state->status); ptr +=4;
902 mi_int4store(ptr,state->update_count); ptr +=4;
904 ptr+=state->state_diff_length;
906 for (i=0; i < keys; i++)
908 mi_sizestore(ptr,state->key_root[i]); ptr +=8;
910 for (i=0; i < key_blocks; i++)
912 mi_sizestore(ptr,state->key_del[i]); ptr +=8;
916 uint key_parts= mi_uint2korr(state->header.key_parts);
917 mi_int4store(ptr,state->sec_index_changed); ptr +=4;
918 mi_int4store(ptr,state->sec_index_used); ptr +=4;
919 mi_int4store(ptr,state->version); ptr +=4;
920 mi_int8store(ptr,state->key_map); ptr +=8;
921 mi_int8store(ptr,(ulonglong) state->create_time); ptr +=8;
922 mi_int8store(ptr,(ulonglong) state->recover_time); ptr +=8;
923 mi_int8store(ptr,(ulonglong) state->check_time); ptr +=8;
924 mi_sizestore(ptr,state->rec_per_key_rows); ptr+=8;
925 for (i=0 ; i < key_parts ; i++)
927 mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
933 MYF(MY_NABP | MY_THREADSAFE)) != 0);
941 uint
i,keys,key_parts,key_blocks;
942 memcpy(&state->header, ptr,
sizeof(state->header));
943 ptr +=
sizeof(state->header);
944 keys=(uint) state->header.keys;
945 key_parts=mi_uint2korr(state->header.key_parts);
946 key_blocks=state->header.max_block_size_index;
948 state->open_count = mi_uint2korr(ptr); ptr +=2;
949 state->changed= *ptr++;
950 state->sortkey = (uint) *ptr++;
951 state->state.records= mi_rowkorr(ptr); ptr +=8;
952 state->state.del = mi_rowkorr(ptr); ptr +=8;
953 state->split = mi_rowkorr(ptr); ptr +=8;
954 state->dellink= mi_sizekorr(ptr); ptr +=8;
955 state->state.key_file_length = mi_sizekorr(ptr); ptr +=8;
956 state->state.data_file_length= mi_sizekorr(ptr); ptr +=8;
957 state->state.empty = mi_sizekorr(ptr); ptr +=8;
958 state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
959 state->auto_increment=mi_uint8korr(ptr); ptr +=8;
960 state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
961 state->process= mi_uint4korr(ptr); ptr +=4;
962 state->unique = mi_uint4korr(ptr); ptr +=4;
963 state->status = mi_uint4korr(ptr); ptr +=4;
964 state->update_count=mi_uint4korr(ptr); ptr +=4;
966 ptr+= state->state_diff_length;
968 for (i=0; i < keys; i++)
970 state->key_root[
i]= mi_sizekorr(ptr); ptr +=8;
972 for (i=0; i < key_blocks; i++)
974 state->key_del[
i] = mi_sizekorr(ptr); ptr +=8;
976 state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
977 state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
978 state->version = mi_uint4korr(ptr); ptr +=4;
979 state->key_map = mi_uint8korr(ptr); ptr +=8;
980 state->create_time = (time_t) mi_sizekorr(ptr); ptr +=8;
981 state->recover_time =(time_t) mi_sizekorr(ptr); ptr +=8;
982 state->check_time = (time_t) mi_sizekorr(ptr); ptr +=8;
983 state->rec_per_key_rows=mi_sizekorr(ptr); ptr +=8;
984 for (i=0 ; i < key_parts ; i++)
986 state->rec_per_key_part[
i]= mi_uint4korr(ptr); ptr+=4;
992 uint mi_state_info_read_dsk(File file,
MI_STATE_INFO *state, my_bool pRead)
994 uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
996 if (!myisam_single_user)
1003 else if (
mysql_file_read(file, buff, state->state_length, MYF(MY_NABP)))
1005 mi_state_info_read(buff, state);
1017 uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
1019 mi_sizestore(ptr,base->keystart); ptr +=8;
1020 mi_sizestore(ptr,base->max_data_file_length); ptr +=8;
1021 mi_sizestore(ptr,base->max_key_file_length); ptr +=8;
1022 mi_rowstore(ptr,base->records); ptr +=8;
1023 mi_rowstore(ptr,base->reloc); ptr +=8;
1024 mi_int4store(ptr,base->mean_row_length); ptr +=4;
1025 mi_int4store(ptr,base->reclength); ptr +=4;
1026 mi_int4store(ptr,base->pack_reclength); ptr +=4;
1027 mi_int4store(ptr,base->min_pack_length); ptr +=4;
1028 mi_int4store(ptr,base->max_pack_length); ptr +=4;
1029 mi_int4store(ptr,base->min_block_length); ptr +=4;
1030 mi_int4store(ptr,base->fields); ptr +=4;
1031 mi_int4store(ptr,base->pack_fields); ptr +=4;
1032 *ptr++=base->rec_reflength;
1033 *ptr++=base->key_reflength;
1035 *ptr++=base->auto_key;
1036 mi_int2store(ptr,base->pack_bits); ptr +=2;
1037 mi_int2store(ptr,base->blobs); ptr +=2;
1038 mi_int2store(ptr,base->max_key_block_length); ptr +=2;
1039 mi_int2store(ptr,base->max_key_length); ptr +=2;
1040 mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2;
1041 *ptr++= base->extra_alloc_procent;
1042 memset(ptr, 0, 13); ptr +=13;
1043 return mysql_file_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1047 uchar *my_n_base_info_read(uchar *ptr,
MI_BASE_INFO *base)
1049 base->keystart = mi_sizekorr(ptr); ptr +=8;
1050 base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
1051 base->max_key_file_length = mi_sizekorr(ptr); ptr +=8;
1052 base->records = (ha_rows) mi_sizekorr(ptr); ptr +=8;
1053 base->reloc = (ha_rows) mi_sizekorr(ptr); ptr +=8;
1054 base->mean_row_length = mi_uint4korr(ptr); ptr +=4;
1055 base->reclength = mi_uint4korr(ptr); ptr +=4;
1056 base->pack_reclength = mi_uint4korr(ptr); ptr +=4;
1057 base->min_pack_length = mi_uint4korr(ptr); ptr +=4;
1058 base->max_pack_length = mi_uint4korr(ptr); ptr +=4;
1059 base->min_block_length = mi_uint4korr(ptr); ptr +=4;
1060 base->fields = mi_uint4korr(ptr); ptr +=4;
1061 base->pack_fields = mi_uint4korr(ptr); ptr +=4;
1063 base->rec_reflength = *ptr++;
1064 base->key_reflength = *ptr++;
1066 base->auto_key= *ptr++;
1067 base->pack_bits = mi_uint2korr(ptr); ptr +=2;
1068 base->blobs = mi_uint2korr(ptr); ptr +=2;
1069 base->max_key_block_length= mi_uint2korr(ptr); ptr +=2;
1070 base->max_key_length = mi_uint2korr(ptr); ptr +=2;
1071 base->extra_alloc_bytes = mi_uint2korr(ptr); ptr +=2;
1072 base->extra_alloc_procent = *ptr++;
1082 uint mi_keydef_write(File file,
MI_KEYDEF *keydef)
1084 uchar buff[MI_KEYDEF_SIZE];
1087 *ptr++ = (uchar) keydef->keysegs;
1088 *ptr++ = keydef->key_alg;
1089 mi_int2store(ptr,keydef->flag); ptr +=2;
1090 mi_int2store(ptr,keydef->block_length); ptr +=2;
1091 mi_int2store(ptr,keydef->keylength); ptr +=2;
1092 mi_int2store(ptr,keydef->minlength); ptr +=2;
1093 mi_int2store(ptr,keydef->maxlength); ptr +=2;
1094 return mysql_file_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1097 uchar *mi_keydef_read(uchar *ptr,
MI_KEYDEF *keydef)
1099 keydef->keysegs = (uint) *ptr++;
1100 keydef->key_alg = *ptr++;
1102 keydef->flag = mi_uint2korr(ptr); ptr +=2;
1103 keydef->block_length = mi_uint2korr(ptr); ptr +=2;
1104 keydef->keylength = mi_uint2korr(ptr); ptr +=2;
1105 keydef->minlength = mi_uint2korr(ptr); ptr +=2;
1106 keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
1107 keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
1108 keydef->underflow_block_length=keydef->block_length/3;
1109 keydef->version = 0;
1110 keydef->parser = &ft_default_parser;
1111 keydef->ftkey_nr = 0;
1119 int mi_keyseg_write(File file,
const HA_KEYSEG *keyseg)
1121 uchar buff[HA_KEYSEG_SIZE];
1125 *ptr++= keyseg->type;
1126 *ptr++= keyseg->language & 0xFF;
1127 *ptr++= keyseg->null_bit;
1128 *ptr++= keyseg->bit_start;
1129 *ptr++= keyseg->language >> 8;
1130 *ptr++= keyseg->bit_length;
1131 mi_int2store(ptr,keyseg->flag); ptr+=2;
1132 mi_int2store(ptr,keyseg->length); ptr+=2;
1133 mi_int4store(ptr,keyseg->start); ptr+=4;
1134 pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
1135 mi_int4store(ptr, pos);
1138 return mysql_file_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1142 uchar *mi_keyseg_read(uchar *ptr,
HA_KEYSEG *keyseg)
1144 keyseg->type = *ptr++;
1145 keyseg->language = *ptr++;
1146 keyseg->null_bit = *ptr++;
1147 keyseg->bit_start = *ptr++;
1148 keyseg->language += ((uint16) (*ptr++)) << 8;
1149 keyseg->bit_length = *ptr++;
1150 keyseg->flag = mi_uint2korr(ptr); ptr +=2;
1151 keyseg->length = mi_uint2korr(ptr); ptr +=2;
1152 keyseg->start = mi_uint4korr(ptr); ptr +=4;
1153 keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
1156 if (keyseg->null_bit)
1158 keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == (1 << 7)));
1161 keyseg->bit_pos= (uint16)keyseg->null_pos;
1162 keyseg->null_pos= 0;
1173 uchar buff[MI_UNIQUEDEF_SIZE];
1176 mi_int2store(ptr,def->keysegs); ptr+=2;
1177 *ptr++= (uchar) def->key;
1178 *ptr++ = (uchar) def->null_are_equal;
1180 return mysql_file_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1183 uchar *mi_uniquedef_read(uchar *ptr,
MI_UNIQUEDEF *def)
1185 def->keysegs = mi_uint2korr(ptr);
1187 def->null_are_equal=ptr[3];
1195 uint mi_recinfo_write(File file,
MI_COLUMNDEF *recinfo)
1197 uchar buff[MI_COLUMNDEF_SIZE];
1200 mi_int2store(ptr,recinfo->type); ptr +=2;
1201 mi_int2store(ptr,recinfo->length); ptr +=2;
1202 *ptr++ = recinfo->null_bit;
1203 mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
1204 return mysql_file_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1207 uchar *mi_recinfo_read(uchar *ptr,
MI_COLUMNDEF *recinfo)
1209 recinfo->type= mi_sint2korr(ptr); ptr +=2;
1210 recinfo->length=mi_uint2korr(ptr); ptr +=2;
1211 recinfo->null_bit= (uint8) *ptr++;
1212 recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1226 File file_to_dup __attribute__((unused)))
1228 char *data_name= share->data_file_name;
1229 char real_data_name[FN_REFLEN];
1233 fn_format(real_data_name,org_name,
"",MI_NAME_DEXT,4);
1234 if (my_is_symlink(real_data_name))
1236 if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
1237 (*myisam_test_invalid_symlink)(real_data_name))
1239 my_errno= HA_WRONG_CREATE_OPTION;
1242 data_name= real_data_name;
1246 data_name, share->mode | O_SHARE, MYF(MY_WME));
1247 return info->dfile >= 0 ? 0 : 1;
1254 share->unique_file_name,
1255 share->mode | O_SHARE,
1276 int mi_disable_indexes(
MI_INFO *info)
1280 mi_clear_all_keys_active(share->state.key_map);
1304 int mi_enable_indexes(
MI_INFO *info)
1309 if (share->state.state.data_file_length ||
1310 (share->state.state.key_file_length != share->base.keystart))
1312 mi_print_error(info->s, HA_ERR_CRASHED);
1313 error= HA_ERR_CRASHED;
1316 mi_set_all_keys_active(share->state.key_map, share->base.keys);
1337 int mi_indexes_are_disabled(
MI_INFO *info)
1346 if (!share->base.keys ||
1347 (mi_is_all_keys_active(share->state.key_map, share->base.keys)))
1351 if (mi_is_any_key_active(share->state.key_map))