~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/ha_myisam.cc

Merge/fix in FAQ.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#pragma implementation                          // gcc: Class implementation
19
19
#endif
20
20
 
21
 
#define DRIZZLE_SERVER 1
22
 
 
23
 
#include <drizzled/server_includes.h>
24
 
#include <mysys/my_bit.h>
 
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>
25
26
#include <myisampack.h>
26
27
#include "ha_myisam.h"
 
28
#include <stdarg.h>
27
29
#include "myisamdef.h"
28
 
#include <drizzled/drizzled_error_messages.h>
29
30
 
30
31
ulong myisam_recover_options= HA_RECOVER_NONE;
31
32
 
32
33
/* bits in myisam_recover_options */
33
34
const char *myisam_recover_names[] =
34
 
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
 
35
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
35
36
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
36
37
                                 myisam_recover_names, NULL};
37
38
 
38
39
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
39
 
                                           "nulls_ignored", NULL};
 
40
                                           "nulls_ignored", NullS};
40
41
TYPELIB myisam_stats_method_typelib= {
41
42
  array_elements(myisam_stats_method_names) - 1, "",
42
43
  myisam_stats_method_names, NULL};
60
61
{
61
62
  THD* thd = (THD*)param->thd;
62
63
  Protocol *protocol= thd->protocol;
63
 
  uint32_t length, msg_length;
 
64
  uint length, msg_length;
64
65
  char msgbuf[MI_MAX_MSG_BUF];
65
66
  char name[NAME_LEN*2+2];
66
67
 
79
80
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
80
81
    return;
81
82
  }
82
 
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NULL) -
 
83
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
83
84
                 name);
84
85
  /*
85
86
    TODO: switch from protocol to push_warning here. The main reason we didn't
102
103
 
103
104
 
104
105
/*
105
 
  Convert Table object to MyISAM key and column definition
 
106
  Convert TABLE object to MyISAM key and column definition
106
107
 
107
108
  SYNOPSIS
108
109
    table2myisam()
109
 
      table_arg   in     Table object.
 
110
      table_arg   in     TABLE object.
110
111
      keydef_out  out    MyISAM key definition.
111
112
      recinfo_out out    MyISAM column definition.
112
113
      records_out out    Number of fields.
125
126
    !0 error code
126
127
*/
127
128
 
128
 
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
129
 
                 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)
130
131
{
131
 
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
 
132
  uint i, j, recpos, minpos, fieldpos, temp_length, length;
132
133
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
133
 
  unsigned char *record;
 
134
  uchar *record;
134
135
  KEY *pos;
135
136
  MI_KEYDEF *keydef;
136
137
  MI_COLUMNDEF *recinfo, *recinfo_pos;
137
138
  HA_KEYSEG *keyseg;
138
139
  TABLE_SHARE *share= table_arg->s;
139
 
  uint32_t options= share->db_options_in_use;
 
140
  uint options= share->db_options_in_use;
140
141
  if (!(my_multi_malloc(MYF(MY_WME),
141
142
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
142
143
          keydef_out, share->keys * sizeof(MI_KEYDEF),
143
144
          &keyseg,
144
145
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
145
 
          NULL)))
 
146
          NullS)))
146
147
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
147
148
  keydef= *keydef_out;
148
149
  recinfo= *recinfo_out;
149
150
  pos= table_arg->key_info;
150
151
  for (i= 0; i < share->keys; i++, pos++)
151
152
  {
152
 
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
153
 
    keydef[i].key_alg= HA_KEY_ALG_BTREE;
 
153
    keydef[i].flag= ((uint16) pos->flags & (HA_NOSAME | HA_FULLTEXT ));
 
154
    keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?  (HA_KEY_ALG_BTREE) : pos->algorithm;
154
155
    keydef[i].block_length= pos->block_size;
155
156
    keydef[i].seg= keyseg;
156
157
    keydef[i].keysegs= pos->key_parts;
172
173
          /* No blobs here */
173
174
          if (j == 0)
174
175
            keydef[i].flag|= HA_PACK_KEY;
175
 
          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))
176
180
            keydef[i].seg[j].flag|= HA_SPACE_PACK;
