~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/ha_myisam.cc

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
 
17
#ifdef USE_PRAGMA_IMPLEMENTATION
 
18
#pragma implementation                          // gcc: Class implementation
 
19
#endif
17
20
 
18
21
#define DRIZZLE_SERVER 1
19
22
 
22
25
#include <myisampack.h>
23
26
#include "ha_myisam.h"
24
27
#include "myisamdef.h"
25
 
#include <drizzled/util/test.h>
26
 
#include <drizzled/error.h>
27
 
#include <drizzled/gettext.h>
 
28
#include <drizzled/drizzled_error_messages.h>
28
29
 
29
30
ulong myisam_recover_options= HA_RECOVER_NONE;
30
31
 
31
32
/* bits in myisam_recover_options */
32
33
const char *myisam_recover_names[] =
33
 
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
 
34
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
34
35
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
35
36
                                 myisam_recover_names, NULL};
36
37
 
37
38
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
38
 
                                           "nulls_ignored", NULL};
 
39
                                           "nulls_ignored", NullS};
39
40
TYPELIB myisam_stats_method_typelib= {
40
41
  array_elements(myisam_stats_method_names) - 1, "",
41
42
  myisam_stats_method_names, NULL};
57
58
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
58
59
                               const char *fmt, va_list args)
59
60
{
60
 
  Session* session = (Session*)param->session;
61
 
  Protocol *protocol= session->protocol;
62
 
  uint32_t length, msg_length;
 
61
  THD* thd = (THD*)param->thd;
 
62
  Protocol *protocol= thd->protocol;
 
63
  uint length, msg_length;
63
64
  char msgbuf[MI_MAX_MSG_BUF];
64
65
  char name[NAME_LEN*2+2];
65
66
 
66
67
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
67
68
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
68
69
 
69
 
  if (!session->vio_ok())
 
70
  if (!thd->vio_ok())
70
71
  {
71
 
    sql_print_error("%s",msgbuf);
 
72
    sql_print_error(msgbuf);
72
73
    return;
73
74
  }
74
75
 
78
79
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
79
80
    return;
80
81
  }
81
 
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NULL) -
 
82
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
82
83
                 name);
83
84
  /*
84
85
    TODO: switch from protocol to push_warning here. The main reason we didn't
125
126
*/
126
127
 
127
128
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
128
 
                 MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
 
129
                 MI_COLUMNDEF **recinfo_out, uint *records_out)
129
130
{
130
 
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
 
131
  uint i, j, recpos, minpos, fieldpos, temp_length, length;
131
132
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
132
 
  unsigned char *record;
 
133
  uchar *record;
133
134
  KEY *pos;
134
135
  MI_KEYDEF *keydef;
135
136
  MI_COLUMNDEF *recinfo, *recinfo_pos;
136
137
  HA_KEYSEG *keyseg;
137
138
  TABLE_SHARE *share= table_arg->s;
138
 
  uint32_t options= share->db_options_in_use;
 
139
  uint options= share->db_options_in_use;
139
140
  if (!(my_multi_malloc(MYF(MY_WME),
140
141
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
141
142
          keydef_out, share->keys * sizeof(MI_KEYDEF),
142
143
          &keyseg,
143
144
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
144
 
          NULL)))
 
145
          NullS)))
145
146
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
146
147
  keydef= *keydef_out;
147
148
  recinfo= *recinfo_out;
189
190
      {
190
191
        keydef[i].seg[j].null_bit= field->null_bit;
191
192
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
192
 
                                           (unsigned char*) table_arg->record[0]);
 
193
                                           (uchar*) table_arg->record[0]);
193
194
      }
194
195
      else
