88 #define MYSQL_SERVER 1
91 #include "sql_cache.h"
93 #include "sql_table.h"
94 #include "probes_mysql.h"
95 #include <mysql/plugin.h>
97 #include "../myisam/ha_myisam.h"
98 #include "ha_myisammrg.h"
100 #include "thr_malloc.h"
101 #include "sql_class.h"
124 init_sql_alloc(&children_mem_root,
125 FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
135 free_root(&children_mem_root, MYF(0));
139 static const char *ha_myisammrg_exts[] = {
146 uint t1_keys, uint t1_recs,
148 uint t2_keys, uint t2_recs,
bool strict,
150 static void split_file_name(
const char *file_name,
154 extern "C" void myrg_print_wrong_table(
const char *
table_name)
158 split_file_name(table_name, &db, &
name);
159 memcpy(buf, db.str, db.length);
161 memcpy(buf + db.length + 1,
name.str,
name.length);
162 buf[db.length +
name.length + 1]= 0;
170 my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), buf);
176 return ha_myisammrg_exts;
180 const char *ha_myisammrg::index_type(uint key_number)
182 return ((table->key_info[key_number].
flags & HA_FULLTEXT) ?
184 (table->key_info[key_number].
flags & HA_SPATIAL) ?
186 (table->key_info[key_number].algorithm == HA_KEY_ALG_RTREE) ?
233 extern "C" int myisammrg_parent_open_callback(
void *callback_param,
234 const char *filename)
237 TABLE *parent= ha_myrg->table_ptr();
243 uint table_name_length;
244 char dir_path[FN_REFLEN];
245 char name_buf[NAME_LEN];
246 DBUG_ENTER(
"myisammrg_parent_open_callback");
254 if (!has_path(filename))
257 db_length= parent->s->db.length;
258 db= strmake_root(&ha_myrg->children_mem_root, parent->s->db.str, db_length);
260 if (parent->s->mysql_version >= 50146)
262 table_name_length= filename_to_tablename(filename, name_buf,
264 table_name= strmake_root(&ha_myrg->children_mem_root, name_buf,
269 table_name_length= strlen(filename);
270 table_name= strmake_root(&ha_myrg->children_mem_root, filename,
276 DBUG_ASSERT(strlen(filename) <
sizeof(dir_path));
277 fn_format(dir_path, filename,
"",
"", 0);
279 dirlen= dirname_length(dir_path);
281 if (parent->s->mysql_version >= 50106)
283 table_name_length= filename_to_tablename(dir_path + dirlen, name_buf,
285 table_name= strmake_root(&ha_myrg->children_mem_root, name_buf,
287 dir_path[dirlen - 1]= 0;
288 dirlen= dirname_length(dir_path);
289 db_length= filename_to_tablename(dir_path + dirlen, name_buf,
sizeof(name_buf));
290 db= strmake_root(&ha_myrg->children_mem_root, name_buf, db_length);
294 table_name_length= strlen(dir_path + dirlen);
295 table_name= strmake_root(&ha_myrg->children_mem_root, dir_path + dirlen,
297 dir_path[dirlen - 1]= 0;
298 dirlen= dirname_length(dir_path);
299 db_length= strlen(dir_path + dirlen);
300 db= strmake_root(&ha_myrg->children_mem_root, dir_path + dirlen,
305 if (! db || ! table_name)
308 DBUG_PRINT(
"myrg", (
"open: '%.*s'.'%.*s'", (
int) db_length, db,
309 (
int) table_name_length, table_name));
312 if (lower_case_table_names && table_name_length)
315 table_name_length= my_casedn_str(files_charset_info, table_name);
319 mrg_child_def=
new (&ha_myrg->children_mem_root)
322 if (! mrg_child_def ||
323 ha_myrg->child_def_list.push_back(mrg_child_def,
324 &ha_myrg->children_mem_root))
351 uint test_if_locked_arg)
353 DBUG_ENTER(
"ha_myisammrg::open");
354 DBUG_PRINT(
"myrg", (
"name: '%s' table: 0x%lx", name, (
long) table));
355 DBUG_PRINT(
"myrg", (
"test_if_locked_arg: %u", test_if_locked_arg));
358 DBUG_ASSERT(!this->file);
361 test_if_locked= test_if_locked_arg;
364 free_root(&this->children_mem_root, MYF(MY_MARK_BLOCKS_FREE));
375 children_last_l= NULL;
376 child_def_list.empty();
390 if (!(file= myrg_open(name, table->db_stat, HA_OPEN_IGNORE_IF_LOCKED)))
392 DBUG_PRINT(
"error", (
"my_errno %d", my_errno));
393 DBUG_RETURN(my_errno ? my_errno : -1);
396 file->children_attached= TRUE;
398 info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
400 else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback,
this)))
403 DBUG_PRINT(
"error", (
"my_errno %d", my_errno));
404 DBUG_RETURN(my_errno ? my_errno : -1);
407 DBUG_PRINT(
"myrg", (
"MYRG_INFO: 0x%lx child tables: %u",
408 (
long) file, file->tables));
429 TABLE_LIST *parent_l= this->table->pos_in_table_list;
430 THD *thd= table->in_use;
433 DBUG_ENTER(
"ha_myisammrg::add_children_list");
434 DBUG_PRINT(
"myrg", (
"table: '%s'.'%s' 0x%lx", this->table->s->db.str,
435 this->table->s->table_name.str, (
long) this->table));
438 DBUG_ASSERT(this->file);
441 if (!this->file->tables)
443 DBUG_PRINT(
"myrg", (
"empty merge table union"));
448 DBUG_ASSERT(!this->file->children_attached);
451 DBUG_ASSERT(this->children_l == NULL);
457 if (parent_l->parent_l)
459 my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), parent_l->alias);
463 while ((mrg_child_def= it++))
470 db= (
char*) thd->memdup(mrg_child_def->db.str, mrg_child_def->db.length+1);
471 table_name= (
char*) thd->memdup(mrg_child_def->name.str,
472 mrg_child_def->name.length+1);
474 if (child_l == NULL || db == NULL || table_name == NULL)
478 table_name, mrg_child_def->name.length,
479 table_name, parent_l->lock_type);
481 child_l->parent_l= parent_l;
483 child_l->select_lex= parent_l->select_lex;
486 mrg_child_def->get_child_def_version());
491 child_l->prelocking_placeholder= parent_l->prelocking_placeholder;
514 if (! thd->locked_tables_mode &&
515 parent_l->mdl_request.
type == MDL_SHARED_UPGRADABLE)
516 child_l->mdl_request.
set_type(MDL_SHARED_NO_WRITE);
518 if (this->children_last_l)
519 child_l->prev_global= this->children_last_l;
523 this->children_last_l= &this->children_l;
525 *this->children_last_l= child_l;
526 this->children_last_l= &child_l->next_global;
530 if (parent_l->next_global)
531 parent_l->next_global->prev_global= this->children_last_l;
532 *this->children_last_l= parent_l->next_global;
533 parent_l->next_global= this->children_l;
534 this->children_l->prev_global= &parent_l->next_global;
540 if (thd->lex->query_tables_last == &parent_l->next_global)
541 thd->lex->query_tables_last= this->children_last_l;
552 if (thd->lex->query_tables_own_last == &parent_l->next_global)
553 thd->lex->query_tables_own_last= this->children_last_l;
585 def_it(child_def_list),
586 mrg_child_def(def_it++)
594 mrg_child_def= def_it++;
616 extern "C" MI_INFO *myisammrg_attach_children_callback(
void *callback_param)
625 DBUG_ENTER(
"myisammrg_attach_children_callback");
631 DBUG_ASSERT(child_l);
633 child= child_l->table;
640 DBUG_PRINT(
"error", (
"failed to open underlying table '%s'.'%s'",
641 child_l->db, child_l->table_name));
653 DBUG_PRINT(
"myrg", (
"table_def_version last: %llu current: %llu",
654 mrg_child_def->get_child_def_version(),
655 child->s->get_table_def_version()));
656 if (mrg_child_def->get_child_def_version() != child->s->get_table_def_version())
670 if (child->s->tmp_table && !parent->s->tmp_table)
672 DBUG_PRINT(
"error", (
"temporary table mismatch parent: %d child: %d",
673 parent->s->tmp_table, child->s->tmp_table));
678 if ((child->file->ht->db_type != DB_TYPE_MYISAM) ||
679 !(myisam= ((
ha_myisam*) child->file)->file_ptr()))
681 DBUG_PRINT(
"error", (
"no MyISAM handle for child table: '%s'.'%s' 0x%lx",
682 child->s->db.str, child->s->table_name.str,
686 DBUG_PRINT(
"myrg", (
"MyISAM handle: 0x%lx", (
long) myisam));
691 (current_thd->open_options & HA_OPEN_FOR_REPAIR))
693 char buf[2*NAME_LEN + 1 + 1];
694 strxnmov(buf,
sizeof(buf) - 1, child_l->db,
".", child_l->table_name, NULL);
702 my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), buf);
720 (
ha_myisammrg*) get_new_handler(table->s, mem_root, table->s->db_type());
725 new_handler->is_cloned= TRUE;
731 if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(
ref_length)*2)))
737 if (new_handler->
ha_open(table, name, table->db_stat,
738 HA_OPEN_IGNORE_IF_LOCKED))
750 newu_table= new_handler->file->open_tables;
751 for (u_table= file->open_tables; u_table < file->end_table; u_table++)
753 newu_table->table->state= u_table->table->state;
788 uint keys= table->s->keys;
789 TABLE_LIST *parent_l= table->pos_in_table_list;
792 DBUG_ENTER(
"ha_myisammrg::attach_children");
793 DBUG_PRINT(
"myrg", (
"table: '%s'.'%s' 0x%lx", table->s->db.str,
794 table->s->table_name.str, (
long) table));
795 DBUG_PRINT(
"myrg", (
"test_if_locked: %u", this->test_if_locked));
798 DBUG_ASSERT(this->file);
804 if (!this->file->tables)
806 DBUG_PRINT(
"myrg", (
"empty merge table union"));
809 DBUG_PRINT(
"myrg", (
"child tables: %u", this->file->tables));
812 DBUG_ASSERT(!this->file->children_attached);
814 DEBUG_SYNC(current_thd,
"before_myisammrg_attach");
816 DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l);
818 if (myrg_attach_children(this->file, this->test_if_locked |
819 current_thd->open_options,
820 myisammrg_attach_children_callback, ¶m,
826 DBUG_PRINT(
"myrg", (
"calling myrg_extrafunc"));
827 myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
828 if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
829 test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
830 myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK,0);
831 info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
832 if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
833 myrg_extra(file,HA_EXTRA_WAIT_LOCK,0);
846 if (table->s->reclength !=
stats.mean_rec_length &&
stats.mean_rec_length)
848 DBUG_PRINT(
"error",(
"reclength: %lu mean_rec_length: %lu",
849 table->s->reclength,
stats.mean_rec_length));
850 if (test_if_locked & HA_OPEN_FOR_REPAIR)
853 myrg_print_wrong_table(file->open_tables->table->filename);
856 error= HA_ERR_WRONG_MRG_TABLE_DEF;
863 if ((error= table2myisam(table, &keyinfo, &recinfo, &recs)))
866 DBUG_PRINT(
"error", (
"failed to convert TABLE object to MyISAM "
867 "key and column definition"));
871 for (u_table= file->open_tables; u_table < file->end_table; u_table++)
873 if (check_definition(keyinfo, recinfo, keys, recs,
874 u_table->table->s->keyinfo, u_table->table->s->rec,
875 u_table->table->s->base.keys,
876 u_table->table->s->base.fields,
false, NULL))
878 DBUG_PRINT(
"error", (
"table definition mismatch: '%s'",
879 u_table->table->filename));
880 error= HA_ERR_WRONG_MRG_TABLE_DEF;
881 if (!(this->test_if_locked & HA_OPEN_FOR_REPAIR))
887 myrg_print_wrong_table(u_table->table->filename);
892 if (error == HA_ERR_WRONG_MRG_TABLE_DEF)
896 DBUG_ASSERT(this->children_l);
897 for (child_l= this->children_l; ; child_l= child_l->next_global)
900 mrg_child_def->set_child_def_version(
902 child_l->table->s->get_table_def_version());
904 if (&child_l->next_global == this->children_last_l)
908 #if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
910 if (table->s->crashed)
912 DBUG_PRINT(
"error", (
"MERGE table marked crashed"));
913 error= HA_ERR_WRONG_MRG_TABLE_DEF;
922 DBUG_PRINT(
"error", (
"attaching MERGE children failed: %d", error));
925 DBUG_RETURN(my_errno= error);
945 DBUG_ENTER(
"ha_myisammrg::detach_children");
948 DBUG_ASSERT(this->file);
951 if (!this->file->tables)
953 DBUG_PRINT(
"myrg", (
"empty merge table union"));
957 if (this->children_l)
959 THD *thd= table->in_use;
962 for (child_l= this->children_l; ; child_l= child_l->next_global)
970 child_l->table= NULL;
972 child_l->mdl_request.
ticket= NULL;
975 if (&child_l->next_global == this->children_last_l)
993 if (this->children_l->prev_global && *this->children_l->prev_global)
994 *this->children_l->prev_global= *this->children_last_l;
995 if (*this->children_last_l)
996 (*this->children_last_l)->prev_global= this->children_l->prev_global;
1003 if (thd->lex->query_tables_last == this->children_last_l)
1004 thd->lex->query_tables_last= this->children_l->prev_global;
1012 if (thd->lex->query_tables_own_last == this->children_last_l)
1013 thd->lex->query_tables_own_last= this->children_l->prev_global;
1016 *this->children_last_l= NULL;
1017 this->children_l->prev_global= NULL;
1020 this->children_l= NULL;
1021 this->children_last_l= NULL;
1024 if (!this->file->children_attached)
1026 DBUG_PRINT(
"myrg", (
"merge children are already detached"));
1030 if (myrg_detach_children(this->file))
1034 DBUG_RETURN(my_errno ? my_errno : -1);
1057 DBUG_ENTER(
"ha_myisammrg::close");
1065 rc= myrg_close(file);
1070 int ha_myisammrg::write_row(uchar * buf)
1072 DBUG_ENTER(
"ha_myisammrg::write_row");
1073 DBUG_ASSERT(this->file->children_attached);
1074 ha_statistic_increment(&SSV::ha_write_count);
1076 if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
1077 DBUG_RETURN(HA_ERR_TABLE_READONLY);
1079 if (table->next_number_field && buf == table->record[0])
1082 if ((error= update_auto_increment()))
1085 DBUG_RETURN(myrg_write(file,buf));
1088 int ha_myisammrg::update_row(
const uchar * old_data, uchar * new_data)
1090 DBUG_ASSERT(this->file->children_attached);
1091 ha_statistic_increment(&SSV::ha_update_count);
1092 return myrg_update(file,old_data,new_data);
1095 int ha_myisammrg::delete_row(
const uchar * buf)
1097 DBUG_ASSERT(this->file->children_attached);
1098 ha_statistic_increment(&SSV::ha_delete_count);
1099 return myrg_delete(file,buf);
1103 key_part_map keypart_map,
1104 enum ha_rkey_function find_flag)
1106 DBUG_ASSERT(this->file->children_attached);
1107 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1108 ha_statistic_increment(&SSV::ha_read_key_count);
1109 int error=myrg_rkey(file,buf,active_index, key, keypart_map, find_flag);
1110 table->status=error ? STATUS_NOT_FOUND: 0;
1111 MYSQL_INDEX_READ_ROW_DONE(error);
1116 key_part_map keypart_map,
1117 enum ha_rkey_function find_flag)
1119 DBUG_ASSERT(this->file->children_attached);
1120 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1121 ha_statistic_increment(&SSV::ha_read_key_count);
1122 int error=myrg_rkey(file,buf,index, key, keypart_map, find_flag);
1123 table->status=error ? STATUS_NOT_FOUND: 0;
1124 MYSQL_INDEX_READ_ROW_DONE(error);
1129 key_part_map keypart_map)
1131 DBUG_ASSERT(this->file->children_attached);
1132 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1133 ha_statistic_increment(&SSV::ha_read_key_count);
1134 int error=myrg_rkey(file,buf,active_index, key, keypart_map,
1135 HA_READ_PREFIX_LAST);
1136 table->status=error ? STATUS_NOT_FOUND: 0;
1137 MYSQL_INDEX_READ_ROW_DONE(error);
1143 DBUG_ASSERT(this->file->children_attached);
1144 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1145 ha_statistic_increment(&SSV::ha_read_next_count);
1146 int error=myrg_rnext(file,buf,active_index);
1147 table->status=error ? STATUS_NOT_FOUND: 0;
1148 MYSQL_INDEX_READ_ROW_DONE(error);
1154 DBUG_ASSERT(this->file->children_attached);
1155 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1156 ha_statistic_increment(&SSV::ha_read_prev_count);
1157 int error=myrg_rprev(file,buf, active_index);
1158 table->status=error ? STATUS_NOT_FOUND: 0;
1159 MYSQL_INDEX_READ_ROW_DONE(error);
1165 DBUG_ASSERT(this->file->children_attached);
1166 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1167 ha_statistic_increment(&SSV::ha_read_first_count);
1168 int error=myrg_rfirst(file, buf, active_index);
1169 table->status=error ? STATUS_NOT_FOUND: 0;
1170 MYSQL_INDEX_READ_ROW_DONE(error);
1176 DBUG_ASSERT(this->file->children_attached);
1177 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1178 ha_statistic_increment(&SSV::ha_read_last_count);
1179 int error=myrg_rlast(file, buf, active_index);
1180 table->status=error ? STATUS_NOT_FOUND: 0;
1181 MYSQL_INDEX_READ_ROW_DONE(error);
1186 const uchar *key __attribute__((unused)),
1187 uint length __attribute__((unused)))
1190 DBUG_ASSERT(this->file->children_attached);
1191 MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
1192 ha_statistic_increment(&SSV::ha_read_next_count);
1195 error= myrg_rnext_same(file,buf);
1196 }
while (error == HA_ERR_RECORD_DELETED);
1197 table->status=error ? STATUS_NOT_FOUND: 0;
1198 MYSQL_INDEX_READ_ROW_DONE(error);
1205 DBUG_ASSERT(this->file->children_attached);
1206 return myrg_reset(file);
1212 DBUG_ASSERT(this->file->children_attached);
1213 MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
1215 ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1216 int error=myrg_rrnd(file, buf, HA_OFFSET_ERROR);
1217 table->status=error ? STATUS_NOT_FOUND: 0;
1218 MYSQL_READ_ROW_DONE(error);
1225 DBUG_ASSERT(this->file->children_attached);
1226 MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
1228 ha_statistic_increment(&SSV::ha_read_rnd_count);
1229 int error=myrg_rrnd(file, buf, my_get_ptr(pos,
ref_length));
1230 table->status=error ? STATUS_NOT_FOUND: 0;
1231 MYSQL_READ_ROW_DONE(error);
1235 void ha_myisammrg::position(
const uchar *
record)
1237 DBUG_ASSERT(this->file->children_attached);
1238 ulonglong row_position= myrg_position(file);
1239 my_store_ptr(ref,
ref_length, (my_off_t) row_position);
1243 ha_rows ha_myisammrg::records_in_range(uint inx,
key_range *min_key,
1246 DBUG_ASSERT(this->file->children_attached);
1247 return (ha_rows) myrg_records_in_range(file, (
int) inx, min_key, max_key);
1255 DBUG_ENTER(
"ha_myisammrg::truncate");
1257 for (table= file->open_tables; table != file->end_table; table++)
1259 if ((err= mi_delete_all_rows(table->table)))
1267 int ha_myisammrg::info(uint flag)
1270 DBUG_ASSERT(this->file->children_attached);
1271 (void) myrg_status(file,&mrg_info,flag);
1276 stats.records = (ha_rows) mrg_info.records;
1277 stats.deleted = (ha_rows) mrg_info.deleted;
1278 #if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
1279 if ((mrg_info.records >= (ulonglong) 1 << 32) ||
1280 (mrg_info.deleted >= (ulonglong) 1 << 32))
1281 table->s->crashed= 1;
1283 stats.data_file_length= mrg_info.data_file_length;
1284 if (mrg_info.errkey >= (
int) table_share->keys)
1292 mrg_info.errkey= MAX_KEY;
1294 table->s->keys_in_use.set_prefix(table->s->keys);
1295 stats.mean_rec_length= mrg_info.reclength;
1313 stats.block_size= 0;
1315 stats.block_size= myisam_block_size / file->tables;
1317 stats.update_time= 0;
1318 #if SIZEOF_OFF_T > 4
1323 if (flag & HA_STATUS_CONST)
1325 if (table->s->key_parts && mrg_info.rec_per_key)
1335 sizeof(table->key_info[0].
rec_per_key[0]) * table->s->key_parts);
1338 (
char*) mrg_info.rec_per_key,
1340 min(file->keys, table->s->key_parts));
1343 if (flag & HA_STATUS_ERRKEY)
1345 errkey= mrg_info.errkey;
1346 my_store_ptr(dup_ref,
ref_length, mrg_info.dupp_key_pos);
1352 int ha_myisammrg::extra(
enum ha_extra_function operation)
1354 if (operation == HA_EXTRA_ADD_CHILDREN_LIST)
1359 else if (operation == HA_EXTRA_ATTACH_CHILDREN)
1363 (void)
extra(HA_EXTRA_NO_READCHECK);
1366 else if (operation == HA_EXTRA_IS_ATTACHED_CHILDREN)
1369 return(file && file->tables && file->children_attached);
1371 else if (operation == HA_EXTRA_DETACH_CHILDREN)
1383 if (operation == HA_EXTRA_FORCE_REOPEN ||
1384 operation == HA_EXTRA_PREPARE_FOR_DROP)
1386 if (operation == HA_EXTRA_MMAP && !opt_myisam_use_mmap)
1388 return myrg_extra(file,operation,0);
1394 return myrg_reset(file);
1399 int ha_myisammrg::extra_opt(
enum ha_extra_function operation, ulong cache_size)
1401 DBUG_ASSERT(this->file->children_attached);
1402 return myrg_extra(file, operation, (
void*) &cache_size);
1405 int ha_myisammrg::external_lock(THD *thd,
int lock_type)
1418 return myrg_lock_database(file, lock_type);
1430 enum thr_lock_type lock_type)
1438 static void split_file_name(
const char *file_name,
1441 size_t dir_length, prefix_length;
1442 char buff[FN_REFLEN];
1445 strmake(buff, file_name,
sizeof(buff)-1);
1446 dir_length= dirname_length(buff);
1450 buff[dir_length-1]= 0;
1451 prefix_length= dirname_length(buff);
1452 db->str= (
char*) file_name+ prefix_length;
1453 db->length= dir_length - prefix_length -1;
1455 name->str= (
char*) file_name+ dir_length;
1456 name->length= (uint) (fn_ext(name->str) - name->str);
1460 void ha_myisammrg::update_create_info(
HA_CREATE_INFO *create_info)
1462 DBUG_ENTER(
"ha_myisammrg::update_create_info");
1464 if (!(create_info->used_fields & HA_CREATE_USED_UNION))
1467 THD *thd=current_thd;
1469 create_info->merge_list.
next= &create_info->merge_list.
first;
1470 create_info->merge_list.elements=0;
1472 if (children_l != NULL)
1474 for (child_table= children_l;;
1475 child_table= child_table->next_global)
1482 if (!(ptr->table_name= thd->strmake(child_table->table_name,
1483 child_table->table_name_length)))
1485 if (child_table->db && !(ptr->db= thd->strmake(child_table->db,
1486 child_table->db_length)))
1489 create_info->merge_list.elements++;
1490 (*create_info->merge_list.
next)= ptr;
1491 create_info->merge_list.
next= &ptr->next_local;
1493 if (&child_table->next_global == children_last_l)
1497 *create_info->merge_list.
next=0;
1499 if (!(create_info->used_fields & HA_CREATE_USED_INSERT_METHOD))
1501 create_info->merge_insert_method = file->merge_insert_method;
1506 create_info->merge_list.elements=0;
1507 create_info->merge_list.
first=0;
1512 int ha_myisammrg::create(
const char *name,
register TABLE *
form,
1515 char buff[FN_REFLEN];
1516 const char **table_names, **pos;
1518 THD *thd= current_thd;
1519 size_t dirlgt= dirname_length(name);
1520 DBUG_ENTER(
"ha_myisammrg::create");
1523 if (!(table_names= (
const char**)
1524 thd->alloc((create_info->merge_list.elements+1) *
sizeof(
char*))))
1525 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1528 for (pos= table_names; tables; tables= tables->next_local)
1530 const char *table_name= buff;
1547 uint length= build_table_filename(buff,
sizeof(buff),
1548 tables->db, tables->table_name,
"", 0);
1555 if ((dirname_length(buff) == dirlgt) && ! memcmp(buff, name, dirlgt))
1557 table_name+= dirlgt;
1560 if (!(table_name= thd->strmake(table_name, length)))
1561 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1568 DBUG_RETURN(myrg_create(fn_format(buff,name,
"",
"",
1569 MY_RESOLVE_SYMLINKS|
1570 MY_UNPACK_FILENAME|MY_APPEND_EXT),
1572 create_info->merge_insert_method,
1577 void ha_myisammrg::append_create_info(
String *packet)
1579 const char *current_db;
1581 THD *thd= current_thd;
1584 if (file->merge_insert_method != MERGE_INSERT_DISABLED)
1586 packet->append(STRING_WITH_LEN(
" INSERT_METHOD="));
1587 packet->append(get_type(&merge_insert_method,file->merge_insert_method-1));
1593 if (file->open_tables == file->end_table)
1595 packet->append(STRING_WITH_LEN(
" UNION=("));
1597 current_db= table->s->db.str;
1598 db_length= table->s->db.length;
1600 for (first= open_table= children_l;;
1601 open_table= open_table->next_global)
1603 LEX_STRING db= { open_table->db, open_table->db_length };
1605 if (open_table != first)
1606 packet->append(
',');
1609 (db_length != db.length ||
1610 strncmp(current_db, db.str, db.length)))
1612 append_identifier(thd, packet, db.str, db.length);
1613 packet->append(
'.');
1615 append_identifier(thd, packet, open_table->table_name,
1616 open_table->table_name_length);
1617 if (&open_table->next_global == children_last_l)
1620 packet->append(
')');
1631 return COMPATIBLE_DATA_NO;
1635 int ha_myisammrg::check(THD* thd,
HA_CHECK_OPT* check_opt)
1637 return this->file->children_attached ? HA_ADMIN_OK : HA_ADMIN_CORRUPT;
1643 return myrg_records(file);
1647 extern int myrg_panic(
enum ha_panic_function flag);
1648 int myisammrg_panic(
handlerton *hton, ha_panic_function flag)
1650 return myrg_panic(flag);
1653 static int myisammrg_init(
void *p)
1659 #ifdef HAVE_PSI_INTERFACE
1660 init_myisammrg_psi_keys();
1663 myisammrg_hton->db_type= DB_TYPE_MRG_MYISAM;
1664 myisammrg_hton->create= myisammrg_create_handler;
1665 myisammrg_hton->panic= myisammrg_panic;
1666 myisammrg_hton->flags= HTON_NO_PARTITION;
1672 { MYSQL_HANDLERTON_INTERFACE_VERSION };
1674 mysql_declare_plugin(myisammrg)
1676 MYSQL_STORAGE_ENGINE_PLUGIN,
1677 &myisammrg_storage_engine,
1680 "Collection of identical MyISAM tables",
1690 mysql_declare_plugin_end;