177
181
        }
178
182
        else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
190
194
      {
191
195
        keydef[i].seg[j].null_bit= field->null_bit;
192
196
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
193
 
                                           (unsigned char*) table_arg->record[0]);
 
197
                                           (uchar*) table_arg->record[0]);
194
198
      }
195
199
      else
196
200
      {
197
201
        keydef[i].seg[j].null_bit= 0;
198
202
        keydef[i].seg[j].null_pos= 0;
199
203
      }
200
 
      if (field->type() == DRIZZLE_TYPE_BLOB)
 
204
      if (field->type() == MYSQL_TYPE_BLOB)
201
205
      {
202
206
        keydef[i].seg[j].flag|= HA_BLOB_PART;
203
207
        /* save number of bytes used to pack length */
237
241
    }
238
242
    if (recpos != minpos)
239
243
    { // Reserved space (Null bits?)
240
 
      memset(recinfo_pos, 0, sizeof(*recinfo_pos));
 
244
      bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
241
245
      recinfo_pos->type= (int) FIELD_NORMAL;
242
 
      recinfo_pos++->length= (uint16_t) (minpos - recpos);
 
246
      recinfo_pos++->length= (uint16) (minpos - recpos);
243
247
    }
244
248
    if (!found)
245
249
      break;
246
250
 
247
251
    if (found->flags & BLOB_FLAG)
248
252
      recinfo_pos->type= (int) FIELD_BLOB;
249
 
    else if (found->type() == DRIZZLE_TYPE_VARCHAR)
 
253
    else if (found->type() == MYSQL_TYPE_VARCHAR)
250
254
      recinfo_pos->type= FIELD_VARCHAR;
251
255
    else if (!(options & HA_OPTION_PACK_RECORD))
252
256
      recinfo_pos->type= (int) FIELD_NORMAL;
253
257
    else if (found->zero_pack())
254
258
      recinfo_pos->type= (int) FIELD_SKIP_ZERO;
255
259
    else
256
 
      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);
257
267
    if (found->null_ptr)
258
268
    {
259
269
      recinfo_pos->null_bit= found->null_bit;
260
270
      recinfo_pos->null_pos= (uint) (found->null_ptr -
261
 
                                     (unsigned char*) table_arg->record[0]);
 
271
                                     (uchar*) table_arg->record[0]);
262
272
    }
263
273
    else
264
274
    {
265
275
      recinfo_pos->null_bit= 0;
266
276
      recinfo_pos->null_pos= 0;
267
277
    }
268
 
    (recinfo_pos++)->length= (uint16_t) length;
 
278
    (recinfo_pos++)->length= (uint16) length;
269
279
    recpos= minpos + length;
270
280
  }
271
281
  *records_out= (uint) (recinfo_pos - recinfo);
314
324
*/
315
325
 
316
326
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
317
 
                     uint32_t t1_keys, uint32_t t1_recs,
 
327
                     uint t1_keys, uint t1_recs,
318
328
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
319
 
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
 
329
                     uint t2_keys, uint t2_recs, bool strict)
320
330
{
321
 
  uint32_t i, j;
 
331
  uint i, j;
322
332
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
323
333
  {
324
334
    return(1);
331
341
  {
332
342
    HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
333
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
    }
334
358
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
335
359
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
336
360
    {
338
362
    }
339
363
    for (j=  t1_keyinfo[i].keysegs; j--;)
340
364
    {
341
 
      uint8_t t1_keysegs_j__type= t1_keysegs[j].type;
 
365
      uint8 t1_keysegs_j__type= t1_keysegs[j].type;
342
366
 
343
367
      /*
344
368
        Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
440
464
*/
441
465
 
442
466
void _mi_report_crashed(MI_INFO *file, const char *message,
443
 
                        const char *sfile, uint32_t sline)
 
467
                        const char *sfile, uint sline)
444
468
{
445
469
  THD *cur_thd;
446
470
  LIST *element;
 
471
  char buf[1024];
447
472
  pthread_mutex_lock(&file->s->intern_lock);
448
473
  if ((cur_thd= (THD*) file->in_use.data))
449
474
    sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
454
479
    sql_print_error("%s", message);
455
480
  for (element= file->s->in_use; element; element= list_rest(element))
456
481
  {
457
 
    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");
458
485
  }
459
486
  pthread_mutex_unlock(&file->s->intern_lock);
460
487
}
463
490
 
464
491
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
465
492
  :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),
 
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),
478
500
   can_enable_indexes(1)
