~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/ha_myisam.cc

  • Committer: Brian Aker
  • Date: 2010-04-05 23:46:43 UTC
  • Revision ID: brian@gaz-20100405234643-0he3xnj902rc70r8
Fixing tests to work with PBXT.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
 
18
 
#include <drizzled/server_includes.h>
19
 
#include <mysys/my_bit.h>
 
18
#include "config.h"
 
19
#include "drizzled/internal/my_bit.h"
20
20
#include "myisampack.h"
21
21
#include "ha_myisam.h"
22
 
#include "myisamdef.h"
23
 
#include <drizzled/util/test.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/errmsg_print.h>
26
 
#include <drizzled/gettext.h>
27
 
#include <drizzled/session.h>
28
 
#include <drizzled/protocol.h>
29
 
#include <drizzled/table.h>
30
 
#include <drizzled/field/timestamp.h>
 
22
#include "myisam_priv.h"
 
23
#include "drizzled/option.h"
 
24
#include "drizzled/internal/my_bit.h"
 
25
#include "drizzled/internal/m_string.h"
 
26
#include "drizzled/util/test.h"
 
27
#include "drizzled/error.h"
 
28
#include "drizzled/errmsg_print.h"
 
29
#include "drizzled/gettext.h"
 
30
#include "drizzled/session.h"
 
31
#include "drizzled/set_var.h"
 
32
#include <drizzled/plugin.h>
 
33
#include "drizzled/plugin/client.h"
 
34
#include "drizzled/table.h"
 
35
#include "drizzled/field/timestamp.h"
 
36
#include "drizzled/memory/multi_malloc.h"
 
37
#include "drizzled/plugin/daemon.h"
31
38
 
32
39
#include <string>
 
40
#include <sstream>
 
41
#include <map>
 
42
#include <algorithm>
33
43
 
34
44
using namespace std;
 
45
using namespace drizzled;
35
46
 
 
47
extern pthread_mutex_t LOCK_global_system_variables;
36
48
static const string engine_name("MyISAM");
37
49
 
38
 
ulong myisam_recover_options= HA_RECOVER_NONE;
39
50
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
40
51
 
41
52
static uint32_t repair_threads;
42
 
static uint32_t block_size;
 
53
static uint32_t myisam_key_cache_block_size;
 
54
static uint32_t myisam_key_cache_size;
 
55
static uint32_t myisam_key_cache_division_limit;
 
56
static uint32_t myisam_key_cache_age_threshold;
43
57
static uint64_t max_sort_file_size;
44
58
static uint64_t sort_buffer_size;
45
59
 
46
 
/* bits in myisam_recover_options */
47
 
const char *myisam_recover_names[] =
48
 
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
49
 
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
50
 
                                 myisam_recover_names, NULL};
51
 
 
52
 
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
53
 
                                           "nulls_ignored", NULL};
54
 
TYPELIB myisam_stats_method_typelib= {
55
 
  array_elements(myisam_stats_method_names) - 1, "",
56
 
  myisam_stats_method_names, NULL};
57
 
 
58
 
 
59
60
/*****************************************************************************
60
61
** MyISAM tables
61
62
*****************************************************************************/
62
63
 
63
 
class MyisamEngine : public StorageEngine
 
64
static const char *ha_myisam_exts[] = {
 
65
  ".MYI",
 
66
  ".MYD",
 
67
  NULL
 
68
};
 
69
 
 
70
class MyisamEngine : public plugin::StorageEngine
64
71
{
 
72
  MyisamEngine();
 
73
  MyisamEngine(const MyisamEngine&);
 
74
  MyisamEngine& operator=(const MyisamEngine&);
65
75
public:
66
 
  MyisamEngine(string name_arg)
67
 
   : StorageEngine(name_arg, HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES) {}
68
 
 
69
 
  virtual handler *create(TABLE_SHARE *table,
70
 
                          MEM_ROOT *mem_root)
71
 
  {
72
 
    return new (mem_root) ha_myisam(this, table);
73
 
  }
 
76
  explicit MyisamEngine(string name_arg) :
 
77
    plugin::StorageEngine(name_arg,
 
78
                          HTON_CAN_INDEX_BLOBS |
 
79
                          HTON_STATS_RECORDS_IS_EXACT |
 
80
                          HTON_TEMPORARY_ONLY |
 
81
                          HTON_NULL_IN_KEY |
 
82
                          HTON_HAS_RECORDS |
 
83
                          HTON_DUPLICATE_POS |
 
84
                          HTON_AUTO_PART_KEY |
 
85
                          HTON_SKIP_STORE_LOCK |
 
86
                          HTON_FILE_BASED )
 
87
  {
 
88
    pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
 
89
  }
 
90
 
 
91
  virtual ~MyisamEngine()
 
92
  { 
 
93
    pthread_mutex_destroy(&THR_LOCK_myisam);
 
94
    end_key_cache(dflt_key_cache, 1);           // Can never fail
 
95
 
 
96
    mi_panic(HA_PANIC_CLOSE);
 
97
  }
 
98
 
 
99
  virtual Cursor *create(TableShare &table,
 
100
                         memory::Root *mem_root)
 
101
  {
 
102
    return new (mem_root) ha_myisam(*this, table);
 
103
  }
 
104
 
 
105
  const char **bas_ext() const {
 
106
    return ha_myisam_exts;
 
107
  }
 
108
 
 
109
  int doCreateTable(Session&,
 
110
                    Table& table_arg,
 
111
                    drizzled::TableIdentifier &identifier,
 
112
                    message::Table&);
 
113
 
 
114
  int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
 
115
 
 
116
  int doDropTable(Session&, drizzled::TableIdentifier &identifier);
 
117
 
 
118
  int doGetTableDefinition(Session& session,
 
119
                           drizzled::TableIdentifier &identifier,
 
120
                           message::Table &table_message);
 
121
 
 
122
  /* Temp only engine, so do not return values. */
 
123
  void doGetTableNames(CachedDirectory &, SchemaIdentifier &, set<string>&) { };
 
124
 
 
125
  uint32_t max_supported_keys()          const { return MI_MAX_KEY; }
 
126
  uint32_t max_supported_key_length()    const { return MI_MAX_KEY_LENGTH; }
 
127
  uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
 
128
 
 
129
  uint32_t index_flags(enum  ha_key_alg) const
 
130
  {
 
131
    return (HA_READ_NEXT |
 
132
            HA_READ_PREV |
 
133
            HA_READ_RANGE |
 
134
            HA_READ_ORDER |
 
135
            HA_KEYREAD_ONLY);
 
136
  }
 
137
  bool doDoesTableExist(Session& session, TableIdentifier &identifier);
 
138
 
 
139
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
 
140
                             drizzled::SchemaIdentifier &schema_identifier,
 
141
                             drizzled::TableIdentifiers &set_of_identifiers);
74
142
};
75
143
 
76
 
// collect errors printed by mi_check routines
77
 
 
78
 
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
79
 
                               const char *fmt, va_list args)
80
 
{
81
 
  Session* session = (Session*)param->session;
82
 
  Protocol *protocol= session->protocol;
83
 
  uint32_t length, msg_length;
84
 
  char msgbuf[MI_MAX_MSG_BUF];
85
 
  char name[NAME_LEN*2+2];
86
 
 
87
 
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
88
 
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
89
 
 
90
 
  if (!session->protocol->isConnected())
91
 
  {
92
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",msgbuf);
93
 
    return;
94
 
  }
95
 
 
96
 
  if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
97
 
                         T_AUTO_REPAIR))
98
 
  {
99
 
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
100
 
    return;
101
 
  }
102
 
  length= sprintf(name,"%s.%s",param->db_name,param->table_name);
103
 
 
104
 
  /*
105
 
    TODO: switch from protocol to push_warning here. The main reason we didn't
106
 
    it yet is parallel repair. Due to following trace:
107
 
    mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
108
 
 
109
 
    Also we likely need to lock mutex here (in both cases with protocol and
110
 
    push_warning).
111
 
  */
112
 
  protocol->prepareForResend();
113
 
  protocol->store(name, length, system_charset_info);
114
 
  protocol->store(param->op_name, system_charset_info);
115
 
  protocol->store(msg_type, system_charset_info);
116
 
  protocol->store(msgbuf, msg_length, system_charset_info);
117
 
  if (protocol->write())
