~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/ha_myisam.cc

  • Committer: Patrick Galbraith
  • Date: 2008-07-24 16:57:40 UTC
  • mto: (202.2.4 rename-mysql-to-drizzle)
  • mto: This revision was merged to the branch mainline in revision 212.
  • Revision ID: patg@ishvara-20080724165740-x58yw6zs6d9o17lf
Most everything working with client rename
mysqlslap test still fails... can't connect to the server

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
 
 
18
 
#define DRIZZLE_SERVER 1
19
 
 
20
 
#include <drizzled/server_includes.h>
21
 
#include <mysys/my_bit.h>
 
17
#ifdef USE_PRAGMA_IMPLEMENTATION
 
18
#pragma implementation                          // gcc: Class implementation
 
19
#endif
 
20
 
 
21
#define MYSQL_SERVER 1
 
22
#include "mysql_priv.h"
 
23
#include <mysql/plugin.h>
 
24
#include <m_ctype.h>
 
25
#include <my_bit.h>
22
26
#include <myisampack.h>
23
27
#include "ha_myisam.h"
 
28
#include <stdarg.h>
24
29
#include "myisamdef.h"
25
 
#include <drizzled/drizzled_error_messages.h>
26
 
#include <drizzled/util/test.h>
27
30
 
28
31
ulong myisam_recover_options= HA_RECOVER_NONE;
29
32
 
30
33
/* bits in myisam_recover_options */
31
34
const char *myisam_recover_names[] =
32
 
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
 
35
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
33
36
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
34
37
                                 myisam_recover_names, NULL};
35
38
 
36
39
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
37
 
                                           "nulls_ignored", NULL};
 
40
                                           "nulls_ignored", NullS};
38
41
TYPELIB myisam_stats_method_typelib= {
39
42
  array_elements(myisam_stats_method_names) - 1, "",
40
43
  myisam_stats_method_names, NULL};
58
61
{
59
62
  THD* thd = (THD*)param->thd;
60
63
  Protocol *protocol= thd->protocol;
61
 
  uint32_t length, msg_length;
 
64
  uint length, msg_length;
62
65
  char msgbuf[MI_MAX_MSG_BUF];
63
66
  char name[NAME_LEN*2+2];
64
67
 
77
80
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
78
81
    return;
79
82
  }
80
 
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NULL) -
 
83
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
81
84
                 name);
82
85
  /*
83
86
    TODO: switch from protocol to push_warning here. The main reason we didn't
100
103
 
101
104
 
102
105
/*
103
 
  Convert Table object to MyISAM key and column definition
 
106
  Convert TABLE object to MyISAM key and column definition
104
107
 
105
108
  SYNOPSIS
106
109
    table2myisam()
107
 
      table_arg   in     Table object.
 
110
      table_arg   in     TABLE object.
108
111
      keydef_out  out    MyISAM key definition.
109
112
      recinfo_out out    MyISAM column definition.
110
113
      records_out out    Number of fields.
123
126
    !0 error code
124
127
*/
125
128
 
126
 
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
127
 
                 MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
 
129
int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
 
130
                 MI_COLUMNDEF **recinfo_out, uint *records_out)
128
131
{
129
 
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
 
132
  uint i, j, recpos, minpos, fieldpos, temp_length, length;
130
133
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
131
 
  unsigned char *record;
 
134
  uchar *record;
132
135
  KEY *pos;
133
136
  MI_KEYDEF *keydef;
134
137
  MI_COLUMNDEF *recinfo, *recinfo_pos;
135
138
  HA_KEYSEG *keyseg;
136
139
  TABLE_SHARE *share= table_arg->s;
137
 
  uint32_t options= share->db_options_in_use;
 
140
  uint options= share->db_options_in_use;
138
141
  if (!(my_multi_malloc(MYF(MY_WME),
139
142
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
140
143
          keydef_out, share->keys * sizeof(MI_KEYDEF),
141
144
          &keyseg,
142
145
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
143
 
          NULL)))
 
146
          NullS)))
144
147
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
145
148
  keydef= *keydef_out;
146
149
  recinfo= *recinfo_out;
147
150
  pos= table_arg->key_info;
148
151
  for (i= 0; i < share->keys; i++, pos++)
149
152
  {
150
 
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
151
 
    keydef[i].key_alg= HA_KEY_ALG_BTREE;
 
153
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME | HA_FULLTEXT ));
 
154
    keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?  (HA_KEY_ALG_BTREE) : pos->algorithm;
152
155
    keydef[i].block_length= pos->block_size;
153
156
    keydef[i].seg= keyseg;
154
157
    keydef[i].keysegs= pos->key_parts;
170
173
          /* No blobs here */
