~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/ha_myisam.cc

  • Committer: Brian Aker
  • Date: 2009-08-21 18:46:31 UTC
  • mto: This revision was merged to the branch mainline in revision 1123.
  • Revision ID: brian@gaz-20090821184631-e11gja79070fvhk4
Cleanup around page checksum removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
 
#ifdef USE_PRAGMA_IMPLEMENTATION
18
 
#pragma implementation                          // gcc: Class implementation
19
 
#endif
20
 
 
21
 
#define DRIZZLE_SERVER 1
22
17
 
23
18
#include <drizzled/server_includes.h>
24
19
#include <mysys/my_bit.h>
25
 
#include <myisampack.h>
 
20
#include "myisampack.h"
26
21
#include "ha_myisam.h"
27
22
#include "myisamdef.h"
28
 
#include <drizzled/drizzled_error_messages.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/plugin/protocol.h>
 
29
#include <drizzled/table.h>
 
30
#include <drizzled/field/timestamp.h>
 
31
 
 
32
#include <string>
 
33
#include <algorithm>
 
34
 
 
35
using namespace std;
 
36
 
 
37
static const string engine_name("MyISAM");
29
38
 
30
39
ulong myisam_recover_options= HA_RECOVER_NONE;
 
40
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
 
41
 
 
42
static uint32_t repair_threads;
 
43
static uint32_t block_size;
 
44
static uint64_t max_sort_file_size;
 
45
static uint64_t sort_buffer_size;
31
46
 
32
47
/* bits in myisam_recover_options */
33
48
const char *myisam_recover_names[] =
34
49
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
35
50
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
36
 
                                 myisam_recover_names, NULL};
 
51
                                 myisam_recover_names, NULL};
37
52
 
38
 
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
39
 
                                           "nulls_ignored", NULL};
40
 
TYPELIB myisam_stats_method_typelib= {
41
 
  array_elements(myisam_stats_method_names) - 1, "",
42
 
  myisam_stats_method_names, NULL};
43
53
 
44
54
 
45
55
/*****************************************************************************
46
56
** MyISAM tables
47
57
*****************************************************************************/
48
58
 
49
 
static handler *myisam_create_handler(handlerton *hton,
50
 
                                      TABLE_SHARE *table, 
51
 
                                      MEM_ROOT *mem_root)
 
59
static const char *ha_myisam_exts[] = {
 
60
  ".MYI",
 
61
  ".MYD",
 
62
  NULL
 
63
};
 
64
 
 
65
class MyisamEngine : public StorageEngine
52
66
{
53
 
  return new (mem_root) ha_myisam(hton, table);
54
 
}
 
67
public:
 
68
  MyisamEngine(string name_arg)
 
69
   : StorageEngine(name_arg, 
 
70
                   HTON_CAN_RECREATE | 
 
71
                   HTON_TEMPORARY_ONLY | 
 
72
                   HTON_FILE_BASED |
 
73
                   HTON_DATA_DIR |
 
74
                   HTON_INDEX_DIR) {}
 
75
 
 
76
  virtual handler *create(TableShare *table,
 
77
                          MEM_ROOT *mem_root)
 
78
  {
 
79
    return new (mem_root) ha_myisam(this, table);
 
80
  }
 
81
 
 
82
  const char **bas_ext() const {
 
83
    return ha_myisam_exts;
 
84
  }
 
85
 
 
86
  int createTableImplementation(Session *, const char *table_name,
 
87
                                Table *table_arg,
 
88
                                HA_CREATE_INFO *ha_create_info,
 
89
                                drizzled::message::Table*);
 
90
 
 
91
  int renameTableImplementation(Session*, const char *from, const char *to);
 
92
 
 
93
  int deleteTableImplementation(Session*, const string table_name);
 
94
};
55
95
 
56
96
// collect errors printed by mi_check routines
57
97
 
58
98
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
59
 
                               const char *fmt, va_list args)
 
99
                               const char *fmt, va_list args)
60
100
{
61
 
  THD* thd = (THD*)param->thd;
62
 
  Protocol *protocol= thd->protocol;
 
101
  Session* session = (Session*)param->session;
 
102
  drizzled::plugin::Protocol *protocol= session->protocol;
63
103
  uint32_t length, msg_length;
64
104
  char msgbuf[MI_MAX_MSG_BUF];
65
105
  char name[NAME_LEN*2+2];
67
107
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
68
108
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
69
109
 
70
 
  if (!thd->vio_ok())
 
110
  if (!session->protocol->isConnected())
71
111
  {
72
 
    sql_print_error(msgbuf);
 
112
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",msgbuf);
73
113
    return;
74
114
  }
75
115
 
79
119
    my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
80
120
    return;
81
121
  }
82
 
  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NULL) -
83
 
                 name);
 
122
  length= sprintf(name,"%s.%s",param->db_name,param->table_name);
 
123
 
84
124
  /*
85
125
    TODO: switch from protocol to push_warning here. The main reason we didn't
86
126
    it yet is parallel repair. Due to following trace:
89
129
    Also we likely need to lock mutex here (in both cases with protocol and
90
130
    push_warning).
91
131
  */
92
 
  protocol->prepare_for_resend();
93
 
  protocol->store(name, length, system_charset_info);
94
 
  protocol->store(param->op_name, system_charset_info);
95
 
  protocol->store(msg_type, system_charset_info);
96
 
  protocol->store(msgbuf, msg_length, system_charset_info);
 
132
  protocol->prepareForResend();
 
133
  protocol->store(name, length);
 
134
  protocol->store(param->op_name);
 
135
  protocol->store(msg_type);
 
136
  protocol->store(msgbuf, msg_length);
97
137
  if (protocol->write())
98
 
    sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
 
138
    errmsg_printf(ERRMSG_LVL_ERROR, "Failed on drizzleclient_net_write, writing to stderr instead: %s\n",
99
139
                    msgbuf);
100
140
  return;
101
141
}
125
165
    !0 error code
126
166
*/
127
167
 
128
 
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
129
 
                 MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
 
168
static int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
 
169
                        MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
