~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-12 06:42:41 UTC
  • mto: (322.2.8 stdize-code)
  • mto: This revision was merged to the branch mainline in revision 386.
  • Revision ID: brian@tangent.org-20080912064241-520utxq2078904l2
Remove 3 byte UTF8 collation

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
 
20
 
 
21
#define DRIZZLE_SERVER 1
17
22
 
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>
30
29
 
31
30
ulong myisam_recover_options= HA_RECOVER_NONE;
32
 
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
33
31
 
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};
39
37
 
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};
49
47
*****************************************************************************/
50
48
 
51
49
static handler *myisam_create_handler(handlerton *hton,
52
 
                                      TABLE_SHARE *table,
 
50
                                      TABLE_SHARE *table, 
53
51
                                      MEM_ROOT *mem_root)
54
52
{
55
53
  return new (mem_root) ha_myisam(hton, table);
58
56
// collect errors printed by mi_check routines
59
57
 
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)
62
60
{
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];
68
66
 
69
67
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
70
68
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
71
69
 
72
 
  if (!session->vio_ok())
 
70
  if (!thd->vio_ok())
73
71
  {
74
 
    sql_print_error("%s",msgbuf);
 
72
    sql_print_error(msgbuf);
75
73
    return;
76
74
  }
77
75
 
81
79
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
82
80
    return;
83
81
  }
84
 
  length= sprintf(name,"%s.%s",param->db_name,param->table_name);
85
 
 
 
82
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
 
83
                 name);
86
84
  /*
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:
128
126
*/
129
127
 
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)
132
130
{
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;
 
133
  uchar *record;
136
134
  KEY *pos;
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),
145
143
          &keyseg,
146
144
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
147
 
          NULL)))
 
145
          NullS)))
148
146
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
149
147
  keydef= *keydef_out;
150
148
  recinfo= *recinfo_out;
192
190
      {
193
191
        keydef[i].seg[j].null_bit= field->null_bit;
194
192
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
195
 
                                           (unsigned char*) table_arg->record[0]);
 
193
                                           (uchar*) table_arg->record[0]);
196
194
      }
197
195
      else
198
196
      {
214
212
  record= table_arg->record[0];
215
213
  recpos= 0;
216
214
  recinfo_pos= recinfo;
217
 
  while (recpos < (uint) share->stored_rec_length)
 
215
  while (recpos < (uint) share->reclength)
218
216
  {
219
217
    Field **field, *found= 0;
220
218
    minpos= share->reclength;
260
258
    {
261
259
      recinfo_pos->null_bit= found->null_bit;
262
260
      recinfo_pos->null_pos= (uint) (found->null_ptr -
263
 
                                     (unsigned char*) table_arg->record[0]);
 
261
                                     (uchar*) table_arg->record[0]);
264
262
    }
265
263
    else
266
264
    {
316
314
*/
317
315
 
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)
322
320
{
323
 
  uint32_t i, j;
 
321
  uint i, j;
324
322
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
325
323
  {
326
324
    return(1);
395
393
volatile int *killed_ptr(MI_CHECK *param)
396
394
{
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);
399
397
}
400
398
 
401
399
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
442
440
*/
443
441
 
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)
446
444
{
447
 
  Session *cur_session;
 
445
  THD *cur_thd;
448
446
  LIST *element;
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,
453
450
                    sfile, sline);
454
451
  else
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);
456
453
  if (message)
457
454
    sql_print_error("%s", message);
458
455
  for (element= file->s->in_use; element; element= list_rest(element))
459
456
  {
460
 
    sql_print_error("%s", _("Unknown thread accessing table"));
 
457
    sql_print_error("%s", "Unknown thread accessing table");
461
458
  }
462
459
  pthread_mutex_unlock(&file->s->intern_lock);
463
460
}
466
463
 
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 |
472
 
                  HA_DUPLICATE_POS |
473
 
                  HA_CAN_INDEX_BLOBS |
474
 
                  HA_AUTO_PART_KEY |
475
 
                  HA_FILE_BASED |
476
 
                  HA_NO_TRANSACTIONS |
477
 
                  HA_HAS_RECORDS |
478
 
                  HA_STATS_RECORDS_IS_EXACT |
479
 
                  HA_NEED_READ_RANGE_BUFFER |
480
 
                  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),
481
473
   can_enable_indexes(1)
482
474
{}
483
475
 