195
196
      {
211
212
  record= table_arg->record[0];
212
213
  recpos= 0;
213
214
  recinfo_pos= recinfo;
214
 
  while (recpos < (uint) share->stored_rec_length)
 
215
  while (recpos < (uint) share->reclength)
215
216
  {
216
217
    Field **field, *found= 0;
217
218
    minpos= share->reclength;
257
258
    {
258
259
      recinfo_pos->null_bit= found->null_bit;
259
260
      recinfo_pos->null_pos= (uint) (found->null_ptr -
260
 
                                     (unsigned char*) table_arg->record[0]);
 
261
                                     (uchar*) table_arg->record[0]);
261
262
    }
262
263
    else
263
264
    {
313
314
*/
314
315
 
315
316
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
316
 
                     uint32_t t1_keys, uint32_t t1_recs,
 
317
                     uint t1_keys, uint t1_recs,
317
318
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
318
 
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
 
319
                     uint t2_keys, uint t2_recs, bool strict)
319
320
{
320
 
  uint32_t i, j;
 
321
  uint i, j;
321
322
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
322
323
  {
323
324
    return(1);
392
393
volatile int *killed_ptr(MI_CHECK *param)
393
394
{
394
395
  /* In theory Unsafe conversion, but should be ok for now */
395
 
  return (int*) &(((Session *)(param->session))->killed);
 
396
  return (int*) &(((THD *)(param->thd))->killed);
396
397
}
397
398
 
398
399
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
439
440
*/
440
441
 
441
442
void _mi_report_crashed(MI_INFO *file, const char *message,
442
 
                        const char *sfile, uint32_t sline)
 
443
                        const char *sfile, uint sline)
443
444
{
444
 
  Session *cur_session;
 
445
  THD *cur_thd;
445
446
  LIST *element;
446
447
  pthread_mutex_lock(&file->s->intern_lock);
447
 
  if ((cur_session= (Session*) file->in_use.data))
448
 
    sql_print_error(_("Got an error from thread_id=%"PRIu64", %s:%d"),
449
 
                    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,
450
450
                    sfile, sline);
451
451
  else
452
 
    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);
453
453
  if (message)
454
454
    sql_print_error("%s", message);
455
455
  for (element= file->s->in_use; element; element= list_rest(element))
456
456
  {
457
 
    sql_print_error("%s", _("Unknown thread accessing table"));
 
457
    sql_print_error("%s", "Unknown thread accessing table");
458
458
  }
459
459
  pthread_mutex_unlock(&file->s->intern_lock);
460
460
}
463
463
 
464
464
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
465
465
  :handler(hton, table_arg), file(0),
466
 
  int_table_flags(HA_NULL_IN_KEY |
467
 
                  HA_BINLOG_ROW_CAPABLE |
468
 
                  HA_BINLOG_STMT_CAPABLE |
469
 
                  HA_DUPLICATE_POS |
470
 
                  HA_CAN_INDEX_BLOBS |
471
 
                  HA_AUTO_PART_KEY |
472
 
                  HA_FILE_BASED |
473
 
                  HA_NO_TRANSACTIONS |
474
 
                  HA_HAS_RECORDS |
475
 
                  HA_STATS_RECORDS_IS_EXACT |
476
 
                  HA_NEED_READ_RANGE_BUFFER |
477
 
                  HA_MRR_CANT_SORT),
 
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),
478
473
   can_enable_indexes(1)
479
474
{}
480
475
 
490
485
static const char *ha_myisam_exts[] = {
491
486
  ".MYI",
492
487
  ".MYD",
493
 
  NULL
 
488
  NullS
494
489
};
495
490
 
496
491
const char **ha_myisam::bas_ext() const
499
494
}
500
495
 
501
496
 
502
 
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
 
497
const char *ha_myisam::index_type(uint key_number __attribute__((unused)))
503
498
{
504
499
  return "BTREE";
505
500
}
506
501
 
507
502
/* Name is here without an extension */
508
 
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)
509
504
{
510
505
  MI_KEYDEF *keyinfo;
511
506
  MI_COLUMNDEF *recinfo= 0;
512
 
  uint32_t recs;
513
 
  uint32_t i;
 
507
  uint recs;
 
508
  uint i;
514
509
 
515
510
  /*
516
511
    If the user wants to have memory mapped data files, add an
549
544
  }
550
545
  
551
546
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
552
 
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
 
547
    VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
553
548
 
554
549
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
555
550
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
556
 
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
 
551
    VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
557
552
  if (!table->s->db_record_offset)
558
553
    int_table_flags|=HA_REC_NOT_IN_SEQ;
559
554
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
585
580
    recinfo must be freed.
586
581
  */
587
582
  if (recinfo)
588
 
    free((unsigned char*) recinfo);
 
583
    my_free((uchar*) recinfo, MYF(0));
589
584
  return my_errno;
590
585
}
591
586
 
596
591
  return mi_close(tmp);
597
592
}
598
593
 
599
 
int ha_myisam::write_row(unsigned char *buf)
 