130
170
{
131
171
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
132
172
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
135
175
  MI_KEYDEF *keydef;
136
176
  MI_COLUMNDEF *recinfo, *recinfo_pos;
137
177
  HA_KEYSEG *keyseg;
138
 
  TABLE_SHARE *share= table_arg->s;
 
178
  TableShare *share= table_arg->s;
139
179
  uint32_t options= share->db_options_in_use;
140
180
  if (!(my_multi_malloc(MYF(MY_WME),
141
181
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
212
252
  record= table_arg->record[0];
213
253
  recpos= 0;
214
254
  recinfo_pos= recinfo;
215
 
  while (recpos < (uint) share->reclength)
 
255
  while (recpos < (uint) share->stored_rec_length)
216
256
  {
217
257
    Field **field, *found= 0;
218
258
    minpos= share->reclength;
313
353
      (should be corretly detected in table2myisam).
314
354
*/
315
355
 
316
 
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
317
 
                     uint32_t t1_keys, uint32_t t1_recs,
318
 
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
319
 
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
 
356
static int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
 
357
                            uint32_t t1_keys, uint32_t t1_recs,
 
358
                            MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
 
359
                            uint32_t t2_keys, uint32_t t2_recs, bool strict)
320
360
{
321
361
  uint32_t i, j;
322
362
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
393
433
volatile int *killed_ptr(MI_CHECK *param)
394
434
{
395
435
  /* In theory Unsafe conversion, but should be ok for now */
396
 
  return (int*) &(((THD *)(param->thd))->killed);
 
436
  return (int*) &(((Session *)(param->session))->killed);
397
437
}
398
438
 
399
439
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
442
482
void _mi_report_crashed(MI_INFO *file, const char *message,
443
483
                        const char *sfile, uint32_t sline)
444
484
{
445
 
  THD *cur_thd;
446
 
  LIST *element;
 
485
  Session *cur_session;
447
486
  pthread_mutex_lock(&file->s->intern_lock);
448
 
  if ((cur_thd= (THD*) file->in_use.data))
449
 
    sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
 
487
  if ((cur_session= file->in_use))
 
488
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
 
489
                    cur_session->thread_id,
450
490
                    sfile, sline);
451
491
  else
452
 
    sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline);
 
492
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from unknown thread, %s:%d"), sfile, sline);
453
493
  if (message)
454
 
    sql_print_error("%s", message);
455
 
  for (element= file->s->in_use; element; element= list_rest(element))
 
494
    errmsg_printf(ERRMSG_LVL_ERROR, "%s", message);
 
495
  list<Session *>::iterator it= file->s->in_use->begin();
 
496
  while (it != file->s->in_use->end())
456
497
  {
457
 
    sql_print_error("%s", "Unknown thread accessing table");
 
498
    errmsg_printf(ERRMSG_LVL_ERROR, "%s", _("Unknown thread accessing table"));
 
499
    ++it;
458
500
  }
459
501
  pthread_mutex_unlock(&file->s->intern_lock);
460
502
}
461
503
 
462
504
}
463
505
 
464
 
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
465
 
  :handler(hton, table_arg), file(0),
 
506
ha_myisam::ha_myisam(StorageEngine *engine_arg, TableShare *table_arg)
 
507
  :handler(engine_arg, table_arg), file(0),
466
508
  int_table_flags(HA_NULL_IN_KEY |
467
 
                  HA_BINLOG_ROW_CAPABLE |
468
 
                  HA_BINLOG_STMT_CAPABLE |
469
509
                  HA_DUPLICATE_POS |
470
510
                  HA_CAN_INDEX_BLOBS |
471
511
                  HA_AUTO_PART_KEY |
472
 
                  HA_FILE_BASED |
473
512
                  HA_NO_TRANSACTIONS |
474
513
                  HA_HAS_RECORDS |
475
514
                  HA_STATS_RECORDS_IS_EXACT |
486
525
  return new_handler;
487
526
}
488
527
 
489
 
 
490
 
static const char *ha_myisam_exts[] = {
491
 
  ".MYI",
492
 
  ".MYD",
493
 
  NULL
494
 
};
495
 
 
496
 
const char **ha_myisam::bas_ext() const
497
 
{
498
 
  return ha_myisam_exts;
499
 
}
500
 
 
501
 
 
502
 
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
 
528
const char *ha_myisam::index_type(uint32_t )
503
529
{
504
530
  return "BTREE";
505
531
}
527
553
    open of a table that is in use by other threads already (if the
528
554
    MyISAM share exists already).
529
555
  */
530
 
  if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
 
556
  if (!(file=mi_open(name, mode, test_if_locked)))
531
557
    return (my_errno ? my_errno : -1);
 
558
 
532
559
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
533
560
  {
534
561
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
547
574
      /* purecov: end */
548
575
    }
549
576
  }
550
 
  
 
577
 
551
578
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
552
579
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
553
580
 
556
583
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
557
584
  if (!table->s->db_record_offset)
558
585
    int_table_flags|=HA_REC_NOT_IN_SEQ;
559
 
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
560
 
    int_table_flags|=HA_HAS_CHECKSUM;
561
 
  
562
 
  keys_with_parts.clear_all();
 
586
 
 
587
  keys_with_parts.reset();
563
588
  for (i= 0; i < table->s->keys; i++)
564
589
  {
565
590
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
568
593
    KEY_PART_INFO *kp_end= kp + table->key_info[i].key_parts;
569
594
    for (; kp != kp_end; kp++)
570
595
    {
571
 
      if (!kp->field->part_of_key.is_set(i))
 
596
      if (!kp->field->part_of_key.test(i))
572
597
      {
573
 
        keys_with_parts.set_bit(i);
 
598
        keys_with_parts.set(i);
574
599
        break;
575
600
      }
576
601
    }
600
625
{
601
626
  ha_statistic_increment(&SSV::ha_write_count);
602
627
 
603
 
  /* If we have a timestamp column, update it to the current time */
604
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
605
 
    table->timestamp_field->set_time();
606
 
 
607
628
  /*
608
629
    If we have an auto_increment column and we are writing a changed row
609
630
    or a new row, then update the auto_increment value in the record.
617
638
  return mi_write(file,buf);
618
639
}
619
640
 
620
 
int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
 
641
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
621
642
{
622
643
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
623
644
  int error;
624
645
  MI_CHECK param;
625
646
  MYISAM_SHARE* share = file->s;
626
 
  const char *old_proc_info= thd->get_proc_info();
 
647
  const char *old_proc_info= session->get_proc_info();
627
648
 
628
 
  thd_proc_info(thd, "Checking table");
 
649
  session->set_proc_info("Checking table");
629
650
  myisamchk_init(&param);
630
 
  param.thd = thd;
 
651
  param.session = session;
631
652
  param.op_name =   "check";
632
653
  param.db_name=    table->s->db.str;
633
654
  param.table_name= table->alias;
634
655
  param.testflag = check_opt->flags | T_CHECK | T_SILENT;
635
 
  param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
 
656
  param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
636
657
 
637
658
  if (!(table->db_stat & HA_READ_ONLY))
638
659
    param.testflag|= T_STATISTICS;
693
714
           HA_STATUS_CONST);
694
715
    }
695
716
  }
696
 
  else if (!mi_is_crashed(file) && !thd->killed)
 
717
  else if (!mi_is_crashed(file) && !session->killed)
697
718
  {
698
719
    mi_mark_crashed(file);
699
720
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
700
721
  }
701
722
 
702
 
  thd_proc_info(thd, old_proc_info);
 
723
  session->set_proc_info(old_proc_info);
703
724
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
704
725
}
705
726
 
710
731
  two threads may do an analyze at the same time!
711
732
*/
712
733
 
713
 
int ha_myisam::analyze(THD *thd,
714
 
                       HA_CHECK_OPT* check_opt __attribute__((unused)))
 
734
int ha_myisam::analyze(Session *session,
 
735
                       HA_CHECK_OPT* )
715
736
{
716
737
  int error=0;
717
738
  MI_CHECK param;
718
739
  MYISAM_SHARE* share = file->s;
719
740
 
720
741
  myisamchk_init(&param);
721
 
  param.thd = thd;
 
742
  param.session = session;
722
743
  param.op_name=    "analyze";
723
744
  param.db_name=    table->s->db.str;
724
745
  param.table_name= table->alias;
725
746
  param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
726
747
                   T_DONT_CHECK_CHECKSUM);
727
748
  param.using_global_keycache = 1;
728
 
  param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
 
749
  param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
729
750
 
730
751
  if (!(share->state.changed & STATE_NOT_ANALYZED))
731
752
    return HA_ADMIN_ALREADY_DONE;
737
758
    error=update_state_info(&param,file,UPDATE_STAT);
738
759
    pthread_mutex_unlock(&share->intern_lock);
739
760
  }
740
 
  else if (!mi_is_crashed(file) && !thd->killed)
 
761
  else if (!mi_is_crashed(file) && !session->killed)
741
762
    mi_mark_crashed(file);
742
763
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
743
764
}
744
765
 
745
766
 
746
 
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
 
767
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
747
768
{
748
769
  int error;
749
770
  MI_CHECK param;
752
773
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
753
774
 
754
775
  myisamchk_init(&param);
755
 
  param.thd = thd;
 
776
  param.session = session;
756
777
  param.op_name=  "repair";
757
778
  param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
758
779
                   T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
759
780
                   (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
760
 
  param.sort_buffer_length=  check_opt->sort_buffer_size;
 
781
  param.sort_buffer_length=  (size_t)sort_buffer_size;
 
782
 
 
783
  // Release latches since this can take a long time
 
784
  ha_release_temporary_latches(session);
 
785
 
761
786
  start_records=file->state->records;
762
 
  while ((error=repair(thd,param,0)) && param.retry_repair)
 
787
  while ((error=repair(session,param,0)) && param.retry_repair)
763
788
  {
764
789
    param.retry_repair=0;
765
790
    if (test_all_bits(param.testflag,
766
791
                      (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
767
792
    {
768
793
      param.testflag&= ~T_RETRY_WITHOUT_QUICK;
769
 
      sql_print_information("Retrying repair of: '%s' without quick",
 
794
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' without quick",
770
795
                            table->s->path.str);
771
796
      continue;
772
797
    }
774
799
    if ((param.testflag & T_REP_BY_SORT))
775
800
    {
776
801
      param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
777
 
      sql_print_information("Retrying repair of: '%s' with keycache",
 
802
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' with keycache",
778
803
                            table->s->path.str);
779
804
      continue;
780
805
    }
784
809
      !(check_opt->flags & T_VERY_SILENT))
785
810
  {
786
811
    char llbuff[22],llbuff2[22];
787
 
    sql_print_information("Found %s of %s rows when repairing '%s'",
 
812
    errmsg_printf(ERRMSG_LVL_INFO, "Found %s of %s rows when repairing '%s'",
788
813
                          llstr(file->state->records, llbuff),
789
814
                          llstr(start_records, llbuff2),
790
815
                          table->s->path.str);
792
817
  return error;
793
818
}
794
819
 
795
 
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
 
820
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
796
821
{
797
822
  int error;
798
823
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
799
824
  MI_CHECK param;
800
825
 
801
826
  myisamchk_init(&param);
802
 
  param.thd = thd;
 
827
  param.session = session;
803
828
  param.op_name= "optimize";
804
829
  param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
805
830
                   T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
806
 
  param.sort_buffer_length=  check_opt->sort_buffer_size;
807
 
  if ((error= repair(thd,param,1)) && param.retry_repair)
 
831
  param.sort_buffer_length= (size_t)sort_buffer_size;
 
832
  if ((error= repair(session,param,1)) && param.retry_repair)
808
833
  {
809
 
    sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
 
834
    errmsg_printf(ERRMSG_LVL_WARN, "Warning: Optimize table got errno %d on %s.%s, retrying",
810
835
                      my_errno, param.db_name, param.table_name);
811
836
    param.testflag&= ~T_REP_BY_SORT;
812
 
    error= repair(thd,param,1);
 
837
    error= repair(session,param,1);
813
838
  }
814
839
  return error;
815
840
}
816
841
 
817
842
 
818
 
int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
 
843
int ha_myisam::repair(Session *session, MI_CHECK &param, bool do_optimize)
819
844
{
820
845
  int error=0;
821
 
  uint32_t local_testflag=param.testflag;
 
846
  uint32_t local_testflag= param.testflag;
822
847
  bool optimize_done= !do_optimize, statistics_done=0;
823
 
  const char *old_proc_info= thd->get_proc_info();
 
848
  const char *old_proc_info= session->get_proc_info();
824
849
  char fixed_name[FN_REFLEN];
825
850
  MYISAM_SHARE* share = file->s;
826
851
  ha_rows rows= file->state->records;
835
860
  */
836
861
  if (file->dfile == -1)
837
862
  {
838
 
    sql_print_information("Retrying repair of: '%s' failed. "
 
863
    errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
839
864
                          "Please try REPAIR EXTENDED or myisamchk",
840
865
                          table->s->path.str);
841
866
    return(HA_ADMIN_FAILED);
845
870
  param.table_name= table->alias;
846
871
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
847
872
  param.using_global_keycache = 1;
848
 
  param.thd= thd;
849
 
  param.tmpdir= &mysql_tmpdir_list;
 
873
  param.session= session;
850
874
  param.out_flag= 0;
851
 
  my_stpcpy(fixed_name,file->filename);
 
875
  param.sort_buffer_length= (size_t)sort_buffer_size;
 
876
  strcpy(fixed_name,file->filename);
852
877
 
853
878
  // Don't lock tables if we have used LOCK Table
854
 
  if (!thd->locked_tables && 
855
 
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
 
879
  if (mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
856
880
  {
857
881
    mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
858
882
    return(HA_ADMIN_FAILED);
873
897
      local_testflag|= T_STATISTICS;
874
898
      param.testflag|= T_STATISTICS;            // We get this for free
875
899
      statistics_done=1;
876
 
      if (thd->variables.myisam_repair_threads>1)
 
900
      if (repair_threads > 1)
877
901
      {
878
902
        char buf[40];
879
903
        /* TODO: respect myisam_repair_threads variable */
880
904
        snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
881
 
        thd_proc_info(thd, buf);
 
905
        session->set_proc_info(buf);
882
906
        error = mi_repair_parallel(&param, file, fixed_name,
883
907
            param.testflag & T_QUICK);
884
 
        thd_proc_info(thd, "Repair done"); // to reset proc_info, as
 
908
        session->set_proc_info("Repair done"); // to reset proc_info, as
885
909
                                      // it was pointing to local buffer
886
910
      }
887
911
      else
888
912
      {
889
 
        thd_proc_info(thd, "Repair by sorting");
 
913
        session->set_proc_info("Repair by sorting");
890
914
        error = mi_repair_by_sort(&param, file, fixed_name,
891
915
            param.testflag & T_QUICK);
892
916
      }
893
917
    }
894
918
    else
895
919
    {
896
 
      thd_proc_info(thd, "Repair with keycache");
 
920
      session->set_proc_info("Repair with keycache");
897
921
      param.testflag &= ~T_REP_BY_SORT;
898
922
      error=  mi_repair(&param, file, fixed_name,
899
923
                        param.testflag & T_QUICK);
907
931
        (share->state.changed & STATE_NOT_SORTED_PAGES))
908
932
    {
909
933
      optimize_done=1;
910
 
      thd_proc_info(thd, "Sorting index");
 
934
      session->set_proc_info("Sorting index");
911
935
      error=mi_sort_index(&param,file,fixed_name);
912
936
    }
913
937
    if (!statistics_done && (local_testflag & T_STATISTICS))
915
939
      if (share->state.changed & STATE_NOT_ANALYZED)
916
940
      {
917
941
        optimize_done=1;
918
 
        thd_proc_info(thd, "Analyzing");
 
942
        session->set_proc_info("Analyzing");
919
943
        error = chk_key(&param, file);
920
944
      }
921
945
      else
922
946
        local_testflag&= ~T_STATISTICS;         // Don't update statistics
923
947
    }
924
948
  }
925
 
  thd_proc_info(thd, "Saving state");
 
949
  session->set_proc_info("Saving state");
926
950
  if (!error)
927
951
  {
928
952
    if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
960
984
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
961
985
    update_state_info(&param, file, 0);
962
986
  }
963
 
  thd_proc_info(thd, old_proc_info);
964
 
  if (!thd->locked_tables)
965
 
    mi_lock_database(file,F_UNLCK);
 
987
  session->set_proc_info(old_proc_info);
 
988
  mi_lock_database(file,F_UNLCK);
 
989
 
966
990
  return(error ? HA_ADMIN_FAILED :
967
991
              !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
968
992
}
972
996
  Assign table indexes to a specific key cache.
973
997
*/
974
998
 
975
 
int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
 
999
int ha_myisam::assign_to_keycache(Session* session, HA_CHECK_OPT *check_opt)
976
1000
{
977
1001
  KEY_CACHE *new_key_cache= check_opt->key_cache;
978
1002
  const char *errmsg= 0;
979
1003
  int error= HA_ADMIN_OK;
980
 
  uint64_t map;
981
1004
  TableList *table_list= table->pos_in_table_list;
982
1005
 
983
 
  table->keys_in_use_for_query.clear_all();
 
1006
  table->keys_in_use_for_query.reset();
984
1007
 
985
1008
  if (table_list->process_index_hints(table))
986
1009
    return(HA_ADMIN_FAILED);
987
 
  map= ~(uint64_t) 0;
988
 
  if (!table->keys_in_use_for_query.is_clear_all())
989
 
    /* use all keys if there's no list specified by the user through hints */
990
 
    map= table->keys_in_use_for_query.to_uint64_t();
991
1010
 
992
 
  if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
993
 
  { 
 
1011
  if ((error= mi_assign_to_key_cache(file, new_key_cache)))
 
1012
  {
994
1013
    char buf[STRING_BUFFER_USUAL_SIZE];
995
1014
    snprintf(buf, sizeof(buf),
996
1015
                "Failed to flush to index file (errno: %d)", error);
1003
1022
    /* Send error to user */
1004
1023
    MI_CHECK param;
1005
1024
    myisamchk_init(&param);
1006
 
    param.thd= thd;
 
1025
    param.session= session;
1007
1026
    param.op_name=    "assign_to_keycache";
1008
1027
    param.db_name=    table->s->db.str;
1009
1028
    param.table_name= table->s->table_name.str;
1107
1126
  }
1108
1127
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1109
1128
  {
1110
 
    THD *thd=current_thd;
 
1129
    Session *session=current_session;
1111
1130
    MI_CHECK param;
1112
 
    const char *save_proc_info= thd->get_proc_info();
1113
 
    thd_proc_info(thd, "Creating index");
 
1131
    const char *save_proc_info= session->get_proc_info();
 
1132
    session->set_proc_info("Creating index");
1114
1133
    myisamchk_init(&param);
1115
1134
    param.op_name= "recreating_index";
1116
1135
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
1117
1136
                     T_CREATE_MISSING_KEYS);
1118
1137
    param.myf_rw&= ~MY_WAIT_IF_FULL;
1119
 
    param.sort_buffer_length=  thd->variables.myisam_sort_buff_size;
1120
 
    param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
1121
 
    param.tmpdir=&mysql_tmpdir_list;
1122
 
    if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
 
1138
    param.sort_buffer_length=  (size_t)sort_buffer_size;
 
1139
    param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
 
1140
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1123
1141
    {
1124
 
      sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
 
1142
      errmsg_printf(ERRMSG_LVL_WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
1125
1143
                        my_errno, param.db_name, param.table_name);
1126
1144
      /* Repairing by sort failed. Now try standard repair method. */
1127
1145
      param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
1128
 
      error= (repair(thd,param,0) != HA_ADMIN_OK);
 
1146
      error= (repair(session,param,0) != HA_ADMIN_OK);
1129
1147
      /*
1130
1148
        If the standard repair succeeded, clear all error messages which
1131
1149
        might have been set by the first repair. They can still be seen
1132
1150
        with SHOW WARNINGS then.
1133
1151
      */
1134
1152
      if (! error)
1135
 
        thd->clear_error();
 
1153
        session->clear_error();
1136
1154
    }
1137
1155
    info(HA_STATUS_CONST);
1138
 
    thd_proc_info(thd, save_proc_info);
 
1156
    session->set_proc_info(save_proc_info);
1139
1157
  }
1140
1158
  else
1141
1159
  {
1163
1181
 
1164
1182
int ha_myisam::indexes_are_disabled(void)
1165
1183
{
1166
 
  
 
1184
 
1167
1185
  return mi_indexes_are_disabled(file);
1168
1186
}
1169
1187
 
1184
1202
 
1185
1203
void ha_myisam::start_bulk_insert(ha_rows rows)
1186
1204
{
1187
 
  THD *thd= current_thd;
1188
 
  ulong size= cmin(thd->variables.read_buff_size,
1189
 
                  (ulong) (table->s->avg_row_length*rows));
 
1205
  Session *session= current_session;
 
1206
  ulong size= session->variables.read_buff_size;
1190
1207
 
1191
1208
  /* don't enable row cache if too few rows */
1192
1209
  if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1208
1225
    if (!file->bulk_insert &&
1209
1226
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1210
1227
    {
1211
 
      mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
 
1228
      mi_init_bulk_insert(file,
 
1229
                          (size_t)session->variables.bulk_insert_buff_size,
 
1230
                          rows);
1212
1231
    }
1213
 
 
1214
 
  return;
1215
1232
}
1216
1233
 
1217
1234
/*
1236
1253
}
1237
1254
 
1238
1255
 
1239
 
bool ha_myisam::check_and_repair(THD *thd)
1240
 
{
1241
 
  int error=0;
1242
 
  int marked_crashed;
1243
 
  char *old_query;
1244
 
  uint32_t old_query_length;
1245
 
  HA_CHECK_OPT check_opt;
1246
 
 
1247
 
  check_opt.init();
1248
 
  check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
1249
 
  // Don't use quick if deleted rows
1250
 
  if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
1251
 
    check_opt.flags|=T_QUICK;
1252
 
  sql_print_warning("Checking table:   '%s'",table->s->path.str);
1253
 
 
1254
 
  old_query= thd->query;
1255
 
  old_query_length= thd->query_length;
1256
 
  pthread_mutex_lock(&LOCK_thread_count);
1257
 
  thd->query=        table->s->table_name.str;
1258
 
  thd->query_length= table->s->table_name.length;
1259
 
  pthread_mutex_unlock(&LOCK_thread_count);
1260
 
 
1261
 
  if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
1262
 
  {
1263
 
    sql_print_warning("Recovering table: '%s'",table->s->path.str);
1264
 
    check_opt.flags=
1265
 
      ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
1266
 
       (marked_crashed                             ? 0 : T_QUICK) |
1267
 
       (myisam_recover_options & HA_RECOVER_FORCE  ? 0 : T_SAFE_REPAIR) |
1268
 
       T_AUTO_REPAIR);
1269
 
    if (repair(thd, &check_opt))
1270
 
      error=1;
1271
 
  }
1272
 
  pthread_mutex_lock(&LOCK_thread_count);
1273
 
  thd->query= old_query;
1274
 
  thd->query_length= old_query_length;
1275
 
  pthread_mutex_unlock(&LOCK_thread_count);
1276
 
  return(error);
1277
 
}
1278
1256
 
1279
1257
bool ha_myisam::is_crashed() const
1280
1258
{
1296
1274
  return mi_delete(file,buf);
1297
1275
}
1298
1276
 
1299
 
#ifdef __cplusplus
1300
 
extern "C" {
1301
 
#endif
1302
1277
 
1303
 
bool index_cond_func_myisam(void *arg)
 
1278
int ha_myisam::index_init(uint32_t idx, bool )
1304
1279
{
1305
 
  ha_myisam *h= (ha_myisam*)arg;
1306
 
  /*if (h->in_range_read)*/
1307
 
  if (h->end_range)
1308
 
  {
1309
 
    if (h->compare_key2(h->end_range) > 0)
1310
 
      return 2; /* caller should return HA_ERR_END_OF_FILE already */
1311
 
  }
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)))
1321
 
1322
1280
  active_index=idx;
1323
1281
  //in_range_read= false;
1324
 
  if (pushed_idx_cond_keyno == idx)
1325
 
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
1326
 
  return 0; 
 
1282
  return 0;
1327
1283
}
1328
1284
 
1329
1285
 
1330
1286
int ha_myisam::index_end()
1331
1287
{
1332
1288
  active_index=MAX_KEY;
1333
 
  //pushed_idx_cond_keyno= MAX_KEY;
1334
 
  mi_set_index_cond_func(file, NULL, 0);
1335
 
  in_range_check_pushed_down= false;
1336
 
  ds_mrr.dsmrr_close();
1337
 
  return 0; 
 
1289
  return 0;
 
1290
}
 
1291
 
 
1292
 
 
1293
uint32_t ha_myisam::index_flags(uint32_t inx, uint32_t, bool) const
 
1294
{
 
1295
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
 
1296
          0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
 
1297
          HA_READ_ORDER | HA_KEYREAD_ONLY |
 
1298
          (keys_with_parts.test(inx)?0:HA_DO_INDEX_COND_PUSHDOWN));
1338
1299
}
1339
1300
 
1340
1301
 
1407
1368
}
1408
1369
 
1409
1370
int ha_myisam::index_next_same(unsigned char *buf,
1410
 
                               const unsigned char *key __attribute__((unused)),
1411
 
                               uint32_t length __attribute__((unused)))
 
1371
                               const unsigned char *,
 
1372
                               uint32_t )
1412
1373
{
1413
1374
  int error;
1414
1375
  assert(inited==INDEX);
1476
1437
}
1477
1438
 
1478
1439
 
1479
 
void ha_myisam::position(const unsigned char *record __attribute__((unused)))
 
1440
void ha_myisam::position(const unsigned char *)
1480
1441
{
1481
1442
  my_off_t row_position= mi_position(file);
1482
1443
  my_store_ptr(ref, ref_length, row_position);
1500
1461
  }
1501
1462
  if (flag & HA_STATUS_CONST)
1502
1463
  {
1503
 
    TABLE_SHARE *share= table->s;
 
1464
    TableShare *share= table->s;
1504
1465
    stats.max_data_file_length=  misam_info.max_data_file_length;
1505
1466
    stats.max_index_file_length= misam_info.max_index_file_length;
1506
1467
    stats.create_time= misam_info.create_time;
1507
1468
    ref_length= misam_info.reflength;
1508
1469
    share->db_options_in_use= misam_info.options;
1509
 
    stats.block_size= myisam_block_size;        /* record block size */
 
1470
    stats.block_size= block_size;        /* record block size */
1510
1471
 
1511
1472
    /* Update share */
1512
1473
    if (share->tmp_table == NO_TMP_TABLE)
1513
1474
      pthread_mutex_lock(&share->mutex);
1514
 
    share->keys_in_use.set_prefix(share->keys);
1515
 
    share->keys_in_use.intersect_extended(misam_info.key_map);
1516
 
    share->keys_for_keyread.intersect(share->keys_in_use);
 
1475
    set_prefix(share->keys_in_use, share->keys);
 
1476
    /*
 
1477
     * Due to bug 394932 (32-bit solaris build failure), we need
 
1478
     * to convert the uint64_t key_map member of the misam_info
 
1479
     * structure in to a std::bitset so that we can logically and
 
1480
     * it with the share->key_in_use key_map.
 
1481
     */
 
1482
    ostringstream ostr;
 
1483
    string binary_key_map;
 
1484
    uint64_t num= misam_info.key_map;
 
1485
    /*
 
1486
     * Convert the uint64_t to a binary
 
1487
     * string representation of it.
 
1488
     */
 
1489
    while (num > 0)
 
1490
    {
 
1491
      uint64_t bin_digit= num % 2;
 
1492
      ostr << bin_digit;
 
1493
      num/= 2;
 
1494
    }
 
1495
    binary_key_map.append(ostr.str());
 
1496
    /*
 
1497
     * Now we have the binary string representation of the
 
1498
     * flags, we need to fill that string representation out
 
1499
     * with the appropriate number of bits. This is needed
 
1500
     * since key_map is declared as a std::bitset of a certain bit
 
1501
     * width that depends on the MAX_INDEXES variable. 
 
1502
     */
 
1503
    if (MAX_INDEXES <= 64)
 
1504
    {
 
1505
      size_t len= 72 - binary_key_map.length();
 
1506
      string all_zeros(len, '0');
 
1507
      binary_key_map.insert(binary_key_map.begin(),
 
1508
                            all_zeros.begin(),
 
1509
                            all_zeros.end());
 
1510
    }
 
1511
    else
 
1512
    {
 
1513
      size_t len= (MAX_INDEXES + 7) / 8 * 8;
 
1514
      string all_zeros(len, '0');
 
1515
      binary_key_map.insert(binary_key_map.begin(),
 
1516
                            all_zeros.begin(),
 
1517
                            all_zeros.end());
 
1518
    }
 
1519
    key_map tmp_map(binary_key_map);
 
1520
    share->keys_in_use&= tmp_map;
 
1521
    share->keys_for_keyread&= share->keys_in_use;
1517
1522
    share->db_record_offset= misam_info.record_offset;
1518
1523
    if (share->key_parts)
1519
1524
      memcpy(table->key_info[0].rec_per_key,
1557
1562
 
1558
1563
int ha_myisam::reset(void)
1559
1564
{
1560
 
  pushed_idx_cond= NULL;
1561
 
  pushed_idx_cond_keyno= MAX_KEY;
1562
 
  mi_set_index_cond_func(file, NULL, 0);
1563
 
  ds_mrr.dsmrr_close();
1564
1565
  return mi_reset(file);
1565
1566
}
1566
1567
 
1576
1577
  return mi_delete_all_rows(file);
1577
1578
}
1578
1579
 
1579
 
int ha_myisam::delete_table(const char *name)
 
1580
int MyisamEngine::deleteTableImplementation(Session*, const string table_name)
1580
1581
{
1581
 
  return mi_delete_table(name);
 
1582
  return mi_delete_table(table_name.c_str());
1582
1583
}
1583
1584
 
1584
1585
 
1585
 
int ha_myisam::external_lock(THD *thd, int lock_type)
 
1586
int ha_myisam::external_lock(Session *session, int lock_type)
1586
1587
{
1587
 
  file->in_use.data= thd;
 
1588
  file->in_use= session;
1588
1589
  return mi_lock_database(file, !table->s->tmp_table ?
1589
1590
                          lock_type : ((lock_type == F_UNLCK) ?
1590
1591
                                       F_UNLCK : F_EXTRA_LCK));
1591
1592
}
1592
1593
 
1593
 
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd __attribute__((unused)),
 
1594
THR_LOCK_DATA **ha_myisam::store_lock(Session *,
1594
1595
                                      THR_LOCK_DATA **to,
1595
1596
                                      enum thr_lock_type lock_type)
1596
1597
{
1597
1598
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
1598
1599
    file->lock.type=lock_type;
1599
1600
  *to++= &file->lock;
 
1601
 
1600
1602
  return to;
1601
1603
}
1602
1604
 
1603
 
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
1604
 
{
1605
 
  ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
1606
 
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
1607
 
  {
1608
 
    create_info->auto_increment_value= stats.auto_increment_value;
1609
 
  }
1610
 
  create_info->data_file_name=data_file_name;
1611
 
  create_info->index_file_name=index_file_name;
1612
 
}
1613
 
 
1614
 
 
1615
 
int ha_myisam::create(const char *name, register Table *table_arg,
1616
 
                      HA_CREATE_INFO *ha_create_info)
 
1605
int MyisamEngine::createTableImplementation(Session *, const char *table_name,
 
1606
                                            Table *table_arg,
 
1607
                                            HA_CREATE_INFO *ha_create_info,
 
1608
                                            drizzled::message::Table* create_proto)
1617
1609
{
1618
1610
  int error;
1619
 
  uint32_t create_flags= 0, records;
 
1611
  uint32_t create_flags= 0, create_records;
1620
1612
  char buff[FN_REFLEN];
1621
1613
  MI_KEYDEF *keydef;
1622
1614
  MI_COLUMNDEF *recinfo;
1623
1615
  MI_CREATE_INFO create_info;
1624
 
  TABLE_SHARE *share= table_arg->s;
 
1616
  TableShare *share= table_arg->s;
1625
1617
  uint32_t options= share->db_options_in_use;
1626
 
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
 
1618
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &create_records)))
1627
1619
    return(error); /* purecov: inspected */
1628
1620
  memset(&create_info, 0, sizeof(create_info));
1629
 
  create_info.max_rows= share->max_rows;
1630
 
  create_info.reloc_rows= share->min_rows;
 
1621
  create_info.max_rows= create_proto->options().max_rows();
 
1622
  create_info.reloc_rows= create_proto->options().min_rows();
1631
1623
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1632
1624
  create_info.auto_increment= (ha_create_info->auto_increment_value ?
1633
1625
                               ha_create_info->auto_increment_value -1 :
1634
1626
                               (uint64_t) 0);
1635
 
  create_info.data_file_length= ((uint64_t) share->max_rows *
1636
 
                                 share->avg_row_length);
 
1627
  create_info.data_file_length= (create_proto->options().max_rows() *
 
1628
                                 create_proto->options().avg_row_length());
1637
1629
  create_info.data_file_name= ha_create_info->data_file_name;
1638
1630
  create_info.index_file_name= ha_create_info->index_file_name;
1639
1631
  create_info.language= share->table_charset->number;
1644
1636
    create_flags|= HA_CREATE_KEEP_FILES;
1645
1637
  if (options & HA_OPTION_PACK_RECORD)
1646
1638
    create_flags|= HA_PACK_RECORD;
1647
 
  if (options & HA_OPTION_CHECKSUM)
1648
 
    create_flags|= HA_CREATE_CHECKSUM;
1649
 
  if (options & HA_OPTION_DELAY_KEY_WRITE)
1650
 
    create_flags|= HA_CREATE_DELAY_KEY_WRITE;
1651
1639
 
1652
1640
  /* TODO: Check that the following fn_format is really needed */
1653
 
  error= mi_create(fn_format(buff, name, "", "",
 
1641
  error= mi_create(fn_format(buff, table_name, "", "",
1654
1642
                             MY_UNPACK_FILENAME|MY_APPEND_EXT),
1655
1643
                   share->keys, keydef,
1656
 
                   records, recinfo,
 
1644
                   create_records, recinfo,
1657
1645
                   0, (MI_UNIQUEDEF*) 0,
1658
1646
                   &create_info, create_flags);
1659
1647
  free((unsigned char*) recinfo);
1661
1649
}
1662
1650
 
1663
1651
 
1664
 
int ha_myisam::rename_table(const char * from, const char * to)
 
1652
int MyisamEngine::renameTableImplementation(Session*,
 
1653
                                            const char *from, const char *to)
1665
1654
{
1666
1655
  return mi_rename(from,to);
1667
1656
}
1668
1657
 
1669
1658
 
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)),
 
1659
void ha_myisam::get_auto_increment(uint64_t ,
 
1660
                                   uint64_t ,
 
1661
                                   uint64_t ,
1673
1662
                                   uint64_t *first_value,
1674
1663
                                   uint64_t *nb_reserved_values)
1675
1664
{
1730
1719
      HA_READ_KEY_EXACT         Include the key in the range
1731
1720
      HA_READ_AFTER_KEY         Don't include key in range
1732
1721
 
1733
 
    max_key.flag can have one of the following values:  
 
1722
    max_key.flag can have one of the following values:
1734
1723
      HA_READ_BEFORE_KEY        Don't include key in range
1735
1724
      HA_READ_AFTER_KEY         Include all 'end_key' values in the range
1736
1725
 
1753
1742
  return (uint)file->state->checksum;
1754
1743
}
1755
1744
 
 
1745
static MyisamEngine *engine= NULL;
1756
1746
 
1757
 
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1758
 
                                           uint32_t table_changes)
 
1747
static int myisam_init(drizzled::plugin::Registry &registry)
1759
1748
{
1760
 
  uint32_t options= table->s->db_options_in_use;
1761
 
 
1762
 
  if (info->auto_increment_value != stats.auto_increment_value ||
1763
 
      info->data_file_name != data_file_name ||
1764
 
      info->index_file_name != index_file_name ||
1765
 
      table_changes == IS_EQUAL_NO ||
1766
 
      table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
1767
 
    return COMPATIBLE_DATA_NO;
1768
 
 
1769
 
  if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
1770
 
                  HA_OPTION_DELAY_KEY_WRITE)) !=
1771
 
      (info->table_options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
1772
 
                              HA_OPTION_DELAY_KEY_WRITE)))