493
485
static const char *ha_myisam_exts[] = {
494
486
  ".MYI",
495
487
  ".MYD",
496
 
  NULL
 
488
  NullS
497
489
};
498
490
 
499
491
const char **ha_myisam::bas_ext() const
502
494
}
503
495
 
504
496
 
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)))
506
498
{
507
499
  return "BTREE";
508
500
}
509
501
 
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)
512
504
{
513
505
  MI_KEYDEF *keyinfo;
514
506
  MI_COLUMNDEF *recinfo= 0;
515
 
  uint32_t recs;
516
 
  uint32_t i;
 
507
  uint recs;
 
508
  uint i;
517
509
 
518
510
  /*
519
511
    If the user wants to have memory mapped data files, add an
550
542
      /* purecov: end */
551
543
    }
552
544
  }
553
 
 
 
545
  
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));
556
548
 
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;
564
 
 
 
556
  
565
557
  keys_with_parts.clear_all();
566
558
  for (i= 0; i < table->s->keys; i++)
567
559
  {
588
580
    recinfo must be freed.
589
581
  */
590
582
  if (recinfo)
591
 
    free((unsigned char*) recinfo);
 
583
    my_free((uchar*) recinfo, MYF(0));
592
584
  return my_errno;
593
585
}
594
586
 
599
591
  return mi_close(tmp);
600
592
}
601
593
 
602
 
int ha_myisam::write_row(unsigned char *buf)
 
594
int ha_myisam::write_row(uchar *buf)
603
595
{
604
596
  ha_statistic_increment(&SSV::ha_write_count);
605
597
 
620
612
  return mi_write(file,buf);
621
613
}
622
614
 
623
 
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
 
615
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
624
616
{
625
617
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
626
618
  int error;
627
619
  MI_CHECK param;
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();
630
622
 
631
 
  session->set_proc_info("Checking table");
 
623
  thd_proc_info(thd, "Checking table");
632
624
  myisamchk_init(&param);
633
 
  param.session = session;
 
625
  param.thd = thd;
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;
639
631
 
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))
666
658
    {
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(&param.read_cache, file->dfile,
670
662
                                 my_default_record_cache_size, READ_CACHE,
696
688
           HA_STATUS_CONST);
697
689
    }
698
690
  }
699
 
  else if (!mi_is_crashed(file) && !session->killed)
 
691
  else if (!mi_is_crashed(file) && !thd->killed)
700
692
  {
701
693
    mi_mark_crashed(file);
702
694
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
703
695
  }
704
696
 
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;
707
699
}
708
700
 
713
705
  two threads may do an analyze at the same time!
714
706
*/
715
707
 
716
 
int ha_myisam::analyze(Session *session,
 
708
int ha_myisam::analyze(THD *thd,
717
709
                       HA_CHECK_OPT* check_opt __attribute__((unused)))
718
710
{
719
711
  int error=0;
721
713
  MYISAM_SHARE* share = file->s;
722
714
 
723
715
  myisamchk_init(&param);
724
 
  param.session = session;
 
716
  param.thd = thd;
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;
732
724
 
733
725
  if (!(share->state.changed & STATE_NOT_ANALYZED))
734
726
    return HA_ADMIN_ALREADY_DONE;
740
732
    error=update_state_info(&param,file,UPDATE_STAT);
741
733
    pthread_mutex_unlock(&share->intern_lock);
742
734
  }
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;
746
738
}
747
739
 
748
740
 
749
 
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
 
741
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
750
742
{
751
743
  int error;
752
744
  MI_CHECK param;
755
747
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
756
748
 
757
749
  myisamchk_init(&param);
758
 
  param.session = session;
 
750
  param.thd = thd;
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)
766
758
  {
767
759
    param.retry_repair=0;
768
760
    if (test_all_bits(param.testflag,
795
787
  return error;
796
788
}
797
789
 
798
 
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
 
790
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
799
791
{
800
792
  int error;
801
793
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
802
794
  MI_CHECK param;
803
795
 
804
796
  myisamchk_init(&param);
805
 
  param.session = session;
 
797
  param.thd = thd;
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)
811
803
  {
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);
816
808
  }
817
809
  return error;
818
810
}
819
811
 
820
812
 
821
 
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)
822
814
{
823
815
  int error=0;
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;
 
843
  param.thd= thd;
 
844
  param.tmpdir= &mysql_tmpdir_list;
852
845
  param.out_flag= 0;
853
 
  strcpy(fixed_name,file->filename);
 
846
  stpcpy(fixed_name,file->filename);
854
847
 
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))
858
851
  {
859
852
    mi_check_print_error(&param,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))