594
int ha_myisam::write_row(uchar *buf)
600
595
{
601
596
  ha_statistic_increment(&SSV::ha_write_count);
602
597
 
617
612
  return mi_write(file,buf);
618
613
}
619
614
 
620
 
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
 
615
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
621
616
{
622
617
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
623
618
  int error;
624
619
  MI_CHECK param;
625
620
  MYISAM_SHARE* share = file->s;
626
 
  const char *old_proc_info= session->get_proc_info();
 
621
  const char *old_proc_info= thd->get_proc_info();
627
622
 
628
 
  session->set_proc_info("Checking table");
 
623
  thd_proc_info(thd, "Checking table");
629
624
  myisamchk_init(&param);
630
 
  param.session = session;
 
625
  param.thd = thd;
631
626
  param.op_name =   "check";
632
627
  param.db_name=    table->s->db.str;
633
628
  param.table_name= table->alias;
634
629
  param.testflag = check_opt->flags | T_CHECK | T_SILENT;
635
 
  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;
636
631
 
637
632
  if (!(table->db_stat & HA_READ_ONLY))
638
633
    param.testflag|= T_STATISTICS;
661
656
          (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
662
657
        mi_is_crashed(file))
663
658
    {
664
 
      uint32_t old_testflag=param.testflag;
 
659
      uint old_testflag=param.testflag;
665
660
      param.testflag|=T_MEDIUM;
666
661
      if (!(error= init_io_cache(&param.read_cache, file->dfile,
667
662
                                 my_default_record_cache_size, READ_CACHE,
693
688
           HA_STATUS_CONST);
694
689
    }
695
690
  }
696
 
  else if (!mi_is_crashed(file) && !session->killed)
 
691
  else if (!mi_is_crashed(file) && !thd->killed)
697
692
  {
698
693
    mi_mark_crashed(file);
699
694
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
700
695
  }
701
696
 
702
 
  session->set_proc_info(old_proc_info);
 
697
  thd_proc_info(thd, old_proc_info);
703
698
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
704
699
}
705
700
 
710
705
  two threads may do an analyze at the same time!
711
706
*/
712
707
 
713
 
int ha_myisam::analyze(Session *session,
 
708
int ha_myisam::analyze(THD *thd,
714
709
                       HA_CHECK_OPT* check_opt __attribute__((unused)))
715
710
{
716
711
  int error=0;
718
713
  MYISAM_SHARE* share = file->s;
719
714
 
720
715
  myisamchk_init(&param);
721
 
  param.session = session;
 
716
  param.thd = thd;
722
717
  param.op_name=    "analyze";
723
718
  param.db_name=    table->s->db.str;
724
719
  param.table_name= table->alias;
725
720
  param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
726
721
                   T_DONT_CHECK_CHECKSUM);
727
722
  param.using_global_keycache = 1;
728
 
  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;
729
724
 
730
725
  if (!(share->state.changed & STATE_NOT_ANALYZED))
731
726
    return HA_ADMIN_ALREADY_DONE;
737
732
    error=update_state_info(&param,file,UPDATE_STAT);
738
733
    pthread_mutex_unlock(&share->intern_lock);
739
734
  }
740
 
  else if (!mi_is_crashed(file) && !session->killed)
 
735
  else if (!mi_is_crashed(file) && !thd->killed)
741
736
    mi_mark_crashed(file);
742
737
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
743
738
}
744
739
 
745
740
 
746
 
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
 