171
174
          if (j == 0)
172
175
            keydef[i].flag|= HA_PACK_KEY;
173
 
          if ((((int) (pos->key_part[j].length - field->decimals())) >= 4))
 
176
          if (!(field->flags & ZEROFILL_FLAG) &&
 
177
              (field->type() == MYSQL_TYPE_STRING ||
 
178
               field->type() == MYSQL_TYPE_VAR_STRING ||
 
179
               ((int) (pos->key_part[j].length - field->decimals())) >= 4))
174
180
            keydef[i].seg[j].flag|= HA_SPACE_PACK;
175
181
        }
176
182
        else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
188
194
      {
189
195
        keydef[i].seg[j].null_bit= field->null_bit;
190
196
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
191
 
                                           (unsigned char*) table_arg->record[0]);
 
197
                                           (uchar*) table_arg->record[0]);
192
198
      }
193
199
      else
194
200
      {
195
201
        keydef[i].seg[j].null_bit= 0;
196
202
        keydef[i].seg[j].null_pos= 0;
197
203
      }
198
 
      if (field->type() == DRIZZLE_TYPE_BLOB)
 
204
      if (field->type() == MYSQL_TYPE_BLOB)
199
205
      {
200
206
        keydef[i].seg[j].flag|= HA_BLOB_PART;
201
207
        /* save number of bytes used to pack length */
210
216
  record= table_arg->record[0];
211
217
  recpos= 0;
212
218
  recinfo_pos= recinfo;
213
 
  while (recpos < (uint) share->stored_rec_length)
 
219
  while (recpos < (uint) share->reclength)
214
220
  {
215
221
    Field **field, *found= 0;
216
222
    minpos= share->reclength;
235
241
    }
236
242
    if (recpos != minpos)
237
243
    { // Reserved space (Null bits?)
238
 
      memset(recinfo_pos, 0, sizeof(*recinfo_pos));
 
244
      bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
239
245
      recinfo_pos->type= (int) FIELD_NORMAL;
240
246
      recinfo_pos++->length= (uint16_t) (minpos - recpos);
241
247
    }
244
250
 
245
251
    if (found->flags & BLOB_FLAG)
246
252
      recinfo_pos->type= (int) FIELD_BLOB;
247
 
    else if (found->type() == DRIZZLE_TYPE_VARCHAR)
 
253
    else if (found->type() == MYSQL_TYPE_VARCHAR)
248
254
      recinfo_pos->type= FIELD_VARCHAR;
249
255
    else if (!(options & HA_OPTION_PACK_RECORD))
250
256
      recinfo_pos->type= (int) FIELD_NORMAL;
251
257
    else if (found->zero_pack())
252
258
      recinfo_pos->type= (int) FIELD_SKIP_ZERO;
253
259
    else
254
 
      recinfo_pos->type= (int) ((length <= 3) ?  FIELD_NORMAL : FIELD_SKIP_PRESPACE);
 
260
      recinfo_pos->type= (int) ((length <= 3 ||
 
261
                                 (found->flags & ZEROFILL_FLAG)) ?
 
262
                                  FIELD_NORMAL :
 
263
                                  found->type() == MYSQL_TYPE_STRING ||
 
264
                                  found->type() == MYSQL_TYPE_VAR_STRING ?
 
265
                                  FIELD_SKIP_ENDSPACE :
 
266
                                  FIELD_SKIP_PRESPACE);
255
267
    if (found->null_ptr)
256
268
    {
257
269
      recinfo_pos->null_bit= found->null_bit;
258
270
      recinfo_pos->null_pos= (uint) (found->null_ptr -
259
 
                                     (unsigned char*) table_arg->record[0]);
 
271
                                     (uchar*) table_arg->record[0]);
260
272
    }
261
273
    else
262
274
    {
312
324
*/
313
325
 
314
326
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
315
 
                     uint32_t t1_keys, uint32_t t1_recs,
 
327
                     uint t1_keys, uint t1_recs,
316
328
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
317
 
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
 
329
                     uint t2_keys, uint t2_recs, bool strict)