479
501
{}
480
502
 
490
512
static const char *ha_myisam_exts[] = {
491
513
  ".MYI",
492
514
  ".MYD",
493
 
  NULL
 
515
  NullS
494
516
};
495
517
 
496
518
const char **ha_myisam::bas_ext() const
499
521
}
500
522
 
501
523
 
502
 
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
 
524
const char *ha_myisam::index_type(uint key_number __attribute__((__unused__)))
503
525
{
504
526
  return "BTREE";
505
527
}
506
528
 
507
529
/* Name is here without an extension */
508
 
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)
509
531
{
510
532
  MI_KEYDEF *keyinfo;
511
533
  MI_COLUMNDEF *recinfo= 0;
512
 
  uint32_t recs;
513
 
  uint32_t i;
 
534
  uint recs;
 
535
  uint i;
514
536
 
515
537
  /*
516
538
    If the user wants to have memory mapped data files, add an
549
571
  }
550
572
  
551
573
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
552
 
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
 
574
    VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
553
575
 
554
576
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
555
577
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
556
 
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
 
578
    VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
557
579
  if (!table->s->db_record_offset)
558
580
    int_table_flags|=HA_REC_NOT_IN_SEQ;
559
581
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
585
607
    recinfo must be freed.
586
608
  */
587
609
  if (recinfo)
588
 
    free((unsigned char*) recinfo);
 
610
    my_free((uchar*) recinfo, MYF(0));
589
611
  return my_errno;
590
612
}
591
613
 
596
618
  return mi_close(tmp);
597
619
}
598
620
 
599
 
int ha_myisam::write_row(unsigned char *buf)
 