741
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
747
742
{
748
743
  int error;
749
744
  MI_CHECK param;
752
747
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
753
748
 
754
749
  myisamchk_init(&param);
755
 
  param.session = session;
 
750
  param.thd = thd;
756
751
  param.op_name=  "repair";
757
752
  param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
758
753
                   T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
759
754
                   (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
760
755
  param.sort_buffer_length=  check_opt->sort_buffer_size;
761
756
  start_records=file->state->records;
762
 
  while ((error=repair(session,param,0)) && param.retry_repair)
 
757
  while ((error=repair(thd,param,0)) && param.retry_repair)
763
758
  {
764
759
    param.retry_repair=0;
765
760
    if (test_all_bits(param.testflag,
792
787
  return error;
793
788
}
794
789
 
795
 
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
 
790
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
796
791
{
797
792
  int error;
798
793
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
799
794
  MI_CHECK param;
800
795
 
801
796
  myisamchk_init(&param);
802
 
  param.session = session;
 
797
  param.thd = thd;
803
798
  param.op_name= "optimize";
804
799
  param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
805
800
                   T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
806
801
  param.sort_buffer_length=  check_opt->sort_buffer_size;
807
 
  if ((error= repair(session,param,1)) && param.retry_repair)
 
802
  if ((error= repair(thd,param,1)) && param.retry_repair)
808
803
  {
809
804
    sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
810
805
                      my_errno, param.db_name, param.table_name);
811
806
    param.testflag&= ~T_REP_BY_SORT;
812
 
    error= repair(session,param,1);
 
807
    error= repair(thd,param,1);
813
808
  }
814
809
  return error;
815
810
}
816
811
 
817
812
 
818
 
int ha_myisam::repair(Session *session, MI_CHECK &param, bool do_optimize)
 
813
int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
819
814
{
820
815
  int error=0;
821
 
  uint32_t local_testflag=param.testflag;
 
816
  uint local_testflag=param.testflag;
822
817
  bool optimize_done= !do_optimize, statistics_done=0;
823
 
  const char *old_proc_info= session->get_proc_info();
 
818
  const char *old_proc_info= thd->get_proc_info();
824
819
  char fixed_name[FN_REFLEN];
825
820
  MYISAM_SHARE* share = file->s;
826
821
  ha_rows rows= file->state->records;
845
840
  param.table_name= table->alias;
846
841
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
847
842
  param.using_global_keycache = 1;
848
 
  param.session= session;
 
843
  param.thd= thd;
849
844
  param.tmpdir= &mysql_tmpdir_list;
850
845
  param.out_flag= 0;
851
 
  my_stpcpy(fixed_name,file->filename);
 
846
  stpcpy(fixed_name,file->filename);
852
847
 
853
848
  // Don't lock tables if we have used LOCK Table
854
 
  if (!session->locked_tables && 
 
849
  if (!thd->locked_tables && 
855
850
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
856
851
  {
857
852
    mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
866
861
    uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
867
862
                        mi_get_mask_all_keys_active(share->base.keys) :
868
863
                        share->state.key_map);
869
 
    uint32_t testflag=param.testflag;
 
864
    uint testflag=param.testflag;
870
865
    if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
871
866
        (local_testflag & T_REP_BY_SORT))
872
867
    {
873
868
      local_testflag|= T_STATISTICS;
874
869
      param.testflag|= T_STATISTICS;            // We get this for free
875
870
      statistics_done=1;
876
 
      if (session->variables.myisam_repair_threads>1)
 
871
      if (thd->variables.myisam_repair_threads>1)
877
872
      {
878
873
        char buf[40];
879
874
        /* TODO: respect myisam_repair_threads variable */
880
875
        snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
881
 
        session->set_proc_info(buf);
 
876
        thd_proc_info(thd, buf);
882
877
        error = mi_repair_parallel(&param, file, fixed_name,
883
878
            param.testflag & T_QUICK);
884
 
        session->set_proc_info("Repair done"); // to reset proc_info, as
 
879
        thd_proc_info(thd, "Repair done"); // to reset proc_info, as
885
880
                                      // it was pointing to local buffer
886
881
      }
887
882
      else
888
883
      {
889
 
        session->set_proc_info("Repair by sorting");
 
884
        thd_proc_info(thd, "Repair by sorting");
890
885
        error = mi_repair_by_sort(&param, file, fixed_name,
891
886
            param.testflag & T_QUICK);
892
887
      }
893
888
    }
894
889
    else
895
890
    {
896
 
      session->set_proc_info("Repair with keycache");
 
891
      thd_proc_info(thd, "Repair with keycache");
897
892
      param.testflag &= ~T_REP_BY_SORT;
898
893
      error=  mi_repair(&param, file, fixed_name,
899
894
                        param.testflag & T_QUICK);
907
902
        (share->state.changed & STATE_NOT_SORTED_PAGES))
908
903
    {
909
904
      optimize_done=1;
910
 
      session->set_proc_info("Sorting index");
 
905
      thd_proc_info(thd, "Sorting index");
911
906
      error=mi_sort_index(&param,file,fixed_name);
912
907
    }
913
908
    if (!statistics_done && (local_testflag & T_STATISTICS))
915
910
      if (share->state.changed & STATE_NOT_ANALYZED)
916
911
      {
917
912
        optimize_done=1;
918
 
        session->set_proc_info("Analyzing");
 
913
        thd_proc_info(thd, "Analyzing");
919
914
        error = chk_key(&param, file);
920
915
      }
921
916
      else
922
917
        local_testflag&= ~T_STATISTICS;         // Don't update statistics
923
918
    }
924
919
  }
925
 
  session->set_proc_info("Saving state");
 
920
  thd_proc_info(thd, "Saving state");
926
921
  if (!error)
927
922
  {
928
923
    if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
960
955
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
961
956
    update_state_info(&param, file, 0);
962
957
  }
963
 
  session->set_proc_info(old_proc_info);
964
 
  if (!session->locked_tables)
 
958
  thd_proc_info(thd, old_proc_info);
 
959
  if (!thd->locked_tables)
965
960
    mi_lock_database(file,F_UNLCK);
966
961
  return(error ? HA_ADMIN_FAILED :
967
962
              !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
972
967
  Assign table indexes to a specific key cache.
973
968
*/
974
969
 
975
 
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)
976
971
{
977
972
  KEY_CACHE *new_key_cache= check_opt->key_cache;
978
973
  const char *errmsg= 0;
1003
998
    /* Send error to user */
1004
999
    MI_CHECK param;
1005
1000
    myisamchk_init(&param);
1006
 
    param.session= session;
 
1001
    param.thd= thd;
1007
1002
    param.op_name=    "assign_to_keycache";
1008
1003
    param.db_name=    table->s->db.str;
1009
1004
    param.table_name= table->s->table_name.str;
1034
1029
    HA_ERR_WRONG_COMMAND  mode not implemented.
1035
1030
*/
1036
1031
 
1037
 
int ha_myisam::disable_indexes(uint32_t mode)
 
1032
int ha_myisam::disable_indexes(uint mode)
1038
1033
{
1039
1034
  int error;
1040
1035
 
1086
1081
    HA_ERR_WRONG_COMMAND  mode not implemented.
1087
1082
*/
1088
1083
 
1089
 
int ha_myisam::enable_indexes(uint32_t mode)
 
1084
int ha_myisam::enable_indexes(uint mode)
1090
1085
{
1091
1086
  int error;
1092
1087
 
1107
1102
  }
1108
1103
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1109
1104
  {
1110
 
    Session *session=current_session;
 
1105
    THD *thd=current_thd;
1111
1106
    MI_CHECK param;
1112
 
    const char *save_proc_info= session->get_proc_info();
1113
 
    session->set_proc_info("Creating index");
 
1107
    const char *save_proc_info= thd->get_proc_info();
 
1108
    thd_proc_info(thd, "Creating index");
1114
1109
    myisamchk_init(&param);
1115
1110
    param.op_name= "recreating_index";
1116
1111
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
1117
1112
                     T_CREATE_MISSING_KEYS);
1118
1113
    param.myf_rw&= ~MY_WAIT_IF_FULL;
1119
 
    param.sort_buffer_length=  session->variables.myisam_sort_buff_size;
1120
 
    param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
 
1114
    param.sort_buffer_length=  thd->variables.myisam_sort_buff_size;
 
1115
    param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
1121
1116
    param.tmpdir=&mysql_tmpdir_list;
1122
 
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
 
1117
    if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1123
1118
    {
1124
1119
      sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
1125
1120
                        my_errno, param.db_name, param.table_name);
1126
1121
      /* Repairing by sort failed. Now try standard repair method. */
1127
1122
      param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
1128
 
      error= (repair(session,param,0) != HA_ADMIN_OK);
 
1123
      error= (repair(thd,param,0) != HA_ADMIN_OK);
1129
1124
      /*
1130
1125
        If the standard repair succeeded, clear all error messages which
1131
1126
        might have been set by the first repair. They can still be seen
1132
1127
        with SHOW WARNINGS then.
1133
1128
      */
1134
1129
      if (! error)
1135
 
        session->clear_error();
 
1130
        thd->clear_error();
1136
1131
    }
1137
1132
    info(HA_STATUS_CONST);
1138
 
    session->set_proc_info(save_proc_info);
 
1133
    thd_proc_info(thd, save_proc_info);
1139
1134
  }
1140
1135
  else
1141
1136
  {
1184
1179
 
1185
1180
void ha_myisam::start_bulk_insert(ha_rows rows)
1186
1181
{
1187
 
  Session *session= current_session;
1188
 
  ulong size= cmin(session->variables.read_buff_size,
 
1182
  THD *thd= current_thd;
 
1183
  ulong size= min(thd->variables.read_buff_size,
1189
1184
                  (ulong) (table->s->avg_row_length*rows));
1190
1185
 
1191
1186
  /* don't enable row cache if too few rows */
1208
1203
    if (!file->bulk_insert &&
1209
1204
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1210
1205
    {
1211
 
      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);
1212
1207
    }
1213
1208
 
1214
1209
  return;
1236
1231
}
1237
1232
 
1238
1233
 
1239
 
bool ha_myisam::check_and_repair(Session *session)
 
1234
bool ha_myisam::check_and_repair(THD *thd)
1240
1235
{
1241
1236
  int error=0;
1242
1237
  int marked_crashed;
1243
1238
  char *old_query;
1244
 
  uint32_t old_query_length;
 
1239
  uint old_query_length;
1245
1240
  HA_CHECK_OPT check_opt;
1246
1241
 
1247
1242
  check_opt.init();
1251
1246
    check_opt.flags|=T_QUICK;
1252
1247
  sql_print_warning("Checking table:   '%s'",table->s->path.str);
1253
1248
 
1254
 
  old_query= session->query;
1255
 
  old_query_length= session->query_length;
 
1249
  old_query= thd->query;
 
1250
  old_query_length= thd->query_length;
1256
1251
  pthread_mutex_lock(&LOCK_thread_count);
1257
 
  session->query=        table->s->table_name.str;
1258
 
  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;
1259
1254
  pthread_mutex_unlock(&LOCK_thread_count);
1260
1255
 
1261
 
  if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
 
1256
  if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
1262
1257
  {
1263
1258
    sql_print_warning("Recovering table: '%s'",table->s->path.str);
1264
1259
    check_opt.flags=
1266
1261
       (marked_crashed                             ? 0 : T_QUICK) |
1267
1262
       (myisam_recover_options & HA_RECOVER_FORCE  ? 0 : T_SAFE_REPAIR) |
1268
1263
       T_AUTO_REPAIR);
1269
 
    if (repair(session, &check_opt))
 
1264
    if (repair(thd, &check_opt))
1270
1265
      error=1;
1271
1266
  }
1272
1267
  pthread_mutex_lock(&LOCK_thread_count);
1273
 
  session->query= old_query;
1274
 
  session->query_length= old_query_length;
 
1268
  thd->query= old_query;
 
1269
  thd->query_length= old_query_length;
1275
1270
  pthread_mutex_unlock(&LOCK_thread_count);
1276
1271
  return(error);
1277
1272
}
1282
1277
          (file->s->state.open_count));
1283
1278
}
1284
1279
 
1285
 
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)
1286
1281
{
1287
1282
  ha_statistic_increment(&SSV::ha_update_count);
1288
1283
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1290
1285
  return mi_update(file,old_data,new_data);
1291
1286
}
1292
1287
 
1293
 
int ha_myisam::delete_row(const unsigned char *buf)
 
1288
int ha_myisam::delete_row(const uchar *buf)
1294
1289
{
1295
1290
  ha_statistic_increment(&SSV::ha_delete_count);
1296
1291
  return mi_delete(file,buf);
1297
1292
}
1298
1293
 
1299
 
#ifdef __cplusplus
1300
 
extern "C" {
1301
 
#endif
 
1294
C_MODE_START
1302
1295
 
1303
1296
bool index_cond_func_myisam(void *arg)
1304
1297
{
1312
1305
  return (bool)h->pushed_idx_cond->val_int();
1313
1306
}
1314
1307
 
1315
 
#ifdef __cplusplus
1316
 
}
1317
 
#endif
1318
 
 
1319
 
 
1320
 
int ha_myisam::index_init(uint32_t idx, bool sorted __attribute__((unused)))
 
1308
C_MODE_END
 
1309
 
 
1310
 
 
1311
int ha_myisam::index_init(uint idx, bool sorted __attribute__((unused)))
1321
1312
1322
1313
  active_index=idx;
1323
1314
  //in_range_read= false;
1338
1329
}
1339
1330
 