1773
 
    return COMPATIBLE_DATA_NO;
1774
 
  return COMPATIBLE_DATA_YES;
 
1749
  int error;
 
1750
  engine= new MyisamEngine(engine_name);
 
1751
  registry.add(engine);
 
1752
 
 
1753
  pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
 
1754
 
 
1755
  /* call ha_init_key_cache() on all key caches to init them */
 
1756
  error= init_key_cache(dflt_key_cache,
 
1757
                        (uint32_t) dflt_key_cache->param_block_size,
 
1758
                        (uint32_t) dflt_key_cache->param_buff_size,
 
1759
                        dflt_key_cache->param_division_limit, 
 
1760
                        dflt_key_cache->param_age_threshold);
 
1761
 
 
1762
  if (error == 0)
 
1763
    exit(1); /* Memory Allocation Failure */
 
1764
 
 
1765
  return 0;
1775
1766
}
1776
1767
 
1777
 
int myisam_deinit(void *hton __attribute__((unused)))
 
1768
static int myisam_deinit(drizzled::plugin::Registry &registry)
1778
1769
{
 
1770
  registry.remove(engine);
 
1771
  delete engine;
 
1772
 
 
1773
  pthread_mutex_destroy(&THR_LOCK_myisam);
 
1774
  end_key_cache(dflt_key_cache, 1);             // Can never fail
 
1775
 
1779
1776
  return mi_panic(HA_PANIC_CLOSE);
1780
1777
}
1781
1778
 