621
int ha_myisam::write_row(uchar *buf)
600
622
{
601
623
  ha_statistic_increment(&SSV::ha_write_count);
602
624
 
623
645
  int error;
624
646
  MI_CHECK param;
625
647
  MYISAM_SHARE* share = file->s;
626
 
  const char *old_proc_info= thd->get_proc_info();
 
648
  const char *old_proc_info=thd->proc_info;
627
649
 
628
650
  thd_proc_info(thd, "Checking table");
629
651
  myisamchk_init(&param);
661
683
          (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
662
684
        mi_is_crashed(file))
663
685
    {
664
 
      uint32_t old_testflag=param.testflag;
 
686
      uint old_testflag=param.testflag;
665
687
      param.testflag|=T_MEDIUM;
666
688
      if (!(error= init_io_cache(&param.read_cache, file->dfile,
667
689
                                 my_default_record_cache_size, READ_CACHE,
711
733
*/
712
734
 
713
735
int ha_myisam::analyze(THD *thd,
714
 
                       HA_CHECK_OPT* check_opt __attribute__((unused)))
 
736
                       HA_CHECK_OPT* check_opt __attribute__((__unused__)))
715
737
{
716
738
  int error=0;
717
739
  MI_CHECK param;
818
840
int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
819
841
{
820
842
  int error=0;
821
 
  uint32_t local_testflag=param.testflag;
 
843
  uint local_testflag=param.testflag;
822
844
  bool optimize_done= !do_optimize, statistics_done=0;
823
 
  const char *old_proc_info= thd->get_proc_info();
 
845
  const char *old_proc_info=thd->proc_info;
824
846
  char fixed_name[FN_REFLEN];
825
847
  MYISAM_SHARE* share = file->s;
826
848
  ha_rows rows= file->state->records;
848
870
  param.thd= thd;
849
871
  param.tmpdir= &mysql_tmpdir_list;
850
872
  param.out_flag= 0;
851
 
  my_stpcpy(fixed_name,file->filename);
 
873
  strmov(fixed_name,file->filename);
852
874
 
853
 
  // Don't lock tables if we have used LOCK Table
 
875
  // Don't lock tables if we have used LOCK TABLE
854
876
  if (!thd->locked_tables && 
855
877
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
856
878
  {
866
888
    uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
867
889
                        mi_get_mask_all_keys_active(share->base.keys) :
868
890
                        share->state.key_map);
869
 
    uint32_t testflag=param.testflag;
 
891
    uint testflag=param.testflag;
870
892
    if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
871
893
        (local_testflag & T_REP_BY_SORT))
872
894
    {
978
1000
  const char *errmsg= 0;
979
1001
  int error= HA_ADMIN_OK;
980
1002
  uint64_t map;
981
 
  TableList *table_list= table->pos_in_table_list;
 
1003
  TABLE_LIST *table_list= table->pos_in_table_list;
982
1004
 
983
1005
  table->keys_in_use_for_query.clear_all();
984
1006
 
1034
1056
    HA_ERR_WRONG_COMMAND  mode not implemented.
1035
1057
*/
1036
1058
 
1037
 
int ha_myisam::disable_indexes(uint32_t mode)
 
1059
int ha_myisam::disable_indexes(uint mode)
1038
1060
{
1039
1061
  int error;
1040
1062
 
1086
1108
    HA_ERR_WRONG_COMMAND  mode not implemented.
1087
1109
*/
1088
1110
 
1089
 
int ha_myisam::enable_indexes(uint32_t mode)
 
1111
int ha_myisam::enable_indexes(uint mode)
1090
1112
{
1091
1113
  int error;
1092
1114
 
1109
1131
  {
1110
1132
    THD *thd=current_thd;
1111
1133
    MI_CHECK param;
1112
 
    const char *save_proc_info= thd->get_proc_info();
 
1134
    const char *save_proc_info=thd->proc_info;
1113
1135
    thd_proc_info(thd, "Creating index");
1114
1136
    myisamchk_init(&param);
1115
1137
    param.op_name= "recreating_index";
1185
1207
void ha_myisam::start_bulk_insert(ha_rows rows)
1186
1208
{
1187
1209
  THD *thd= current_thd;
1188
 
  ulong size= cmin(thd->variables.read_buff_size,
 
1210
  ulong size= min(thd->variables.read_buff_size,
1189
1211
                  (ulong) (table->s->avg_row_length*rows));
1190
1212
 
1191
1213
  /* don't enable row cache if too few rows */
1195
1217
  can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
1196
1218
                                            file->s->base.keys);
1197
1219
 
1198
 
  /*
1199
 
    Only disable old index if the table was empty and we are inserting
1200
 
    a lot of rows.
1201
 
    We should not do this for only a few rows as this is slower and
1202
 
    we don't want to update the key statistics based of only a few rows.
1203
 
  */
1204
 
  if (file->state->records == 0 && can_enable_indexes &&
1205
 
      (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1206
 
    mi_disable_non_unique_index(file,rows);
1207
 
  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
1208
1232
    if (!file->bulk_insert &&
1209
1233
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1210
1234
    {
1211
1235
      mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
1212
1236
    }
1213
 
 
 
1237
  }
1214
1238
  return;
1215
1239
}
1216
1240
 
1241
1265
  int error=0;
1242
1266
  int marked_crashed;
1243
1267
  char *old_query;
1244
 
  uint32_t old_query_length;
 
1268
  uint old_query_length;
1245
1269
  HA_CHECK_OPT check_opt;
1246
1270
 
1247
1271
  check_opt.init();
1282
1306
          (file->s->state.open_count));
1283
1307
}
1284
1308
 
1285
 
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)
1286
1310
{
1287
1311
  ha_statistic_increment(&SSV::ha_update_count);
1288
1312
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1290
1314
  return mi_update(file,old_data,new_data);
1291
1315
}
1292
1316
 
1293
 
int ha_myisam::delete_row(const unsigned char *buf)
 
1317
int ha_myisam::delete_row(const uchar *buf)
1294
1318
{
1295
1319
  ha_statistic_increment(&SSV::ha_delete_count);
1296
1320
  return mi_delete(file,buf);
1297
1321
}
1298
1322
 
1299
 
#ifdef __cplusplus
1300
 
extern "C" {
1301
 
#endif
 
1323
C_MODE_START
1302
1324
 
1303
 
bool index_cond_func_myisam(void *arg)
 
1325
my_bool index_cond_func_myisam(void *arg)
1304
1326
{
1305
1327
  ha_myisam *h= (ha_myisam*)arg;
1306
1328
  /*if (h->in_range_read)*/
1309
1331
    if (h->compare_key2(h->end_range) > 0)
1310
1332
      return 2; /* caller should return HA_ERR_END_OF_FILE already */
1311
1333
  }
1312
 
  return (bool)h->pushed_idx_cond->val_int();
1313
 
}
1314
 
 
1315
 
#ifdef __cplusplus
1316
 
}
1317
 
#endif
1318
 
 
1319
 
 
1320
 
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__)))
1321
1341
1322
1342
  active_index=idx;
1323
1343
  //in_range_read= false;
1338
1358
}
1339
1359
 
1340
1360
 
1341
 
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,
1342
1362
                              key_part_map keypart_map,
1343
1363
                              enum ha_rkey_function find_flag)
1344
1364
{
1349
1369
  return error;
1350
1370
}
1351
1371
 
1352
 
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,
1353
1373
                                  key_part_map keypart_map,
1354
1374
                                  enum ha_rkey_function find_flag)
1355
1375
{
1359
1379
  return error;
1360
1380
}
1361
1381
 
1362
 
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,
1363
1383
                                   key_part_map keypart_map)
1364
1384
{
1365
1385
  assert(inited==INDEX);
1370
1390
  return(error);
1371
1391
}
1372
1392
 
1373
 
int ha_myisam::index_next(unsigned char *buf)
 
1393
int ha_myisam::index_next(uchar *buf)
1374
1394
{
1375
1395
  assert(inited==INDEX);
1376
1396
  ha_statistic_increment(&SSV::ha_read_next_count);
1379
1399
  return error;
1380
1400
}
1381
1401
 
1382
 
int ha_myisam::index_prev(unsigned char *buf)
 
1402
int ha_myisam::index_prev(uchar *buf)
1383
1403
{
1384
1404
  assert(inited==INDEX);
1385
1405
  ha_statistic_increment(&SSV::ha_read_prev_count);
1388
1408
  return error;
1389
1409
}
1390
1410
 
1391
 
int ha_myisam::index_first(unsigned char *buf)
 
1411
int ha_myisam::index_first(uchar *buf)
1392
1412
{
1393
1413
  assert(inited==INDEX);
1394
1414
  ha_statistic_increment(&SSV::ha_read_first_count);
1397
1417
  return error;
1398
1418
}
1399
1419
 
1400
 
int ha_myisam::index_last(unsigned char *buf)
 
1420
int ha_myisam::index_last(uchar *buf)
1401
1421
{
1402
1422
  assert(inited==INDEX);
1403
1423
  ha_statistic_increment(&SSV::ha_read_last_count);
1406
1426
  return error;
1407
1427
}
1408
1428
 
1409
 
int ha_myisam::index_next_same(unsigned char *buf,
1410
 
                               const unsigned char *key __attribute__((unused)),
1411
 
                               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)))