874
867
    {
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)
879
872
      {
880
873
        char buf[40];
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(&param, 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
888
881
      }
889
882
      else
890
883
      {
891
 
        session->set_proc_info("Repair by sorting");
 
884
        thd_proc_info(thd, "Repair by sorting");
892
885
        error = mi_repair_by_sort(&param, file, fixed_name,
893
886
            param.testflag & T_QUICK);
894
887
      }
895
888
    }
896
889
    else
897
890
    {
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(&param, file, fixed_name,
901
894
                        param.testflag & T_QUICK);
909
902
        (share->state.changed & STATE_NOT_SORTED_PAGES))
910
903
    {
911
904
      optimize_done=1;
912
 
      session->set_proc_info("Sorting index");
 
905
      thd_proc_info(thd, "Sorting index");
913
906
      error=mi_sort_index(&param,file,fixed_name);
914
907
    }
915
908
    if (!statistics_done && (local_testflag & T_STATISTICS))
917
910
      if (share->state.changed & STATE_NOT_ANALYZED)
918
911
      {
919
912
        optimize_done=1;
920
 
        session->set_proc_info("Analyzing");
 
913
        thd_proc_info(thd, "Analyzing");
921
914
        error = chk_key(&param, file);
922
915
      }
923
916
      else
924
917
        local_testflag&= ~T_STATISTICS;         // Don't update statistics
925
918
    }
926
919
  }
927
 
  session->set_proc_info("Saving state");
 
920
  thd_proc_info(thd, "Saving state");
928
921
  if (!error)
929
922
  {
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(&param, file, 0);
964
957
  }
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.
975
968
*/
976
969
 
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)
978
971
{
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();
993
986
 
994
987
  if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
995
 
  {
 
988
  { 
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);
1005
998
    /* Send error to user */
1006
999
    MI_CHECK param;
1007
1000
    myisamchk_init(&param);
1008
 
    param.session= session;
 
1001
    param.thd= thd;
1009
1002
    param.op_name=    "assign_to_keycache";
1010
1003
    param.db_name=    table->s->db.str;
1011
1004
    param.table_name= table->s->table_name.str;
1036
1029
    HA_ERR_WRONG_COMMAND  mode not implemented.
1037
1030
*/
1038
1031
 
1039
 
int ha_myisam::disable_indexes(uint32_t mode)
 
1032
int ha_myisam::disable_indexes(uint mode)
1040
1033
{
1041
1034
  int error;
1042
1035
 
1088
1081
    HA_ERR_WRONG_COMMAND  mode not implemented.
1089
1082
*/
1090
1083
 
1091
 
int ha_myisam::enable_indexes(uint32_t mode)
 
1084
int ha_myisam::enable_indexes(uint mode)
1092
1085
{
1093
1086
  int error;
1094
1087
 
1109
1102
  }
1110
1103
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1111
1104
  {
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(&param);
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)
1124
1118
    {
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);
1130
1124
      /*
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.
1134
1128
      */
1135
1129
      if (! error)
1136
 
        session->clear_error();
 
1130
        thd->clear_error();
1137
1131
    }
1138
1132
    info(HA_STATUS_CONST);
1139
 
    session->set_proc_info(save_proc_info);
 
1133
    thd_proc_info(thd, save_proc_info);
1140
1134
  }
1141
1135
  else
1142
1136
  {
1164
1158
 
1165
1159
int ha_myisam::indexes_are_disabled(void)
1166
1160
{
1167
 
 
 
1161
  
1168
1162
  return mi_indexes_are_disabled(file);
1169
1163
}
1170
1164
 
1185
1179
 
1186
1180
void ha_myisam::start_bulk_insert(ha_rows rows)
1187
1181
{
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));
1191
1185
 
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))
1211
1205
    {
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);
1213
1207
    }
1214
1208
 
1215
1209
  return;
1237
1231
}
1238
1232
 
1239
1233
 
1240
 
bool ha_myisam::check_and_repair(Session *session)
 