118
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Failed on drizzleclient_net_write, writing to stderr instead: %s\n",
119
 
                    msgbuf);
120
 
  return;
 
144
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
 
145
                                         drizzled::SchemaIdentifier&,
 
146
                                         drizzled::TableIdentifiers&)
 
147
{
 
148
}
 
149
 
 
150
bool MyisamEngine::doDoesTableExist(Session &session, TableIdentifier &identifier)
 
151
{
 
152
  return session.doesTableMessageExist(identifier);
 
153
}
 
154
 
 
155
int MyisamEngine::doGetTableDefinition(Session &session,
 
156
                                       drizzled::TableIdentifier &identifier,
 
157
                                       message::Table &table_message)
 
158
{
 
159
  if (session.getTableMessage(identifier, table_message))
 
160
    return EEXIST;
 
161
  return ENOENT;
 
162
}
 
163
 
 
164
/* 
 
165
  Convert to push_Warnings if you ever care about this, otherwise, it is a no-op.
 
166
*/
 
167
 
 
168
static void mi_check_print_msg(MI_CHECK *,      const char* ,
 
169
                               const char *, va_list )
 
170
{
121
171
}
122
172
 
123
173
 
137
187
    table conformance in merge engine.
138
188
 
139
189
    The caller needs to free *recinfo_out after use. Since *recinfo_out
140
 
    and *keydef_out are allocated with a my_multi_malloc, *keydef_out
 
190
    and *keydef_out are allocated with a multi_malloc, *keydef_out
141
191
    is freed automatically when *recinfo_out is freed.
142
192
 
143
193
  RETURN VALUE
145
195
    !0 error code
146
196
*/
147
197
 
148
 
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
149
 
                 MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
 
198
static int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
 
199
                        MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