1412
1432
{
1413
1433
  int error;
1414
1434
  assert(inited==INDEX);
1454
1474
  return mi_reset(file);                        // Free buffers
1455
1475
}
1456
1476
 
1457
 
int ha_myisam::rnd_next(unsigned char *buf)
 
1477
int ha_myisam::rnd_next(uchar *buf)
1458
1478
{
1459
1479
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1460
1480
  int error=mi_scan(file, buf);
1462
1482
  return error;
1463
1483
}
1464
1484
 
1465
 
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
 
1485
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
1466
1486
{
1467
1487
  return rnd_pos(buf,pos);
1468
1488
}
1469
1489
 
1470
 
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
 
1490
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)
1471
1491
{
1472
1492
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1473
1493
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1476
1496
}
1477
1497
 
1478
1498
 
1479
 
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
 
1499
void ha_myisam::position(const uchar *record __attribute__((__unused__)))
1480
1500
{
1481
1501
  my_off_t row_position= mi_position(file);
1482
1502
  my_store_ptr(ref, ref_length, row_position);
1483
1503
}
1484
1504
 
1485
 
int ha_myisam::info(uint32_t flag)
 
1505
int ha_myisam::info(uint flag)
1486
1506
{
1487
1507
  MI_ISAMINFO misam_info;
1488
1508
  char name_buff[FN_REFLEN];
1516
1536
    share->keys_for_keyread.intersect(share->keys_in_use);
1517
1537
    share->db_record_offset= misam_info.record_offset;
1518
1538
    if (share->key_parts)
1519
 
      memcpy(table->key_info[0].rec_per_key,
1520
 
             misam_info.rec_per_key,
 
1539
      memcpy((char*) table->key_info[0].rec_per_key,
 
1540
             (char*) misam_info.rec_per_key,
1521
1541
             sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1522
1542
    if (share->tmp_table == NO_TMP_TABLE)
1523
1543
      pthread_mutex_unlock(&share->mutex);
1552
1572
 
1553
1573
int ha_myisam::extra(enum ha_extra_function operation)
1554
1574
{
 
1575
  if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
 
1576
    return 0;
1555
1577
  return mi_extra(file, operation, 0);
1556
1578
}
1557
1579
 
1568
1590
 
1569
1591
int ha_myisam::extra_opt(enum ha_extra_function operation, uint32_t cache_size)
1570
1592
{
 
1593
  if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE)
 
1594
    return 0;
1571
1595
  return mi_extra(file, operation, (void*) &cache_size);
1572
1596
}
1573
1597
 
1590
1614
                                       F_UNLCK : F_EXTRA_LCK));