1340
1331
 
1341
 
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,
1342
1333
                              key_part_map keypart_map,
1343
1334
                              enum ha_rkey_function find_flag)
1344
1335
{
1349
1340
  return error;
1350
1341
}
1351
1342
 
1352
 
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,
1353
1344
                                  key_part_map keypart_map,
1354
1345
                                  enum ha_rkey_function find_flag)
1355
1346
{
1359
1350
  return error;
1360
1351
}
1361
1352
 
1362
 
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,
1363
1354
                                   key_part_map keypart_map)
1364
1355
{
1365
1356
  assert(inited==INDEX);
1370
1361
  return(error);
1371
1362
}
1372
1363
 
1373
 
int ha_myisam::index_next(unsigned char *buf)
 
1364
int ha_myisam::index_next(uchar *buf)
1374
1365
{
1375
1366
  assert(inited==INDEX);
1376
1367
  ha_statistic_increment(&SSV::ha_read_next_count);
1379
1370
  return error;
1380
1371
}
1381
1372
 
1382
 
int ha_myisam::index_prev(unsigned char *buf)
 
1373
int ha_myisam::index_prev(uchar *buf)
1383
1374
{
1384
1375
  assert(inited==INDEX);
1385
1376
  ha_statistic_increment(&SSV::ha_read_prev_count);
1388
1379
  return error;
1389
1380
}
1390
1381
 