318
330
{
319
 
  uint32_t i, j;
 
331
  uint i, j;
320
332
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
321
333
  {
322
334
    return(1);
329
341
  {
330
342
    HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
331
343
    HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
 
344
    if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
 
345
      continue;
 
346
    else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
 
347
             t2_keyinfo[i].flag & HA_FULLTEXT)
 
348
    {
 
349
       return(1);
 
350
    }
 
351
    if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
 
352
      continue;
 
353
    else if (t1_keyinfo[i].flag & HA_SPATIAL ||
 
354
             t2_keyinfo[i].flag & HA_SPATIAL)
 
355
    {
 
356
       return(1);
 
357
    }
332
358
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
333
359
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
334
360
    {
438
464
*/
439
465
 
440
466
void _mi_report_crashed(MI_INFO *file, const char *message,
441
 
                        const char *sfile, uint32_t sline)
 
467
                        const char *sfile, uint sline)
442
468
{
443
469
  THD *cur_thd;
444
470
  LIST *element;
 
471
  char buf[1024];
445
472
  pthread_mutex_lock(&file->s->intern_lock);
446
473
  if ((cur_thd= (THD*) file->in_use.data))
447
474
    sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
452
479
    sql_print_error("%s", message);
453
480
  for (element= file->s->in_use; element; element= list_rest(element))
454
481
  {
455
 
    sql_print_error("%s", "Unknown thread accessing table");
 
482
    THD *thd= (THD*) element->data;
 
483
    sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0)
 
484
                              : "Unknown thread accessing table");
456
485
  }
457
486
  pthread_mutex_unlock(&file->s->intern_lock);
458
487
}
461
490
 
462
491
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
463
492
  :handler(hton, table_arg), file(0),
464
 
  int_table_flags(HA_NULL_IN_KEY |
465
 
                  HA_BINLOG_ROW_CAPABLE |
466
 
                  HA_BINLOG_STMT_CAPABLE |
467
 
                  HA_DUPLICATE_POS |
468
 
                  HA_CAN_INDEX_BLOBS |
469
 
                  HA_AUTO_PART_KEY |
470
 
                  HA_FILE_BASED |
471
 
                  HA_NO_TRANSACTIONS |
472
 
                  HA_HAS_RECORDS |
473
 
                  HA_STATS_RECORDS_IS_EXACT |
474
 
                  HA_NEED_READ_RANGE_BUFFER |
475
 
                  HA_MRR_CANT_SORT),
 
493
  int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
 
494
                  HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
 
495
                  HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
 
496
                  HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
 
497
                  HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
 
498
                  HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
 
499
                  HA_NEED_READ_RANGE_BUFFER | HA_MRR_CANT_SORT),
476
500
   can_enable_indexes(1)
477
501
{}
478
502
 
488
512
static const char *ha_myisam_exts[] = {
489
513
  ".MYI",
490
514
  ".MYD",
491
 
  NULL
 
515
  NullS
492
516
};
493
517
 
494
518
const char **ha_myisam::bas_ext() const
497
521
}
498
522
 
499
523
 
500
 
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
 
524
const char *ha_myisam::index_type(uint key_number __attribute__((__unused__)))
501
525
{
502
526
  return "BTREE";
503
527
}
504
528
 
505
529
/* Name is here without an extension */
506
 
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
 
530
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
507
531
{
508
532
  MI_KEYDEF *keyinfo;
509
533
  MI_COLUMNDEF *recinfo= 0;
510
 
  uint32_t recs;
511
 
  uint32_t i;
 
534
  uint recs;
 
535
  uint i;
512
536
 
513
537
  /*
514
538
    If the user wants to have memory mapped data files, add an
547
571
  }
548
572
  
549
573
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
550
 
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
 
574
    VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
551
575
 
552
576
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
553
577
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
554
 
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
 
578
    VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
555
579
  if (!table->s->db_record_offset)
556
580
    int_table_flags|=HA_REC_NOT_IN_SEQ;
557
581
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
583
607
    recinfo must be freed.
584
608
  */
585
609
  if (recinfo)
586
 
    free((unsigned char*) recinfo);
 
610
    my_free((uchar*) recinfo, MYF(0));
587
611
  return my_errno;
588
612
}
589
613
 
594
618
  return mi_close(tmp);
595
619
}
596
620
 
597
 
int ha_myisam::write_row(unsigned char *buf)
 