150
200
{
151
201
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
152
202
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
155
205
  MI_KEYDEF *keydef;
156
206
  MI_COLUMNDEF *recinfo, *recinfo_pos;
157
207
  HA_KEYSEG *keyseg;
158
 
  TABLE_SHARE *share= table_arg->s;
 
208
  TableShare *share= table_arg->s;
159
209
  uint32_t options= share->db_options_in_use;
160
 
  if (!(my_multi_malloc(MYF(MY_WME),
 
210
  if (!(memory::multi_malloc(false,
161
211
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
162
212
          keydef_out, share->keys * sizeof(MI_KEYDEF),
163
 
          &keyseg,
164
 
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
 
213
          &keyseg, (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
165
214
          NULL)))
166
 
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
 
215
    return(HA_ERR_OUT_OF_MEM);
167
216
  keydef= *keydef_out;
168
217
  recinfo= *recinfo_out;
169
218
  pos= table_arg->key_info;
186
235
      {
187
236
        if (pos->key_part[j].length > 8 &&
188
237
            (type == HA_KEYTYPE_TEXT ||
189
 
             type == HA_KEYTYPE_NUM ||
190
238
             (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
191
239
        {
192
240
          /* No blobs here */
292
340
  return(0);
293
341
}
294
342
 
 
343
int ha_myisam::reset_auto_increment(uint64_t value)
 
344
{
 
345
  file->s->state.auto_increment= value;
 
346
  return 0;
 
347
}
295
348
 
296
349
/*
297
350
  Check for underlying table conformance
333
386
      (should be corretly detected in table2myisam).
334
387
*/
335
388
 
336
 
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
337
 
                     uint32_t t1_keys, uint32_t t1_recs,
338
 
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
339
 
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
 
389
static int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
 
390
                            uint32_t t1_keys, uint32_t t1_recs,
 
391
                            MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
 
392
                            uint32_t t2_keys, uint32_t t2_recs, bool strict)
340
393
{
341
394
  uint32_t i, j;
342
395
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
371
424
      {
372
425
        if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
373
426
            (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
374
 
          t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1; /* purecov: tested */
 
427
          t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1;
375
428
        else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
376
429
                 (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
377
 
          t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
 
430
          t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1;
378
431
      }
379
432
 
380
433
      if (t1_keysegs_j__type != t2_keysegs[j].type ||
408
461
}
409
462
 
410
463
 
411
 
extern "C" {
412
 
 
413
464
volatile int *killed_ptr(MI_CHECK *param)
414
465
{
415
466
  /* In theory Unsafe conversion, but should be ok for now */
481
532
  pthread_mutex_unlock(&file->s->intern_lock);
482
533
}
483
534
 
484
 
}
485
 
 
486
 
ha_myisam::ha_myisam(StorageEngine *engine_arg, TABLE_SHARE *table_arg)
487
 
  :handler(engine_arg, table_arg), file(0),
488
 
  int_table_flags(HA_NULL_IN_KEY |
489
 
                  HA_BINLOG_ROW_CAPABLE |
490
 
                  HA_BINLOG_STMT_CAPABLE |
491
 
                  HA_DUPLICATE_POS |
492
 
                  HA_CAN_INDEX_BLOBS |
493
 
                  HA_AUTO_PART_KEY |
494
 
                  HA_FILE_BASED |
495
 
                  HA_NO_TRANSACTIONS |
496
 
                  HA_HAS_RECORDS |
497
 
                  HA_STATS_RECORDS_IS_EXACT |
498
 
                  HA_NEED_READ_RANGE_BUFFER |
499
 
                  HA_MRR_CANT_SORT),
500
 
   can_enable_indexes(1)
501
 
{}
502
 
 
503
 
handler *ha_myisam::clone(MEM_ROOT *mem_root)
 
535
ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
 
536
                     TableShare &table_arg)
 
537
  : Cursor(engine_arg, table_arg),
 
538
  file(0),
 
539
  can_enable_indexes(true),
 
540
  is_ordered(true)
 
541
{ }
 
542
 
 
543
Cursor *ha_myisam::clone(memory::Root *mem_root)
504
544
{
505
 
  ha_myisam *new_handler= static_cast <ha_myisam *>(handler::clone(mem_root));
 
545
  ha_myisam *new_handler= static_cast <ha_myisam *>(Cursor::clone(mem_root));
506
546
  if (new_handler)
507
547
    new_handler->file->state= file->state;
508
548
  return new_handler;
509
549
}
510
550
 
511
 
 
512
 
static const char *ha_myisam_exts[] = {
513
 
  ".MYI",
514
 
  ".MYD",
515
 
  NULL
516
 
};
517
 
 
518
 
const char **ha_myisam::bas_ext() const
519
 
{
520
 
  return ha_myisam_exts;
521
 
}
522
 
 
523
 
 
524
551
const char *ha_myisam::index_type(uint32_t )
525
552
{
526
553
  return "BTREE";
549
576
    open of a table that is in use by other threads already (if the
550
577
    MyISAM share exists already).
551
578
  */
552
 
  if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
553
 
    return (my_errno ? my_errno : -1);
 
579
  if (!(file=mi_open(name, mode, test_if_locked)))
 
580
    return (errno ? errno : -1);
 
581
 
554
582
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
555
583
  {
556
 
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
 
584
    if ((errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
557
585
    {
558
 
      /* purecov: begin inspected */
559
586
      goto err;
560
 
      /* purecov: end */
561
587
    }
562
588
    if (check_definition(keyinfo, recinfo, table->s->keys, recs,
563
589
                         file->s->keyinfo, file->s->rec,
564
590
                         file->s->base.keys, file->s->base.fields, true))
565
591
    {
566
 
      /* purecov: begin inspected */
567
 
      my_errno= HA_ERR_CRASHED;
 
592
      errno= HA_ERR_CRASHED;
568
593
      goto err;
569
 
      /* purecov: end */
570
594
    }
571
595
  }
572
596
 
577
601
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
578
602
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
579
603
  if (!table->s->db_record_offset)
580
 
    int_table_flags|=HA_REC_NOT_IN_SEQ;
581
 
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
582
 
    int_table_flags|=HA_HAS_CHECKSUM;
583
 
 
584
 
  keys_with_parts.clear_all();
 
604
    is_ordered= false;
 
605
 
 
606
 
 
607
  keys_with_parts.reset();
585
608
  for (i= 0; i < table->s->keys; i++)
586
609
  {
587
610
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
590
613
    KEY_PART_INFO *kp_end= kp + table->key_info[i].key_parts;
591
614
    for (; kp != kp_end; kp++)
592
615
    {
593
 
      if (!kp->field->part_of_key.is_set(i))
 
616
      if (!kp->field->part_of_key.test(i))
594
617
      {
595
 
        keys_with_parts.set_bit(i);
 
618
        keys_with_parts.set(i);
596
619
        break;
597
620
      }
598
621
    }
599
622
  }
600
 
  my_errno= 0;
 
623
  errno= 0;
601
624
  goto end;
602
625
 err:
603
626
  this->close();
604
627
 end:
605
628
  /*
606
 
    Both recinfo and keydef are allocated by my_multi_malloc(), thus only
 
629
    Both recinfo and keydef are allocated by multi_malloc(), thus only
607
630
    recinfo must be freed.
608
631
  */
609
632
  if (recinfo)
610
633
    free((unsigned char*) recinfo);
611
 
  return my_errno;
 
634
  return errno;
612
635
}
613
636
 
614
637
int ha_myisam::close(void)
620
643
 
621
644
int ha_myisam::write_row(unsigned char *buf)
622
645
{
623
 
  ha_statistic_increment(&SSV::ha_write_count);
 
646
  ha_statistic_increment(&system_status_var::ha_write_count);
624
647
 
625
648
  /*
626
649
    If we have an auto_increment column and we are writing a changed row
635
658
  return mi_write(file,buf);
636
659
}
637
660
 
638
 
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
639
 
{
640
 
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
641
 
  int error;
642
 
  MI_CHECK param;
643
 
  MYISAM_SHARE* share = file->s;
644
 
  const char *old_proc_info= session->get_proc_info();
645
 
 
646
 
  session->set_proc_info("Checking table");
647
 
  myisamchk_init(&param);
648
 
  param.session = session;
649
 
  param.op_name =   "check";
650
 
  param.db_name=    table->s->db.str;
651
 
  param.table_name= table->alias;
652
 
  param.testflag = check_opt->flags | T_CHECK | T_SILENT;
653
 
  param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
654
 
 
655
 
  if (!(table->db_stat & HA_READ_ONLY))
656
 
    param.testflag|= T_STATISTICS;
657
 
  param.using_global_keycache = 1;
658
 
 
659
 
  if (!mi_is_crashed(file) &&
660
 
      (((param.testflag & T_CHECK_ONLY_CHANGED) &&
661
 
        !(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
662
 
                                  STATE_CRASHED_ON_REPAIR)) &&
663
 
        share->state.open_count == 0) ||
664
 
       ((param.testflag & T_FAST) && (share->state.open_count ==
665
 
                                      (uint) (share->global_changed ? 1 : 0)))))
666
 
    return HA_ADMIN_ALREADY_DONE;
667
 
 
668
 
  error = chk_status(&param, file);             // Not fatal
669
 
  error = chk_size(&param, file);
670
 
  if (!error)
671
 
    error |= chk_del(&param, file, param.testflag);
672
 
  if (!error)
673
 
    error = chk_key(&param, file);
674
 
  if (!error)
675
 
  {
676
 
    if ((!(param.testflag & T_QUICK) &&
677
 
         ((share->options &
678
 
           (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
679
 
          (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
680
 
        mi_is_crashed(file))
681
 
    {
682
 
      uint32_t old_testflag=param.testflag;
683
 
      param.testflag|=T_MEDIUM;
684
 
      if (!(error= init_io_cache(&param.read_cache, file->dfile,
685
 
                                 my_default_record_cache_size, READ_CACHE,
686
 
                                 share->pack.header_length, 1, MYF(MY_WME))))
687
 
      {
688
 
        error= chk_data_link(&param, file, param.testflag & T_EXTEND);
689
 
        end_io_cache(&(param.read_cache));
690
 
      }
691
 
      param.testflag= old_testflag;
692
 
    }
693
 
  }
694
 
  if (!error)
695
 
  {
696
 
    if ((share->state.changed & (STATE_CHANGED |
697
 
                                 STATE_CRASHED_ON_REPAIR |
698
 
                                 STATE_CRASHED | STATE_NOT_ANALYZED)) ||
699
 
        (param.testflag & T_STATISTICS) ||
700
 
        mi_is_crashed(file))
701
 
    {
702
 
      file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
703
 
      pthread_mutex_lock(&share->intern_lock);
704
 
      share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
705
 
                               STATE_CRASHED_ON_REPAIR);
706
 
      if (!(table->db_stat & HA_READ_ONLY))
707
 
        error=update_state_info(&param,file,UPDATE_TIME | UPDATE_OPEN_COUNT |
708
 
                                UPDATE_STAT);
709
 
      pthread_mutex_unlock(&share->intern_lock);
710
 
      info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
711
 
           HA_STATUS_CONST);
712
 
    }
713
 
  }
714
 
  else if (!mi_is_crashed(file) && !session->killed)
715
 
  {
716
 
    mi_mark_crashed(file);
717
 
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
718
 
  }
719
 
 
720
 
  session->set_proc_info(old_proc_info);
721
 
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
722
 
}
723
 
 
724
 
 
725
 
/*
726
 
  analyze the key distribution in the table
727
 
  As the table may be only locked for read, we have to take into account that
728
 
  two threads may do an analyze at the same time!
729
 
*/
730
 
 
731
 
int ha_myisam::analyze(Session *session,
732
 
                       HA_CHECK_OPT* )
733
 
{
734
 
  int error=0;
735
 
  MI_CHECK param;
736
 
  MYISAM_SHARE* share = file->s;
737
 
 
738
 
  myisamchk_init(&param);
739
 
  param.session = session;
740
 
  param.op_name=    "analyze";
741
 
  param.db_name=    table->s->db.str;
742
 
  param.table_name= table->alias;
743
 
  param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
744
 
                   T_DONT_CHECK_CHECKSUM);
745
 
  param.using_global_keycache = 1;
746
 
  param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
747
 
 
748
 
  if (!(share->state.changed & STATE_NOT_ANALYZED))
749
 
    return HA_ADMIN_ALREADY_DONE;
750
 
 
751
 
  error = chk_key(&param, file);
752
 
  if (!error)
753
 
  {
754
 
    pthread_mutex_lock(&share->intern_lock);
755
 
    error=update_state_info(&param,file,UPDATE_STAT);
756
 
    pthread_mutex_unlock(&share->intern_lock);
757
 
  }
758
 
  else if (!mi_is_crashed(file) && !session->killed)
759
 
    mi_mark_crashed(file);
760
 
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
761
 
}
762
 
 
763
 
 
764
 
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
765
 
{
766
 
  int error;
767
 
  MI_CHECK param;
768
 
  ha_rows start_records;
769
 
 
770
 
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
771
 
 
772
 
  myisamchk_init(&param);
773
 
  param.session = session;
774
 
  param.op_name=  "repair";
775
 
  param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
776
 
                   T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
777
 
                   (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
778
 
  param.sort_buffer_length=  (size_t)sort_buffer_size;
779
 
 
780
 
  // Release latches since this can take a long time
781
 
  ha_release_temporary_latches(session);
782
 
 
783
 
  start_records=file->state->records;
784
 
  while ((error=repair(session,param,0)) && param.retry_repair)
785
 
  {
786
 
    param.retry_repair=0;
787
 
    if (test_all_bits(param.testflag,
788
 
                      (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
789
 
    {
790
 
      param.testflag&= ~T_RETRY_WITHOUT_QUICK;
791
 
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' without quick",
792
 
                            table->s->path.str);
793
 
      continue;
794
 
    }
795
 
    param.testflag&= ~T_QUICK;
796
 
    if ((param.testflag & T_REP_BY_SORT))
797
 
    {
798
 
      param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
799
 
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' with keycache",
800
 
                            table->s->path.str);
801
 
      continue;
802
 
    }
803
 
    break;
804
 
  }
805
 
  if (!error && start_records != file->state->records &&
806
 
      !(check_opt->flags & T_VERY_SILENT))
807
 
  {
808
 
    char llbuff[22],llbuff2[22];
809
 
    errmsg_printf(ERRMSG_LVL_INFO, "Found %s of %s rows when repairing '%s'",
810
 
                          llstr(file->state->records, llbuff),
811
 
                          llstr(start_records, llbuff2),
812
 
                          table->s->path.str);
813
 
  }
814
 
  return error;
815
 
}
816
 
 
817
 
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
818
 
{
819
 
  int error;
820
 
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
821
 
  MI_CHECK param;
822
 
 
823
 
  myisamchk_init(&param);
824
 
  param.session = session;
825
 
  param.op_name= "optimize";
826
 
  param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
827
 
                   T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
828
 
  param.sort_buffer_length= (size_t)sort_buffer_size;
829
 
  if ((error= repair(session,param,1)) && param.retry_repair)
830
 
  {
831
 
    errmsg_printf(ERRMSG_LVL_WARN, "Warning: Optimize table got errno %d on %s.%s, retrying",
832
 
                      my_errno, param.db_name, param.table_name);
833
 
    param.testflag&= ~T_REP_BY_SORT;
834
 
    error= repair(session,param,1);
835
 
  }
836
 
  return error;
837
 
}
838
 
 
839
661
 
840
662
int ha_myisam::repair(Session *session, MI_CHECK &param, bool do_optimize)
841
663
{
863
685
    return(HA_ADMIN_FAILED);
864
686
  }
865
687
 
866
 
  param.db_name=    table->s->db.str;
 
688
  param.db_name=    table->s->getSchemaName();
867
689
  param.table_name= table->alias;
868
690
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
869
691
  param.using_global_keycache = 1;
873
695
  strcpy(fixed_name,file->filename);
874
696
 
875
697
  // Don't lock tables if we have used LOCK Table
876
 
  if (!session->locked_tables &&
877
 
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
 
698
  if (mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
878
699
  {
879
 
    mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
 
700
    mi_check_print_error(&param,ER(ER_CANT_LOCK),errno);
880
701
    return(HA_ADMIN_FAILED);
881
702
  }
882
703
 
899
720
      {
900
721
        char buf[40];
901
722
        /* TODO: respect myisam_repair_threads variable */
902
 
        snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
 
723
        snprintf(buf, 40, "Repair with %d threads", internal::my_count_bits(key_map));
903
724
        session->set_proc_info(buf);
904
725
        error = mi_repair_parallel(&param, file, fixed_name,
905
726
            param.testflag & T_QUICK);
972
793
    {
973
794
      char llbuff[22],llbuff2[22];
974
795
      mi_check_print_warning(&param,"Number of rows changed from %s to %s",
975
 
                             llstr(rows,llbuff),
976
 
                             llstr(file->state->records,llbuff2));
 
796
                             internal::llstr(rows,llbuff),
 
797
                             internal::llstr(file->state->records,llbuff2));
977
798
    }
978
799
  }
979
800
  else
983
804
    update_state_info(&param, file, 0);
984
805
  }
985
806
  session->set_proc_info(old_proc_info);
986
 
  if (!session->locked_tables)
987
 
    mi_lock_database(file,F_UNLCK);
 
807
  mi_lock_database(file,F_UNLCK);
 
808
 
988
809
  return(error ? HA_ADMIN_FAILED :
989
810
              !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
990
811
}
991
812
 
992
813
 
993
814
/*
994
 
  Assign table indexes to a specific key cache.
995
 
*/
996
 
 
997
 
int ha_myisam::assign_to_keycache(Session* session, HA_CHECK_OPT *check_opt)
998
 
{
999
 
  KEY_CACHE *new_key_cache= check_opt->key_cache;
1000
 
  const char *errmsg= 0;
1001
 
  int error= HA_ADMIN_OK;
1002
 
  uint64_t map;
1003
 
  TableList *table_list= table->pos_in_table_list;
1004
 
 
1005
 
  table->keys_in_use_for_query.clear_all();
1006
 
 
1007
 
  if (table_list->process_index_hints(table))
1008
 
    return(HA_ADMIN_FAILED);
1009
 
  map= ~(uint64_t) 0;
1010
 
  if (!table->keys_in_use_for_query.is_clear_all())
1011
 
    /* use all keys if there's no list specified by the user through hints */
1012
 
    map= table->keys_in_use_for_query.to_uint64_t();
1013
 
 
1014
 
  if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
1015
 
  {
1016
 
    char buf[STRING_BUFFER_USUAL_SIZE];
1017
 
    snprintf(buf, sizeof(buf),
1018
 
                "Failed to flush to index file (errno: %d)", error);
1019
 
    errmsg= buf;
1020
 
    error= HA_ADMIN_CORRUPT;
1021
 
  }
1022
 
 
1023
 
  if (error != HA_ADMIN_OK)
1024
 
  {
1025
 
    /* Send error to user */
1026
 
    MI_CHECK param;
1027
 
    myisamchk_init(&param);
1028
 
    param.session= session;
1029
 
    param.op_name=    "assign_to_keycache";
1030
 
    param.db_name=    table->s->db.str;
1031
 
    param.table_name= table->s->table_name.str;
1032
 
    param.testflag= 0;
1033
 
    mi_check_print_error(&param, errmsg);
1034
 
  }
1035
 
  return(error);
1036
 
}
1037
 
 
1038
 
 
1039
 
/*
1040
815
  Disable indexes, making it persistent if requested.
1041
816
 
1042
817
  SYNOPSIS
1095
870
    Enable indexes, which might have been disabled by disable_index() before.
1096
871
    The modes without _SAVE work only if both data and indexes are empty,
1097
872
    since the MyISAM repair would enable them persistently.
1098
 
    To be sure in these cases, call handler::delete_all_rows() before.
 
873
    To be sure in these cases, call Cursor::delete_all_rows() before.
1099
874
 
1100
875
  IMPLEMENTATION
1101
876
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
1139
914
                     T_CREATE_MISSING_KEYS);
1140
915
    param.myf_rw&= ~MY_WAIT_IF_FULL;
1141
916
    param.sort_buffer_length=  (size_t)sort_buffer_size;
1142
 
    param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
 
917
    param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
1143
918
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1144
919
    {
1145
920
      errmsg_printf(ERRMSG_LVL_WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
1146
 
                        my_errno, param.db_name, param.table_name);
 
921
                        errno, param.db_name, param.table_name);
1147
922
      /* Repairing by sort failed. Now try standard repair method. */
1148
923
      param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
1149
924
      error= (repair(session,param,0) != HA_ADMIN_OK);
1206
981
void ha_myisam::start_bulk_insert(ha_rows rows)
1207
982
{
1208
983
  Session *session= current_session;
1209
 
  ulong size= cmin(session->variables.read_buff_size,
1210
 
                  (ulong) (table->s->avg_row_length*rows));
 
984
  ulong size= session->variables.read_buff_size;
1211
985
 
1212
986
  /* don't enable row cache if too few rows */
1213
987
  if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1233
1007
                          (size_t)session->variables.bulk_insert_buff_size,
1234
1008
                          rows);
1235
1009
    }
1236
 
 
1237
 
  return;
1238
1010
}
1239
1011
 
1240
1012
/*
1259
1031
}
1260
1032
 
1261
1033
 
1262
 
bool ha_myisam::check_and_repair(Session *session)
1263
 
{
1264
 
  int error=0;
1265
 
  int marked_crashed;
1266
 
  char *old_query;
1267
 
  uint32_t old_query_length;
1268
 
  HA_CHECK_OPT check_opt;
1269
 
 
1270
 
  check_opt.init();
1271
 
  check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
1272
 
  // Don't use quick if deleted rows
1273
 
  if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
1274
 
    check_opt.flags|=T_QUICK;
1275
 
  errmsg_printf(ERRMSG_LVL_WARN, "Checking table:   '%s'",table->s->path.str);
1276
 
 
1277
 
  old_query= session->query;
1278
 
  old_query_length= session->query_length;
1279
 
  pthread_mutex_lock(&LOCK_thread_count);
1280
 
  session->query=        table->s->table_name.str;
1281
 
  session->query_length= table->s->table_name.length;
1282
 
  pthread_mutex_unlock(&LOCK_thread_count);
1283
 
 
1284
 
  if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
1285
 
  {
1286
 
    errmsg_printf(ERRMSG_LVL_WARN, "Recovering table: '%s'",table->s->path.str);
1287
 
    check_opt.flags=
1288
 
      ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
1289
 
       (marked_crashed                             ? 0 : T_QUICK) |
1290
 
       (myisam_recover_options & HA_RECOVER_FORCE  ? 0 : T_SAFE_REPAIR) |
1291
 
       T_AUTO_REPAIR);
1292
 
    if (repair(session, &check_opt))
1293
 
      error=1;
1294
 
  }
1295
 
  pthread_mutex_lock(&LOCK_thread_count);
1296
 
  session->query= old_query;
1297
 
  session->query_length= old_query_length;
1298
 
  pthread_mutex_unlock(&LOCK_thread_count);
1299
 
  return(error);
1300
 
}
1301
 
 
1302
 
bool ha_myisam::is_crashed() const
1303
 
{
1304
 
  return (file->s->state.changed & STATE_CRASHED ||
1305
 
          (file->s->state.open_count));
1306
 
}
1307
1034
 
1308
1035
int ha_myisam::update_row(const unsigned char *old_data, unsigned char *new_data)
1309
1036
{
1310
 
  ha_statistic_increment(&SSV::ha_update_count);
 
1037
  ha_statistic_increment(&system_status_var::ha_update_count);
1311
1038
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1312
1039
    table->timestamp_field->set_time();
1313
1040
  return mi_update(file,old_data,new_data);
1315
1042
 
1316
1043
int ha_myisam::delete_row(const unsigned char *buf)
1317
1044
{
1318
 
  ha_statistic_increment(&SSV::ha_delete_count);
 
1045
  ha_statistic_increment(&system_status_var::ha_delete_count);
1319
1046
  return mi_delete(file,buf);
1320
1047
}
1321
1048
 
1322
 
#ifdef __cplusplus
1323
 
extern "C" {
1324
 
#endif
1325
 
 
1326
 
bool index_cond_func_myisam(void *arg)
1327
 
{
1328
 
  ha_myisam *h= (ha_myisam*)arg;
1329
 
  /*if (h->in_range_read)*/
1330
 
  if (h->end_range)
1331
 
  {
1332
 
    if (h->compare_key2(h->end_range) > 0)
1333
 
      return 2; /* caller should return HA_ERR_END_OF_FILE already */
1334
 
  }
1335
 
  return (bool)h->pushed_idx_cond->val_int();
1336
 
}
1337
 
 
1338
 
#ifdef __cplusplus
1339
 
}
1340
 
#endif
1341
 
 
1342
1049
 
1343
1050
int ha_myisam::index_init(uint32_t idx, bool )
1344
1051
{
1345
1052
  active_index=idx;
1346
1053
  //in_range_read= false;
1347
 
  if (pushed_idx_cond_keyno == idx)
1348
 
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
1349
1054
  return 0;
1350
1055
}
1351
1056
 
1353
1058
int ha_myisam::index_end()
1354
1059
{
1355
1060
  active_index=MAX_KEY;
1356
 
  //pushed_idx_cond_keyno= MAX_KEY;
1357
 
  mi_set_index_cond_func(file, NULL, 0);
1358
 
  in_range_check_pushed_down= false;
1359
 
  ds_mrr.dsmrr_close();
1360
1061
  return 0;
1361
1062
}
1362
1063
 
1363
1064
 
1364
 
uint32_t ha_myisam::index_flags(uint32_t inx, uint32_t, bool) const
1365
 
{
1366
 
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
1367
 
          0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
1368
 
          HA_READ_ORDER | HA_KEYREAD_ONLY |
1369
 
          (keys_with_parts.is_set(inx)?0:HA_DO_INDEX_COND_PUSHDOWN));
1370
 
}
1371
 
 
1372
 
 
1373
1065
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
1374
1066
                              key_part_map keypart_map,
1375
1067
                              enum ha_rkey_function find_flag)
1376
1068
{
1377
1069
  assert(inited==INDEX);
1378
 
  ha_statistic_increment(&SSV::ha_read_key_count);
 
1070
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1379
1071
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1380
1072
  table->status=error ? STATUS_NOT_FOUND: 0;
1381
1073
  return error;
1385
1077
                                  key_part_map keypart_map,
1386
1078
                                  enum ha_rkey_function find_flag)
1387
1079
{
1388
 
  ha_statistic_increment(&SSV::ha_read_key_count);
 
1080
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1389
1081
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1390
1082
  table->status=error ? STATUS_NOT_FOUND: 0;
1391
1083
  return error;
1395
1087
                                   key_part_map keypart_map)
1396
1088
{
1397
1089
  assert(inited==INDEX);
1398
 
  ha_statistic_increment(&SSV::ha_read_key_count);
 
1090
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1399
1091
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1400
1092
                    HA_READ_PREFIX_LAST);
1401
1093
  table->status=error ? STATUS_NOT_FOUND: 0;
1405
1097
int ha_myisam::index_next(unsigned char *buf)
1406
1098
{
1407
1099
  assert(inited==INDEX);
1408
 
  ha_statistic_increment(&SSV::ha_read_next_count);
 
1100
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1409
1101
  int error=mi_rnext(file,buf,active_index);
1410
1102
  table->status=error ? STATUS_NOT_FOUND: 0;
1411
1103
  return error;
1414
1106
int ha_myisam::index_prev(unsigned char *buf)
1415
1107
{
1416
1108
  assert(inited==INDEX);
1417
 
  ha_statistic_increment(&SSV::ha_read_prev_count);
 
1109
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
1418
1110
  int error=mi_rprev(file,buf, active_index);
1419
1111
  table->status=error ? STATUS_NOT_FOUND: 0;
1420
1112
  return error;
1423
1115
int ha_myisam::index_first(unsigned char *buf)
1424
1116
{
1425
1117
  assert(inited==INDEX);
1426
 
  ha_statistic_increment(&SSV::ha_read_first_count);
 
1118
  ha_statistic_increment(&system_status_var::ha_read_first_count);
1427
1119
  int error=mi_rfirst(file, buf, active_index);
1428
1120
  table->status=error ? STATUS_NOT_FOUND: 0;
1429
1121
  return error;
1432
1124
int ha_myisam::index_last(unsigned char *buf)
1433
1125
{
1434
1126
  assert(inited==INDEX);
1435
 
  ha_statistic_increment(&SSV::ha_read_last_count);
 
1127
  ha_statistic_increment(&system_status_var::ha_read_last_count);
1436
1128
  int error=mi_rlast(file, buf, active_index);
1437
1129
  table->status=error ? STATUS_NOT_FOUND: 0;
1438
1130
  return error;
1444
1136
{
1445
1137
  int error;
1446
1138
  assert(inited==INDEX);
1447
 
  ha_statistic_increment(&SSV::ha_read_next_count);
 
1139
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1448
1140
  do
1449
1141
  {
1450
1142
    error= mi_rnext_same(file,buf);
1462
1154
  //if (!eq_range_arg)
1463
1155
  //  in_range_read= true;
1464
1156
 
1465
 
  res= handler::read_range_first(start_key, end_key, eq_range_arg, sorted);
 
1157
  res= Cursor::read_range_first(start_key, end_key, eq_range_arg, sorted);
1466
1158
 
1467
1159
  //if (res)
1468
1160
  //  in_range_read= false;
1472
1164
 
1473
1165
int ha_myisam::read_range_next()
1474
1166
{
1475
 
  int res= handler::read_range_next();
 
1167
  int res= Cursor::read_range_next();
1476
1168
  //if (res)
1477
1169
  //  in_range_read= false;
1478
1170
  return res;
1488
1180
 
1489
1181
int ha_myisam::rnd_next(unsigned char *buf)
1490
1182
{
1491
 
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
 
1183
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1492
1184
  int error=mi_scan(file, buf);
1493
1185
  table->status=error ? STATUS_NOT_FOUND: 0;
1494
1186
  return error;
1501
1193
 
1502
1194
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
1503
1195
{
1504
 
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1505
 
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
 
1196
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
 
1197
  int error=mi_rrnd(file, buf, internal::my_get_ptr(pos,ref_length));
1506
1198
  table->status=error ? STATUS_NOT_FOUND: 0;
1507
1199
  return error;
1508
1200
}
1510
1202
 
1511
1203
void ha_myisam::position(const unsigned char *)
1512
1204
{
1513
 
  my_off_t row_position= mi_position(file);
1514
 
  my_store_ptr(ref, ref_length, row_position);
 
1205
  internal::my_off_t row_position= mi_position(file);
 
1206
  internal::my_store_ptr(ref, ref_length, row_position);
1515
1207
}
1516
1208
 
1517
1209
int ha_myisam::info(uint32_t flag)
1532
1224
  }
1533
1225
  if (flag & HA_STATUS_CONST)
1534
1226
  {
1535
 
    TABLE_SHARE *share= table->s;
 
1227
    TableShare *share= table->s;
1536
1228
    stats.max_data_file_length=  misam_info.max_data_file_length;
1537
1229
    stats.max_index_file_length= misam_info.max_index_file_length;
1538
1230
    stats.create_time= misam_info.create_time;
1539
1231
    ref_length= misam_info.reflength;
1540
1232
    share->db_options_in_use= misam_info.options;
1541
 
    stats.block_size= block_size;        /* record block size */
 
1233
    stats.block_size= myisam_key_cache_block_size;        /* record block size */
1542
1234
 
1543
1235
    /* Update share */
1544
 
    if (share->tmp_table == NO_TMP_TABLE)
 
1236
    if (share->tmp_table == message::Table::STANDARD)
1545
1237
      pthread_mutex_lock(&share->mutex);
1546
 
    share->keys_in_use.set_prefix(share->keys);
1547
 
    share->keys_in_use.intersect_extended(misam_info.key_map);
1548
 
    share->keys_for_keyread.intersect(share->keys_in_use);
 
1238
    set_prefix(share->keys_in_use, share->keys);
 
1239
    /*
 
1240
     * Due to bug 394932 (32-bit solaris build failure), we need
 
1241
     * to convert the uint64_t key_map member of the misam_info
 
1242
     * structure in to a std::bitset so that we can logically and
 
1243
     * it with the share->key_in_use key_map.
 
1244
     */
 
1245
    ostringstream ostr;
 
1246
    string binary_key_map;
 
1247
    uint64_t num= misam_info.key_map;
 
1248
    /*
 
1249
     * Convert the uint64_t to a binary
 
1250
     * string representation of it.
 
1251
     */
 
1252
    while (num > 0)
 
1253
    {
 
1254
      uint64_t bin_digit= num % 2;
 
1255
      ostr << bin_digit;
 
1256
      num/= 2;
 
1257
    }
 
1258
    binary_key_map.append(ostr.str());
 
1259
    /*
 
1260
     * Now we have the binary string representation of the
 
1261
     * flags, we need to fill that string representation out
 
1262
     * with the appropriate number of bits. This is needed
 
1263
     * since key_map is declared as a std::bitset of a certain bit
 
1264
     * width that depends on the MAX_INDEXES variable. 
 
1265
     */
 
1266
    if (MAX_INDEXES <= 64)
 
1267
    {
 
1268
      size_t len= 72 - binary_key_map.length();
 
1269
      string all_zeros(len, '0');
 
1270
      binary_key_map.insert(binary_key_map.begin(),
 
1271
                            all_zeros.begin(),
 
1272
                            all_zeros.end());
 
1273
    }
 
1274
    else
 
1275
    {
 
1276
      size_t len= (MAX_INDEXES + 7) / 8 * 8;
 
1277
      string all_zeros(len, '0');
 
1278
      binary_key_map.insert(binary_key_map.begin(),
 
1279
                            all_zeros.begin(),
 
1280
                            all_zeros.end());
 
1281
    }
 
1282
    key_map tmp_map(binary_key_map);
 
1283
    share->keys_in_use&= tmp_map;
 
1284
    share->keys_for_keyread&= share->keys_in_use;
1549
1285
    share->db_record_offset= misam_info.record_offset;
1550
1286
    if (share->key_parts)
1551
1287
      memcpy(table->key_info[0].rec_per_key,
1552
1288
             misam_info.rec_per_key,
1553
1289
             sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1554
 
    if (share->tmp_table == NO_TMP_TABLE)
 
1290
    if (share->tmp_table == message::Table::STANDARD)
1555
1291
      pthread_mutex_unlock(&share->mutex);
1556
1292
 
1557
1293
   /*
1559
1295
     if table is symlinked (Ie;  Real name is not same as generated name)
1560
1296
   */
1561
1297
    data_file_name= index_file_name= 0;
1562
 
    fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
 
1298
    internal::fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
1563
1299
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1564
1300
    if (strcmp(name_buff, misam_info.data_file_name))
1565
1301
      data_file_name=misam_info.data_file_name;
1566
 
    fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
 
1302
    internal::fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
1567
1303
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1568
1304
    if (strcmp(name_buff, misam_info.index_file_name))
1569
1305
      index_file_name=misam_info.index_file_name;
1571
1307
  if (flag & HA_STATUS_ERRKEY)
1572
1308
  {
1573
1309
    errkey  = misam_info.errkey;
1574
 
    my_store_ptr(dup_ref, ref_length, misam_info.dupp_key_pos);
 
1310
    internal::my_store_ptr(dup_ref, ref_length, misam_info.dupp_key_pos);
1575
1311
  }
1576
1312
  if (flag & HA_STATUS_TIME)
1577
1313
    stats.update_time = misam_info.update_time;
1589
1325
 
1590
1326
int ha_myisam::reset(void)
1591
1327
{
1592
 
  pushed_idx_cond= NULL;
1593
 
  pushed_idx_cond_keyno= MAX_KEY;
1594
 
  mi_set_index_cond_func(file, NULL, 0);
1595
 
  ds_mrr.dsmrr_close();
1596
1328
  return mi_reset(file);
1597
1329
}
1598
1330
 
1608
1340
  return mi_delete_all_rows(file);
1609
1341
}
1610
1342
 
1611
 
int ha_myisam::delete_table(const char *name)
 
1343
int MyisamEngine::doDropTable(Session &session,
 
1344
                              drizzled::TableIdentifier &identifier)
1612
1345
{
1613
 
  return mi_delete_table(name);
 
1346
  session.removeTableMessage(identifier);
 
1347
 
 
1348
  return mi_delete_table(identifier.getPath().c_str());
1614
1349
}
1615
1350
 
1616
1351
 
1622
1357
                                       F_UNLCK : F_EXTRA_LCK));
1623
1358
}
1624
1359
 
1625
 
THR_LOCK_DATA **ha_myisam::store_lock(Session *,
1626
 
                                      THR_LOCK_DATA **to,
1627
 
                                      enum thr_lock_type lock_type)
1628
 
{
1629
 
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
1630
 
    file->lock.type=lock_type;
1631
 
  *to++= &file->lock;
1632
 
  return to;
1633
 
}
1634
 
 
1635
 
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
1636
 
{
1637
 
  ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
1638
 
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
1639
 
  {
1640
 
    create_info->auto_increment_value= stats.auto_increment_value;
1641
 
  }
1642
 
  create_info->data_file_name=data_file_name;
1643
 
  create_info->index_file_name=index_file_name;
1644
 
}
1645
 
 
1646
 
 
1647
 
int ha_myisam::create(const char *name, register Table *table_arg,
1648
 
                      HA_CREATE_INFO *ha_create_info)
 
1360
int MyisamEngine::doCreateTable(Session &session,
 
1361
                                Table& table_arg,
 
1362
                                drizzled::TableIdentifier &identifier,
 
1363
                                message::Table& create_proto)
1649
1364
{
1650
1365
  int error;
1651
1366
  uint32_t create_flags= 0, create_records;
1653
1368
  MI_KEYDEF *keydef;
1654
1369
  MI_COLUMNDEF *recinfo;
1655
1370
  MI_CREATE_INFO create_info;
1656
 
  TABLE_SHARE *share= table_arg->s;
 
1371
  TableShare *share= table_arg.s;
1657
1372
  uint32_t options= share->db_options_in_use;
1658
 
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &create_records)))
1659
 
    return(error); /* purecov: inspected */
 
1373
  if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
 
1374
    return(error);
1660
1375
  memset(&create_info, 0, sizeof(create_info));
1661
 
  create_info.max_rows= share->max_rows;
1662
 
  create_info.reloc_rows= share->min_rows;
 
1376
  create_info.max_rows= create_proto.options().max_rows();
 
1377
  create_info.reloc_rows= create_proto.options().min_rows();
1663
1378
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1664
 
  create_info.auto_increment= (ha_create_info->auto_increment_value ?
1665
 
                               ha_create_info->auto_increment_value -1 :
 
1379
  create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
 
1380
                               create_proto.options().auto_increment_value() -1 :
1666
1381
                               (uint64_t) 0);
1667
 
  create_info.data_file_length= ((uint64_t) share->max_rows *
1668
 
                                 share->avg_row_length);
1669
 
  create_info.data_file_name= ha_create_info->data_file_name;
1670
 
  create_info.index_file_name= ha_create_info->index_file_name;
 
1382
  create_info.data_file_length= (create_proto.options().max_rows() *
 
1383
                                 create_proto.options().avg_row_length());
 
1384
  create_info.data_file_name= NULL;
 
1385
  create_info.index_file_name=  NULL;
1671
1386
  create_info.language= share->table_charset->number;
1672
1387
 
1673
 
  if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
1388
  if (create_proto.type() == message::Table::TEMPORARY)
1674
1389
    create_flags|= HA_CREATE_TMP_TABLE;
1675
 
  if (ha_create_info->options & HA_CREATE_KEEP_FILES)
1676
 
    create_flags|= HA_CREATE_KEEP_FILES;
1677
1390
  if (options & HA_OPTION_PACK_RECORD)
1678
1391
    create_flags|= HA_PACK_RECORD;
1679
 
  if (options & HA_OPTION_CHECKSUM)
1680
 
    create_flags|= HA_CREATE_CHECKSUM;
1681
 
  if (options & HA_OPTION_DELAY_KEY_WRITE)
1682
 
    create_flags|= HA_CREATE_DELAY_KEY_WRITE;
1683
1392
 
1684
 
  /* TODO: Check that the following fn_format is really needed */
1685
 
  error= mi_create(fn_format(buff, name, "", "",
1686
 
                             MY_UNPACK_FILENAME|MY_APPEND_EXT),
 
1393
  /* TODO: Check that the following internal::fn_format is really needed */
 
1394
  error= mi_create(internal::fn_format(buff, identifier.getPath().c_str(), "", "",
 
1395
                                       MY_UNPACK_FILENAME|MY_APPEND_EXT),
1687
1396
                   share->keys, keydef,
1688
1397
                   create_records, recinfo,
1689
1398
                   0, (MI_UNIQUEDEF*) 0,
1690
1399
                   &create_info, create_flags);
1691
1400
  free((unsigned char*) recinfo);
1692
 
  return(error);
 
1401
 
 
1402
  session.storeTableMessage(identifier, create_proto);
 
1403
 
 
1404
  return error;
1693
1405
}
1694
1406
 
1695
1407
 
1696
 
int ha_myisam::rename_table(const char * from, const char * to)
 
1408
int MyisamEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
1697
1409
{
1698
 
  return mi_rename(from,to);
 
1410
  session.renameTableMessage(from, to);
 
1411
 
 
1412
  return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1699
1413
}
1700
1414
 
1701
1415
 
1785
1499
  return (uint)file->state->checksum;
1786
1500
}
1787
1501
 
1788
 
 
1789
 
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
1790
 
                                           uint32_t table_changes)
1791
 
{
1792
 
  uint32_t options= table->s->db_options_in_use;
1793
 
 
1794
 
  if (create_info->auto_increment_value != stats.auto_increment_value ||
1795
 
      create_info->data_file_name != data_file_name ||
1796
 
      create_info->index_file_name != index_file_name ||
1797
 
      table_changes == IS_EQUAL_NO ||
1798
 
      table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
1799
 
    return COMPATIBLE_DATA_NO;
1800
 
 
1801
 
  if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
1802
 
                  HA_OPTION_DELAY_KEY_WRITE)) !=
1803
 
      (create_info->table_options & (HA_OPTION_PACK_RECORD |
1804
 
                                     HA_OPTION_CHECKSUM |
1805
 
                              HA_OPTION_DELAY_KEY_WRITE)))
1806
 
    return COMPATIBLE_DATA_NO;
1807
 
  return COMPATIBLE_DATA_YES;
1808
 
}
1809
 
 
1810
1502
static MyisamEngine *engine= NULL;
1811
1503
 
1812
 
static int myisam_init(PluginRegistry &registry)
 
1504
static int myisam_init(plugin::Context &context)
1813
1505
{
1814
1506
  engine= new MyisamEngine(engine_name);
1815
 
  registry.add(engine);
1816
 
 
1817
 
  pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
 
1507
  context.add(engine);
 
1508
 
 
1509
  /* call ha_init_key_cache() on all key caches to init them */
 
1510
  int error= init_key_cache(dflt_key_cache,
 
1511
                            myisam_key_cache_block_size,
 
1512
                            myisam_key_cache_size,
 
1513
                            myisam_key_cache_division_limit, 
 
1514
                            myisam_key_cache_age_threshold);
 
1515
 
 
1516
  if (error == 0)
 
1517
    exit(1); /* Memory Allocation Failure */
1818
1518
 
1819
1519
  return 0;
1820
1520
}
1821
1521
 
1822
 
int myisam_deinit(PluginRegistry &registry)
1823
 
{
1824
 
  registry.remove(engine);
1825
 
  delete engine;
1826
 
 
1827
 
  pthread_mutex_destroy(&THR_LOCK_myisam);
1828
 
 
1829
 
  return mi_panic(HA_PANIC_CLOSE);
1830
 
}
1831
 
 
1832
 
 
1833
 
/****************************************************************************
1834
 
 * MyISAM MRR implementation: use DS-MRR
1835
 
 ***************************************************************************/
1836
 
 
1837
 
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1838
 
                                     uint32_t n_ranges, uint32_t mode,
1839
 
                                     HANDLER_BUFFER *buf)
1840
 
{
1841
 
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index],
1842
 
                           seq, seq_init_param, n_ranges, mode, buf);
1843
 
}
1844
 
 
1845
 
int ha_myisam::multi_range_read_next(char **range_info)
1846
 
{
1847
 
  return ds_mrr.dsmrr_next(this, range_info);
1848
 
}
1849
 
 
1850
 
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1851
 
                                               void *seq_init_param,
1852
 
                                               uint32_t n_ranges, uint32_t *bufsz,
1853
 
                                               uint32_t *flags, COST_VECT *cost)
1854
 
{
1855
 
  /*
1856
 
    This call is here because there is no location where this->table would
1857
 
    already be known.
1858
 
    TODO: consider moving it into some per-query initialization call.
1859
 
  */
1860
 
  ds_mrr.init(this, table);
1861
 
  return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
1862
 
                                 flags, cost);
1863
 
}
1864
 
 
1865
 
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1866
 
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1867
 
{
1868
 
  ds_mrr.init(this, table);
1869
 
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1870
 
}
1871
 
 
1872
 
/* MyISAM MRR implementation ends */
1873
 
 
1874
 
 
1875
 
/* Index condition pushdown implementation*/
1876
 
 
1877
 
 
1878
 
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
1879
 
{
1880
 
  pushed_idx_cond_keyno= keyno_arg;
1881
 
  pushed_idx_cond= idx_cond_arg;
1882
 
  in_range_check_pushed_down= true;
1883
 
  if (active_index == pushed_idx_cond_keyno)
1884
 
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
1885
 
  return NULL;
1886
 
}
1887
 
 
1888
 
static DRIZZLE_SYSVAR_UINT(block_size, block_size,
1889
 
                           PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1890
 
                           N_("Block size to be used for MyISAM index pages."),
1891
 
                           NULL, NULL, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, 
1892
 
                           MI_MAX_KEY_BLOCK_LENGTH, 0);
 
1522
 
 
1523
static void sys_var_key_cache_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1524
{
 
1525
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1526
  bool error= 0;
 
1527
 
 
1528
        struct option option_limits;
 
1529
  plugin_opt_set_limits(&option_limits, var);
 
1530
        option_limits.name= "myisam_key_cache_size";
 
1531
 
 
1532
  if (dflt_key_cache->in_init)
 
1533
    return;
 
1534
 
 
1535
  myisam_key_cache_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1536
 
 
1537
  /* If key cache didn't existed initialize it, else resize it */
 
1538
  dflt_key_cache->in_init= 1;
 
1539
 
 
1540
  error= ! resize_key_cache(dflt_key_cache,
 
1541
                                                                                                                myisam_key_cache_block_size,
 
1542
                            myisam_key_cache_size,
 
1543
                            myisam_key_cache_division_limit,
 
1544
                                                                                                          myisam_key_cache_age_threshold);
 
1545
  dflt_key_cache->in_init= 0;
 
1546
}
 
1547
 
 
1548
static void sys_var_key_cache_block_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1549
{
 
1550
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1551
  bool error= 0;
 
1552
 
 
1553
        struct option option_limits;
 
1554
  plugin_opt_set_limits(&option_limits, var);
 
1555
        option_limits.name= "myisam_key_cache_block_size";
 
1556
 
 
1557
  if (dflt_key_cache->in_init)
 
1558
    return;
 
1559
 
 
1560
  myisam_key_cache_block_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1561
 
 
1562
  dflt_key_cache->in_init= 1;
 
1563
 
 
1564
  error= ! resize_key_cache(dflt_key_cache,
 
1565
                                                                                                                myisam_key_cache_block_size,
 
1566
                            myisam_key_cache_size,
 
1567
                            myisam_key_cache_division_limit,
 
1568
                                                                                                          myisam_key_cache_age_threshold);
 
1569
 
 
1570
  dflt_key_cache->in_init= 0;
 
1571
}
 
1572
 
 
1573
static void sys_var_key_cache_division_limit_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1574
{
 
1575
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1576
  bool error= 0;
 
1577
 
 
1578
        struct option option_limits;
 
1579
  plugin_opt_set_limits(&option_limits, var);
 
1580
        option_limits.name= "myisam_key_cache_division_limit";
 
1581
 
 
1582
  if (dflt_key_cache->in_init)
 
1583
    return;
 
1584
 
 
1585
  myisam_key_cache_division_limit= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1586
 
 
1587
  dflt_key_cache->in_init= 1;
 
1588
 
 
1589
  error= ! resize_key_cache(dflt_key_cache,
 
1590
                                                                                                                myisam_key_cache_block_size,
 
1591
                            myisam_key_cache_size,
 
1592
                            myisam_key_cache_division_limit,
 
1593
                                                                                                          myisam_key_cache_age_threshold);
 
1594
 
 
1595
  dflt_key_cache->in_init= 0;
 
1596
}
 
1597
 
 
1598
static void sys_var_key_cache_age_threshold_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1599
{
 
1600
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1601
  bool error= 0;
 
1602
 
 
1603
        struct option option_limits;
 
1604
  plugin_opt_set_limits(&option_limits, var);
 
1605
        option_limits.name= "myisam_key_cache_age_threshold";
 
1606
 
 
1607
  if (dflt_key_cache->in_init)
 
1608
    return;
 
1609
 
 
1610
  myisam_key_cache_age_threshold= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1611
 
 
1612
  dflt_key_cache->in_init= 1;
 
1613
 
 
1614
  error= ! resize_key_cache(dflt_key_cache,
 
1615
                                                                                                                myisam_key_cache_block_size,
 
1616
                            myisam_key_cache_size,
 
1617
                            myisam_key_cache_division_limit,
 
1618
                                                                                                          myisam_key_cache_age_threshold);
 
1619
 
 
1620
  dflt_key_cache->in_init= 0;
 
1621
}
 
1622
 
 
1623
static DRIZZLE_SYSVAR_UINT(key_cache_block_size,
 
1624
                            myisam_key_cache_block_size,
 
1625
                            PLUGIN_VAR_RQCMDARG,
 
1626
                            N_("Block size to be used for MyISAM index pages."),
 
1627
                            NULL,
 
1628
                            sys_var_key_cache_block_size_update,
 
1629
                            KEY_CACHE_BLOCK_SIZE,
 
1630
                            512, 
 
1631
                            16 * 1024,
 
1632
                            0);
 
1633
 
 
1634
static DRIZZLE_SYSVAR_UINT(key_cache_age_threshold, myisam_key_cache_age_threshold,
 
1635
                            PLUGIN_VAR_RQCMDARG,
 
1636
                            N_("This characterizes the number of hits a hot block has to be untouched "
 
1637
                            "until it is considered aged enough to be downgraded to a warm block. "
 
1638
                            "This specifies the percentage ratio of that number of hits to the "
 
1639
                            "total number of blocks in key cache"),
 
1640
                            NULL,
 
1641
                            sys_var_key_cache_age_threshold_update,
 
1642
                            300,
 
1643
                            100, 
 
1644
                            UINT32_MAX,
 
1645
                            0);
 
1646
 
 
1647
static DRIZZLE_SYSVAR_UINT(key_cache_division_limit, myisam_key_cache_division_limit,
 
1648
                            PLUGIN_VAR_RQCMDARG,
 
1649
                            N_("The minimum percentage of warm blocks in key cache"),
 
1650
                            NULL,
 
1651
                            sys_var_key_cache_division_limit_update,
 
1652
                            100,
 
1653
                            1, 
 
1654
                            100,
 
1655
                            0);
 
1656
 
 
1657
static DRIZZLE_SYSVAR_UINT(key_cache_size,
 
1658
                            myisam_key_cache_size,
 
1659
                            PLUGIN_VAR_RQCMDARG,
 
1660
                            N_("The size of the buffer used for index blocks for MyISAM tables. "
 
1661
                            "Increase this to get better index handling (for all reads and multiple "
 
1662
                            "writes) to as much as you can afford;"),
 
1663
                            NULL,
 
1664
                            sys_var_key_cache_size_update,
 
1665
                            KEY_CACHE_SIZE,
 
1666
                            1 * 1024 * 1024, 
 
1667
                            UINT32_MAX,
 
1668
                            IO_SIZE);
1893
1669
 
1894
1670
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
1895
 
                           PLUGIN_VAR_RQCMDARG,
1896
 
                           N_("Number of threads to use when repairing MyISAM tables. The value of "
1897
 
                              "1 disables parallel repair."),
1898
 
                           NULL, NULL, 1, 1, UINT32_MAX, 0);
 
1671
                            PLUGIN_VAR_RQCMDARG,
 
1672
                            N_("Number of threads to use when repairing MyISAM tables. The value of "
 
1673
                            "1 disables parallel repair."),
 
1674
                            NULL, NULL, 1, 1, UINT32_MAX, 0);