1391
 
int ha_myisam::index_first(unsigned char *buf)
 
1382
int ha_myisam::index_first(uchar *buf)
1392
1383
{
1393
1384
  assert(inited==INDEX);
1394
1385
  ha_statistic_increment(&SSV::ha_read_first_count);
1397
1388
  return error;
1398
1389
}
1399
1390
 
1400
 
int ha_myisam::index_last(unsigned char *buf)
 
1391
int ha_myisam::index_last(uchar *buf)
1401
1392
{
1402
1393
  assert(inited==INDEX);
1403
1394
  ha_statistic_increment(&SSV::ha_read_last_count);
1406
1397
  return error;
1407
1398
}
1408
1399
 
1409
 
int ha_myisam::index_next_same(unsigned char *buf,
1410
 
                               const unsigned char *key __attribute__((unused)),
1411
 
                               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)))
1412
1403
{
1413
1404
  int error;
1414
1405
  assert(inited==INDEX);
1454
1445
  return mi_reset(file);                        // Free buffers
1455
1446
}
1456
1447
 
1457
 
int ha_myisam::rnd_next(unsigned char *buf)
 
1448
int ha_myisam::rnd_next(uchar *buf)
1458
1449
{
1459
1450
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1460
1451
  int error=mi_scan(file, buf);
1462
1453
  return error;
1463
1454
}
1464
1455
 