621
int ha_myisam::write_row(uchar *buf)
598
622
{
599
623
  ha_statistic_increment(&SSV::ha_write_count);
600
624
 
621
645
  int error;
622
646
  MI_CHECK param;
623
647
  MYISAM_SHARE* share = file->s;
624
 
  const char *old_proc_info= thd->get_proc_info();
 
648
  const char *old_proc_info=thd->proc_info;
625
649
 
626
 
  thd->set_proc_info("Checking table");
 
650
  thd_proc_info(thd, "Checking table");
627
651
  myisamchk_init(&param);
628
652
  param.thd = thd;
629
653
  param.op_name =   "check";
659
683
          (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
660
684
        mi_is_crashed(file))
661
685
    {
662
 
      uint32_t old_testflag=param.testflag;
 
686
      uint old_testflag=param.testflag;
663
687
      param.testflag|=T_MEDIUM;
664
688
      if (!(error= init_io_cache(&param.read_cache, file->dfile,
665
689
                                 my_default_record_cache_size, READ_CACHE,
697
721
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
698
722
  }
699
723
 
700
 
  thd->set_proc_info(old_proc_info);
 
724
  thd_proc_info(thd, old_proc_info);
701
725
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
702
726
}
703
727
 
709
733
*/
710
734
 
711
735
int ha_myisam::analyze(THD *thd,
712
 
                       HA_CHECK_OPT* check_opt __attribute__((unused)))
 
736
                       HA_CHECK_OPT* check_opt __attribute__((__unused__)))
713
737
{
714
738
  int error=0;
715
739
  MI_CHECK param;
816
840
int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
817
841
{
818
842
  int error=0;
819
 
  uint32_t local_testflag=param.testflag;
 
843
  uint local_testflag=param.testflag;
820
844
  bool optimize_done= !do_optimize, statistics_done=0;
821
 
  const char *old_proc_info= thd->get_proc_info();
 
845
  const char *old_proc_info=thd->proc_info;
822
846
  char fixed_name[FN_REFLEN];
823
847
  MYISAM_SHARE* share = file->s;
824
848
  ha_rows rows= file->state->records;
846
870
  param.thd= thd;
847
871
  param.tmpdir= &mysql_tmpdir_list;
848
872
  param.out_flag= 0;
849
 
  my_stpcpy(fixed_name,file->filename);
 
873
  strmov(fixed_name,file->filename);
850
874
 
851
 
  // Don't lock tables if we have used LOCK Table
 
875
  // Don't lock tables if we have used LOCK TABLE
852
876
  if (!thd->locked_tables && 
853
877
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
854
878
  {
864
888
    uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
865
889
                        mi_get_mask_all_keys_active(share->base.keys) :
866
890
                        share->state.key_map);
867
 
    uint32_t testflag=param.testflag;
 
891
    uint testflag=param.testflag;
868
892
    if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
869
893
        (local_testflag & T_REP_BY_SORT))
870
894
    {
876
900
        char buf[40];
877
901
        /* TODO: respect myisam_repair_threads variable */
878
902
        snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
879
 
        thd->set_proc_info(buf);
 
903
        thd_proc_info(thd, buf);
880
904
        error = mi_repair_parallel(&param, file, fixed_name,
881
905
            param.testflag & T_QUICK);
882
 
        thd->set_proc_info("Repair done"); // to reset proc_info, as
 
906
        thd_proc_info(thd, "Repair done"); // to reset proc_info, as
883
907
                                      // it was pointing to local buffer
884
908
      }
885
909
      else
886
910
      {
887
 
        thd->set_proc_info("Repair by sorting");
 
911
        thd_proc_info(thd, "Repair by sorting");
888
912
        error = mi_repair_by_sort(&param, file, fixed_name,
889
913
            param.testflag & T_QUICK);
890
914
      }
891
915
    }
892
916
    else
893
917
    {
894
 
      thd->set_proc_info("Repair with keycache");
 
918
      thd_proc_info(thd, "Repair with keycache");
895
919
      param.testflag &= ~T_REP_BY_SORT;
896
920
      error=  mi_repair(&param, file, fixed_name,
897
921
                        param.testflag & T_QUICK);
905
929
        (share->state.changed & STATE_NOT_SORTED_PAGES))
906
930
    {
907
931
      optimize_done=1;
908
 
      thd->set_proc_info("Sorting index");
 
932
      thd_proc_info(thd, "Sorting index");
909
933
      error=mi_sort_index(&param,file,fixed_name);
910
934
    }
911
935
    if (!statistics_done && (local_testflag & T_STATISTICS))
913
937
      if (share->state.changed & STATE_NOT_ANALYZED)
914
938
      {
915
939
        optimize_done=1;
916
 
        thd->set_proc_info("Analyzing");
 
940
        thd_proc_info(thd, "Analyzing");
917
941
        error = chk_key(&param, file);
918
942
      }
919
943
      else
920
944
        local_testflag&= ~T_STATISTICS;         // Don't update statistics
921
945
    }
922
946
  }
923
 
  thd->set_proc_info("Saving state");
 
947
  thd_proc_info(thd, "Saving state");
924
948
  if (!error)
925
949
  {
926
950
    if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
958
982
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
959
983
    update_state_info(&param, file, 0);
960
984
  }
961
 
  thd->set_proc_info(old_proc_info);
 
985
  thd_proc_info(thd, old_proc_info);
962
986
  if (!thd->locked_tables)
963
987
    mi_lock_database(file,F_UNLCK);
964
988
  return(error ? HA_ADMIN_FAILED :
976
1000
  const char *errmsg= 0;
977
1001
  int error= HA_ADMIN_OK;
978
1002
  uint64_t map;
979
 
  TableList *table_list= table->pos_in_table_list;
 
1003
  TABLE_LIST *table_list= table->pos_in_table_list;
980
1004
 
981
1005
  table->keys_in_use_for_query.clear_all();
982
1006
 
1032
1056
    HA_ERR_WRONG_COMMAND  mode not implemented.
1033
1057
*/
1034
1058
 
1035
 
int ha_myisam::disable_indexes(uint32_t mode)
 
1059
int ha_myisam::disable_indexes(uint mode)
1036
1060
{
1037
1061
  int error;
1038
1062
 
1084
1108
    HA_ERR_WRONG_COMMAND  mode not implemented.
1085
1109
*/
1086
1110
 
1087
 
int ha_myisam::enable_indexes(uint32_t mode)
 
1111
int ha_myisam::enable_indexes(uint mode)
1088
1112
{
1089
1113
  int error;
1090
1114
 
1107
1131
  {
1108
1132
    THD *thd=current_thd;
1109
1133
    MI_CHECK param;
1110
 
    const char *save_proc_info= thd->get_proc_info();
1111
 
    thd->set_proc_info("Creating index");
 
1134
    const char *save_proc_info=thd->proc_info;
 
1135
    thd_proc_info(thd, "Creating index");
1112
1136
    myisamchk_init(&param);
1113
1137
    param.op_name= "recreating_index";
1114
1138
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
1133
1157
        thd->clear_error();
1134
1158
    }
1135
1159
    info(HA_STATUS_CONST);
1136
 
    thd->set_proc_info(save_proc_info);
 
1160
    thd_proc_info(thd, save_proc_info);
1137
1161
  }
1138
1162
  else
1139
1163
  {
1183
1207
void ha_myisam::start_bulk_insert(ha_rows rows)
1184
1208
{
1185
1209
  THD *thd= current_thd;
1186
 
  ulong size= cmin(thd->variables.read_buff_size,
 
1210
  ulong size= min(thd->variables.read_buff_size,
1187
1211
                  (ulong) (table->s->avg_row_length*rows));
1188
1212
 
1189
1213
  /* don't enable row cache if too few rows */
1193
1217
  can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
1194
1218
                                            file->s->base.keys);
1195
1219
 
1196
 
  /*
1197
 
    Only disable old index if the table was empty and we are inserting
1198
 
    a lot of rows.
1199
 
    We should not do this for only a few rows as this is slower and
1200
 
    we don't want to update the key statistics based of only a few rows.
1201
 
  */
1202
 
  if (file->state->records == 0 && can_enable_indexes &&
1203
 
      (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1204
 
    mi_disable_non_unique_index(file,rows);
1205
 
  else
 
1220
  if (!(specialflag & SPECIAL_SAFE_MODE))
 
1221
  {
 
1222
    /*
 
1223
      Only disable old index if the table was empty and we are inserting
 
1224
      a lot of rows.
 
1225
      We should not do this for only a few rows as this is slower and
 
1226
      we don't want to update the key statistics based of only a few rows.
 
1227
    */
 
1228
    if (file->state->records == 0 && can_enable_indexes &&
 
1229
        (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
 
1230
      mi_disable_non_unique_index(file,rows);
 
1231
    else
1206
1232
    if (!file->bulk_insert &&
1207
1233
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1208
1234
    {
1209
1235
      mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
1210
1236
    }
1211
 
 
 
1237
  }
1212
1238
  return;
1213
1239
}
1214
1240
 
1239
1265
  int error=0;
1240
1266
  int marked_crashed;
1241
1267
  char *old_query;
1242
 
  uint32_t old_query_length;
 
1268
  uint old_query_length;
1243
1269
  HA_CHECK_OPT check_opt;
1244
1270
 
1245
1271
  check_opt.init();
1280
1306
          (file->s->state.open_count));
1281
1307
}
1282
1308
 
1283
 
int ha_myisam::update_row(const unsigned char *old_data, unsigned char *new_data)
 
1309
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
1284
1310
{
1285
1311
  ha_statistic_increment(&SSV::ha_update_count);
1286
1312
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1288
1314
  return mi_update(file,old_data,new_data);
1289
1315
}
1290
1316
 
1291
 
int ha_myisam::delete_row(const unsigned char *buf)
 
1317
int ha_myisam::delete_row(const uchar *buf)
1292
1318
{
1293
1319
  ha_statistic_increment(&SSV::ha_delete_count);
1294
1320
  return mi_delete(file,buf);
1295
1321
}
1296
1322
 
1297
 
#ifdef __cplusplus
1298
 
extern "C" {
1299
 
#endif
 
1323
C_MODE_START
1300
1324
 
1301
 
bool index_cond_func_myisam(void *arg)
 
1325
my_bool index_cond_func_myisam(void *arg)
1302
1326
{
1303
1327
  ha_myisam *h= (ha_myisam*)arg;
1304
1328
  /*if (h->in_range_read)*/
1307
1331
    if (h->compare_key2(h->end_range) > 0)
1308
1332
      return 2; /* caller should return HA_ERR_END_OF_FILE already */
1309
1333
  }
1310
 
  return (bool)h->pushed_idx_cond->val_int();
1311
 
}
1312
 
 
1313
 
#ifdef __cplusplus
1314
 
}
1315
 
#endif
1316
 
 
1317
 
 
1318
 
int ha_myisam::index_init(uint32_t idx, bool sorted __attribute__((unused)))
 
1334
  return (my_bool)h->pushed_idx_cond->val_int();
 
1335
}
 
1336
 
 
1337
C_MODE_END
 
1338
 
 
1339
 
 
1340
int ha_myisam::index_init(uint idx, bool sorted __attribute__((__unused__)))
1319
1341
1320
1342
  active_index=idx;
1321
1343
  //in_range_read= false;
1336
1358
}
1337
1359
 
1338
1360
 
1339
 
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
 
1361
int ha_myisam::index_read_map(uchar *buf, const uchar *key,
1340
1362
                              key_part_map keypart_map,
1341
1363
                              enum ha_rkey_function find_flag)
1342
1364
{
1347
1369
  return error;
1348
1370
}
1349
1371
 
1350
 
int ha_myisam::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
 
1372
int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key,
1351
1373
                                  key_part_map keypart_map,
1352
1374
                                  enum ha_rkey_function find_flag)
1353
1375
{
1357
1379
  return error;
1358
1380
}
1359
1381
 
1360
 
int ha_myisam::index_read_last_map(unsigned char *buf, const unsigned char *key,
 
1382
int ha_myisam::index_read_last_map(uchar *buf, const uchar *key,
1361
1383
                                   key_part_map keypart_map)
1362
1384
{
1363
1385
  assert(inited==INDEX);
1368
1390
  return(error);
1369
1391
}
1370
1392
 
1371
 
int ha_myisam::index_next(unsigned char *buf)
 
1393
int ha_myisam::index_next(uchar *buf)
1372
1394
{
1373
1395
  assert(inited==INDEX);
1374
1396
  ha_statistic_increment(&SSV::ha_read_next_count);
1377
1399
  return error;
1378
1400
}
1379
1401
 
1380
 
int ha_myisam::index_prev(unsigned char *buf)
 
1402
int ha_myisam::index_prev(uchar *buf)
1381
1403
{
1382
1404
  assert(inited==INDEX);
1383
1405
  ha_statistic_increment(&SSV::ha_read_prev_count);
1386
1408
  return error;
1387
1409
}
1388
1410
 
1389
 
int ha_myisam::index_first(unsigned char *buf)
 
1411
int ha_myisam::index_first(uchar *buf)
1390
1412
{
1391
1413
  assert(inited==INDEX);
1392
1414
  ha_statistic_increment(&SSV::ha_read_first_count);
1395
1417
  return error;
1396
1418
}
1397
1419
 
1398
 
int ha_myisam::index_last(unsigned char *buf)
 
1420
int ha_myisam::index_last(uchar *buf)
1399
1421
{
1400
1422
  assert(inited==INDEX);
1401
1423
  ha_statistic_increment(&SSV::ha_read_last_count);
1404
1426
  return error;
1405
1427
}
1406
1428
 
1407
 
int ha_myisam::index_next_same(unsigned char *buf,
1408
 
                               const unsigned char *key __attribute__((unused)),
1409
 
                               uint32_t length __attribute__((unused)))
 
1429
int ha_myisam::index_next_same(uchar *buf,
 
1430
                               const uchar *key __attribute__((unused)),
 
1431
                               uint length __attribute__((unused)))
1410
1432
{
1411
1433
  int error;
1412
1434
  assert(inited==INDEX);
1452
1474
  return mi_reset(file);                        // Free buffers
1453
1475
}
1454
1476
 
1455
 
int ha_myisam::rnd_next(unsigned char *buf)
 
1477
int ha_myisam::rnd_next(uchar *buf)
1456
1478
{
1457
1479
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1458
1480
  int error=mi_scan(file, buf);
1460
1482
  return error;
1461
1483
}
1462
1484
 
1463
 
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
 
1485
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
1464
1486
{
1465
1487
  return rnd_pos(buf,pos);
1466
1488
}
1467
1489
 
1468
 
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
 
1490
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
1469
1491
{
1470
1492
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1471
1493
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1474
1496
}
1475
1497
 
1476
1498
 
1477
 
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
 
1499
void ha_myisam::position(const uchar *record __attribute__((__unused__)))
1478
1500
{
1479
1501
  my_off_t row_position= mi_position(file);
1480
1502
  my_store_ptr(ref, ref_length, row_position);
1481
1503
}
1482
1504
 
1483
 
int ha_myisam::info(uint32_t flag)
 
1505
int ha_myisam::info(uint flag)
1484
1506
{
1485
1507
  MI_ISAMINFO misam_info;
1486
1508
  char name_buff[FN_REFLEN];
1514
1536
    share->keys_for_keyread.intersect(share->keys_in_use);
1515
1537
    share->db_record_offset= misam_info.record_offset;
1516
1538
    if (share->key_parts)
1517
 
      memcpy(table->key_info[0].rec_per_key,
1518
 
             misam_info.rec_per_key,
 
1539
      memcpy((char*) table->key_info[0].rec_per_key,
 
1540
             (char*) misam_info.rec_per_key,
1519
1541
             sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1520
1542
    if (share->tmp_table == NO_TMP_TABLE)
1521
1543
      pthread_mutex_unlock(&share->mutex);
1550
1572
 
1551
1573
int ha_myisam::extra(enum ha_extra_function operation)
1552
1574
{
 
1575
  if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
 
1576
    return 0;
1553
1577
  return mi_extra(file, operation, 0);
1554
1578
}
1555
1579
 
1566
1590
 
1567
1591
int ha_myisam::extra_opt(enum ha_extra_function operation, uint32_t cache_size)
1568
1592
{
 
1593
  if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE)
 
1594
    return 0;
1569
1595
  return mi_extra(file, operation, (void*) &cache_size);
1570
1596
}
1571
1597
 
1588
1614
                                       F_UNLCK : F_EXTRA_LCK));
1589
1615
}
1590
1616
 
1591
 
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((unused)),
 
1617
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((__unused__)),
1592
1618
                                      THR_LOCK_DATA **to,
1593
1619
                                      enum thr_lock_type lock_type)
1594
1620
{
1610
1636
}
1611
1637
 
1612
1638
 
1613
 
int ha_myisam::create(const char *name, register Table *table_arg,
 
1639
int ha_myisam::create(const char *name, register TABLE *table_arg,
1614
1640
                      HA_CREATE_INFO *ha_create_info)
1615
1641
{
1616
1642
  int error;
1617
 
  uint32_t create_flags= 0, records;
 
1643
  uint create_flags= 0, records, i;
1618
1644
  char buff[FN_REFLEN];
1619
1645
  MI_KEYDEF *keydef;
1620
1646
  MI_COLUMNDEF *recinfo;
1621
1647
  MI_CREATE_INFO create_info;
1622
1648
  TABLE_SHARE *share= table_arg->s;
1623
 
  uint32_t options= share->db_options_in_use;
 
1649
  uint options= share->db_options_in_use;
 
1650
  for (i= 0; i < share->keys; i++)
 
1651
  {
 
1652
    if (table_arg->key_info[i].flags & HA_USES_PARSER)
 
1653
    {
 
1654
      create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER;
 
1655
      break;
 
1656
    }
 
1657
  }
1624
1658
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1625
1659
    return(error); /* purecov: inspected */
1626
 
  memset(&create_info, 0, sizeof(create_info));
 
1660
  bzero((char*) &create_info, sizeof(create_info));
1627
1661
  create_info.max_rows= share->max_rows;
1628
1662
  create_info.reloc_rows= share->min_rows;
1629
1663
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1654
1688
                   records, recinfo,
1655
1689
                   0, (MI_UNIQUEDEF*) 0,
1656
1690
                   &create_info, create_flags);
1657
 
  free((unsigned char*) recinfo);
 
1691
  my_free((uchar*) recinfo, MYF(0));
1658
1692
  return(error);
1659
1693
}
1660
1694
 
1665
1699
}
1666
1700
 
1667
1701
 
1668
 
void ha_myisam::get_auto_increment(uint64_t offset __attribute__((unused)),
1669
 
                                   uint64_t increment __attribute__((unused)),
1670
 
                                   uint64_t nb_desired_values __attribute__((unused)),
 
1702
void ha_myisam::get_auto_increment(uint64_t offset __attribute__((__unused__)),
 
1703
                                   uint64_t increment __attribute__((__unused__)),
 
1704
                                   uint64_t nb_desired_values __attribute__((__unused__)),
1671
1705
                                   uint64_t *first_value,
1672
1706
                                   uint64_t *nb_reserved_values)
1673
1707
{
1674
1708
  uint64_t nr;
1675
1709
  int error;
1676
 
  unsigned char key[MI_MAX_KEY_LENGTH];
 
1710
  uchar key[MI_MAX_KEY_LENGTH];
1677
1711
 
1678
1712
  if (!table->s->next_number_key_offset)
1679
1713
  {                                             // Autoincrement at key-start
1739
1773
                        the range.
1740
1774
*/
1741
1775
 
1742
 
ha_rows ha_myisam::records_in_range(uint32_t inx, key_range *min_key,
 
1776
ha_rows ha_myisam::records_in_range(uint inx, key_range *min_key,
1743
1777
                                    key_range *max_key)
1744
1778
{
1745
1779
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1746
1780
}
1747
1781
 
1748
1782
 
1749
 
uint32_t ha_myisam::checksum() const
 
1783
uint ha_myisam::checksum() const
1750
1784
{
1751
1785
  return (uint)file->state->checksum;
1752
1786
}
1753
1787
 
1754
1788
 
1755
1789
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1756
 
                                           uint32_t table_changes)
 
1790
                                           uint table_changes)
1757
1791
{
1758
 
  uint32_t options= table->s->db_options_in_use;
 
1792
  uint options= table->s->db_options_in_use;
1759
1793
 
1760
1794
  if (info->auto_increment_value != stats.auto_increment_value ||
1761
1795
      info->data_file_name != data_file_name ||
1772
1806
  return COMPATIBLE_DATA_YES;
1773
1807
}
1774
1808
 
1775
 
int myisam_deinit(void *hton __attribute__((unused)))
 
1809
int myisam_panic(handlerton *hton __attribute__((__unused__)), ha_panic_function flag)
1776
1810
{
1777
 
  return mi_panic(HA_PANIC_CLOSE);
 
1811
  return mi_panic(flag);
1778
1812
}
1779
1813
 
1780
1814
static int myisam_init(void *p)
1783
1817
 
1784
1818
  myisam_hton= (handlerton *)p;
1785
1819
  myisam_hton->state= SHOW_OPTION_YES;
 
1820
  myisam_hton->db_type= DB_TYPE_MYISAM;
1786
1821
  myisam_hton->create= myisam_create_handler;
 
1822
  myisam_hton->panic= myisam_panic;
1787
1823
  myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
1788
1824
  return 0;
1789
1825
}
1795
1831
 ***************************************************************************/
1796
1832
 
1797
1833
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1798
 
                                     uint32_t n_ranges, uint32_t mode, 
 
1834
                                     uint n_ranges, uint mode, 
1799
1835
                                     HANDLER_BUFFER *buf)
1800
1836
{
1801
1837
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index], 
1807
1843
  return ds_mrr.dsmrr_next(this, range_info);
1808
1844
}
1809
1845
 
1810
 
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
1846
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
1811
1847
                                               void *seq_init_param, 
1812
 
                                               uint32_t n_ranges, uint32_t *bufsz,
1813
 
                                               uint32_t *flags, COST_VECT *cost)
 
