diff options
Diffstat (limited to 'storage/myisam/ha_myisam.cc')
-rw-r--r-- | storage/myisam/ha_myisam.cc | 328 |
1 files changed, 241 insertions, 87 deletions
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 87de58076cd..fc6a9829072 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -132,13 +132,13 @@ static handler *myisam_create_handler(handlerton *hton, // collect errors printed by mi_check routines -static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, +static void mi_check_print_msg(HA_CHECK *param, const char* msg_type, const char *fmt, va_list args) { THD* thd = (THD*)param->thd; Protocol *protocol= thd->protocol; size_t length, msg_length; - char msgbuf[MI_MAX_MSG_BUF]; + char msgbuf[HA_MAX_MSG_BUF]; char name[NAME_LEN*2+2]; msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); @@ -313,7 +313,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, record= table_arg->record[0]; recpos= 0; recinfo_pos= recinfo; - while (recpos < (uint) share->reclength) + while (recpos < (uint) share->stored_rec_length) { Field **field, *found= 0; minpos= share->reclength; @@ -339,30 +339,31 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d", (long) found, recpos, minpos, length)); if (recpos != minpos) - { // Reserved space (Null bits?) + { + /* reserve space for null bits */ bzero((char*) recinfo_pos, sizeof(*recinfo_pos)); - recinfo_pos->type= (int) FIELD_NORMAL; + recinfo_pos->type= FIELD_NORMAL; recinfo_pos++->length= (uint16) (minpos - recpos); } if (!found) break; if (found->flags & BLOB_FLAG) - recinfo_pos->type= (int) FIELD_BLOB; + recinfo_pos->type= 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; + recinfo_pos->type= FIELD_NORMAL; else if (found->zero_pack()) - recinfo_pos->type= (int) FIELD_SKIP_ZERO; + recinfo_pos->type= FIELD_SKIP_ZERO; else - recinfo_pos->type= (int) ((length <= 3 || - (found->flags & ZEROFILL_FLAG)) ? - FIELD_NORMAL : - found->type() == MYSQL_TYPE_STRING || - found->type() == MYSQL_TYPE_VAR_STRING ? - FIELD_SKIP_ENDSPACE : - FIELD_SKIP_PRESPACE); + recinfo_pos->type= ((length <= 3 || + (found->flags & ZEROFILL_FLAG)) ? + FIELD_NORMAL : + found->type() == MYSQL_TYPE_STRING || + found->type() == MYSQL_TYPE_VAR_STRING ? + FIELD_SKIP_ENDSPACE : + FIELD_SKIP_PRESPACE); if (found->null_ptr) { recinfo_pos->null_bit= found->null_bit; @@ -388,7 +389,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, Check for underlying table conformance SYNOPSIS - check_definition() + myisam_check_definition() t1_keyinfo in First table key definition t1_recinfo in First table record definition t1_keys in Number of keys in first table @@ -557,13 +558,12 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, extern "C" { -volatile int *killed_ptr(MI_CHECK *param) +int killed_ptr(HA_CHECK *param) { - /* In theory Unsafe conversion, but should be ok for now */ - return (int*) &(((THD *)(param->thd))->killed); + return thd_killed((THD*)param->thd); } -void mi_check_print_error(MI_CHECK *param, const char *fmt,...) +void mi_check_print_error(HA_CHECK *param, const char *fmt,...) { param->error_printed|=1; param->out_flag|= O_DATA_LOST; @@ -573,7 +573,7 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...) va_end(args); } -void mi_check_print_info(MI_CHECK *param, const char *fmt,...) +void mi_check_print_info(HA_CHECK *param, const char *fmt,...) { va_list args; va_start(args, fmt); @@ -581,7 +581,7 @@ void mi_check_print_info(MI_CHECK *param, const char *fmt,...) va_end(args); } -void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) +void mi_check_print_warning(HA_CHECK *param, const char *fmt,...) { param->warning_printed=1; param->out_flag|= O_DATA_LOST; @@ -705,6 +705,9 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER))) return (my_errno ? my_errno : -1); + + file->s->chst_invalidator= query_cache_invalidate_by_MyISAM_filename_ref; + if (!table->s->tmp_table) /* No need to perform a check for tmp table */ { if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs))) @@ -736,7 +739,19 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) 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; + { + /* + Set which type of automatic checksum we have + The old checksum and new checksum are identical if there is no + null fields. + Files with new checksum has the HA_OPTION_NULL_FIELDS bit set. + */ + if ((file->s->options & HA_OPTION_NULL_FIELDS) || + !file->s->has_null_fields) + int_table_flags|= HA_HAS_NEW_CHECKSUM; + if (!(file->s->options & HA_OPTION_NULL_FIELDS)) + int_table_flags|= HA_HAS_OLD_CHECKSUM; + } for (i= 0; i < table->s->keys; i++) { @@ -763,14 +778,14 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) int ha_myisam::close(void) { MI_INFO *tmp=file; + if (!tmp) + return 0; file=0; return mi_close(tmp); } int ha_myisam::write_row(uchar *buf) { - ha_statistic_increment(&SSV::ha_write_count); - /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); @@ -792,10 +807,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { if (!file) return HA_ADMIN_INTERNAL_ERROR; int error; - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; const char *old_proc_info=thd->proc_info; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Checking table"); myisamchk_init(¶m); param.thd = thd; @@ -803,7 +821,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) param.db_name= table->s->db.str; param.table_name= table->alias; param.testflag = check_opt->flags | T_CHECK | T_SILENT; - param.stats_method= (enum_mi_stats_method)THDVAR(thd, stats_method); + param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method); if (!(table->db_stat & HA_READ_ONLY)) param.testflag|= T_STATISTICS; @@ -832,13 +850,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) (param.testflag & (T_EXTEND | T_MEDIUM)))) || mi_is_crashed(file)) { - uint old_testflag=param.testflag; + ulonglong old_testflag= param.testflag; param.testflag|=T_MEDIUM; 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); + error= chk_data_link(¶m, file, test(param.testflag & T_EXTEND)); end_io_cache(&(param.read_cache)); } param.testflag= old_testflag; @@ -884,9 +902,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) { int error=0; - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd = thd; param.op_name= "analyze"; @@ -895,7 +916,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) 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)THDVAR(thd, stats_method); + param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method); if (!(share->state.changed & STATE_NOT_ANALYZED)) return HA_ADMIN_ALREADY_DONE; @@ -916,10 +937,10 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { int error; - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); ha_rows start_records; - if (!file) return HA_ADMIN_INTERNAL_ERROR; + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -935,7 +956,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) if (test_all_bits(param.testflag, (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK))) { - param.testflag&= ~T_RETRY_WITHOUT_QUICK; + param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK); + /* Ensure we don't loose any rows when retrying without quick */ + param.testflag|= T_SAFE_REPAIR; sql_print_information("Retrying repair of: '%s' without quick", table->s->path.str); continue; @@ -965,8 +988,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) { int error; - if (!file) return HA_ADMIN_INTERNAL_ERROR; - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -985,10 +1009,10 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) } -int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) +int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) { int error=0; - uint local_testflag=param.testflag; + ulonglong local_testflag= param.testflag; bool optimize_done= !do_optimize, statistics_done=0; const char *old_proc_info=thd->proc_info; char fixed_name[FN_REFLEN]; @@ -1024,7 +1048,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ? mi_get_mask_all_keys_active(share->base.keys) : share->state.key_map); - uint testflag=param.testflag; + ulonglong testflag= param.testflag; if (mi_test_if_sort_rep(file,file->state->records,key_map,0) && (local_testflag & T_REP_BY_SORT)) { @@ -1038,7 +1062,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map)); thd_proc_info(thd, buf); error = mi_repair_parallel(¶m, file, fixed_name, - param.testflag & T_QUICK); + test(param.testflag & T_QUICK)); thd_proc_info(thd, "Repair done"); // to reset proc_info, as // it was pointing to local buffer } @@ -1046,7 +1070,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) { thd_proc_info(thd, "Repair by sorting"); error = mi_repair_by_sort(¶m, file, fixed_name, - param.testflag & T_QUICK); + test(param.testflag & T_QUICK)); } } else @@ -1054,9 +1078,9 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) thd_proc_info(thd, "Repair with keycache"); param.testflag &= ~T_REP_BY_SORT; error= mi_repair(¶m, file, fixed_name, - param.testflag & T_QUICK); + test(param.testflag & T_QUICK)); } - param.testflag=testflag; + param.testflag= testflag | (param.testflag & T_RETRY_WITHOUT_QUICK); optimize_done=1; } if (!error) @@ -1160,7 +1184,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) if (error != HA_ADMIN_OK) { /* Send error to user */ - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd= thd; param.op_name= "assign_to_keycache"; @@ -1224,7 +1251,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) err: { - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd= thd; param.op_name= "preload_keys"; @@ -1334,8 +1363,12 @@ int ha_myisam::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd=current_thd; - MI_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); const char *save_proc_info=thd->proc_info; + + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Creating index"); myisamchk_init(¶m); param.op_name= "recreating_index"; @@ -1343,7 +1376,7 @@ int ha_myisam::enable_indexes(uint mode) T_CREATE_MISSING_KEYS); param.myf_rw&= ~MY_WAIT_IF_FULL; param.sort_buffer_length= THDVAR(thd, sort_buffer_size); - param.stats_method= (enum_mi_stats_method)THDVAR(thd, stats_method); + param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method); param.tmpdir=&mysql_tmpdir_list; if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair) { @@ -1471,7 +1504,7 @@ int ha_myisam::end_bulk_insert() { mi_end_bulk_insert(file); int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0); - if (!err) + if (!err && !file->s->deleting) { if (can_enable_indexes) { @@ -1539,7 +1572,6 @@ bool ha_myisam::is_crashed() const int ha_myisam::update_row(const uchar *old_data, uchar *new_data) { - ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return mi_update(file,old_data,new_data); @@ -1547,19 +1579,58 @@ int ha_myisam::update_row(const uchar *old_data, uchar *new_data) int ha_myisam::delete_row(const uchar *buf) { - ha_statistic_increment(&SSV::ha_delete_count); return mi_delete(file,buf); } + +C_MODE_START + +ICP_RESULT index_cond_func_myisam(void *arg) +{ + ha_myisam *h= (ha_myisam*)arg; + if (h->end_range) + { + if (h->compare_key2(h->end_range) > 0) + return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ + } + return (ICP_RESULT) test(h->pushed_idx_cond->val_int()); +} + +C_MODE_END + + +int ha_myisam::index_init(uint idx, bool sorted) +{ + active_index=idx; + if (pushed_idx_cond_keyno == idx) + mi_set_index_cond_func(file, index_cond_func_myisam, this); + return 0; +} + + +int ha_myisam::index_end() +{ + active_index=MAX_KEY; + //pushed_idx_cond_keyno= MAX_KEY; + mi_set_index_cond_func(file, NULL, 0); + in_range_check_pushed_down= FALSE; + ds_mrr.dsmrr_close(); + return 0; +} + +int ha_myisam::rnd_end() +{ + ds_mrr.dsmrr_close(); + return 0; +} + int ha_myisam::index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1569,34 +1640,16 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, enum ha_rkey_function find_flag) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); - ha_statistic_increment(&SSV::ha_read_key_count); int error=mi_rkey(file, buf, index, key, keypart_map, find_flag); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } -int ha_myisam::index_read_last_map(uchar *buf, const uchar *key, - key_part_map keypart_map) -{ - MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); - DBUG_ENTER("ha_myisam::index_read_last"); - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); - int error=mi_rkey(file, buf, active_index, key, keypart_map, - HA_READ_PREFIX_LAST); - table->status=error ? STATUS_NOT_FOUND: 0; - MYSQL_INDEX_READ_ROW_DONE(error); - DBUG_RETURN(error); -} - int ha_myisam::index_next(uchar *buf) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); int error=mi_rnext(file,buf,active_index); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1605,9 +1658,7 @@ int ha_myisam::index_prev(uchar *buf) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_prev_count); int error=mi_rprev(file,buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1616,9 +1667,7 @@ int ha_myisam::index_first(uchar *buf) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_first_count); int error=mi_rfirst(file, buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1627,10 +1676,9 @@ int ha_myisam::index_last(uchar *buf) { MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_last_count); int error=mi_rlast(file, buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); +#warning move that to wrappers return error; } @@ -1641,12 +1689,10 @@ int ha_myisam::index_next_same(uchar *buf, int error; DBUG_ASSERT(inited==INDEX); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); - ha_statistic_increment(&SSV::ha_read_next_count); do { error= mi_rnext_same(file,buf); } while (error == HA_ERR_RECORD_DELETED); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1663,25 +1709,27 @@ int ha_myisam::rnd_next(uchar *buf) { MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, TRUE); - ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error=mi_scan(file, buf); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_READ_ROW_DONE(error); return error; } -int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos) +int ha_myisam::remember_rnd_pos() { - return rnd_pos(buf,pos); + position((uchar*) 0); + return 0; +} + +int ha_myisam::restart_rnd_next(uchar *buf) +{ + return rnd_pos(buf, ref); } int ha_myisam::rnd_pos(uchar *buf, uchar *pos) { MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, FALSE); - ha_statistic_increment(&SSV::ha_read_rnd_count); int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); - table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_READ_ROW_DONE(error); return error; } @@ -1714,6 +1762,16 @@ int ha_myisam::info(uint flag) stats.max_data_file_length= misam_info.max_data_file_length; stats.max_index_file_length= misam_info.max_index_file_length; stats.create_time= (ulong) misam_info.create_time; + /* + We want the value of stats.mrr_length_per_rec to be platform independent. + The size of the chunk at the end of the join buffer used for MRR needs + is calculated now basing on the values passed in the stats structure. + The remaining part of the join buffer is used for records. A different + number of records in the buffer results in a different number of buffer + refills and in a different order of records in the result set. + */ + stats.mrr_length_per_rec= misam_info.reflength + 8; // 8=max(sizeof(void *)) + ref_length= misam_info.reflength; share->db_options_in_use= misam_info.options; stats.block_size= myisam_block_size; /* record block size */ @@ -1769,8 +1827,13 @@ int ha_myisam::extra(enum ha_extra_function operation) return mi_extra(file, operation, 0); } + int ha_myisam::reset(void) { + pushed_idx_cond= NULL; + pushed_idx_cond_keyno= MAX_KEY; + mi_set_index_cond_func(file, NULL, 0); + ds_mrr.dsmrr_close(); return mi_reset(file); } @@ -1901,7 +1964,7 @@ void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment, { ulonglong nr; int error; - uchar key[MI_MAX_KEY_LENGTH]; + uchar key[HA_MAX_KEY_LENGTH]; if (!table->s->next_number_key_offset) { // Autoincrement at key-start @@ -1985,8 +2048,6 @@ int ha_myisam::ft_read(uchar *buf) &LOCK_status); // why ? error=ft_handler->please->read_next(ft_handler,(char*) buf); - - table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -2016,6 +2077,27 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info, return COMPATIBLE_DATA_YES; } + +/** + Check if a table is incompatible with the current version. + + The cases are: + - Table has checksum, varchars and are not of dynamic record type +*/ + +int ha_myisam::check_for_upgrade(HA_CHECK_OPT *check_opt) +{ + if (!(file->s->options & HA_OPTION_NULL_FIELDS) && + !(file->s->options & HA_OPTION_PACK_RECORD) && + file->s->has_varchar_fields) + { + /* We need alter there to get the HA_OPTION_NULL_FIELDS flag to be set */ + return HA_ADMIN_NEEDS_ALTER; + } + return HA_ADMIN_OK; +} + + extern int mi_panic(enum ha_panic_function flag); int myisam_panic(handlerton *hton, ha_panic_function flag) { @@ -2060,6 +2142,61 @@ static struct st_mysql_sys_var* myisam_sysvars[]= { 0 }; +/**************************************************************************** + * MyISAM MRR implementation: use DS-MRR + ***************************************************************************/ + +int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, + uint n_ranges, uint mode, + HANDLER_BUFFER *buf) +{ + return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf); +} + +int ha_myisam::multi_range_read_next(char **range_info) +{ + return ds_mrr.dsmrr_next(range_info); +} + +ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, + void *seq_init_param, + uint n_ranges, uint *bufsz, + uint *flags, COST_VECT *cost) +{ + /* + This call is here because there is no location where this->table would + already be known. + TODO: consider moving it into some per-query initialization call. + */ + ds_mrr.init(this, table); + return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, + flags, cost); +} + +ha_rows ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys, + uint *bufsz, uint *flags, + COST_VECT *cost) +{ + ds_mrr.init(this, table); + return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost); +} + +/* MyISAM MRR implementation ends */ + + +/* Index condition pushdown implementation*/ + + +Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) +{ + pushed_idx_cond_keyno= keyno_arg; + pushed_idx_cond= idx_cond_arg; + in_range_check_pushed_down= TRUE; + if (active_index == pushed_idx_cond_keyno) + mi_set_index_cond_func(file, index_cond_func_myisam, this); + return NULL; +} + struct st_mysql_storage_engine myisam_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -2079,6 +2216,23 @@ mysql_declare_plugin(myisam) NULL } mysql_declare_plugin_end; +maria_declare_plugin(myisam) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &myisam_storage_engine, + "MyISAM", + "MySQL AB", + "Default engine as of MySQL 3.23 with great performance", + PLUGIN_LICENSE_GPL, + myisam_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100, /* 1.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; #ifdef HAVE_QUERY_CACHE |