1465
 
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
 
1456
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
1466
1457
{
1467
1458
  return rnd_pos(buf,pos);
1468
1459
}
1469
1460
 
1470
 
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
 
1461
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
1471
1462
{
1472
1463
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1473
1464
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1476
1467
}
1477
1468
 
1478
1469
 
1479
 
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
 
1470
void ha_myisam::position(const uchar *record __attribute__((unused)))
1480
1471
{
1481
1472
  my_off_t row_position= mi_position(file);
1482
1473
  my_store_ptr(ref, ref_length, row_position);
1483
1474
}
1484
1475
 
1485
 
int ha_myisam::info(uint32_t flag)
 
1476
int ha_myisam::info(uint flag)
1486
1477
{
1487
1478
  MI_ISAMINFO misam_info;
1488
1479
  char name_buff[FN_REFLEN];
1582
1573
}
1583
1574
 
1584
1575
 
1585
 
int ha_myisam::external_lock(Session *session, int lock_type)
 
1576
int ha_myisam::external_lock(THD *thd, int lock_type)
1586
1577
{
1587
 
  file->in_use.data= session;
 
1578
  file->in_use.data= thd;
1588
1579
  return mi_lock_database(file, !table->s->tmp_table ?
1589
1580
                          lock_type : ((lock_type == F_UNLCK) ?
1590
1581
                                       F_UNLCK : F_EXTRA_LCK));
1591
1582
}
1592
1583
 
1593
 