1782
 
static int myisam_init(void *p)
1783
 
{
1784
 
  handlerton *myisam_hton;
1785
 
 
1786
 
  myisam_hton= (handlerton *)p;
1787
 
  myisam_hton->state= SHOW_OPTION_YES;
1788
 
  myisam_hton->create= myisam_create_handler;
1789
 
  myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
1790
 
  return 0;
1791
 
}
1792
 
 
1793
 
 
1794
 
 
1795
 
/****************************************************************************
1796
 
 * MyISAM MRR implementation: use DS-MRR
1797
 
 ***************************************************************************/
1798
 
 
1799
 
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1800
 
                                     uint32_t n_ranges, uint32_t mode, 
1801
 
                                     HANDLER_BUFFER *buf)
1802
 
{
1803
 
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index], 
1804
 
                           seq, seq_init_param, n_ranges, mode, buf);
1805
 
}
1806
 
 
1807
 
int ha_myisam::multi_range_read_next(char **range_info)
1808
 
{
1809
 
  return ds_mrr.dsmrr_next(this, range_info);
1810
 
}
1811
 
 
1812
 
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1813
 
                                               void *seq_init_param, 
1814
 
                                               uint32_t n_ranges, uint32_t *bufsz,
1815
 
                                               uint32_t *flags, COST_VECT *cost)