1591
1615
}
1592
1616
 
1593
 
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((unused)),
 
1617
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((__unused__)),
1594
1618
                                      THR_LOCK_DATA **to,
1595
1619
                                      enum thr_lock_type lock_type)
1596
1620
{
1612
1636
}
1613
1637
 
1614
1638
 
1615
 
int ha_myisam::create(const char *name, register Table *table_arg,
 
1639
int ha_myisam::create(const char *name, register TABLE *table_arg,
1616
1640
                      HA_CREATE_INFO *ha_create_info)
1617
1641
{
1618
1642
  int error;
1619
 
  uint32_t create_flags= 0, records;
 
1643
  uint create_flags= 0, records, i;
1620
1644
  char buff[FN_REFLEN];
1621
1645
  MI_KEYDEF *keydef;
1622
1646
  MI_COLUMNDEF *recinfo;
1623
1647
  MI_CREATE_INFO create_info;
1624
1648
  TABLE_SHARE *share= table_arg->s;
1625
 
  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
  }
1626
1658
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1627
1659
    return(error); /* purecov: inspected */
1628
 
  memset(&create_info, 0, sizeof(create_info));
 
1660
  bzero((char*) &create_info, sizeof(create_info));
1629
1661
  create_info.max_rows= share->max_rows;
1630
1662
  create_info.reloc_rows= share->min_rows;
1631
1663
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1656
1688
                   records, recinfo,
1657
1689
                   0, (MI_UNIQUEDEF*) 0,
1658
1690
                   &create_info, create_flags);
1659
 
  free((unsigned char*) recinfo);
 
1691
  my_free((uchar*) recinfo, MYF(0));
1660
1692
  return(error);
1661
1693
}
1662
1694
 
1667
1699
}
1668
1700
 
1669
1701
 
1670
 
void ha_myisam::get_auto_increment(uint64_t offset __attribute__((unused)),
1671
 
                                   uint64_t increment __attribute__((unused)),
1672
 
                                   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__)),
1673
1705
                                   uint64_t *first_value,
1674
1706
                                   uint64_t *nb_reserved_values)