THR_LOCK_DATA **ha_myisam::store_lock(Session *session __attribute__((unused)),
 
1584
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((unused)),
1594
1585
                                      THR_LOCK_DATA **to,
1595
1586
                                      enum thr_lock_type lock_type)
1596
1587
{
1616
1607
                      HA_CREATE_INFO *ha_create_info)
1617
1608
{
1618
1609
  int error;
1619
 
  uint32_t create_flags= 0, records;
 
1610
  uint create_flags= 0, records;
1620
1611
  char buff[FN_REFLEN];
1621
1612
  MI_KEYDEF *keydef;
1622
1613
  MI_COLUMNDEF *recinfo;
1623
1614
  MI_CREATE_INFO create_info;
1624
1615
  TABLE_SHARE *share= table_arg->s;
1625
 
  uint32_t options= share->db_options_in_use;
 
1616
  uint options= share->db_options_in_use;
1626
1617
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1627
1618
    return(error); /* purecov: inspected */
1628
1619
  memset(&create_info, 0, sizeof(create_info));
1656
1647
                   records, recinfo,
1657
1648
                   0, (MI_UNIQUEDEF*) 0,
1658
1649
                   &create_info, create_flags);
1659
 
  free((unsigned char*) recinfo);
 
1650
  my_free((uchar*) recinfo, MYF(0));
1660
1651
  return(error);
1661
1652
}
1662
1653
 
1675
1666
{
1676
1667
  uint64_t nr;
1677
1668
  int error;
1678
 
  unsigned char key[MI_MAX_KEY_LENGTH];
 
1669
  uchar key[MI_MAX_KEY_LENGTH];
1679
1670
 
1680
1671
  if (!table->s->next_number_key_offset)
1681
1672
  {                                             // Autoincrement at key-start
1741
1732
                        the range.
1742
1733
*/
1743
1734
 
1744
 
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,
1745
1736
                                    key_range *max_key)
1746
1737
{
1747
1738
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1748
1739
}
1749
1740
 
1750
1741
 
1751
 
uint32_t ha_myisam::checksum() const
 
1742
uint ha_myisam::checksum() const
1752
1743
{
1753
1744
  return (uint)file->state->checksum;
1754
1745
}
1755
1746
 
1756
1747
 
1757
1748
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1758
 
                                           uint32_t table_changes)
 
1749
                                           uint table_changes)
1759
1750
{
1760
 
  uint32_t options= table->s->db_options_in_use;
 
1751
  uint options= table->s->db_options_in_use;
1761
1752
 
1762
1753
  if (info->auto_increment_value != stats.auto_increment_value ||
1763
1754
      info->data_file_name != data_file_name ||
1785
1776
 
1786
1777
  myisam_hton= (handlerton *)p;
1787
1778
  myisam_hton->state= SHOW_OPTION_YES;
 
1779
  myisam_hton->db_type= DB_TYPE_MYISAM;
1788
1780
  myisam_hton->create= myisam_create_handler;
1789
1781
  myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
1790
1782
  return 0;
1797
1789
 ***************************************************************************/
1798
1790
 
1799
1791
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1800
 
                                     uint32_t n_ranges, uint32_t mode, 
 
1792
                                     uint n_ranges, uint mode, 
1801
1793
                                     HANDLER_BUFFER *buf)
1802
1794
{
1803
1795
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index], 
1809
1801
  return ds_mrr.dsmrr_next(this, range_info);
1810
1802
}
1811
1803
 
1812
 
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
1804
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
1813
1805
                                               void *seq_init_param, 
1814
 
                                               uint32_t n_ranges, uint32_t *bufsz,
1815
 
                                               uint32_t *flags, COST_VECT *cost)
 
1806
                                               uint n_ranges, uint *bufsz,
 
1807
                                               uint *flags, COST_VECT *cost)
1816
1808
{
1817
1809
  /*
1818
1810
    This call is here because there is no location where this->table would
1824
1816
                                 flags, cost);
1825
1817
}
1826
1818
 
1827
 
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1828
 
                                     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)
1829
1821
{
1830
1822
  ds_mrr.init(this, table);
1831
1823
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1837
1829
/* Index condition pushdown implementation*/
1838
1830
 
1839
1831
 
1840
 
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)
1841
1833
{
1842
1834
  pushed_idx_cond_keyno= keyno_arg;
1843
1835
  pushed_idx_cond= idx_cond_arg;