1848
                                               uint n_ranges, uint *bufsz,
 
1849
                                               uint *flags, COST_VECT *cost)
1814
1850
{
1815
1851
  /*
1816
1852
    This call is here because there is no location where this->table would
1822
1858
                                 flags, cost);
1823
1859
}
1824
1860
 
1825
 
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1826
 
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
 
1861
int ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
 
1862
                                     uint *bufsz, uint *flags, COST_VECT *cost)
1827
1863
{
1828
1864
  ds_mrr.init(this, table);
1829
1865
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1835
1871
/* Index condition pushdown implementation*/
1836
1872
 
1837
1873
 
1838
 
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
 
1874
Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
1839
1875
{
1840
1876
  pushed_idx_cond_keyno= keyno_arg;
1841
1877
  pushed_idx_cond= idx_cond_arg;
1848
1884
 
1849
1885
mysql_declare_plugin(myisam)
1850
1886
{
1851
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
1887
  MYSQL_STORAGE_ENGINE_PLUGIN,
1852
1888
  "MyISAM",
1853
1889
  "1.0",
1854
1890
  "MySQL AB",
1855
1891
  "Default engine as of MySQL 3.23 with great performance",
1856
1892
  PLUGIN_LICENSE_GPL,
1857
1893
  myisam_init, /* Plugin Init */
1858
 
  myisam_deinit, /* Plugin Deinit */
 
1894
  NULL, /* Plugin Deinit */
1859
1895
  NULL,                       /* status variables                */
1860
1896
  NULL,                       /* system variables                */
1861
1897
  NULL                        /* config options                  */