19 #include <drizzled/internal/my_bit.h>
20 #include "myisampack.h"
21 #include "ha_myisam.h"
22 #include "myisam_priv.h"
23 #include <drizzled/option.h>
24 #include <drizzled/internal/my_bit.h>
25 #include <drizzled/internal/m_string.h>
26 #include <drizzled/util/test.h>
27 #include <drizzled/error.h>
28 #include <drizzled/errmsg_print.h>
29 #include <drizzled/gettext.h>
30 #include <drizzled/session.h>
31 #include <drizzled/plugin.h>
32 #include <drizzled/plugin/client.h>
33 #include <drizzled/table.h>
34 #include <drizzled/memory/multi_malloc.h>
35 #include <drizzled/plugin/daemon.h>
36 #include <drizzled/session/table_messages.h>
37 #include <drizzled/plugin/storage_engine.h>
38 #include <drizzled/key.h>
39 #include <drizzled/statistics_variables.h>
40 #include <drizzled/system_variables.h>
42 #include <boost/algorithm/string.hpp>
43 #include <boost/scoped_ptr.hpp>
50 #include <boost/program_options.hpp>
53 namespace po= boost::program_options;
56 using namespace drizzled;
58 static const string engine_name(
"MyISAM");
60 boost::mutex THR_LOCK_myisam;
62 static uint32_t myisam_key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
63 static uint64_t max_sort_file_size;
71 static const char *ha_myisam_exts[] = {
81 plugin::StorageEngine(name_arg,
82 HTON_CAN_INDEX_BLOBS |
83 HTON_STATS_RECORDS_IS_EXACT |
95 mi_panic(HA_PANIC_CLOSE);
103 const char **bas_ext()
const {
104 return ha_myisam_exts;
116 int doGetTableDefinition(
Session& session,
120 uint32_t max_supported_keys()
const {
return MI_MAX_KEY; }
121 uint32_t max_supported_key_length()
const {
return MI_MAX_KEY_LENGTH; }
122 uint32_t max_supported_key_part_length()
const {
return MI_MAX_KEY_LENGTH; }
124 uint32_t index_flags(
enum ha_key_alg)
const
126 return (HA_READ_NEXT |
136 drizzled::identifier::table::vector &set_of_identifiers);
137 bool validateCreateTableOption(
const std::string &key,
const std::string &state)
140 if (boost::iequals(key,
"ROW_FORMAT"))
151 drizzled::identifier::table::vector&)
157 return session.getMessageCache().doesTableMessageExist(identifier);
160 int MyisamEngine::doGetTableDefinition(
Session &session,
164 if (session.getMessageCache().getTableMessage(identifier, table_message))
173 static void mi_check_print_msg(
MI_CHECK *,
const char* ,
174 const char *, va_list )
206 uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
207 enum ha_base_keytype type= HA_KEYTYPE_BINARY;
208 unsigned char *record;
212 TableShare *share= table_arg->getMutableShare();
213 uint32_t options= share->db_options_in_use;
214 if (!(memory::multi_malloc(
false,
215 recinfo_out, (share->sizeFields() * 2 + 2) *
sizeof(
MI_COLUMNDEF),
216 keydef_out, share->sizeKeys() *
sizeof(
MI_KEYDEF),
217 &keyseg, (share->key_parts + share->sizeKeys()) *
sizeof(
HA_KEYSEG),
219 return(HA_ERR_OUT_OF_MEM);
221 recinfo= *recinfo_out;
222 for (i= 0; i < share->sizeKeys(); i++)
225 keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
226 keydef[i].key_alg= HA_KEY_ALG_BTREE;
227 keydef[i].block_length= pos->block_size;
228 keydef[i].seg= keyseg;
229 keydef[i].keysegs= pos->key_parts;
230 for (j= 0; j < pos->key_parts; j++)
232 Field *field= pos->key_part[j].field;
233 type= field->key_type();
234 keydef[i].seg[j].flag= pos->key_part[j].key_part_flag;
236 if (options & HA_OPTION_PACK_KEYS ||
237 (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY |
238 HA_SPACE_PACK_USED)))
240 if (pos->key_part[j].length > 8 &&
241 (type == HA_KEYTYPE_TEXT ||
242 (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
246 keydef[i].flag|= HA_PACK_KEY;
247 if ((((
int) (pos->key_part[j].length - field->decimals())) >= 4))
248 keydef[i].seg[j].flag|= HA_SPACE_PACK;
250 else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
251 keydef[i].flag|= HA_BINARY_PACK_KEY;
253 keydef[i].seg[j].type= (int) type;
254 keydef[i].seg[j].start= pos->key_part[j].offset;
255 keydef[i].seg[j].length= pos->key_part[j].length;
256 keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end=
257 keydef[i].seg[j].bit_length= 0;
258 keydef[i].seg[j].bit_pos= 0;
259 keydef[i].seg[j].language= field->charset()->number;
263 keydef[i].seg[j].null_bit= field->
null_bit;
264 keydef[i].seg[j].null_pos= (uint) (field->
null_ptr-
265 (
unsigned char*) table_arg->getInsertRecord());
269 keydef[i].seg[j].null_bit= 0;
270 keydef[i].seg[j].null_pos= 0;
272 if (field->type() == DRIZZLE_TYPE_BLOB)
274 keydef[i].seg[j].flag|= HA_BLOB_PART;
276 keydef[i].seg[j].bit_start= (uint) (field->
pack_length() -
277 share->sizeBlobPtr());
280 keyseg+= pos->key_parts;
283 keydef[share->next_number_index].flag|= HA_AUTO_KEY;
284 record= table_arg->getInsertRecord();
286 recinfo_pos= recinfo;
288 while (recpos < (uint) share->sizeStoredRecord())
290 Field **field, *found= 0;
291 minpos= share->getRecordLength();
294 for (field= table_arg->getFields(); *field; field++)
296 if ((fieldpos= (*field)->offset(record)) >= recpos &&
300 if (!(temp_length= (*field)->pack_length_in_rec()))
303 if (! found || fieldpos < minpos ||
304 (fieldpos == minpos && temp_length < length))
312 if (recpos != minpos)
314 memset(recinfo_pos, 0,
sizeof(*recinfo_pos));
315 recinfo_pos->type= (int) FIELD_NORMAL;
316 recinfo_pos++->length= (uint16_t) (minpos - recpos);
321 if (found->flags & BLOB_FLAG)
322 recinfo_pos->type= (int) FIELD_BLOB;
323 else if (found->type() == DRIZZLE_TYPE_VARCHAR)
324 recinfo_pos->type= FIELD_VARCHAR;
325 else if (!(options & HA_OPTION_PACK_RECORD))
326 recinfo_pos->type= (
int) FIELD_NORMAL;
327 else if (found->zero_pack())
328 recinfo_pos->type= (
int) FIELD_SKIP_ZERO;
330 recinfo_pos->type= (int) ((length <= 3) ? FIELD_NORMAL : FIELD_SKIP_PRESPACE);
333 recinfo_pos->null_bit= found->
null_bit;
334 recinfo_pos->null_pos= (uint) (found->
null_ptr -
335 (
unsigned char*) table_arg->getInsertRecord());
339 recinfo_pos->null_bit= 0;
340 recinfo_pos->null_pos= 0;
342 (recinfo_pos++)->length= (uint16_t) length;
343 recpos= minpos + length;
345 *records_out= (uint) (recinfo_pos - recinfo);
351 file->s->state.auto_increment= value;
396 uint32_t t1_keys, uint32_t t1_recs,
398 uint32_t t2_keys, uint32_t t2_recs,
bool strict)
401 if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
405 if (t1_recs != t2_recs)
409 for (i= 0; i < t1_keys; i++)
411 HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
412 HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
413 if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
414 t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
418 for (j= t1_keyinfo[i].keysegs; j--;)
420 uint8_t t1_keysegs_j__type= t1_keysegs[j].type;
428 if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
429 (t2_keysegs[j].flag & HA_BLOB_PART))
431 if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
432 (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
433 t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1;
434 else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
435 (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
436 t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1;
439 if (t1_keysegs_j__type != t2_keysegs[j].type ||
440 t1_keysegs[j].language != t2_keysegs[j].language ||
441 t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
442 t1_keysegs[j].length != t2_keysegs[j].length)
448 for (i= 0; i < t1_recs; i++)
456 if ((t1_rec->type != t2_rec->type &&
457 !(t1_rec->type == (
int) FIELD_SKIP_ZERO &&
458 t1_rec->length == 1 &&
459 t2_rec->type == (
int) FIELD_NORMAL)) ||
460 t1_rec->length != t2_rec->length ||
461 t1_rec->null_bit != t2_rec->null_bit)
470 volatile int *killed_ptr(
MI_CHECK *param)
473 return (
int*) (((
Session *)(param->session))->getKilledPtr());
476 void mi_check_print_error(
MI_CHECK *param,
const char *fmt,...)
478 param->error_printed|=1;
479 param->out_flag|= O_DATA_LOST;
482 mi_check_print_msg(param,
"error", fmt, args);
486 void mi_check_print_info(
MI_CHECK *param,
const char *fmt,...)
490 mi_check_print_msg(param,
"info", fmt, args);
494 void mi_check_print_warning(
MI_CHECK *param,
const char *fmt,...)
496 param->warning_printed=1;
497 param->out_flag|= O_DATA_LOST;
500 mi_check_print_msg(param,
"warning", fmt, args);
519 void _mi_report_crashed(
MI_INFO *file,
const char *message,
520 const char *sfile, uint32_t sline)
523 if ((cur_session= file->in_use))
525 errmsg_printf(error::ERROR, _(
"Got an error from thread_id=%"PRIu64
", %s:%d"),
526 cur_session->thread_id,
531 errmsg_printf(error::ERROR, _(
"Got an error from unknown thread, %s:%d"), sfile, sline);
535 errmsg_printf(error::ERROR,
"%s", message);
537 list<Session *>::iterator it= file->s->in_use->begin();
538 while (it != file->s->in_use->end())
540 errmsg_printf(error::ERROR,
"%s", _(
"Unknown thread accessing table"));
545 ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
547 :
Cursor(engine_arg, table_arg),
549 can_enable_indexes(true),
557 new_handler->file->state= file->state;
561 const char *ha_myisam::index_type(uint32_t )
589 if (!(file= mi_open(identifier, mode, test_if_locked)))
590 return (errno ? errno : -1);
592 if (!getTable()->getShare()->getType())
594 if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
598 if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
599 file->s->keyinfo, file->s->rec,
600 file->s->base.keys, file->s->base.fields,
true))
602 errno= HA_ERR_CRASHED;
607 assert(test_if_locked);
608 if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
609 mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
611 info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
612 if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
613 mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
614 if (!getTable()->getShare()->db_record_offset)
618 keys_with_parts.reset();
619 for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
621 getTable()->
key_info[i].block_size= file->s->keyinfo[i].block_length;
625 for (; kp != kp_end; kp++)
627 if (!kp->field->part_of_key.test(i))
629 keys_with_parts.set(i);
644 free((
unsigned char*) recinfo);
648 int ha_myisam::close(
void)
652 return mi_close(tmp);
655 int ha_myisam::doInsertRecord(
unsigned char *buf)
661 if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
664 if ((error= update_auto_increment()))
667 return mi_write(file,buf);
671 int ha_myisam::repair(
Session *session,
MI_CHECK ¶m,
bool do_optimize)
674 uint32_t local_testflag= param.testflag;
675 bool optimize_done= !do_optimize, statistics_done=0;
676 const char *old_proc_info= session->get_proc_info();
677 char fixed_name[FN_REFLEN];
679 ha_rows rows= file->state->records;
689 if (file->dfile == -1)
691 errmsg_printf(error::INFO,
"Retrying repair of: '%s' failed. "
692 "Please try REPAIR EXTENDED or myisamchk",
693 getTable()->getShare()->getPath());
694 return(HA_ADMIN_FAILED);
697 param.db_name= getTable()->getShare()->getSchemaName();
698 param.table_name= getTable()->getAlias();
699 param.tmpfile_createflag = O_RDWR | O_TRUNC;
700 param.using_global_keycache = 1;
701 param.session= session;
703 param.sort_buffer_length=
static_cast<size_t>(sort_buffer_size);
704 strcpy(fixed_name,file->filename);
707 if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
709 mi_check_print_error(¶m,ER(ER_CANT_LOCK),errno);
710 return(HA_ADMIN_FAILED);
714 ((file->state->del || share->state.split != file->state->records) &&
715 (!(param.testflag & T_QUICK) ||
716 !(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
718 uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
719 mi_get_mask_all_keys_active(share->base.keys) :
720 share->state.key_map);
721 uint32_t testflag=param.testflag;
722 if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
723 (local_testflag & T_REP_BY_SORT))
725 local_testflag|= T_STATISTICS;
726 param.testflag|= T_STATISTICS;
730 error = mi_repair_by_sort(¶m, file, fixed_name,
731 param.testflag & T_QUICK);
737 param.testflag &= ~T_REP_BY_SORT;
738 error= mi_repair(¶m, file, fixed_name,
739 param.testflag & T_QUICK);
741 param.testflag=testflag;
746 if ((local_testflag & T_SORT_INDEX) &&
747 (share->state.changed & STATE_NOT_SORTED_PAGES))
751 error=mi_sort_index(¶m,file,fixed_name);
753 if (!statistics_done && (local_testflag & T_STATISTICS))
755 if (share->state.changed & STATE_NOT_ANALYZED)
759 error = chk_key(¶m, file);
762 local_testflag&= ~T_STATISTICS;
768 if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
770 share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
771 STATE_CRASHED_ON_REPAIR);
772 file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
778 if (file->state != &file->s->state.state)
779 file->s->state.state = *file->state;
780 if (file->s->base.auto_key)
781 update_auto_increment_key(¶m, file, 1);
783 error = update_state_info(¶m, file,
784 UPDATE_TIME | UPDATE_OPEN_COUNT |
786 T_STATISTICS ? UPDATE_STAT : 0));
787 info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
789 if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT))
791 char llbuff[22],llbuff2[22];
792 mi_check_print_warning(¶m,
"Number of rows changed from %s to %s",
793 internal::llstr(rows,llbuff),
794 internal::llstr(file->state->records,llbuff2));
799 mi_mark_crashed_on_repair(file);
800 file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
801 update_state_info(¶m, file, 0);
804 mi_lock_database(file,F_UNLCK);
806 return(error ? HA_ADMIN_FAILED :
807 !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
831 int ha_myisam::disable_indexes(uint32_t mode)
835 if (mode == HA_KEY_SWITCH_ALL)
838 error= mi_disable_indexes(file);
840 else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
842 mi_extra(file, HA_EXTRA_NO_KEYS, 0);
843 info(HA_STATUS_CONST);
849 error= HA_ERR_WRONG_COMMAND;
883 int ha_myisam::enable_indexes(uint32_t mode)
887 if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys))
893 if (mode == HA_KEY_SWITCH_ALL)
895 error= mi_enable_indexes(file);
902 else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
905 boost::scoped_ptr<MI_CHECK> param_ap(
new MI_CHECK);
907 const char *save_proc_info= session->get_proc_info();
909 myisamchk_init(¶m);
910 param.op_name=
"recreating_index";
911 param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
912 T_CREATE_MISSING_KEYS);
913 param.myf_rw&= ~MY_WAIT_IF_FULL;
914 param.sort_buffer_length=
static_cast<size_t>(sort_buffer_size);
915 param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
916 if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
918 errmsg_printf(error::WARN,
"Warning: Enabling keys got errno %d on %s.%s, retrying",
919 errno, param.db_name, param.table_name);
921 param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
922 error= (repair(session,param,0) != HA_ADMIN_OK);
929 session->clear_error();
931 info(HA_STATUS_CONST);
937 error= HA_ERR_WRONG_COMMAND;
958 int ha_myisam::indexes_are_disabled(
void)
961 return mi_indexes_are_disabled(file);
979 void ha_myisam::start_bulk_insert(ha_rows rows)
982 ulong size= session->
variables.read_buff_size;
985 if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
986 mi_extra(file, HA_EXTRA_WRITE_CACHE, (
void*) &size);
988 can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
997 if (file->state->records == 0 && can_enable_indexes &&
998 (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
999 mi_disable_non_unique_index(file,rows);
1001 if (!file->bulk_insert &&
1002 (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1004 mi_init_bulk_insert(file,
1005 (
size_t)session->
variables.bulk_insert_buff_size,
1023 int ha_myisam::end_bulk_insert()
1025 mi_end_bulk_insert(file);
1026 int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0);
1027 return err ? err : can_enable_indexes ?
1028 enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE) : 0;
1033 int ha_myisam::doUpdateRecord(
const unsigned char *old_data,
unsigned char *new_data)
1035 return mi_update(file,old_data,new_data);
1038 int ha_myisam::doDeleteRecord(
const unsigned char *buf)
1040 return mi_delete(file,buf);
1044 int ha_myisam::doStartIndexScan(uint32_t idx,
bool )
1052 int ha_myisam::doEndIndexScan()
1054 active_index=MAX_KEY;
1060 key_part_map keypart_map,
1061 enum ha_rkey_function find_flag)
1063 assert(inited==INDEX);
1064 ha_statistic_increment(&system_status_var::ha_read_key_count);
1065 int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1066 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1071 key_part_map keypart_map,
1072 enum ha_rkey_function find_flag)
1074 ha_statistic_increment(&system_status_var::ha_read_key_count);
1075 int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1076 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1081 key_part_map keypart_map)
1083 assert(inited==INDEX);
1084 ha_statistic_increment(&system_status_var::ha_read_key_count);
1085 int error=mi_rkey(file, buf, active_index, key, keypart_map,
1086 HA_READ_PREFIX_LAST);
1087 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1091 int ha_myisam::index_next(
unsigned char *buf)
1093 assert(inited==INDEX);
1094 ha_statistic_increment(&system_status_var::ha_read_next_count);
1095 int error=mi_rnext(file,buf,active_index);
1096 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1100 int ha_myisam::index_prev(
unsigned char *buf)
1102 assert(inited==INDEX);
1103 ha_statistic_increment(&system_status_var::ha_read_prev_count);
1104 int error=mi_rprev(file,buf, active_index);
1105 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1109 int ha_myisam::index_first(
unsigned char *buf)
1111 assert(inited==INDEX);
1112 ha_statistic_increment(&system_status_var::ha_read_first_count);
1113 int error=mi_rfirst(file, buf, active_index);
1114 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1118 int ha_myisam::index_last(
unsigned char *buf)
1120 assert(inited==INDEX);
1121 ha_statistic_increment(&system_status_var::ha_read_last_count);
1122 int error=mi_rlast(file, buf, active_index);
1123 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1127 int ha_myisam::index_next_same(
unsigned char *buf,
1128 const unsigned char *,
1132 assert(inited==INDEX);
1133 ha_statistic_increment(&system_status_var::ha_read_next_count);
1136 error= mi_rnext_same(file,buf);
1137 }
while (error == HA_ERR_RECORD_DELETED);
1138 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1151 res= Cursor::read_range_first(start_key, end_key, eq_range_arg, sorted);
1161 int res= Cursor::read_range_next();
1171 return mi_scan_init(file);
1172 return mi_reset(file);
1175 int ha_myisam::rnd_next(
unsigned char *buf)
1177 ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1178 int error=mi_scan(file, buf);
1179 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1183 int ha_myisam::rnd_pos(
unsigned char *buf,
unsigned char *pos)
1185 ha_statistic_increment(&system_status_var::ha_read_rnd_count);
1186 int error=mi_rrnd(file, buf, internal::my_get_ptr(pos,
ref_length));
1187 getTable()->status=error ? STATUS_NOT_FOUND: 0;
1192 void ha_myisam::position(
const unsigned char *)
1194 internal::my_off_t row_position= mi_position(file);
1195 internal::my_store_ptr(ref,
ref_length, row_position);
1198 int ha_myisam::info(uint32_t flag)
1201 char name_buff[FN_REFLEN];
1203 (void) mi_status(file,&misam_info,flag);
1204 if (flag & HA_STATUS_VARIABLE)
1206 stats.records= misam_info.records;
1207 stats.deleted= misam_info.deleted;
1208 stats.data_file_length= misam_info.data_file_length;
1209 stats.index_file_length= misam_info.index_file_length;
1210 stats.delete_length= misam_info.delete_length;
1211 stats.check_time= misam_info.check_time;
1212 stats.mean_rec_length= misam_info.mean_reclength;
1214 if (flag & HA_STATUS_CONST)
1216 TableShare *share= getTable()->getMutableShare();
1217 stats.max_data_file_length= misam_info.max_data_file_length;
1218 stats.max_index_file_length= misam_info.max_index_file_length;
1219 stats.create_time= misam_info.create_time;
1221 share->db_options_in_use= misam_info.options;
1222 stats.block_size= myisam_key_cache_block_size;
1224 set_prefix(share->keys_in_use, share->sizeKeys());
1232 string binary_key_map;
1233 uint64_t num= misam_info.key_map;
1240 uint64_t bin_digit= num % 2;
1244 binary_key_map.append(ostr.str());
1252 if (MAX_INDEXES <= 64)
1254 size_t len= 72 - binary_key_map.length();
1255 string all_zeros(len,
'0');
1256 binary_key_map.insert(binary_key_map.begin(),
1262 size_t len= (MAX_INDEXES + 7) / 8 * 8;
1263 string all_zeros(len,
'0');
1264 binary_key_map.insert(binary_key_map.begin(),
1268 key_map tmp_map(binary_key_map);
1269 share->keys_in_use&= tmp_map;
1270 share->keys_for_keyread&= share->keys_in_use;
1271 share->db_record_offset= misam_info.record_offset;
1272 if (share->key_parts)
1273 memcpy(getTable()->key_info[0].rec_per_key,
1274 misam_info.rec_per_key,
1275 sizeof(getTable()->key_info[0].rec_per_key)*share->key_parts);
1276 assert(share->getType() != message::Table::STANDARD);
1282 data_file_name= index_file_name= 0;
1283 internal::fn_format(name_buff, file->filename,
"", MI_NAME_DEXT,
1284 MY_APPEND_EXT | MY_UNPACK_FILENAME);
1285 if (strcmp(name_buff, misam_info.data_file_name))
1286 data_file_name=misam_info.data_file_name;
1287 internal::fn_format(name_buff, file->filename,
"", MI_NAME_IEXT,
1288 MY_APPEND_EXT | MY_UNPACK_FILENAME);
1289 if (strcmp(name_buff, misam_info.index_file_name))
1290 index_file_name=misam_info.index_file_name;
1292 if (flag & HA_STATUS_ERRKEY)
1294 errkey = misam_info.errkey;
1295 internal::my_store_ptr(dup_ref,
ref_length, misam_info.dupp_key_pos);
1297 if (flag & HA_STATUS_TIME)
1298 stats.update_time = misam_info.update_time;
1299 if (flag & HA_STATUS_AUTO)
1300 stats.auto_increment_value= misam_info.auto_increment;
1306 int ha_myisam::extra(
enum ha_extra_function operation)
1308 return mi_extra(file, operation, 0);
1313 return mi_reset(file);
1318 int ha_myisam::extra_opt(
enum ha_extra_function operation, uint32_t cache_size)
1320 return mi_extra(file, operation, (
void*) &cache_size);
1325 return mi_delete_all_rows(file);
1328 int MyisamEngine::doDropTable(
Session &session,
1331 session.getMessageCache().removeTableMessage(identifier);
1333 return mi_delete_table(identifier.getPath().c_str());
1339 file->in_use= session;
1340 return mi_lock_database(file, !getTable()->getShare()->getType() ?
1341 lock_type : ((lock_type == F_UNLCK) ?
1342 F_UNLCK : F_EXTRA_LCK));
1345 int MyisamEngine::doCreateTable(
Session &session,
1351 uint32_t create_flags= 0, create_records;
1352 char buff[FN_REFLEN];
1356 TableShare *share= table_arg.getMutableShare();
1357 uint32_t options= share->db_options_in_use;
1358 if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
1360 memset(&create_info, 0,
sizeof(create_info));
1361 create_info.max_rows= create_proto.options().max_rows();
1362 create_info.reloc_rows= create_proto.options().min_rows();
1363 create_info.with_auto_increment= share->next_number_key_offset == 0;
1364 create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
1365 create_proto.options().auto_increment_value() -1 :
1367 create_info.data_file_length= (create_proto.options().max_rows() *
1368 create_proto.options().avg_row_length());
1369 create_info.data_file_name= NULL;
1370 create_info.index_file_name= NULL;
1371 create_info.language= share->table_charset->number;
1373 if (create_proto.type() == message::Table::TEMPORARY)
1374 create_flags|= HA_CREATE_TMP_TABLE;
1375 if (options & HA_OPTION_PACK_RECORD)
1376 create_flags|= HA_PACK_RECORD;
1379 error= mi_create(internal::fn_format(buff, identifier.getPath().c_str(),
"",
"",
1380 MY_UNPACK_FILENAME|MY_APPEND_EXT),
1381 share->sizeKeys(), keydef,
1382 create_records, recinfo,
1384 &create_info, create_flags);
1385 free((
unsigned char*) recinfo);
1387 session.getMessageCache().storeTableMessage(identifier, create_proto);
1395 session.getMessageCache().renameTableMessage(from, to);
1397 return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1401 void ha_myisam::get_auto_increment(uint64_t ,
1404 uint64_t *first_value,
1405 uint64_t *nb_reserved_values)
1409 unsigned char key[MI_MAX_KEY_LENGTH];
1411 if (!getTable()->getShare()->next_number_key_offset)
1413 ha_myisam::info(HA_STATUS_AUTO);
1414 *first_value= stats.auto_increment_value;
1416 *nb_reserved_values= UINT64_MAX;
1421 mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
1423 (void) extra(HA_EXTRA_KEYREAD);
1424 key_copy(key, getTable()->getInsertRecord(),
1425 &getTable()->key_info[getTable()->getShare()->next_number_index],
1426 getTable()->getShare()->next_number_key_offset);
1427 error= mi_rkey(file, getTable()->getUpdateRecord(), (
int) getTable()->getShare()->next_number_index,
1428 key, make_prev_keypart_map(getTable()->getShare()->next_number_keypart),
1429 HA_READ_PREFIX_LAST);
1436 val_int_offset(getTable()->getShare()->rec_buff_length)+1);
1438 extra(HA_EXTRA_NO_KEYREAD);
1446 *nb_reserved_values= 1;
1475 ha_rows ha_myisam::records_in_range(uint32_t inx,
key_range *min_key,
1478 return (ha_rows) mi_records_in_range(file, (
int) inx, min_key, max_key);
1482 uint32_t ha_myisam::checksum()
const
1484 return (uint)file->state->checksum;
1493 &max_sort_file_size,
1494 context.getOptions()[
"max-sort-file-size"].as<uint64_t>()));
1502 context(
"max-sort-file-size",
1503 po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
1504 _(
"Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1505 context(
"sort-buffer-size",
1506 po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
1507 _(
"The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1511 DRIZZLE_DECLARE_PLUGIN
1517 N_(
"MyISAM storage engine: non-transactional, legacy, deprecated"),
1523 DRIZZLE_DECLARE_PLUGIN_END;