1816
 
{
1817
 
  /*
1818
 
    This call is here because there is no location where this->table would
1819
 
    already be known.
1820
 
    TODO: consider moving it into some per-query initialization call.
1821
 
  */
1822
 
  ds_mrr.init(this, table);
1823
 
  return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
1824
 
                                 flags, cost);
1825
 
}
1826
 
 
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)
1829
 
{
1830
 
  ds_mrr.init(this, table);
1831
 
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1832
 
}
1833
 
 
1834
 
/* MyISAM MRR implementation ends */
1835
 
 
1836
 
 
1837
 
/* Index condition pushdown implementation*/
1838
 
 
1839
 
 
1840
 
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
1841
 
{
1842
 
  pushed_idx_cond_keyno= keyno_arg;
1843
 
  pushed_idx_cond= idx_cond_arg;
1844
 
  in_range_check_pushed_down= true;
1845
 
  if (active_index == pushed_idx_cond_keyno)
1846
 
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
1847
 
  return NULL;
1848
 
}
1849
 
 
1850
 
 
1851
 
mysql_declare_plugin(myisam)
1852
 
{
1853
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
1779
static DRIZZLE_SYSVAR_UINT(block_size, block_size,
 
1780
                           PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
1781
                           N_("Block size to be used for MyISAM index pages."),
 
1782
                           NULL, NULL, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, 
 
1783
                           MI_MAX_KEY_BLOCK_LENGTH, 0);
 
1784
 
 
1785
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
 
1786
                           PLUGIN_VAR_RQCMDARG,
 
1787
                           N_("Number of threads to use when repairing MyISAM tables. The value of "
 
1788
                              "1 disables parallel repair."),
 
1789
                           NULL, NULL, 1, 1, UINT32_MAX, 0);
 
