36 int save_errno,errpos=0;
37 uint files= 0,
i, dir_length, length, UNINIT_VAR(key_parts), min_keys= 0;
38 ulonglong file_offset=0;
39 char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
44 uint found_merge_insert_method= 0;
45 size_t name_buff_length;
46 my_bool bad_children= FALSE;
47 DBUG_ENTER(
"myrg_open");
49 memset(&file, 0,
sizeof(file));
51 fn_format(name_buff, name,
"", MYRG_NAME_EXT,
52 MY_UNPACK_FILENAME|MY_APPEND_EXT),
53 O_RDONLY | O_SHARE, MYF(0))) < 0)
56 if (init_io_cache(&file, fd, 4*IO_SIZE, READ_CACHE, 0, 0,
57 MYF(MY_WME | MY_NABP)))
60 dir_length=dirname_part(name_buff, name, &name_buff_length);
61 while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
63 if ((end=buff+length)[-1] ==
'\n')
65 if (buff[0] && buff[0] !=
'#')
70 while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
72 if ((end=buff+length)[-1] ==
'\n')
78 if (!strncmp(buff+1,
"INSERT_METHOD=",14))
80 int tmp= find_type(buff + 15, &merge_insert_method, FIND_TYPE_BASIC);
81 found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
88 (void) strmake(name_buff+dir_length,buff,
89 sizeof(name_buff)-1-dir_length);
90 (void) cleanup_dirname(buff,name_buff);
93 fn_format(buff, buff,
"",
"", 0);
94 if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
96 if (handle_locking & HA_OPEN_FOR_REPAIR)
98 myrg_print_wrong_table(buff);
106 key_parts=isam->s->base.key_parts;
109 key_parts*
sizeof(
long),
110 MYF(MY_WME|MY_ZEROFILL))))
113 m_info->open_tables=(
MYRG_TABLE *) (m_info+1);
114 m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files);
115 m_info->tables= files;
117 m_info->reclength=isam->s->base.reclength;
118 min_keys= isam->s->base.keys;
121 m_info->open_tables[files].table= isam;
122 m_info->open_tables[files].file_offset=(my_off_t) file_offset;
123 file_offset+=isam->state->data_file_length;
125 if (m_info->reclength != isam->s->base.reclength)
127 if (handle_locking & HA_OPEN_FOR_REPAIR)
129 myrg_print_wrong_table(buff);
135 m_info->options|= isam->s->options;
136 m_info->records+= isam->state->records;
137 m_info->del+= isam->state->del;
138 m_info->data_file_length+= isam->state->data_file_length;
139 if (min_keys > isam->s->base.keys)
140 min_keys= isam->s->base.keys;
141 for (
i=0;
i < key_parts;
i++)
142 m_info->rec_per_key_part[
i]+= (isam->s->state.rec_per_key_part[
i] /
149 MYF(MY_WME | MY_ZEROFILL))))
152 m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
153 m_info->merge_insert_method= found_merge_insert_method;
155 if (
sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
157 my_errno=HA_ERR_RECORD_FILE_FULL;
160 m_info->keys= min_keys;
161 memset(&m_info->by_key, 0,
sizeof(m_info->by_key));
164 m_info->end_table=m_info->open_tables+files;
165 m_info->last_used_table=m_info->open_tables;
166 m_info->children_attached= TRUE;
171 &m_info->mutex, MY_MUTEX_INIT_FAST);
172 m_info->open_list.data=(
void*) m_info;
174 myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
179 my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
185 (void) mi_close(m_info->open_tables[--files].table);
219 MYRG_INFO *myrg_parent_open(
const char *parent_name,
220 int (*callback)(
void*,
const char*),
221 void *callback_param)
232 char parent_name_buff[FN_REFLEN * 2];
233 char child_name_buff[FN_REFLEN];
234 DBUG_ENTER(
"myrg_parent_open");
238 memset(&file_cache, 0,
sizeof(file_cache));
242 fn_format(parent_name_buff, parent_name,
244 MY_UNPACK_FILENAME|MY_APPEND_EXT),
245 O_RDONLY | O_SHARE, MYF(0))) < 0)
249 if (init_io_cache(&file_cache, fd, 4 * IO_SIZE, READ_CACHE, 0, 0,
250 MYF(MY_WME | MY_NABP)))
257 while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1)))
260 if (child_name_buff[length - 1] ==
'\n')
261 child_name_buff[--length]=
'\0';
264 if (!child_name_buff[0])
268 if (child_name_buff[0] ==
'#')
270 if (!strncmp(child_name_buff + 1,
"INSERT_METHOD=", 14))
273 insert_method= find_type(child_name_buff + 15,
274 &merge_insert_method, FIND_TYPE_BASIC);
286 MYF(MY_WME | MY_ZEROFILL))))
289 m_info->open_tables= (
MYRG_TABLE*) (m_info + 1);
290 m_info->tables= child_count;
291 m_info->merge_insert_method= insert_method > 0 ? insert_method : 0;
293 m_info->end_table= m_info->open_tables + child_count;
297 m_info->children_attached= TRUE;
301 my_b_seek(&file_cache, 0);
302 while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1)))
305 if (child_name_buff[length - 1] ==
'\n')
306 child_name_buff[--length]=
'\0';
309 if (!child_name_buff[0] || (child_name_buff[0] ==
'#'))
312 DBUG_PRINT(
"info", (
"child: '%s'", child_name_buff));
315 if ((rc= (*callback)(callback_param, child_name_buff)))
319 end_io_cache(&file_cache);
322 &m_info->mutex, MY_MUTEX_INIT_FAST);
324 m_info->open_list.data= (
void*) m_info;
326 myrg_open_list= list_add(myrg_open_list, &m_info->open_list);
333 save_errno= my_errno;
339 end_io_cache(&file_cache);
344 my_errno= save_errno;
375 int myrg_attach_children(
MYRG_INFO *m_info,
int handle_locking,
377 void *callback_param, my_bool *need_compat_check)
379 ulonglong file_offset;
385 uint UNINIT_VAR(key_parts);
387 my_bool bad_children= FALSE;
388 my_bool first_child= TRUE;
389 DBUG_ENTER(
"myrg_attach_children");
390 DBUG_PRINT(
"myrg", (
"handle_locking: %d", handle_locking));
403 for (child_nr= 0; child_nr < m_info->tables; child_nr++)
405 if (! (myisam= (*callback)(callback_param)))
407 if (handle_locking & HA_OPEN_FOR_REPAIR)
416 DBUG_PRINT(
"myrg", (
"child_nr: %u table: '%s'",
417 child_nr, myisam->filename));
423 m_info->reclength= myisam->s->base.reclength;
424 min_keys= myisam->s->base.keys;
425 key_parts= myisam->s->base.key_parts;
426 if (*need_compat_check && m_info->rec_per_key_part)
428 my_free(m_info->rec_per_key_part);
429 m_info->rec_per_key_part= NULL;
431 if (!m_info->rec_per_key_part)
433 if(!(m_info->rec_per_key_part= (ulong*)
434 my_malloc(key_parts *
sizeof(
long), MYF(MY_WME))))
438 memset(m_info->rec_per_key_part, 0, key_parts *
sizeof(
long));
442 m_info->open_tables[child_nr].table= myisam;
443 m_info->open_tables[child_nr].file_offset= (my_off_t) file_offset;
444 file_offset+= myisam->state->data_file_length;
447 if (m_info->reclength != myisam->s->base.reclength)
449 DBUG_PRINT(
"error", (
"definition mismatch table: '%s' repair: %d",
451 (handle_locking & HA_OPEN_FOR_REPAIR)));
452 if (handle_locking & HA_OPEN_FOR_REPAIR)
454 myrg_print_wrong_table(myisam->filename);
461 m_info->options|= myisam->s->options;
462 m_info->records+= myisam->state->records;
463 m_info->del+= myisam->state->del;
464 m_info->data_file_length+= myisam->state->data_file_length;
465 if (min_keys > myisam->s->base.keys)
466 min_keys= myisam->s->base.keys;
467 for (idx= 0; idx < key_parts; idx++)
468 m_info->rec_per_key_part[idx]+= (myisam->s->state.rec_per_key_part[idx] /
475 if (
sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
477 my_errno= HA_ERR_RECORD_FILE_FULL;
481 m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
482 m_info->keys= min_keys;
483 m_info->last_used_table= m_info->open_tables;
484 m_info->children_attached= TRUE;
489 my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
491 save_errno= my_errno;
494 my_free(m_info->rec_per_key_part);
495 m_info->rec_per_key_part= NULL;
498 my_errno= save_errno;
516 int myrg_detach_children(
MYRG_INFO *m_info)
518 DBUG_ENTER(
"myrg_detach_children");
524 m_info->children_attached= FALSE;
525 memset(m_info->open_tables, 0, m_info->tables *
sizeof(
MYRG_TABLE));
529 m_info->data_file_length= 0;