1675
1707
{
1676
1708
  uint64_t nr;
1677
1709
  int error;
1678
 
  unsigned char key[MI_MAX_KEY_LENGTH];
 
1710
  uchar key[MI_MAX_KEY_LENGTH];
1679
1711
 
1680
1712
  if (!table->s->next_number_key_offset)
1681
1713
  {                                             // Autoincrement at key-start
1741
1773
                        the range.
1742
1774
*/
1743
1775
 
1744
 
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,
1745
1777
                                    key_range *max_key)
1746
1778
{
1747
1779
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1748
1780
}
1749
1781
 
1750
1782
 
1751
 
uint32_t ha_myisam::checksum() const
 
1783
uint ha_myisam::checksum() const
1752
1784
{
1753
1785
  return (uint)file->state->checksum;
1754
1786
}
1755
1787
 
1756
1788
 
1757
1789
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1758
 
                                           uint32_t table_changes)
 
1790
                                           uint table_changes)
1759
1791
{
1760
 
  uint32_t options= table->s->db_options_in_use;
 
1792
  uint options= table->s->db_options_in_use;
1761
1793
 
1762
1794
  if (info->auto_increment_value != stats.auto_increment_value ||
1763
1795
      info->data_file_name != data_file_name ||
1774
1806
  return COMPATIBLE_DATA_YES;
1775
1807
}
1776
1808
 
1777
 
int myisam_deinit(void *hton __attribute__((unused)))
 
1809
int myisam_panic(handlerton *hton __attribute__((__unused__)), ha_panic_function flag)
1778
1810
{
1779
 
  return mi_panic(HA_PANIC_CLOSE);
 
1811
  return mi_panic(flag);
1780
1812
}
1781
1813
 
1782
1814
static int myisam_init(void *p)
1785
1817
 
1786
1818
  myisam_hton= (handlerton *)p;
1787
1819
  myisam_hton->state= SHOW_OPTION_YES;
 
1820
  myisam_hton->db_type= DB_TYPE_MYISAM;
1788
1821
  myisam_hton->create= myisam_create_handler;
 
1822
  myisam_hton->panic= myisam_panic;
1789
1823
  myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
1790
1824
  return 0;
1791
1825
}
1797
1831
 ***************************************************************************/
1798
1832
 
1799
1833
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1800
 
                                     uint32_t n_ranges, uint32_t mode, 
 
1834
                                     uint n_ranges, uint mode, 
1801
1835
                                     HANDLER_BUFFER *buf)
1802
1836
{
1803
1837
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index], 
1809
1843
  return ds_mrr.dsmrr_next(this, range_info);
1810
1844
}
1811
1845
 
1812
 
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,
1813
1847
                                               void *seq_init_param, 
1814
 
                                               uint32_t n_ranges, uint32_t *bufsz,
1815
 
                                               uint32_t *flags, COST_VECT *cost)
 
1848
                                               uint n_ranges, uint *bufsz,
 
1849
                                               uint *flags, COST_VECT *cost)
1816
1850
{
1817
1851
  /*
1818
1852
    This call is here because there is no location where this->table would
1824
1858
                                 flags, cost);
1825
1859
}
1826
1860
 
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)
 
1861
int ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
 
1862
                                     uint *bufsz, uint *flags, COST_VECT *cost)
1829
1863
{
1830
1864
  ds_mrr.init(this, table);
1831
1865
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1837
1871
/* Index condition pushdown implementation*/
1838
1872
 
1839
1873
 
1840
 
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)
1841
1875
{
1842
1876
  pushed_idx_cond_keyno= keyno_arg;
1843
1877
  pushed_idx_cond= idx_cond_arg;
1850
1884
 
1851
1885
mysql_declare_plugin(myisam)
1852
1886
{
1853
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
1887
  MYSQL_STORAGE_ENGINE_PLUGIN,
1854
1888
  "MyISAM",
1855
1889
  "1.0",
1856
1890
  "MySQL AB",
1857
1891
  "Default engine as of MySQL 3.23 with great performance",
1858
1892
  PLUGIN_LICENSE_GPL,
1859
1893
  myisam_init, /* Plugin Init */
1860
 
  myisam_deinit, /* Plugin Deinit */
 
1894
  NULL, /* Plugin Deinit */
1861
1895
  NULL,                       /* status variables                */
1862
1896
  NULL,                       /* system variables                */
1863
1897
  NULL                        /* config options                  */