1790
 
 
1791
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
 
1792
                                PLUGIN_VAR_RQCMDARG,
 
1793
                                N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
 
1794
                                NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
 
1795
 
 
1796
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
 
1797
                                PLUGIN_VAR_RQCMDARG,
 
1798
                                N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
 
1799
                                NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
 
1800
 
 
1801
extern uint32_t data_pointer_size;
 
1802
static DRIZZLE_SYSVAR_UINT(data_pointer_size, data_pointer_size,
 
1803
                           PLUGIN_VAR_RQCMDARG,
 
1804
                           N_("Default pointer size to be used for MyISAM tables."),
 
1805
                           NULL, NULL, 6, 2, 7, 0);
 
1806
 
 
1807
static struct st_mysql_sys_var* system_variables[]= {
 
1808
  DRIZZLE_SYSVAR(block_size),
 
1809
  DRIZZLE_SYSVAR(repair_threads),
 
1810
  DRIZZLE_SYSVAR(max_sort_file_size),
 
1811
  DRIZZLE_SYSVAR(sort_buffer_size),
 
1812
  DRIZZLE_SYSVAR(data_pointer_size),
 
1813
  NULL
 
1814
};
 
1815
 
 
1816
 
 
1817
drizzle_declare_plugin(myisam)
 
1818
{
1854
1819
  "MyISAM",
1855
1820
  "1.0",
1856
1821
  "MySQL AB",
1859
1824
  myisam_init, /* Plugin Init */
1860
1825
  myisam_deinit, /* Plugin Deinit */
1861
1826
  NULL,                       /* status variables                */
1862
 
  NULL,                       /* system variables                */
 
1827
  system_variables,           /* system variables */
1863
1828
  NULL                        /* config options                  */
1864
1829
}
1865
 
mysql_declare_plugin_end;
 
1830
drizzle_declare_plugin_end;