1234
bool ha_myisam::check_and_repair(THD *thd)
1241
1235
{
1242
1236
  int error=0;
1243
1237
  int marked_crashed;
1244
1238
  char *old_query;
1245
 
  uint32_t old_query_length;
 
1239
  uint old_query_length;
1246
1240
  HA_CHECK_OPT check_opt;
1247
1241
 
1248
1242
  check_opt.init();
1252
1246
    check_opt.flags|=T_QUICK;
1253
1247
  sql_print_warning("Checking table:   '%s'",table->s->path.str);
1254
1248
 
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);
1261
1255
 
1262
 
  if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
 
1256
  if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
1263
1257
  {
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))
1271
1265
      error=1;
1272
1266
  }
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);
1277
1271
  return(error);
1278
1272
}
1283
1277
          (file->s->state.open_count));
1284
1278
}
1285
1279
 
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)
1287
1281
{
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);
1292
1286
}
1293
1287
 
1294
 
int ha_myisam::delete_row(const unsigned char *buf)
 
1288
int ha_myisam::delete_row(const uchar *buf)
1295
1289
{
1296
1290
  ha_statistic_increment(&SSV::ha_delete_count);
1297
1291
  return mi_delete(file,buf);
1298
1292
}
1299
1293
 
1300
 
#ifdef __cplusplus
1301
 
extern "C" {
1302
 
#endif
 
1294
C_MODE_START
1303
1295
 
1304
1296
bool index_cond_func_myisam(void *arg)
1305
1297
{
1313
1305
  return (bool)h->pushed_idx_cond->val_int();
1314
1306
}
1315
1307
 
1316
 
#ifdef __cplusplus
1317
 
}
1318
 
#endif
1319
 
 
1320
 
 
1321
 
int ha_myisam::index_init(uint32_t idx, bool sorted __attribute__((unused)))
1322
 
{
 
1308
C_MODE_END
 
1309
 
 
1310
 
 
1311
int ha_myisam::index_init(uint idx, bool sorted __attribute__((unused)))
 
1312
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);
1327
 
  return 0;
 
1317
  return 0; 
1328
1318
}
1329
1319
 
1330
1320
 
1335
1325
  mi_set_index_cond_func(file, NULL, 0);
1336
1326
  in_range_check_pushed_down= false;
1337
1327
  ds_mrr.dsmrr_close();
1338
 
  return 0;
1339
 
}
1340
 
 
1341
 
 
1342
 
uint32_t ha_myisam::index_flags(uint32_t inx, uint32_t, bool) const
1343
 
{
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));
1348
 
}
1349
 
 
1350
 
 
1351
 
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
 
1328
  return 0; 
 
1329
}
 
1330
 
 
1331
 
 
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)
1354
1335
{
1359
1340
  return error;
1360
1341
}
1361
1342
 
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)
1365
1346
{
1369
1350
  return error;
1370
1351
}
1371
1352
 
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)
1374
1355
{
1375
1356
  assert(inited==INDEX);
1380
1361
  return(error);
1381
1362
}
1382
1363
 
1383
 
int ha_myisam::index_next(unsigned char *buf)
 
1364
int ha_myisam::index_next(uchar *buf)
1384
1365
{
1385
1366
  assert(inited==INDEX);
1386
1367
  ha_statistic_increment(&SSV::ha_read_next_count);
1389
1370
  return error;
1390
1371
}
1391
1372
 
1392
 
int ha_myisam::index_prev(unsigned char *buf)
 
1373
int ha_myisam::index_prev(uchar *buf)
1393
1374
{
1394
1375
  assert(inited==INDEX);
1395
1376
  ha_statistic_increment(&SSV::ha_read_prev_count);
1398
1379
  return error;
1399
1380
}
1400
1381
 
1401
 
int ha_myisam::index_first(unsigned char *buf)
 
1382
int ha_myisam::index_first(uchar *buf)
1402
1383
{
1403
1384
  assert(inited==INDEX);
1404
1385
  ha_statistic_increment(&SSV::ha_read_first_count);
1407
1388
  return error;
1408
1389
}
1409
1390
 
1410
 
int ha_myisam::index_last(unsigned char *buf)
 
1391
int ha_myisam::index_last(uchar *buf)
1411
1392
{
1412
1393
  assert(inited==INDEX);
1413
1394
  ha_statistic_increment(&SSV::ha_read_last_count);
1416
1397
  return error;
1417
1398
}
1418
1399
 
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)))
1422
1403
{
1423
1404
  int error;
1424
1405
  assert(inited==INDEX);
1464
1445
  return mi_reset(file);                        // Free buffers
1465
1446
}
1466
1447
 
