diff options
Diffstat (limited to 'sql/ha_myisam.cc')
-rw-r--r-- | sql/ha_myisam.cc | 414 |
1 files changed, 257 insertions, 157 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 2cec03a51db..18e621142f7 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -50,6 +49,36 @@ TYPELIB myisam_stats_method_typelib= { ** MyISAM tables *****************************************************************************/ +/* MyISAM handlerton */ + +handlerton myisam_hton= { + "MyISAM", + SHOW_OPTION_YES, + "Default engine as of MySQL 3.23 with great performance", + DB_TYPE_MYISAM, + NULL, + 0, /* slot */ + 0, /* savepoint size. */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ + /* + MyISAM doesn't support transactions and doesn't have + transaction-dependent context: cursors can survive a commit. + */ + HTON_CAN_RECREATE +}; + // collect errors printed by mi_check routines static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, @@ -116,25 +145,25 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, MI_COLUMNDEF **recinfo_out, uint *records_out) { uint i, j, recpos, minpos, fieldpos, temp_length, length; - uint options= table_arg->db_options_in_use; enum ha_base_keytype type= HA_KEYTYPE_BINARY; KEY *pos; MI_KEYDEF *keydef; MI_COLUMNDEF *recinfo, *recinfo_pos; HA_KEYSEG *keyseg; - + TABLE_SHARE *share= table_arg->s; + uint options= share->db_options_in_use; DBUG_ENTER("table2myisam"); if (!(my_multi_malloc(MYF(MY_WME), - recinfo_out, (table_arg->fields * 2 + 2) * sizeof(MI_COLUMNDEF), - keydef_out, table_arg->keys * sizeof(MI_KEYDEF), + recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF), + keydef_out, share->keys * sizeof(MI_KEYDEF), &keyseg, - (table_arg->key_parts + table_arg->keys) * sizeof(HA_KEYSEG), + (share->key_parts + share->keys) * sizeof(HA_KEYSEG), NullS))) DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */ keydef= *keydef_out; recinfo= *recinfo_out; pos= table_arg->key_info; - for (i= 0; i < table_arg->keys; i++, pos++) + for (i= 0; i < share->keys; i++, pos++) { keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? @@ -144,9 +173,9 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, keydef[i].keysegs= pos->key_parts; for (j= 0; j < pos->key_parts; j++) { - keydef[i].seg[j].flag= pos->key_part[j].key_part_flag; Field *field= pos->key_part[j].field; type= field->key_type(); + keydef[i].seg[j].flag= pos->key_part[j].key_part_flag; if (options & HA_OPTION_PACK_KEYS || (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | @@ -161,8 +190,8 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, if (j == 0) keydef[i].flag|= HA_PACK_KEY; if (!(field->flags & ZEROFILL_FLAG) && - (field->type() == FIELD_TYPE_STRING || - field->type() == FIELD_TYPE_VAR_STRING || + (field->type() == MYSQL_TYPE_STRING || + field->type() == MYSQL_TYPE_VAR_STRING || ((int) (pos->key_part[j].length - field->decimals())) >= 4)) keydef[i].seg[j].flag|= HA_SPACE_PACK; } @@ -172,7 +201,9 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, keydef[i].seg[j].type= (int) type; keydef[i].seg[j].start= pos->key_part[j].offset; keydef[i].seg[j].length= pos->key_part[j].length; - keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end= 0; + keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end= + keydef[i].seg[j].bit_length= 0; + keydef[i].seg[j].bit_pos= 0; keydef[i].seg[j].language= field->charset()->number; if (field->null_ptr) @@ -192,19 +223,26 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, keydef[i].seg[j].flag|= HA_BLOB_PART; /* save number of bytes used to pack length */ keydef[i].seg[j].bit_start= (uint) (field->pack_length() - - table_arg->blob_ptr_size); + share->blob_ptr_size); + } + else if (field->type() == FIELD_TYPE_BIT) + { + keydef[i].seg[j].bit_length= ((Field_bit *) field)->bit_len; + keydef[i].seg[j].bit_start= ((Field_bit *) field)->bit_ofs; + keydef[i].seg[j].bit_pos= (uint) (((Field_bit *) field)->bit_ptr - + (uchar*) table_arg->record[0]); } } keyseg+= pos->key_parts; } if (table_arg->found_next_number_field) - keydef[table_arg->next_number_index].flag|= HA_AUTO_KEY; + keydef[share->next_number_index].flag|= HA_AUTO_KEY; recpos= 0; recinfo_pos= recinfo; - while (recpos < (uint) table_arg->reclength) + while (recpos < (uint) share->reclength) { Field **field, *found= 0; - minpos= table_arg->reclength; + minpos= share->reclength; length= 0; for (field= table_arg->field; *field; field++) @@ -213,7 +251,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, fieldpos <= minpos) { /* skip null fields */ - if (!(temp_length= (*field)->pack_length())) + if (!(temp_length= (*field)->pack_length_in_rec())) continue; /* Skip null-fields */ if (! found || fieldpos < minpos || (fieldpos == minpos && temp_length < length)) @@ -224,7 +262,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, } } } - DBUG_PRINT("loop", ("found: %lx recpos: %d minpos: %d length: %d", + DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d", (long) found, recpos, minpos, length)); if (recpos != minpos) { // Reserved space (Null bits?) @@ -236,9 +274,9 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, break; if (found->flags & BLOB_FLAG) - { recinfo_pos->type= (int) FIELD_BLOB; - } + else if (found->type() == MYSQL_TYPE_VARCHAR) + recinfo_pos->type= FIELD_VARCHAR; else if (!(options & HA_OPTION_PACK_RECORD)) recinfo_pos->type= (int) FIELD_NORMAL; else if (found->zero_pack()) @@ -247,8 +285,8 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, recinfo_pos->type= (int) ((length <= 3 || (found->flags & ZEROFILL_FLAG)) ? FIELD_NORMAL : - found->type() == FIELD_TYPE_STRING || - found->type() == FIELD_TYPE_VAR_STRING ? + found->type() == MYSQL_TYPE_STRING || + found->type() == MYSQL_TYPE_VAR_STRING ? FIELD_SKIP_ENDSPACE : FIELD_SKIP_PRESPACE); if (found->null_ptr) @@ -383,9 +421,10 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, extern "C" { -volatile my_bool *killed_ptr(MI_CHECK *param) +volatile int *killed_ptr(MI_CHECK *param) { - return &(((THD *)(param->thd))->killed); + /* In theory Unsafe conversion, but should be ok for now */ + return (int*) &(((THD *)(param->thd))->killed); } void mi_check_print_error(MI_CHECK *param, const char *fmt,...) @@ -418,8 +457,35 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) } + +ha_myisam::ha_myisam(TABLE *table_arg) + :handler(&myisam_hton, table_arg), file(0), + int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | + HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | + HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME | + HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS), + can_enable_indexes(1) +{} + +handler *ha_myisam::clone(MEM_ROOT *mem_root) +{ + ha_myisam *new_handler= static_cast <ha_myisam *>(handler::clone(mem_root)); + if (new_handler) + new_handler->file->state= file->state; + return new_handler; +} + + +static const char *ha_myisam_exts[] = { + ".MYI", + ".MYD", + NullS +}; + const char **ha_myisam::bas_ext() const -{ static const char *ext[]= { ".MYI",".MYD", NullS }; return ext; } +{ + return ha_myisam_exts; +} const char *ha_myisam::index_type(uint key_number) @@ -506,7 +572,8 @@ int ha_myisam::dump(THD* thd, int fd) if (fd < 0) { - my_net_write(net, "", 0); + if (my_net_write(net, "", 0)) + error = errno ? errno : EPIPE; net_flush(net); } @@ -528,7 +595,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0)); - if (!table->db_record_offset) + if (!table->s->db_record_offset) int_table_flags|=HA_REC_NOT_IN_SEQ; if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) int_table_flags|=HA_HAS_CHECKSUM; @@ -544,7 +611,7 @@ int ha_myisam::close(void) int ha_myisam::write_row(byte * buf) { - statistic_increment(ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) @@ -555,7 +622,11 @@ int ha_myisam::write_row(byte * buf) or a new row, then update the auto_increment value in the record. */ if (table->next_number_field && buf == table->record[0]) - update_auto_increment(); + { + int error; + if ((error= update_auto_increment())) + return error; + } return mi_write(file,buf); } @@ -570,9 +641,9 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) thd->proc_info="Checking table"; myisamchk_init(¶m); param.thd = thd; - param.op_name = (char*)"check"; - param.db_name = table->table_cache_key; - param.table_name = table->table_name; + param.op_name = "check"; + param.db_name= table->s->db; + param.table_name= table->alias; param.testflag = check_opt->flags | T_CHECK | T_SILENT; param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method; @@ -605,12 +676,14 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { uint old_testflag=param.testflag; param.testflag|=T_MEDIUM; - init_io_cache(¶m.read_cache, file->dfile, - my_default_record_cache_size, READ_CACHE, - share->pack.header_length, 1, MYF(MY_WME)); - error |= chk_data_link(¶m, file, param.testflag & T_EXTEND); - end_io_cache(&(param.read_cache)); - param.testflag=old_testflag; + if (!(error= init_io_cache(¶m.read_cache, file->dfile, + my_default_record_cache_size, READ_CACHE, + share->pack.header_length, 1, MYF(MY_WME)))) + { + error= chk_data_link(¶m, file, param.testflag & T_EXTEND); + end_io_cache(&(param.read_cache)); + } + param.testflag= old_testflag; } } if (!error) @@ -658,11 +731,11 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) myisamchk_init(¶m); param.thd = thd; - param.op_name = (char*) "analyze"; - param.db_name = table->table_cache_key; - param.table_name = table->table_name; - param.testflag=(T_FAST | T_CHECK | T_SILENT | T_STATISTICS | - T_DONT_CHECK_CHECKSUM); + param.op_name= "analyze"; + param.db_name= table->s->db; + param.table_name= table->alias; + param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS | + T_DONT_CHECK_CHECKSUM); param.using_global_keycache = 1; param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method; @@ -685,9 +758,9 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) { HA_CHECK_OPT tmp_check_opt; - char* backup_dir= thd->lex->backup_dir; + char *backup_dir= thd->lex->backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char* table_name = table->real_name; + const char *table_name= table->s->table_name; int error; const char* errmsg; DBUG_ENTER("restore"); @@ -696,11 +769,11 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) MI_NAME_DEXT)) DBUG_RETURN(HA_ADMIN_INVALID); - if (my_copy(src_path, fn_format(dst_path, table->path, "", + if (my_copy(src_path, fn_format(dst_path, table->s->path, "", MI_NAME_DEXT, 4), MYF(MY_WME))) { - error = HA_ADMIN_FAILED; - errmsg = "Failed in my_copy (Error %d)"; + error= HA_ADMIN_FAILED; + errmsg= "Failed in my_copy (Error %d)"; goto err; } @@ -712,11 +785,11 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) { MI_CHECK param; myisamchk_init(¶m); - param.thd = thd; - param.op_name = (char*)"restore"; - param.db_name = table->table_cache_key; - param.table_name = table->table_name; - param.testflag = 0; + param.thd= thd; + param.op_name= "restore"; + param.db_name= table->s->db; + param.table_name= table->s->table_name; + param.testflag= 0; mi_check_print_error(¶m, errmsg, my_errno); DBUG_RETURN(error); } @@ -725,9 +798,9 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) { - char* backup_dir= thd->lex->backup_dir; + char *backup_dir= thd->lex->backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char* table_name = table->real_name; + const char *table_name= table->s->table_name; int error; const char *errmsg; DBUG_ENTER("ha_myisam::backup"); @@ -735,12 +808,13 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, reg_ext)) { - errmsg = "Failed in fn_format() for .frm file (errno: %d)"; - error = HA_ADMIN_INVALID; + errmsg= "Failed in fn_format() for .frm file (errno: %d)"; + error= HA_ADMIN_INVALID; goto err; } - if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME), + if (my_copy(fn_format(src_path, table->s->path, "", reg_ext, + MY_UNPACK_FILENAME), dst_path, MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE))) { @@ -758,7 +832,7 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) goto err; } - if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, + if (my_copy(fn_format(src_path, table->s->path, "", MI_NAME_DEXT, MY_UNPACK_FILENAME), dst_path, MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE))) @@ -773,11 +847,11 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) { MI_CHECK param; myisamchk_init(¶m); - param.thd = thd; - param.op_name = (char*)"backup"; - param.db_name = table->table_cache_key; - param.table_name = table->table_name; - param.testflag = 0; + param.thd= thd; + param.op_name= "backup"; + param.db_name= table->s->db; + param.table_name= table->s->table_name; + param.testflag = 0; mi_check_print_error(¶m,errmsg, my_errno); DBUG_RETURN(error); } @@ -794,10 +868,10 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) myisamchk_init(¶m); param.thd = thd; - param.op_name = (char*) "repair"; - param.testflag = ((check_opt->flags & ~(T_EXTEND)) | - T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM | - (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT)); + param.op_name= "repair"; + param.testflag= ((check_opt->flags & ~(T_EXTEND)) | + T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM | + (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT)); param.sort_buffer_length= check_opt->sort_buffer_size; start_records=file->state->records; while ((error=repair(thd,param,0)) && param.retry_repair) @@ -808,7 +882,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { param.testflag&= ~T_RETRY_WITHOUT_QUICK; sql_print_information("Retrying repair of: '%s' without quick", - table->path); + table->s->path); continue; } param.testflag&= ~T_QUICK; @@ -816,7 +890,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP; sql_print_information("Retrying repair of: '%s' with keycache", - table->path); + table->s->path); continue; } break; @@ -828,7 +902,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) sql_print_information("Found %s of %s rows when repairing '%s'", llstr(file->state->records, llbuff), llstr(start_records, llbuff2), - table->path); + table->s->path); } return error; } @@ -841,9 +915,9 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) myisamchk_init(¶m); param.thd = thd; - param.op_name = (char*) "optimize"; - param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE | - T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX); + param.op_name= "optimize"; + param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE | + T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX); param.sort_buffer_length= check_opt->sort_buffer_size; if ((error= repair(thd,param,1)) && param.retry_repair) { @@ -867,18 +941,18 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) ha_rows rows= file->state->records; DBUG_ENTER("ha_myisam::repair"); - param.db_name = table->table_cache_key; - param.table_name = table->table_name; + param.db_name= table->s->db; + param.table_name= table->alias; param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; - param.thd=thd; - param.tmpdir=&mysql_tmpdir_list; - param.out_flag=0; + param.thd= thd; + param.tmpdir= &mysql_tmpdir_list; + param.out_flag= 0; strmov(fixed_name,file->filename); // Don't lock tables if we have used LOCK TABLE if (!thd->locked_tables && - mi_lock_database(file, table->tmp_table ? F_EXTRA_LCK : F_WRLCK)) + mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK)) { mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno); DBUG_RETURN(HA_ADMIN_FAILED); @@ -890,7 +964,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) !(share->state.changed & STATE_NOT_OPTIMIZED_KEYS)))) { ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ? - ((ulonglong) 1L << share->base.keys)-1 : + mi_get_mask_all_keys_active(share->base.keys) : share->state.key_map); uint testflag=param.testflag; if (mi_test_if_sort_rep(file,file->state->records,key_map,0) && @@ -899,7 +973,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) local_testflag|= T_STATISTICS; param.testflag|= T_STATISTICS; // We get this for free statistics_done=1; - if (current_thd->variables.myisam_repair_threads>1) + if (thd->variables.myisam_repair_threads>1) { char buf[40]; /* TODO: respect myisam_repair_threads variable */ @@ -1023,7 +1097,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) if ((error= mi_assign_to_key_cache(file, map, new_key_cache))) { - char buf[80]; + char buf[STRING_BUFFER_USUAL_SIZE]; my_snprintf(buf, sizeof(buf), "Failed to flush to index file (errno: %d)", error); errmsg= buf; @@ -1037,9 +1111,9 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) MI_CHECK param; myisamchk_init(¶m); param.thd= thd; - param.op_name= (char*)"assign_to_keycache"; - param.db_name= table->table_cache_key; - param.table_name= table->table_name; + param.op_name= "assign_to_keycache"; + param.db_name= table->s->db; + param.table_name= table->s->table_name; param.testflag= 0; mi_check_print_error(¶m, errmsg); } @@ -1105,10 +1179,10 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) MI_CHECK param; myisamchk_init(¶m); param.thd= thd; - param.op_name= (char*)"preload_keys"; - param.db_name= table->table_cache_key; - param.table_name= table->table_name; - param.testflag= 0; + param.op_name= "preload_keys"; + param.db_name= table->s->db; + param.table_name= table->s->table_name; + param.testflag= 0; mi_check_print_error(¶m, errmsg); DBUG_RETURN(error); } @@ -1191,7 +1265,7 @@ int ha_myisam::enable_indexes(uint mode) { int error; - if (file->s->state.key_map == set_bits(ulonglong, file->s->base.keys)) + if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys)) { /* All indexes are enabled already. */ return 0; @@ -1213,9 +1287,9 @@ int ha_myisam::enable_indexes(uint mode) const char *save_proc_info=thd->proc_info; thd->proc_info="Creating index"; myisamchk_init(¶m); - param.op_name = (char*) "recreating_index"; - param.testflag = (T_SILENT | T_REP_BY_SORT | T_QUICK | - T_CREATE_MISSING_KEYS); + param.op_name= "recreating_index"; + param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK | + T_CREATE_MISSING_KEYS); param.myf_rw&= ~MY_WAIT_IF_FULL; param.sort_buffer_length= thd->variables.myisam_sort_buff_size; param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method; @@ -1224,8 +1298,16 @@ int ha_myisam::enable_indexes(uint mode) { sql_print_warning("Warning: Enabling keys got errno %d, retrying", my_errno); + /* Repairing by sort failed. Now try standard repair method. */ param.testflag&= ~(T_REP_BY_SORT | T_QUICK); error= (repair(thd,param,0) != HA_ADMIN_OK); + /* + If the standard repair succeeded, clear all error messages which + might have been set by the first repair. They can still be seen + with SHOW WARNINGS then. + */ + if (! error) + thd->clear_error(); } info(HA_STATUS_CONST); thd->proc_info=save_proc_info; @@ -1278,8 +1360,9 @@ int ha_myisam::indexes_are_disabled(void) void ha_myisam::start_bulk_insert(ha_rows rows) { DBUG_ENTER("ha_myisam::start_bulk_insert"); - THD *thd=current_thd; - ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows); + THD *thd= current_thd; + ulong size= min(thd->variables.read_buff_size, + table->s->avg_row_length*rows); DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu", (ulong) rows, size)); @@ -1287,8 +1370,8 @@ void ha_myisam::start_bulk_insert(ha_rows rows) if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE)) mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size); - can_enable_indexes= (file->s->state.key_map == - set_bits(ulonglong, file->s->base.keys)); + can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map, + file->s->base.keys); if (!(specialflag & SPECIAL_SAFE_MODE)) { @@ -1347,18 +1430,18 @@ bool ha_myisam::check_and_repair(THD *thd) // Don't use quick if deleted rows if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK)) check_opt.flags|=T_QUICK; - sql_print_warning("Checking table: '%s'",table->path); + sql_print_warning("Checking table: '%s'",table->s->path); old_query= thd->query; old_query_length= thd->query_length; pthread_mutex_lock(&LOCK_thread_count); - thd->query= table->real_name; - thd->query_length= strlen(table->real_name); + thd->query= (char*) table->s->table_name; + thd->query_length= (uint32) strlen(table->s->table_name); pthread_mutex_unlock(&LOCK_thread_count); if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt)) { - sql_print_warning("Recovering table: '%s'",table->path); + sql_print_warning("Recovering table: '%s'",table->s->path); check_opt.flags= ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) | (marked_crashed ? 0 : T_QUICK) | @@ -1382,7 +1465,7 @@ bool ha_myisam::is_crashed() const int ha_myisam::update_row(const byte * old_data, byte * new_data) { - statistic_increment(ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return mi_update(file,old_data,new_data); @@ -1390,7 +1473,7 @@ int ha_myisam::update_row(const byte * old_data, byte * new_data) int ha_myisam::delete_row(const byte * buf) { - statistic_increment(ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return mi_delete(file,buf); } @@ -1398,7 +1481,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1407,7 +1491,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1416,7 +1501,8 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1425,7 +1511,8 @@ int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) int ha_myisam::index_next(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1434,7 +1521,8 @@ int ha_myisam::index_next(byte * buf) int ha_myisam::index_prev(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=mi_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1443,7 +1531,8 @@ int ha_myisam::index_prev(byte * buf) int ha_myisam::index_first(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_first_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_first_count, + &LOCK_status); int error=mi_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1452,7 +1541,8 @@ int ha_myisam::index_first(byte * buf) int ha_myisam::index_last(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=mi_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1463,7 +1553,8 @@ int ha_myisam::index_next_same(byte * buf, uint length __attribute__((unused))) { DBUG_ASSERT(inited==INDEX); - statistic_increment(ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext_same(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1479,7 +1570,8 @@ int ha_myisam::rnd_init(bool scan) int ha_myisam::rnd_next(byte *buf) { - statistic_increment(ha_read_rnd_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, + &LOCK_status); int error=mi_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1492,8 +1584,9 @@ int ha_myisam::restart_rnd_next(byte *buf, byte *pos) int ha_myisam::rnd_pos(byte * buf, byte *pos) { - statistic_increment(ha_read_rnd_count,&LOCK_status); - int error=mi_rrnd(file, buf, ha_get_ptr(pos,ref_length)); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); + int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -1501,7 +1594,7 @@ int ha_myisam::rnd_pos(byte * buf, byte *pos) void ha_myisam::position(const byte* record) { my_off_t position=mi_position(file); - ha_store_ptr(ref, ref_length, position); + my_store_ptr(ref, ref_length, position); } int ha_myisam::info(uint flag) @@ -1522,25 +1615,25 @@ int ha_myisam::info(uint flag) } if (flag & HA_STATUS_CONST) { - max_data_file_length=info.max_data_file_length; - max_index_file_length=info.max_index_file_length; - create_time = info.create_time; - sortkey = info.sortkey; - ref_length=info.reflength; - table->db_options_in_use = info.options; - block_size=myisam_block_size; - table->keys_in_use.set_prefix(table->keys); - table->keys_in_use.intersect(info.key_map); - table->keys_for_keyread= table->keys_in_use; - table->keys_for_keyread.subtract(table->read_only_keys); - table->db_record_offset=info.record_offset; - if (table->key_parts) + TABLE_SHARE *share= table->s; + max_data_file_length= info.max_data_file_length; + max_index_file_length= info.max_index_file_length; + create_time= info.create_time; + sortkey= info.sortkey; + ref_length= info.reflength; + share->db_options_in_use= info.options; + block_size= myisam_block_size; + share->keys_in_use.set_prefix(share->keys); + share->keys_in_use.intersect_extended(info.key_map); + share->keys_for_keyread.intersect(share->keys_in_use); + share->db_record_offset= info.record_offset; + if (share->key_parts) memcpy((char*) table->key_info[0].rec_per_key, (char*) info.rec_per_key, - sizeof(table->key_info[0].rec_per_key)*table->key_parts); - raid_type=info.raid_type; - raid_chunks=info.raid_chunks; - raid_chunksize=info.raid_chunksize; + sizeof(table->key_info[0].rec_per_key)*share->key_parts); + raid_type= info.raid_type; + raid_chunks= info.raid_chunks; + raid_chunksize= info.raid_chunksize; /* Set data_file_name and index_file_name to point at the symlink value @@ -1557,7 +1650,7 @@ int ha_myisam::info(uint flag) if (flag & HA_STATUS_ERRKEY) { errkey = info.errkey; - ha_store_ptr(dupp_ref, ref_length, info.dupp_key_pos); + my_store_ptr(dupp_ref, ref_length, info.dupp_key_pos); } if (flag & HA_STATUS_TIME) update_time = info.update_time; @@ -1598,7 +1691,7 @@ int ha_myisam::delete_table(const char *name) int ha_myisam::external_lock(THD *thd, int lock_type) { - return mi_lock_database(file, !table->tmp_table ? + return mi_lock_database(file, !table->s->tmp_table ? lock_type : ((lock_type == F_UNLCK) ? F_UNLCK : F_EXTRA_LCK)); } @@ -1640,18 +1733,19 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, MI_KEYDEF *keydef; MI_COLUMNDEF *recinfo; MI_CREATE_INFO create_info; + TABLE_SHARE *share= table->s; DBUG_ENTER("ha_myisam::create"); if ((error= table2myisam(table_arg, &keydef, &recinfo, &records))) DBUG_RETURN(error); /* purecov: inspected */ bzero((char*) &create_info, sizeof(create_info)); - create_info.max_rows= table_arg->max_rows; - create_info.reloc_rows= table_arg->min_rows; - create_info.with_auto_increment= table_arg->next_number_key_offset == 0; + create_info.max_rows= share->max_rows; + create_info.reloc_rows= share->min_rows; + create_info.with_auto_increment= share->next_number_key_offset == 0; create_info.auto_increment= (info->auto_increment_value ? info->auto_increment_value -1 : (ulonglong) 0); - create_info.data_file_length= ((ulonglong) table_arg->max_rows * - table_arg->avg_row_length); + create_info.data_file_length= ((ulonglong) share->max_rows * + share->avg_row_length); create_info.raid_type= info->raid_type; create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks : RAID_DEFAULT_CHUNKS); @@ -1672,7 +1766,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, /* TODO: Check that the following fn_format is really needed */ error= mi_create(fn_format(buff, name, "", "", MY_UNPACK_FILENAME|MY_REPLACE_EXT), - table_arg->keys, keydef, + share->keys, keydef, records, recinfo, 0, (MI_UNIQUEDEF*) 0, &create_info, create_flags); @@ -1687,30 +1781,35 @@ int ha_myisam::rename_table(const char * from, const char * to) } -longlong ha_myisam::get_auto_increment() +ulonglong ha_myisam::get_auto_increment() { - if (!table->next_number_key_offset) + ulonglong nr; + int error; + byte key[MI_MAX_KEY_LENGTH]; + + if (!table->s->next_number_key_offset) { // Autoincrement at key-start ha_myisam::info(HA_STATUS_AUTO); return auto_increment_value; } /* it's safe to call the following if bulk_insert isn't on */ - mi_flush_bulk_insert(file, table->next_number_index); + mi_flush_bulk_insert(file, table->s->next_number_index); - longlong nr; - int error; - byte key[MI_MAX_KEY_LENGTH]; (void) extra(HA_EXTRA_KEYREAD); - key_copy(key,table,table->next_number_index, - table->next_number_key_offset); - error=mi_rkey(file,table->record[1],(int) table->next_number_index, - key,table->next_number_key_offset,HA_READ_PREFIX_LAST); + key_copy(key, table->record[0], + table->key_info + table->s->next_number_index, + table->s->next_number_key_offset); + error= mi_rkey(file,table->record[1],(int) table->s->next_number_index, + key,table->s->next_number_key_offset,HA_READ_PREFIX_LAST); if (error) - nr=1; + nr= 1; else - nr=(longlong) - table->next_number_field->val_int_offset(table->rec_buff_length)+1; + { + /* Get data from record[1] */ + nr= ((ulonglong) table->next_number_field-> + val_int_offset(table->s->rec_buff_length)+1); + } extra(HA_EXTRA_NO_KEYREAD); return nr; } @@ -1755,7 +1854,8 @@ int ha_myisam::ft_read(byte * buf) if (!ft_handler) return -1; - thread_safe_increment(ha_read_next_count,&LOCK_status); // why ? + thread_safe_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); // why ? error=ft_handler->please->read_next(ft_handler,(char*) buf); @@ -1765,6 +1865,6 @@ int ha_myisam::ft_read(byte * buf) uint ha_myisam::checksum() const { - return (uint)file->s->state.checksum; + return (uint)file->state->checksum; } |