1899
1675
 
1900
1676
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
1901
1677
                                PLUGIN_VAR_RQCMDARG,
1909
1685
 
1910
1686
extern uint32_t data_pointer_size;
1911
1687
static DRIZZLE_SYSVAR_UINT(data_pointer_size, data_pointer_size,
1912
 
                           PLUGIN_VAR_RQCMDARG,
1913
 
                           N_("Default pointer size to be used for MyISAM tables."),
1914
 
                           NULL, NULL, 6, 2, 7, 0);
 
1688
                            PLUGIN_VAR_RQCMDARG,
 
1689
                            N_("Default pointer size to be used for MyISAM tables."),
 
1690
                            NULL, NULL, 6, 2, 7, 0);
1915
1691
 
1916
 
static struct st_mysql_sys_var* system_variables[]= {
1917
 
  DRIZZLE_SYSVAR(block_size),
 
1692
static drizzle_sys_var* sys_variables[]= {
 
1693
  DRIZZLE_SYSVAR(key_cache_block_size),
 
1694
  DRIZZLE_SYSVAR(key_cache_size),
 
1695
  DRIZZLE_SYSVAR(key_cache_division_limit),
 
1696
  DRIZZLE_SYSVAR(key_cache_age_threshold),
1918
1697
  DRIZZLE_SYSVAR(repair_threads),
1919
1698
  DRIZZLE_SYSVAR(max_sort_file_size),
1920
1699
  DRIZZLE_SYSVAR(sort_buffer_size),
1923
1702
};
1924
1703
 
1925
1704
 
1926
 
drizzle_declare_plugin(myisam)
 
1705
DRIZZLE_DECLARE_PLUGIN
1927
1706
{
 
1707
  DRIZZLE_VERSION_ID,
1928
1708
  "MyISAM",
1929
1709
  "1.0",
1930
1710
  "MySQL AB",
1931
1711
  "Default engine as of MySQL 3.23 with great performance",
1932
1712
  PLUGIN_LICENSE_GPL,
1933
1713
  myisam_init, /* Plugin Init */
1934
 
  myisam_deinit, /* Plugin Deinit */
1935
 
  NULL,                       /* status variables                */
1936
 
  system_variables,           /* system variables */
 
1714
  sys_variables,           /* system variables */
1937
1715
  NULL                        /* config options                  */
1938
1716
}
1939
 
drizzle_declare_plugin_end;
 
1717
DRIZZLE_DECLARE_PLUGIN_END;