14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
#ifdef USE_PRAGMA_IMPLEMENTATION
18
#pragma implementation // gcc: Class implementation
21
#define DRIZZLE_SERVER 1
18
23
#include <drizzled/server_includes.h>
19
24
#include <mysys/my_bit.h>
20
#include "myisampack.h"
25
#include <myisampack.h>
21
26
#include "ha_myisam.h"
22
27
#include "myisamdef.h"
23
#include <drizzled/util/test.h>
24
#include <drizzled/error.h>
25
#include <drizzled/gettext.h>
26
#include <drizzled/session.h>
27
#include <drizzled/protocol.h>
28
#include <drizzled/table.h>
29
#include <drizzled/field/timestamp.h>
28
#include <drizzled/drizzled_error_messages.h>
31
30
ulong myisam_recover_options= HA_RECOVER_NONE;
32
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
34
32
/* bits in myisam_recover_options */
35
33
const char *myisam_recover_names[] =
36
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
34
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
37
35
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
38
myisam_recover_names, NULL};
36
myisam_recover_names, NULL};
40
38
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
41
"nulls_ignored", NULL};
39
"nulls_ignored", NullS};
42
40
TYPELIB myisam_stats_method_typelib= {
43
41
array_elements(myisam_stats_method_names) - 1, "",
44
42
myisam_stats_method_names, NULL};
58
56
// collect errors printed by mi_check routines
60
58
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
61
const char *fmt, va_list args)
59
const char *fmt, va_list args)
63
Session* session = (Session*)param->session;
64
Protocol *protocol= session->protocol;
65
uint32_t length, msg_length;
61
THD* thd = (THD*)param->thd;
62
Protocol *protocol= thd->protocol;
63
uint length, msg_length;
66
64
char msgbuf[MI_MAX_MSG_BUF];
67
65
char name[NAME_LEN*2+2];
69
67
msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
70
68
msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
72
if (!session->vio_ok())
74
sql_print_error("%s",msgbuf);
72
sql_print_error(msgbuf);
81
79
my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
84
length= sprintf(name,"%s.%s",param->db_name,param->table_name);
82
length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
87
85
TODO: switch from protocol to push_warning here. The main reason we didn't
88
86
it yet is parallel repair. Due to following trace:
130
128
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
131
MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
129
MI_COLUMNDEF **recinfo_out, uint *records_out)
133
uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
131
uint i, j, recpos, minpos, fieldpos, temp_length, length;
134
132
enum ha_base_keytype type= HA_KEYTYPE_BINARY;
135
unsigned char *record;
137
135
MI_KEYDEF *keydef;
138
136
MI_COLUMNDEF *recinfo, *recinfo_pos;
139
137
HA_KEYSEG *keyseg;
140
138
TABLE_SHARE *share= table_arg->s;
141
uint32_t options= share->db_options_in_use;
139
uint options= share->db_options_in_use;
142
140
if (!(my_multi_malloc(MYF(MY_WME),
143
141
recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
144
142
keydef_out, share->keys * sizeof(MI_KEYDEF),
146
144
(share->key_parts + share->keys) * sizeof(HA_KEYSEG),
148
146
return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
149
147
keydef= *keydef_out;
150
148
recinfo= *recinfo_out;
214
212
record= table_arg->record[0];
216
214
recinfo_pos= recinfo;
217
while (recpos < (uint) share->stored_rec_length)
215
while (recpos < (uint) share->reclength)
219
217
Field **field, *found= 0;
220
218
minpos= share->reclength;
318
316
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
319
uint32_t t1_keys, uint32_t t1_recs,
317
uint t1_keys, uint t1_recs,
320
318
MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
321
uint32_t t2_keys, uint32_t t2_recs, bool strict)
319
uint t2_keys, uint t2_recs, bool strict)
324
322
if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
395
393
volatile int *killed_ptr(MI_CHECK *param)
397
395
/* In theory Unsafe conversion, but should be ok for now */
398
return (int*) &(((Session *)(param->session))->killed);
396
return (int*) &(((THD *)(param->thd))->killed);
401
399
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
444
442
void _mi_report_crashed(MI_INFO *file, const char *message,
445
const char *sfile, uint32_t sline)
443
const char *sfile, uint sline)
447
Session *cur_session;
449
447
pthread_mutex_lock(&file->s->intern_lock);
450
if ((cur_session= (Session*) file->in_use.data))
451
sql_print_error(_("Got an error from thread_id=%"PRIu64", %s:%d"),
452
cur_session->thread_id,
448
if ((cur_thd= (THD*) file->in_use.data))
449
sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
455
sql_print_error(_("Got an error from unknown thread, %s:%d"), sfile, sline);
452
sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline);
457
454
sql_print_error("%s", message);
458
455
for (element= file->s->in_use; element; element= list_rest(element))
460
sql_print_error("%s", _("Unknown thread accessing table"));
457
sql_print_error("%s", "Unknown thread accessing table");
462
459
pthread_mutex_unlock(&file->s->intern_lock);
467
464
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
468
465
:handler(hton, table_arg), file(0),
469
int_table_flags(HA_NULL_IN_KEY |
470
HA_BINLOG_ROW_CAPABLE |
471
HA_BINLOG_STMT_CAPABLE |
478
HA_STATS_RECORDS_IS_EXACT |
479
HA_NEED_READ_RANGE_BUFFER |
466
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
467
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
468
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
469
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
470
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
471
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
472
HA_NEED_READ_RANGE_BUFFER | HA_MRR_CANT_SORT),
481
473
can_enable_indexes(1)
505
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
497
const char *ha_myisam::index_type(uint key_number __attribute__((unused)))
510
502
/* Name is here without an extension */
511
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
503
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
513
505
MI_KEYDEF *keyinfo;
514
506
MI_COLUMNDEF *recinfo= 0;
519
511
If the user wants to have memory mapped data files, add an
550
542
/* purecov: end */
554
546
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
555
mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
547
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
557
549
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
558
550
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
559
mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
551
VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
560
552
if (!table->s->db_record_offset)
561
553
int_table_flags|=HA_REC_NOT_IN_SEQ;
562
554
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
563
555
int_table_flags|=HA_HAS_CHECKSUM;
565
557
keys_with_parts.clear_all();
566
558
for (i= 0; i < table->s->keys; i++)
620
612
return mi_write(file,buf);
623
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
615
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
625
617
if (!file) return HA_ADMIN_INTERNAL_ERROR;
628
620
MYISAM_SHARE* share = file->s;
629
const char *old_proc_info= session->get_proc_info();
621
const char *old_proc_info= thd->get_proc_info();
631
session->set_proc_info("Checking table");
623
thd_proc_info(thd, "Checking table");
632
624
myisamchk_init(¶m);
633
param.session = session;
634
626
param.op_name = "check";
635
627
param.db_name= table->s->db.str;
636
628
param.table_name= table->alias;
637
629
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
638
param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
630
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
640
632
if (!(table->db_stat & HA_READ_ONLY))
641
633
param.testflag|= T_STATISTICS;
664
656
(param.testflag & (T_EXTEND | T_MEDIUM)))) ||
665
657
mi_is_crashed(file))
667
uint32_t old_testflag=param.testflag;
659
uint old_testflag=param.testflag;
668
660
param.testflag|=T_MEDIUM;
669
661
if (!(error= init_io_cache(¶m.read_cache, file->dfile,
670
662
my_default_record_cache_size, READ_CACHE,
696
688
HA_STATUS_CONST);
699
else if (!mi_is_crashed(file) && !session->killed)
691
else if (!mi_is_crashed(file) && !thd->killed)
701
693
mi_mark_crashed(file);
702
694
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
705
session->set_proc_info(old_proc_info);
697
thd_proc_info(thd, old_proc_info);
706
698
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
713
705
two threads may do an analyze at the same time!
716
int ha_myisam::analyze(Session *session,
708
int ha_myisam::analyze(THD *thd,
717
709
HA_CHECK_OPT* check_opt __attribute__((unused)))
721
713
MYISAM_SHARE* share = file->s;
723
715
myisamchk_init(¶m);
724
param.session = session;
725
717
param.op_name= "analyze";
726
718
param.db_name= table->s->db.str;
727
719
param.table_name= table->alias;
728
720
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
729
721
T_DONT_CHECK_CHECKSUM);
730
722
param.using_global_keycache = 1;
731
param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
723
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
733
725
if (!(share->state.changed & STATE_NOT_ANALYZED))
734
726
return HA_ADMIN_ALREADY_DONE;
740
732
error=update_state_info(¶m,file,UPDATE_STAT);
741
733
pthread_mutex_unlock(&share->intern_lock);
743
else if (!mi_is_crashed(file) && !session->killed)
735
else if (!mi_is_crashed(file) && !thd->killed)
744
736
mi_mark_crashed(file);
745
737
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
749
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
741
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
755
747
if (!file) return HA_ADMIN_INTERNAL_ERROR;
757
749
myisamchk_init(¶m);
758
param.session = session;
759
751
param.op_name= "repair";
760
752
param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
761
753
T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
762
754
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
763
755
param.sort_buffer_length= check_opt->sort_buffer_size;
764
756
start_records=file->state->records;
765
while ((error=repair(session,param,0)) && param.retry_repair)
757
while ((error=repair(thd,param,0)) && param.retry_repair)
767
759
param.retry_repair=0;
768
760
if (test_all_bits(param.testflag,
798
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
790
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
801
793
if (!file) return HA_ADMIN_INTERNAL_ERROR;
804
796
myisamchk_init(¶m);
805
param.session = session;
806
798
param.op_name= "optimize";
807
799
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
808
800
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
809
801
param.sort_buffer_length= check_opt->sort_buffer_size;
810
if ((error= repair(session,param,1)) && param.retry_repair)
802
if ((error= repair(thd,param,1)) && param.retry_repair)
812
804
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
813
805
my_errno, param.db_name, param.table_name);
814
806
param.testflag&= ~T_REP_BY_SORT;
815
error= repair(session,param,1);
807
error= repair(thd,param,1);
821
int ha_myisam::repair(Session *session, MI_CHECK ¶m, bool do_optimize)
813
int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
824
uint32_t local_testflag=param.testflag;
816
uint local_testflag=param.testflag;
825
817
bool optimize_done= !do_optimize, statistics_done=0;
826
const char *old_proc_info= session->get_proc_info();
818
const char *old_proc_info= thd->get_proc_info();
827
819
char fixed_name[FN_REFLEN];
828
820
MYISAM_SHARE* share = file->s;
829
821
ha_rows rows= file->state->records;
848
840
param.table_name= table->alias;
849
841
param.tmpfile_createflag = O_RDWR | O_TRUNC;
850
842
param.using_global_keycache = 1;
851
param.session= session;
844
param.tmpdir= &mysql_tmpdir_list;
852
845
param.out_flag= 0;
853
strcpy(fixed_name,file->filename);
846
stpcpy(fixed_name,file->filename);
855
848
// Don't lock tables if we have used LOCK Table
856
if (!session->locked_tables &&
849
if (!thd->locked_tables &&
857
850
mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
859
852
mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno);
868
861
uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
869
862
mi_get_mask_all_keys_active(share->base.keys) :
870
863
share->state.key_map);
871
uint32_t testflag=param.testflag;
864
uint testflag=param.testflag;
872
865
if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
873
866
(local_testflag & T_REP_BY_SORT))
875
868
local_testflag|= T_STATISTICS;
876
869
param.testflag|= T_STATISTICS; // We get this for free
877
870
statistics_done=1;
878
if (session->variables.myisam_repair_threads>1)
871
if (thd->variables.myisam_repair_threads>1)
881
874
/* TODO: respect myisam_repair_threads variable */
882
875
snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
883
session->set_proc_info(buf);
876
thd_proc_info(thd, buf);
884
877
error = mi_repair_parallel(¶m, file, fixed_name,
885
878
param.testflag & T_QUICK);
886
session->set_proc_info("Repair done"); // to reset proc_info, as
879
thd_proc_info(thd, "Repair done"); // to reset proc_info, as
887
880
// it was pointing to local buffer
891
session->set_proc_info("Repair by sorting");
884
thd_proc_info(thd, "Repair by sorting");
892
885
error = mi_repair_by_sort(¶m, file, fixed_name,
893
886
param.testflag & T_QUICK);
898
session->set_proc_info("Repair with keycache");
891
thd_proc_info(thd, "Repair with keycache");
899
892
param.testflag &= ~T_REP_BY_SORT;
900
893
error= mi_repair(¶m, file, fixed_name,
901
894
param.testflag & T_QUICK);
909
902
(share->state.changed & STATE_NOT_SORTED_PAGES))
912
session->set_proc_info("Sorting index");
905
thd_proc_info(thd, "Sorting index");
913
906
error=mi_sort_index(¶m,file,fixed_name);
915
908
if (!statistics_done && (local_testflag & T_STATISTICS))
917
910
if (share->state.changed & STATE_NOT_ANALYZED)
920
session->set_proc_info("Analyzing");
913
thd_proc_info(thd, "Analyzing");
921
914
error = chk_key(¶m, file);
924
917
local_testflag&= ~T_STATISTICS; // Don't update statistics
927
session->set_proc_info("Saving state");
920
thd_proc_info(thd, "Saving state");
930
923
if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
962
955
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
963
956
update_state_info(¶m, file, 0);
965
session->set_proc_info(old_proc_info);
966
if (!session->locked_tables)
958
thd_proc_info(thd, old_proc_info);
959
if (!thd->locked_tables)
967
960
mi_lock_database(file,F_UNLCK);
968
961
return(error ? HA_ADMIN_FAILED :
969
962
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
974
967
Assign table indexes to a specific key cache.
977
int ha_myisam::assign_to_keycache(Session* session, HA_CHECK_OPT *check_opt)
970
int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
979
972
KEY_CACHE *new_key_cache= check_opt->key_cache;
980
973
const char *errmsg= 0;
992
985
map= table->keys_in_use_for_query.to_uint64_t();
994
987
if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
996
989
char buf[STRING_BUFFER_USUAL_SIZE];
997
990
snprintf(buf, sizeof(buf),
998
991
"Failed to flush to index file (errno: %d)", error);
1110
1103
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1112
Session *session=current_session;
1105
THD *thd=current_thd;
1113
1106
MI_CHECK param;
1114
const char *save_proc_info= session->get_proc_info();
1115
session->set_proc_info("Creating index");
1107
const char *save_proc_info= thd->get_proc_info();
1108
thd_proc_info(thd, "Creating index");
1116
1109
myisamchk_init(¶m);
1117
1110
param.op_name= "recreating_index";
1118
1111
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
1119
1112
T_CREATE_MISSING_KEYS);
1120
1113
param.myf_rw&= ~MY_WAIT_IF_FULL;
1121
param.sort_buffer_length= session->variables.myisam_sort_buff_size;
1122
param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
1123
if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1114
param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
1115
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
1116
param.tmpdir=&mysql_tmpdir_list;
1117
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1125
1119
sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
1126
1120
my_errno, param.db_name, param.table_name);
1127
1121
/* Repairing by sort failed. Now try standard repair method. */
1128
1122
param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
1129
error= (repair(session,param,0) != HA_ADMIN_OK);
1123
error= (repair(thd,param,0) != HA_ADMIN_OK);
1131
1125
If the standard repair succeeded, clear all error messages which
1132
1126
might have been set by the first repair. They can still be seen
1133
1127
with SHOW WARNINGS then.
1136
session->clear_error();
1138
1132
info(HA_STATUS_CONST);
1139
session->set_proc_info(save_proc_info);
1133
thd_proc_info(thd, save_proc_info);
1186
1180
void ha_myisam::start_bulk_insert(ha_rows rows)
1188
Session *session= current_session;
1189
ulong size= cmin(session->variables.read_buff_size,
1182
THD *thd= current_thd;
1183
ulong size= min(thd->variables.read_buff_size,
1190
1184
(ulong) (table->s->avg_row_length*rows));
1192
1186
/* don't enable row cache if too few rows */
1209
1203
if (!file->bulk_insert &&
1210
1204
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1212
mi_init_bulk_insert(file, session->variables.bulk_insert_buff_size, rows);
1206
mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
1252
1246
check_opt.flags|=T_QUICK;
1253
1247
sql_print_warning("Checking table: '%s'",table->s->path.str);
1255
old_query= session->query;
1256
old_query_length= session->query_length;
1249
old_query= thd->query;
1250
old_query_length= thd->query_length;
1257
1251
pthread_mutex_lock(&LOCK_thread_count);
1258
session->query= table->s->table_name.str;
1259
session->query_length= table->s->table_name.length;
1252
thd->query= table->s->table_name.str;
1253
thd->query_length= table->s->table_name.length;
1260
1254
pthread_mutex_unlock(&LOCK_thread_count);
1262
if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
1256
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
1264
1258
sql_print_warning("Recovering table: '%s'",table->s->path.str);
1265
1259
check_opt.flags=
1267
1261
(marked_crashed ? 0 : T_QUICK) |
1268
1262
(myisam_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
1269
1263
T_AUTO_REPAIR);
1270
if (repair(session, &check_opt))
1264
if (repair(thd, &check_opt))
1273
1267
pthread_mutex_lock(&LOCK_thread_count);
1274
session->query= old_query;
1275
session->query_length= old_query_length;
1268
thd->query= old_query;
1269
thd->query_length= old_query_length;
1276
1270
pthread_mutex_unlock(&LOCK_thread_count);
1283
1277
(file->s->state.open_count));
1286
int ha_myisam::update_row(const unsigned char *old_data, unsigned char *new_data)
1280
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
1288
1282
ha_statistic_increment(&SSV::ha_update_count);
1289
1283
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1291
1285
return mi_update(file,old_data,new_data);
1294
int ha_myisam::delete_row(const unsigned char *buf)
1288
int ha_myisam::delete_row(const uchar *buf)
1296
1290
ha_statistic_increment(&SSV::ha_delete_count);
1297
1291
return mi_delete(file,buf);
1304
1296
bool index_cond_func_myisam(void *arg)
1313
1305
return (bool)h->pushed_idx_cond->val_int();
1321
int ha_myisam::index_init(uint32_t idx, bool sorted __attribute__((unused)))
1311
int ha_myisam::index_init(uint idx, bool sorted __attribute__((unused)))
1323
1313
active_index=idx;
1324
1314
//in_range_read= false;
1325
1315
if (pushed_idx_cond_keyno == idx)
1326
1316
mi_set_index_cond_func(file, index_cond_func_myisam, this);
1335
1325
mi_set_index_cond_func(file, NULL, 0);
1336
1326
in_range_check_pushed_down= false;
1337
1327
ds_mrr.dsmrr_close();
1342
uint32_t ha_myisam::index_flags(uint32_t inx, uint32_t, bool) const
1344
return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
1345
0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
1346
HA_READ_ORDER | HA_KEYREAD_ONLY |
1347
(keys_with_parts.is_set(inx)?0:HA_DO_INDEX_COND_PUSHDOWN));
1351
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
1332
int ha_myisam::index_read_map(uchar *buf, const uchar *key,
1352
1333
key_part_map keypart_map,
1353
1334
enum ha_rkey_function find_flag)
1362
int ha_myisam::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
1343
int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key,
1363
1344
key_part_map keypart_map,
1364
1345
enum ha_rkey_function find_flag)
1372
int ha_myisam::index_read_last_map(unsigned char *buf, const unsigned char *key,
1353
int ha_myisam::index_read_last_map(uchar *buf, const uchar *key,
1373
1354
key_part_map keypart_map)
1375
1356
assert(inited==INDEX);
1419
int ha_myisam::index_next_same(unsigned char *buf,
1420
const unsigned char *key __attribute__((unused)),
1421
uint32_t length __attribute__((unused)))
1400
int ha_myisam::index_next_same(uchar *buf,
1401
const uchar *key __attribute__((unused)),
1402
uint length __attribute__((unused)))
1424
1405
assert(inited==INDEX);
1464
1445
return mi_reset(file); // Free buffers
1467
int ha_myisam::rnd_next(unsigned char *buf)
1448
int ha_myisam::rnd_next(uchar *buf)
1469
1450
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1470
1451
int error=mi_scan(file, buf);
1475
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
1456
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
1477
1458
return rnd_pos(buf,pos);
1480
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
1461
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
1482
1463
ha_statistic_increment(&SSV::ha_read_rnd_count);
1483
1464
int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1489
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
1470
void ha_myisam::position(const uchar *record __attribute__((unused)))
1491
1472
my_off_t row_position= mi_position(file);
1492
1473
my_store_ptr(ref, ref_length, row_position);
1495
int ha_myisam::info(uint32_t flag)
1476
int ha_myisam::info(uint flag)
1497
1478
MI_ISAMINFO misam_info;
1498
1479
char name_buff[FN_REFLEN];
1595
int ha_myisam::external_lock(Session *session, int lock_type)
1576
int ha_myisam::external_lock(THD *thd, int lock_type)
1597
file->in_use.data= session;
1578
file->in_use.data= thd;
1598
1579
return mi_lock_database(file, !table->s->tmp_table ?
1599
1580
lock_type : ((lock_type == F_UNLCK) ?
1600
1581
F_UNLCK : F_EXTRA_LCK));
1603
THR_LOCK_DATA **ha_myisam::store_lock(Session *session __attribute__((unused)),
1584
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((unused)),
1604
1585
THR_LOCK_DATA **to,
1605
1586
enum thr_lock_type lock_type)
1626
1607
HA_CREATE_INFO *ha_create_info)
1629
uint32_t create_flags= 0, records;
1610
uint create_flags= 0, records;
1630
1611
char buff[FN_REFLEN];
1631
1612
MI_KEYDEF *keydef;
1632
1613
MI_COLUMNDEF *recinfo;
1633
1614
MI_CREATE_INFO create_info;
1634
1615
TABLE_SHARE *share= table_arg->s;
1635
uint32_t options= share->db_options_in_use;
1616
uint options= share->db_options_in_use;
1636
1617
if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1637
1618
return(error); /* purecov: inspected */
1638
1619
memset(&create_info, 0, sizeof(create_info));
1740
1721
HA_READ_KEY_EXACT Include the key in the range
1741
1722
HA_READ_AFTER_KEY Don't include key in range
1743
max_key.flag can have one of the following values:
1724
max_key.flag can have one of the following values:
1744
1725
HA_READ_BEFORE_KEY Don't include key in range
1745
1726
HA_READ_AFTER_KEY Include all 'end_key' values in the range
1754
ha_rows ha_myisam::records_in_range(uint32_t inx, key_range *min_key,
1735
ha_rows ha_myisam::records_in_range(uint inx, key_range *min_key,
1755
1736
key_range *max_key)
1757
1738
return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1761
uint32_t ha_myisam::checksum() const
1742
uint ha_myisam::checksum() const
1763
1744
return (uint)file->state->checksum;
1767
1748
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1768
uint32_t table_changes)
1770
uint32_t options= table->s->db_options_in_use;
1751
uint options= table->s->db_options_in_use;
1772
1753
if (info->auto_increment_value != stats.auto_increment_value ||
1773
1754
info->data_file_name != data_file_name ||
1798
1777
myisam_hton= (handlerton *)p;
1799
1778
myisam_hton->state= SHOW_OPTION_YES;
1779
myisam_hton->db_type= DB_TYPE_MYISAM;
1800
1780
myisam_hton->create= myisam_create_handler;
1801
1781
myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
1809
1789
***************************************************************************/
1811
1791
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1812
uint32_t n_ranges, uint32_t mode,
1792
uint n_ranges, uint mode,
1813
1793
HANDLER_BUFFER *buf)
1815
return ds_mrr.dsmrr_init(this, &table->key_info[active_index],
1795
return ds_mrr.dsmrr_init(this, &table->key_info[active_index],
1816
1796
seq, seq_init_param, n_ranges, mode, buf);
1821
1801
return ds_mrr.dsmrr_next(this, range_info);
1824
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1825
void *seq_init_param,
1826
uint32_t n_ranges, uint32_t *bufsz,
1827
uint32_t *flags, COST_VECT *cost)
1804
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
1805
void *seq_init_param,
1806
uint n_ranges, uint *bufsz,
1807
uint *flags, COST_VECT *cost)
1830
1810
This call is here because there is no location where this->table would
1839
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1840
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1819
int ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
1820
uint *bufsz, uint *flags, COST_VECT *cost)
1842
1822
ds_mrr.init(this, table);
1843
1823
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1849
1829
/* Index condition pushdown implementation*/
1852
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
1832
Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
1854
1834
pushed_idx_cond_keyno= keyno_arg;
1855
1835
pushed_idx_cond= idx_cond_arg;