1467
 
int ha_myisam::rnd_next(unsigned char *buf)
 
1448
int ha_myisam::rnd_next(uchar *buf)
1468
1449
{
1469
1450
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1470
1451
  int error=mi_scan(file, buf);
1472
1453
  return error;
1473
1454
}
1474
1455
 
1475
 
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
 
1456
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
1476
1457
{
1477
1458
  return rnd_pos(buf,pos);
1478
1459
}
1479
1460
 
1480
 
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
 
1461
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
1481
1462
{
1482
1463
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1483
1464
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1486
1467
}
1487
1468
 
1488
1469
 
1489
 
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
 
1470
void ha_myisam::position(const uchar *record __attribute__((unused)))
1490
1471
{
1491
1472
  my_off_t row_position= mi_position(file);
1492
1473
  my_store_ptr(ref, ref_length, row_position);
1493
1474
}
1494
1475
 
1495
 
int ha_myisam::info(uint32_t flag)
 
1476
int ha_myisam::info(uint flag)
1496
1477
{
1497
1478
  MI_ISAMINFO misam_info;
1498
1479
  char name_buff[FN_REFLEN];
1592
1573
}
1593
1574
 
1594
1575
 
1595
 
int ha_myisam::external_lock(Session *session, int lock_type)
 
1576
int ha_myisam::external_lock(THD *thd, int lock_type)
1596
1577
{
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));
1601
1582
}
1602
1583
 
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)
1606
1587
{
1626
1607
                      HA_CREATE_INFO *ha_create_info)
1627
1608
{
1628
1609
  int error;
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));
1666
1647
                   records, recinfo,
1667
1648
                   0, (MI_UNIQUEDEF*) 0,
1668
1649
                   &create_info, create_flags);
1669
 
  free((unsigned char*) recinfo);
 
1650
  my_free((uchar*) recinfo, MYF(0));
1670
1651
  return(error);
1671
1652
}
1672
1653
 
1685
1666
{
1686
1667
  uint64_t nr;
1687
1668
  int error;
1688
 
  unsigned char key[MI_MAX_KEY_LENGTH];
 
1669
  uchar key[MI_MAX_KEY_LENGTH];
1689
1670
 
1690
1671
  if (!table->s->next_number_key_offset)
1691
1672
  {                                             // Autoincrement at key-start
1740
1721
      HA_READ_KEY_EXACT         Include the key in the range
1741
1722
      HA_READ_AFTER_KEY         Don't include key in range
1742
1723
 
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
1746
1727
 
1751
1732
                        the range.
1752
1733
*/
1753
1734
 
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)
1756
1737
{
1757
1738
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1758
1739
}
1759
1740
 
1760
1741
 
1761
 
uint32_t ha_myisam::checksum() const
 
1742
uint ha_myisam::checksum() const
1762
1743
{
1763
1744
  return (uint)file->state->checksum;
1764
1745
}
1765
1746
 
1766
1747
 
1767
1748
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1768
 
                                           uint32_t table_changes)
 
1749
                                           uint table_changes)
1769
1750
{
1770
 
  uint32_t options= table->s->db_options_in_use;
 
1751
  uint options= table->s->db_options_in_use;
1771
1752
 
1772
1753
  if (info->auto_increment_value != stats.auto_increment_value ||
1773
1754
      info->data_file_name != data_file_name ||
1786
1767
 
1787
1768
int myisam_deinit(void *hton __attribute__((unused)))
1788
1769
{
1789
 
  pthread_mutex_destroy(&THR_LOCK_myisam);
1790
 
 
1791
1770
  return mi_panic(HA_PANIC_CLOSE);
1792
1771
}
1793
1772
 
1797
1776
 
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;
1802
1782
  return 0;
1809
1789
 ***************************************************************************/
1810
1790
 
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)
1814
1794
{
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);
1817
1797
}
1818
1798
 
1821
1801
  return ds_mrr.dsmrr_next(this, range_info);
1822
1802
}
1823
1803
 
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)
1828
1808
{
1829
1809
  /*
1830
1810
    This call is here because there is no location where this->table would
1836
1816
                                 flags, cost);
1837
1817
}
1838
1818
 
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)
1841
1821
{
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*/
1850
1830
 
1851
1831
 
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)
1853
1833
{
1854
1834
  pushed_idx_cond_keyno= keyno_arg;
1855
1835
  pushed_idx_cond= idx_cond_arg;