~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
18
#include <drizzled/server_includes.h>
212.5.28 by Monty Taylor
Moved my_bit and my_list
19
#include <mysys/my_bit.h>
685.1.3 by Monty Taylor
Turned off stdinc - and then fixed the carnage.
20
#include "myisampack.h"
1 by brian
clean slate
21
#include "ha_myisam.h"
22
#include "myisamdef.h"
492.1.7 by Monty Taylor
Moved test() to its own file.
23
#include <drizzled/util/test.h>
549 by Monty Taylor
Took gettext.h out of header files.
24
#include <drizzled/error.h>
722.4.1 by Mark Atwood
integrate errmsg plugin into sql_print_* functions
25
#include <drizzled/errmsg_print.h>
549 by Monty Taylor
Took gettext.h out of header files.
26
#include <drizzled/gettext.h>
916.1.31 by Padraig O'Sullivan
Reverting some refactoring changes I made to MyISAM that didn't really work
27
#include <drizzled/session.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
28
#include <drizzled/protocol.h>
29
#include <drizzled/table.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
30
#include <drizzled/field/timestamp.h>
1 by brian
clean slate
31
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
32
#include <string>
33
34
using namespace std;
35
36
static const string engine_name("MyISAM");
37
1 by brian
clean slate
38
ulong myisam_recover_options= HA_RECOVER_NONE;
598 by Brian Aker
Removed mutex which are myisam from global to just engine.
39
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
1 by brian
clean slate
40
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
41
static uint32_t repair_threads;
754 by Brian Aker
Make block_size for myisam fit into plugin.
42
static uint32_t block_size;
788 by Brian Aker
Move MyISAM bits to myisam plugin
43
static uint64_t max_sort_file_size;
789 by Brian Aker
MyISAM fix.
44
static uint64_t sort_buffer_size;
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
45
1 by brian
clean slate
46
/* bits in myisam_recover_options */
47
const char *myisam_recover_names[] =
461 by Monty Taylor
Removed NullS. bu-bye.
48
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
1 by brian
clean slate
49
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
584.5.1 by Monty Taylor
Removed field includes from field.h.
50
                                 myisam_recover_names, NULL};
1 by brian
clean slate
51
52
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
461 by Monty Taylor
Removed NullS. bu-bye.
53
                                           "nulls_ignored", NULL};
1 by brian
clean slate
54
TYPELIB myisam_stats_method_typelib= {
55
  array_elements(myisam_stats_method_names) - 1, "",
56
  myisam_stats_method_names, NULL};
57
58
59
/*****************************************************************************
60
** MyISAM tables
61
*****************************************************************************/
62
960.2.33 by Monty Taylor
Converted MyISAM.
63
class MyisamEngine : public StorageEngine
1 by brian
clean slate
64
{
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
65
public:
964.1.4 by Monty Taylor
Moved flags into private area.
66
  MyisamEngine(string name_arg)
67
   : StorageEngine(name_arg, HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES) {}
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
68
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
69
  virtual handler *create(TableShare *table,
960.2.33 by Monty Taylor
Converted MyISAM.
70
                          MEM_ROOT *mem_root)
71
  {
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
72
    return new (mem_root) ha_myisam(this, table);
960.2.33 by Monty Taylor
Converted MyISAM.
73
  }
74
};
1 by brian
clean slate
75
76
// collect errors printed by mi_check routines
77
78
static void mi_check_print_msg(MI_CHECK *param,	const char* msg_type,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
79
                               const char *fmt, va_list args)
1 by brian
clean slate
80
{
520.1.22 by Brian Aker
Second pass of thd cleanup
81
  Session* session = (Session*)param->session;
82
  Protocol *protocol= session->protocol;
482 by Brian Aker
Remove uint.
83
  uint32_t length, msg_length;
1 by brian
clean slate
84
  char msgbuf[MI_MAX_MSG_BUF];
85
  char name[NAME_LEN*2+2];
86
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
87
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
1 by brian
clean slate
88
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
89
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
90
  if (!session->protocol->isConnected())
1 by brian
clean slate
91
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
92
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",msgbuf);
1 by brian
clean slate
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
  }
673.2.2 by Toru Maesaka
Final pass of replacing MySQL's strxmov with libc's alternatives
102
  length= sprintf(name,"%s.%s",param->db_name,param->table_name);
103
1 by brian
clean slate
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
  */
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
112
  protocol->prepareForResend();
1 by brian
clean slate
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())
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
118
    errmsg_printf(ERRMSG_LVL_ERROR, "Failed on drizzleclient_net_write, writing to stderr instead: %s\n",
1 by brian
clean slate
119
		    msgbuf);
120
  return;
121
}
122
123
124
/*
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
125
  Convert Table object to MyISAM key and column definition
1 by brian
clean slate
126
127
  SYNOPSIS
128
    table2myisam()
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
129
      table_arg   in     Table object.
1 by brian
clean slate
130
      keydef_out  out    MyISAM key definition.
131
      recinfo_out out    MyISAM column definition.
132
      records_out out    Number of fields.
133
134
  DESCRIPTION
135
    This function will allocate and initialize MyISAM key and column
136
    definition for further use in mi_create or for a check for underlying
137
    table conformance in merge engine.
138
139
    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
141
    is freed automatically when *recinfo_out is freed.
142
143
  RETURN VALUE
144
    0  OK
145
    !0 error code
146
*/
147
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
148
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
482 by Brian Aker
Remove uint.
149
                 MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
1 by brian
clean slate
150
{
482 by Brian Aker
Remove uint.
151
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
1 by brian
clean slate
152
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
481 by Brian Aker
Remove all of uchar.
153
  unsigned char *record;
1 by brian
clean slate
154
  KEY *pos;
155
  MI_KEYDEF *keydef;
156
  MI_COLUMNDEF *recinfo, *recinfo_pos;
157
  HA_KEYSEG *keyseg;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
158
  TableShare *share= table_arg->s;
482 by Brian Aker
Remove uint.
159
  uint32_t options= share->db_options_in_use;
1 by brian
clean slate
160
  if (!(my_multi_malloc(MYF(MY_WME),
161
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
162
          keydef_out, share->keys * sizeof(MI_KEYDEF),
163
          &keyseg,
164
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
461 by Monty Taylor
Removed NullS. bu-bye.
165
          NULL)))
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
166
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
1 by brian
clean slate
167
  keydef= *keydef_out;
168
  recinfo= *recinfo_out;
169
  pos= table_arg->key_info;
170
  for (i= 0; i < share->keys; i++, pos++)
171
  {
249 by Brian Aker
Random key cleanup (it is a friday...)
172
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
173
    keydef[i].key_alg= HA_KEY_ALG_BTREE;
1 by brian
clean slate
174
    keydef[i].block_length= pos->block_size;
175
    keydef[i].seg= keyseg;
176
    keydef[i].keysegs= pos->key_parts;
177
    for (j= 0; j < pos->key_parts; j++)
178
    {
179
      Field *field= pos->key_part[j].field;
180
      type= field->key_type();
181
      keydef[i].seg[j].flag= pos->key_part[j].key_part_flag;
182
183
      if (options & HA_OPTION_PACK_KEYS ||
184
          (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY |
185
                         HA_SPACE_PACK_USED)))
186
      {
187
        if (pos->key_part[j].length > 8 &&
188
            (type == HA_KEYTYPE_TEXT ||
189
             type == HA_KEYTYPE_NUM ||
190
             (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
191
        {
192
          /* No blobs here */
193
          if (j == 0)
194
            keydef[i].flag|= HA_PACK_KEY;
241 by Brian Aker
First pass of CHAR removal.
195
          if ((((int) (pos->key_part[j].length - field->decimals())) >= 4))
1 by brian
clean slate
196
            keydef[i].seg[j].flag|= HA_SPACE_PACK;
197
        }
198
        else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
199
          keydef[i].flag|= HA_BINARY_PACK_KEY;
200
      }
201
      keydef[i].seg[j].type= (int) type;
202
      keydef[i].seg[j].start= pos->key_part[j].offset;
203
      keydef[i].seg[j].length= pos->key_part[j].length;
204
      keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end=
205
        keydef[i].seg[j].bit_length= 0;
206
      keydef[i].seg[j].bit_pos= 0;
207
      keydef[i].seg[j].language= field->charset()->number;
208
209
      if (field->null_ptr)
210
      {
211
        keydef[i].seg[j].null_bit= field->null_bit;
212
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
481 by Brian Aker
Remove all of uchar.
213
                                           (unsigned char*) table_arg->record[0]);
1 by brian
clean slate
214
      }
215
      else
216
      {
217
        keydef[i].seg[j].null_bit= 0;
218
        keydef[i].seg[j].null_pos= 0;
219
      }
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
220
      if (field->type() == DRIZZLE_TYPE_BLOB)
1 by brian
clean slate
221
      {
222
        keydef[i].seg[j].flag|= HA_BLOB_PART;
223
        /* save number of bytes used to pack length */
224
        keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
225
                                            share->blob_ptr_size);
226
      }
227
    }
228
    keyseg+= pos->key_parts;
229
  }
230
  if (table_arg->found_next_number_field)
231
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
232
  record= table_arg->record[0];
233
  recpos= 0;
234
  recinfo_pos= recinfo;
383.7.1 by Andrey Zhakov
Initial submit of code and tests
235
  while (recpos < (uint) share->stored_rec_length)
1 by brian
clean slate
236
  {
237
    Field **field, *found= 0;
238
    minpos= share->reclength;
239
    length= 0;
240
241
    for (field= table_arg->field; *field; field++)
242
    {
243
      if ((fieldpos= (*field)->offset(record)) >= recpos &&
244
          fieldpos <= minpos)
245
      {
246
        /* skip null fields */
247
        if (!(temp_length= (*field)->pack_length_in_rec()))
248
          continue; /* Skip null-fields */
249
        if (! found || fieldpos < minpos ||
250
            (fieldpos == minpos && temp_length < length))
251
        {
252
          minpos= fieldpos;
253
          found= *field;
254
          length= temp_length;
255
        }
256
      }
257
    }
258
    if (recpos != minpos)
259
    { // Reserved space (Null bits?)
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
260
      memset(recinfo_pos, 0, sizeof(*recinfo_pos));
1 by brian
clean slate
261
      recinfo_pos->type= (int) FIELD_NORMAL;
206 by Brian Aker
Removed final uint dead types.
262
      recinfo_pos++->length= (uint16_t) (minpos - recpos);
1 by brian
clean slate
263
    }
264
    if (!found)
265
      break;
266
267
    if (found->flags & BLOB_FLAG)
268
      recinfo_pos->type= (int) FIELD_BLOB;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
269
    else if (found->type() == DRIZZLE_TYPE_VARCHAR)
1 by brian
clean slate
270
      recinfo_pos->type= FIELD_VARCHAR;
271
    else if (!(options & HA_OPTION_PACK_RECORD))
272
      recinfo_pos->type= (int) FIELD_NORMAL;
273
    else if (found->zero_pack())
274
      recinfo_pos->type= (int) FIELD_SKIP_ZERO;
275
    else
241 by Brian Aker
First pass of CHAR removal.
276
      recinfo_pos->type= (int) ((length <= 3) ?  FIELD_NORMAL : FIELD_SKIP_PRESPACE);
1 by brian
clean slate
277
    if (found->null_ptr)
278
    {
279
      recinfo_pos->null_bit= found->null_bit;
280
      recinfo_pos->null_pos= (uint) (found->null_ptr -
481 by Brian Aker
Remove all of uchar.
281
                                     (unsigned char*) table_arg->record[0]);
1 by brian
clean slate
282
    }
283
    else
284
    {
285
      recinfo_pos->null_bit= 0;
286
      recinfo_pos->null_pos= 0;
287
    }
206 by Brian Aker
Removed final uint dead types.
288
    (recinfo_pos++)->length= (uint16_t) length;
1 by brian
clean slate
289
    recpos= minpos + length;
290
  }
291
  *records_out= (uint) (recinfo_pos - recinfo);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
292
  return(0);
1 by brian
clean slate
293
}
294
295
296
/*
297
  Check for underlying table conformance
298
299
  SYNOPSIS
300
    check_definition()
301
      t1_keyinfo       in    First table key definition
302
      t1_recinfo       in    First table record definition
303
      t1_keys          in    Number of keys in first table
304
      t1_recs          in    Number of records in first table
305
      t2_keyinfo       in    Second table key definition
306
      t2_recinfo       in    Second table record definition
307
      t2_keys          in    Number of keys in second table
308
      t2_recs          in    Number of records in second table
309
      strict           in    Strict check switch
310
311
  DESCRIPTION
312
    This function compares two MyISAM definitions. By intention it was done
313
    to compare merge table definition against underlying table definition.
314
    It may also be used to compare dot-frm and MYI definitions of MyISAM
315
    table as well to compare different MyISAM table definitions.
316
317
    For merge table it is not required that number of keys in merge table
318
    must exactly match number of keys in underlying table. When calling this
319
    function for underlying table conformance check, 'strict' flag must be
320
    set to false, and converted merge definition must be passed as t1_*.
321
322
    Otherwise 'strict' flag must be set to 1 and it is not required to pass
323
    converted dot-frm definition as t1_*.
324
325
  RETURN VALUE
326
    0 - Equal definitions.
327
    1 - Different definitions.
328
329
  TODO
330
    - compare FULLTEXT keys;
331
    - compare SPATIAL keys;
332
    - compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
333
      (should be corretly detected in table2myisam).
334
*/
335
336
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
482 by Brian Aker
Remove uint.
337
                     uint32_t t1_keys, uint32_t t1_recs,
1 by brian
clean slate
338
                     MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
482 by Brian Aker
Remove uint.
339
                     uint32_t t2_keys, uint32_t t2_recs, bool strict)
1 by brian
clean slate
340
{
482 by Brian Aker
Remove uint.
341
  uint32_t i, j;
1 by brian
clean slate
342
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
343
  {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
344
    return(1);
1 by brian
clean slate
345
  }
346
  if (t1_recs != t2_recs)
347
  {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
348
    return(1);
1 by brian
clean slate
349
  }
350
  for (i= 0; i < t1_keys; i++)
351
  {
352
    HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
353
    HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
354
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
355
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
356
    {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
357
      return(1);
1 by brian
clean slate
358
    }
359
    for (j=  t1_keyinfo[i].keysegs; j--;)
360
    {
206 by Brian Aker
Removed final uint dead types.
361
      uint8_t t1_keysegs_j__type= t1_keysegs[j].type;
1 by brian
clean slate
362
363
      /*
364
        Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
365
        always HA_KEYTYPE_VARTEXT2. In 4.1 we had only the equivalent of
366
        HA_KEYTYPE_VARTEXT1. Since we treat both the same on MyISAM
367
        level, we can ignore a mismatch between these types.
368
      */
369
      if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
370
          (t2_keysegs[j].flag & HA_BLOB_PART))
371
      {
372
        if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
373
            (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
374
          t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1; /* purecov: tested */
375
        else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
376
                 (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
377
          t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
378
      }
379
380
      if (t1_keysegs_j__type != t2_keysegs[j].type ||
381
          t1_keysegs[j].language != t2_keysegs[j].language ||
382
          t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
383
          t1_keysegs[j].length != t2_keysegs[j].length)
384
      {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
385
        return(1);
1 by brian
clean slate
386
      }
387
    }
388
  }
389
  for (i= 0; i < t1_recs; i++)
390
  {
391
    MI_COLUMNDEF *t1_rec= &t1_recinfo[i];
392
    MI_COLUMNDEF *t2_rec= &t2_recinfo[i];
393
    /*
394
      FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in mi_create,
395
      see NOTE1 in mi_create.c
396
    */
397
    if ((t1_rec->type != t2_rec->type &&
398
         !(t1_rec->type == (int) FIELD_SKIP_ZERO &&
399
           t1_rec->length == 1 &&
400
           t2_rec->type == (int) FIELD_NORMAL)) ||
401
        t1_rec->length != t2_rec->length ||
402
        t1_rec->null_bit != t2_rec->null_bit)
403
    {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
404
      return(1);
1 by brian
clean slate
405
    }
406
  }
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
407
  return(0);
1 by brian
clean slate
408
}
409
410
411
extern "C" {
412
413
volatile int *killed_ptr(MI_CHECK *param)
414
{
415
  /* In theory Unsafe conversion, but should be ok for now */
520.1.22 by Brian Aker
Second pass of thd cleanup
416
  return (int*) &(((Session *)(param->session))->killed);
1 by brian
clean slate
417
}
418
419
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
420
{
421
  param->error_printed|=1;
422
  param->out_flag|= O_DATA_LOST;
423
  va_list args;
424
  va_start(args, fmt);
425
  mi_check_print_msg(param, "error", fmt, args);
426
  va_end(args);
427
}
428
429
void mi_check_print_info(MI_CHECK *param, const char *fmt,...)
430
{
431
  va_list args;
432
  va_start(args, fmt);
433
  mi_check_print_msg(param, "info", fmt, args);
434
  va_end(args);
435
}
436
437
void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
438
{
439
  param->warning_printed=1;
440
  param->out_flag|= O_DATA_LOST;
441
  va_list args;
442
  va_start(args, fmt);
443
  mi_check_print_msg(param, "warning", fmt, args);
444
  va_end(args);
445
}
446
447
/**
448
  Report list of threads (and queries) accessing a table, thread_id of a
449
  thread that detected corruption, ource file name and line number where
450
  this corruption was detected, optional extra information (string).
451
452
  This function is intended to be used when table corruption is detected.
453
454
  @param[in] file      MI_INFO object.
455
  @param[in] message   Optional error message.
456
  @param[in] sfile     Name of source file.
457
  @param[in] sline     Line number in source file.
458
459
  @return void
460
*/
461
462
void _mi_report_crashed(MI_INFO *file, const char *message,
482 by Brian Aker
Remove uint.
463
                        const char *sfile, uint32_t sline)
1 by brian
clean slate
464
{
520.1.22 by Brian Aker
Second pass of thd cleanup
465
  Session *cur_session;
1 by brian
clean slate
466
  pthread_mutex_lock(&file->s->intern_lock);
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
467
  if ((cur_session= file->in_use))
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
468
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
553 by Monty Taylor
Changed my_thread_id type.
469
                    cur_session->thread_id,
1 by brian
clean slate
470
                    sfile, sline);
471
  else
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
472
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from unknown thread, %s:%d"), sfile, sline);
1 by brian
clean slate
473
  if (message)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
474
    errmsg_printf(ERRMSG_LVL_ERROR, "%s", message);
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
475
  list<Session *>::iterator it= file->s->in_use->begin();
476
  while (it != file->s->in_use->end())
1 by brian
clean slate
477
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
478
    errmsg_printf(ERRMSG_LVL_ERROR, "%s", _("Unknown thread accessing table"));
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
479
    ++it;
1 by brian
clean slate
480
  }
481
  pthread_mutex_unlock(&file->s->intern_lock);
482
}
483
77.1.13 by Monty Taylor
Fixed wonky linkage thing.
484
}
1 by brian
clean slate
485
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
486
ha_myisam::ha_myisam(StorageEngine *engine_arg, TableShare *table_arg)
960.2.37 by Monty Taylor
More naming fixes.
487
  :handler(engine_arg, table_arg), file(0),
413.2.2 by Brian Aker
Removed UNSIGNED from parser.
488
  int_table_flags(HA_NULL_IN_KEY |
489
                  HA_DUPLICATE_POS |
490
                  HA_CAN_INDEX_BLOBS |
491
                  HA_AUTO_PART_KEY |
492
                  HA_FILE_BASED |
493
                  HA_NO_TRANSACTIONS |
494
                  HA_HAS_RECORDS |
495
                  HA_STATS_RECORDS_IS_EXACT |
496
                  HA_NEED_READ_RANGE_BUFFER |
497
                  HA_MRR_CANT_SORT),
1 by brian
clean slate
498
   can_enable_indexes(1)
499
{}
500
501
handler *ha_myisam::clone(MEM_ROOT *mem_root)
502
{
503
  ha_myisam *new_handler= static_cast <ha_myisam *>(handler::clone(mem_root));
504
  if (new_handler)
505
    new_handler->file->state= file->state;
506
  return new_handler;
507
}
508
509
510
static const char *ha_myisam_exts[] = {
511
  ".MYI",
512
  ".MYD",
461 by Monty Taylor
Removed NullS. bu-bye.
513
  NULL
1 by brian
clean slate
514
};
515
516
const char **ha_myisam::bas_ext() const
517
{
518
  return ha_myisam_exts;
519
}
520
521
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
522
const char *ha_myisam::index_type(uint32_t )
1 by brian
clean slate
523
{
74 by Brian Aker
More removal of FT from MyISAM
524
  return "BTREE";
1 by brian
clean slate
525
}
526
527
/* Name is here without an extension */
482 by Brian Aker
Remove uint.
528
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
1 by brian
clean slate
529
{
530
  MI_KEYDEF *keyinfo;
531
  MI_COLUMNDEF *recinfo= 0;
482 by Brian Aker
Remove uint.
532
  uint32_t recs;
533
  uint32_t i;
1 by brian
clean slate
534
535
  /*
536
    If the user wants to have memory mapped data files, add an
537
    open_flag. Do not memory map temporary tables because they are
538
    expected to be inserted and thus extended a lot. Memory mapping is
539
    efficient for files that keep their size, but very inefficient for
540
    growing files. Using an open_flag instead of calling mi_extra(...
541
    HA_EXTRA_MMAP ...) after mi_open() has the advantage that the
542
    mapping is not repeated for every open, but just done on the initial
543
    open, when the MyISAM share is created. Everytime the server
544
    requires to open a new instance of a table it calls this method. We
545
    will always supply HA_OPEN_MMAP for a permanent table. However, the
546
    MyISAM storage engine will ignore this flag if this is a secondary
547
    open of a table that is in use by other threads already (if the
548
    MyISAM share exists already).
549
  */
550
  if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
551
    return (my_errno ? my_errno : -1);
552
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
553
  {
554
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
555
    {
556
      /* purecov: begin inspected */
557
      goto err;
558
      /* purecov: end */
559
    }
560
    if (check_definition(keyinfo, recinfo, table->s->keys, recs,
561
                         file->s->keyinfo, file->s->rec,
562
                         file->s->base.keys, file->s->base.fields, true))
563
    {
564
      /* purecov: begin inspected */
565
      my_errno= HA_ERR_CRASHED;
566
      goto err;
567
      /* purecov: end */
568
    }
569
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
570
1 by brian
clean slate
571
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
398.1.10 by Monty Taylor
Actually removed VOID() this time.
572
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
1 by brian
clean slate
573
574
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
575
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
398.1.10 by Monty Taylor
Actually removed VOID() this time.
576
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
1 by brian
clean slate
577
  if (!table->s->db_record_offset)
578
    int_table_flags|=HA_REC_NOT_IN_SEQ;
579
  if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
580
    int_table_flags|=HA_HAS_CHECKSUM;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
581
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
582
  keys_with_parts.reset();
1 by brian
clean slate
583
  for (i= 0; i < table->s->keys; i++)
584
  {
585
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
586
587
    KEY_PART_INFO *kp= table->key_info[i].key_part;
588
    KEY_PART_INFO *kp_end= kp + table->key_info[i].key_parts;
589
    for (; kp != kp_end; kp++)
590
    {
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
591
      if (!kp->field->part_of_key.test(i))
1 by brian
clean slate
592
      {
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
593
        keys_with_parts.set(i);
1 by brian
clean slate
594
        break;
595
      }
596
    }
597
  }
598
  my_errno= 0;
599
  goto end;
600
 err:
601
  this->close();
602
 end:
603
  /*
604
    Both recinfo and keydef are allocated by my_multi_malloc(), thus only
605
    recinfo must be freed.
606
  */
607
  if (recinfo)
481 by Brian Aker
Remove all of uchar.
608
    free((unsigned char*) recinfo);
1 by brian
clean slate
609
  return my_errno;
610
}
611
612
int ha_myisam::close(void)
613
{
614
  MI_INFO *tmp=file;
615
  file=0;
616
  return mi_close(tmp);
617
}
618
481 by Brian Aker
Remove all of uchar.
619
int ha_myisam::write_row(unsigned char *buf)
1 by brian
clean slate
620
{
621
  ha_statistic_increment(&SSV::ha_write_count);
622
623
  /*
624
    If we have an auto_increment column and we are writing a changed row
625
    or a new row, then update the auto_increment value in the record.
626
  */
627
  if (table->next_number_field && buf == table->record[0])
628
  {
629
    int error;
630
    if ((error= update_auto_increment()))
631
      return error;
632
  }
633
  return mi_write(file,buf);
634
}
635
520.1.22 by Brian Aker
Second pass of thd cleanup
636
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
1 by brian
clean slate
637
{
638
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
639
  int error;
640
  MI_CHECK param;
641
  MYISAM_SHARE* share = file->s;
520.1.22 by Brian Aker
Second pass of thd cleanup
642
  const char *old_proc_info= session->get_proc_info();
1 by brian
clean slate
643
520.1.22 by Brian Aker
Second pass of thd cleanup
644
  session->set_proc_info("Checking table");
1 by brian
clean slate
645
  myisamchk_init(&param);
520.1.22 by Brian Aker
Second pass of thd cleanup
646
  param.session = session;
1 by brian
clean slate
647
  param.op_name =   "check";
648
  param.db_name=    table->s->db.str;
649
  param.table_name= table->alias;
650
  param.testflag = check_opt->flags | T_CHECK | T_SILENT;
520.1.22 by Brian Aker
Second pass of thd cleanup
651
  param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
1 by brian
clean slate
652
653
  if (!(table->db_stat & HA_READ_ONLY))
654
    param.testflag|= T_STATISTICS;
655
  param.using_global_keycache = 1;
656
657
  if (!mi_is_crashed(file) &&
658
      (((param.testflag & T_CHECK_ONLY_CHANGED) &&
659
	!(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
660
				  STATE_CRASHED_ON_REPAIR)) &&
661
	share->state.open_count == 0) ||
662
       ((param.testflag & T_FAST) && (share->state.open_count ==
663
				      (uint) (share->global_changed ? 1 : 0)))))
664
    return HA_ADMIN_ALREADY_DONE;
665
666
  error = chk_status(&param, file);		// Not fatal
667
  error = chk_size(&param, file);
668
  if (!error)
669
    error |= chk_del(&param, file, param.testflag);
670
  if (!error)
671
    error = chk_key(&param, file);
672
  if (!error)
673
  {
674
    if ((!(param.testflag & T_QUICK) &&
675
	 ((share->options &
676
	   (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
677
	  (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
678
	mi_is_crashed(file))
679
    {
482 by Brian Aker
Remove uint.
680
      uint32_t old_testflag=param.testflag;
1 by brian
clean slate
681
      param.testflag|=T_MEDIUM;
682
      if (!(error= init_io_cache(&param.read_cache, file->dfile,
683
                                 my_default_record_cache_size, READ_CACHE,
684
                                 share->pack.header_length, 1, MYF(MY_WME))))
685
      {
686
        error= chk_data_link(&param, file, param.testflag & T_EXTEND);
687
        end_io_cache(&(param.read_cache));
688
      }
689
      param.testflag= old_testflag;
690
    }
691
  }
692
  if (!error)
693
  {
694
    if ((share->state.changed & (STATE_CHANGED |
695
				 STATE_CRASHED_ON_REPAIR |
696
				 STATE_CRASHED | STATE_NOT_ANALYZED)) ||
697
	(param.testflag & T_STATISTICS) ||
698
	mi_is_crashed(file))
699
    {
700
      file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
701
      pthread_mutex_lock(&share->intern_lock);
702
      share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
703
			       STATE_CRASHED_ON_REPAIR);
704
      if (!(table->db_stat & HA_READ_ONLY))
705
	error=update_state_info(&param,file,UPDATE_TIME | UPDATE_OPEN_COUNT |
706
				UPDATE_STAT);
707
      pthread_mutex_unlock(&share->intern_lock);
708
      info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
709
	   HA_STATUS_CONST);
710
    }
711
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
712
  else if (!mi_is_crashed(file) && !session->killed)
1 by brian
clean slate
713
  {
714
    mi_mark_crashed(file);
715
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
716
  }
717
520.1.22 by Brian Aker
Second pass of thd cleanup
718
  session->set_proc_info(old_proc_info);
1 by brian
clean slate
719
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
720
}
721
722
723
/*
724
  analyze the key distribution in the table
725
  As the table may be only locked for read, we have to take into account that
726
  two threads may do an analyze at the same time!
727
*/
728
520.1.22 by Brian Aker
Second pass of thd cleanup
729
int ha_myisam::analyze(Session *session,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
730
                       HA_CHECK_OPT* )
1 by brian
clean slate
731
{
732
  int error=0;
733
  MI_CHECK param;
734
  MYISAM_SHARE* share = file->s;
735
736
  myisamchk_init(&param);
520.1.22 by Brian Aker
Second pass of thd cleanup
737
  param.session = session;
1 by brian
clean slate
738
  param.op_name=    "analyze";
739
  param.db_name=    table->s->db.str;
740
  param.table_name= table->alias;
741
  param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
742
                   T_DONT_CHECK_CHECKSUM);
743
  param.using_global_keycache = 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
744
  param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
1 by brian
clean slate
745
746
  if (!(share->state.changed & STATE_NOT_ANALYZED))
747
    return HA_ADMIN_ALREADY_DONE;
748
749
  error = chk_key(&param, file);
750
  if (!error)
751
  {
752
    pthread_mutex_lock(&share->intern_lock);
753
    error=update_state_info(&param,file,UPDATE_STAT);
754
    pthread_mutex_unlock(&share->intern_lock);
755
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
756
  else if (!mi_is_crashed(file) && !session->killed)
1 by brian
clean slate
757
    mi_mark_crashed(file);
758
  return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
759
}
760
761
520.1.22 by Brian Aker
Second pass of thd cleanup
762
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
1 by brian
clean slate
763
{
764
  int error;
765
  MI_CHECK param;
766
  ha_rows start_records;
767
768
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
769
770
  myisamchk_init(&param);
520.1.22 by Brian Aker
Second pass of thd cleanup
771
  param.session = session;
1 by brian
clean slate
772
  param.op_name=  "repair";
773
  param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
774
                   T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
775
                   (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
776
  param.sort_buffer_length=  (size_t)sort_buffer_size;
873.2.11 by Monty Taylor
call ha_release_temporary_latches
777
778
  // Release latches since this can take a long time
779
  ha_release_temporary_latches(session);
780
1 by brian
clean slate
781
  start_records=file->state->records;
520.1.22 by Brian Aker
Second pass of thd cleanup
782
  while ((error=repair(session,param,0)) && param.retry_repair)
1 by brian
clean slate
783
  {
784
    param.retry_repair=0;
785
    if (test_all_bits(param.testflag,
786
		      (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
787
    {
788
      param.testflag&= ~T_RETRY_WITHOUT_QUICK;
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
789
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' without quick",
1 by brian
clean slate
790
                            table->s->path.str);
791
      continue;
792
    }
793
    param.testflag&= ~T_QUICK;
794
    if ((param.testflag & T_REP_BY_SORT))
795
    {
796
      param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
797
      errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' with keycache",
1 by brian
clean slate
798
                            table->s->path.str);
799
      continue;
800
    }
801
    break;
802
  }
803
  if (!error && start_records != file->state->records &&
804
      !(check_opt->flags & T_VERY_SILENT))
805
  {
806
    char llbuff[22],llbuff2[22];
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
807
    errmsg_printf(ERRMSG_LVL_INFO, "Found %s of %s rows when repairing '%s'",
1 by brian
clean slate
808
                          llstr(file->state->records, llbuff),
809
                          llstr(start_records, llbuff2),
810
                          table->s->path.str);
811
  }
812
  return error;
813
}
814
520.1.22 by Brian Aker
Second pass of thd cleanup
815
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
1 by brian
clean slate
816
{
817
  int error;
818
  if (!file) return HA_ADMIN_INTERNAL_ERROR;
819
  MI_CHECK param;
820
821
  myisamchk_init(&param);
520.1.22 by Brian Aker
Second pass of thd cleanup
822
  param.session = session;
1 by brian
clean slate
823
  param.op_name= "optimize";
824
  param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
825
                   T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
826
  param.sort_buffer_length= (size_t)sort_buffer_size;
520.1.22 by Brian Aker
Second pass of thd cleanup
827
  if ((error= repair(session,param,1)) && param.retry_repair)
1 by brian
clean slate
828
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
829
    errmsg_printf(ERRMSG_LVL_WARN, "Warning: Optimize table got errno %d on %s.%s, retrying",
1 by brian
clean slate
830
                      my_errno, param.db_name, param.table_name);
831
    param.testflag&= ~T_REP_BY_SORT;
520.1.22 by Brian Aker
Second pass of thd cleanup
832
    error= repair(session,param,1);
1 by brian
clean slate
833
  }
834
  return error;
835
}
836
837
520.1.22 by Brian Aker
Second pass of thd cleanup
838
int ha_myisam::repair(Session *session, MI_CHECK &param, bool do_optimize)
1 by brian
clean slate
839
{
840
  int error=0;
789 by Brian Aker
MyISAM fix.
841
  uint32_t local_testflag= param.testflag;
1 by brian
clean slate
842
  bool optimize_done= !do_optimize, statistics_done=0;
520.1.22 by Brian Aker
Second pass of thd cleanup
843
  const char *old_proc_info= session->get_proc_info();
1 by brian
clean slate
844
  char fixed_name[FN_REFLEN];
845
  MYISAM_SHARE* share = file->s;
846
  ha_rows rows= file->state->records;
847
848
  /*
849
    Normally this method is entered with a properly opened table. If the
850
    repair fails, it can be repeated with more elaborate options. Under
851
    special circumstances it can happen that a repair fails so that it
852
    closed the data file and cannot re-open it. In this case file->dfile
853
    is set to -1. We must not try another repair without an open data
854
    file. (Bug #25289)
855
  */
856
  if (file->dfile == -1)
857
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
858
    errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
1 by brian
clean slate
859
                          "Please try REPAIR EXTENDED or myisamchk",
860
                          table->s->path.str);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
861
    return(HA_ADMIN_FAILED);
1 by brian
clean slate
862
  }
863
864
  param.db_name=    table->s->db.str;
865
  param.table_name= table->alias;
866
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
867
  param.using_global_keycache = 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
868
  param.session= session;
1 by brian
clean slate
869
  param.out_flag= 0;
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
870
  param.sort_buffer_length= (size_t)sort_buffer_size;
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
871
  strcpy(fixed_name,file->filename);
1 by brian
clean slate
872
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
873
  // Don't lock tables if we have used LOCK Table
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
874
  if (!session->locked_tables &&
1 by brian
clean slate
875
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
876
  {
877
    mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
878
    return(HA_ADMIN_FAILED);
1 by brian
clean slate
879
  }
880
881
  if (!do_optimize ||
882
      ((file->state->del || share->state.split != file->state->records) &&
883
       (!(param.testflag & T_QUICK) ||
884
	!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
885
  {
886
    uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
887
			mi_get_mask_all_keys_active(share->base.keys) :
888
			share->state.key_map);
482 by Brian Aker
Remove uint.
889
    uint32_t testflag=param.testflag;
1 by brian
clean slate
890
    if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
891
	(local_testflag & T_REP_BY_SORT))
892
    {
893
      local_testflag|= T_STATISTICS;
894
      param.testflag|= T_STATISTICS;		// We get this for free
895
      statistics_done=1;
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
896
      if (repair_threads > 1)
1 by brian
clean slate
897
      {
898
        char buf[40];
899
        /* TODO: respect myisam_repair_threads variable */
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
900
        snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
520.1.22 by Brian Aker
Second pass of thd cleanup
901
        session->set_proc_info(buf);
1 by brian
clean slate
902
        error = mi_repair_parallel(&param, file, fixed_name,
903
            param.testflag & T_QUICK);
520.1.22 by Brian Aker
Second pass of thd cleanup
904
        session->set_proc_info("Repair done"); // to reset proc_info, as
1 by brian
clean slate
905
                                      // it was pointing to local buffer
906
      }
907
      else
908
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
909
        session->set_proc_info("Repair by sorting");
1 by brian
clean slate
910
        error = mi_repair_by_sort(&param, file, fixed_name,
911
            param.testflag & T_QUICK);
912
      }
913
    }
914
    else
915
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
916
      session->set_proc_info("Repair with keycache");
1 by brian
clean slate
917
      param.testflag &= ~T_REP_BY_SORT;
918
      error=  mi_repair(&param, file, fixed_name,
919
			param.testflag & T_QUICK);
920
    }
921
    param.testflag=testflag;
922
    optimize_done=1;
923
  }
924
  if (!error)
925
  {
926
    if ((local_testflag & T_SORT_INDEX) &&
927
	(share->state.changed & STATE_NOT_SORTED_PAGES))
928
    {
929
      optimize_done=1;
520.1.22 by Brian Aker
Second pass of thd cleanup
930
      session->set_proc_info("Sorting index");
1 by brian
clean slate
931
      error=mi_sort_index(&param,file,fixed_name);
932
    }
933
    if (!statistics_done && (local_testflag & T_STATISTICS))
934
    {
935
      if (share->state.changed & STATE_NOT_ANALYZED)
936
      {
937
	optimize_done=1;
520.1.22 by Brian Aker
Second pass of thd cleanup
938
	session->set_proc_info("Analyzing");
1 by brian
clean slate
939
	error = chk_key(&param, file);
940
      }
941
      else
942
	local_testflag&= ~T_STATISTICS;		// Don't update statistics
943
    }
944
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
945
  session->set_proc_info("Saving state");
1 by brian
clean slate
946
  if (!error)
947
  {
948
    if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
949
    {
950
      share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
951
			       STATE_CRASHED_ON_REPAIR);
952
      file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
953
    }
954
    /*
955
      the following 'if', thought conceptually wrong,
956
      is a useful optimization nevertheless.
957
    */
958
    if (file->state != &file->s->state.state)
959
      file->s->state.state = *file->state;
960
    if (file->s->base.auto_key)
961
      update_auto_increment_key(&param, file, 1);
962
    if (optimize_done)
963
      error = update_state_info(&param, file,
964
				UPDATE_TIME | UPDATE_OPEN_COUNT |
965
				(local_testflag &
966
				 T_STATISTICS ? UPDATE_STAT : 0));
967
    info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
968
	 HA_STATUS_CONST);
969
    if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT))
970
    {
971
      char llbuff[22],llbuff2[22];
972
      mi_check_print_warning(&param,"Number of rows changed from %s to %s",
973
			     llstr(rows,llbuff),
974
			     llstr(file->state->records,llbuff2));
975
    }
976
  }
977
  else
978
  {
979
    mi_mark_crashed_on_repair(file);
980
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
981
    update_state_info(&param, file, 0);
982
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
983
  session->set_proc_info(old_proc_info);
984
  if (!session->locked_tables)
1 by brian
clean slate
985
    mi_lock_database(file,F_UNLCK);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
986
  return(error ? HA_ADMIN_FAILED :
1 by brian
clean slate
987
	      !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
988
}
989
990
991
/*
992
  Assign table indexes to a specific key cache.
993
*/
994
520.1.22 by Brian Aker
Second pass of thd cleanup
995
int ha_myisam::assign_to_keycache(Session* session, HA_CHECK_OPT *check_opt)
1 by brian
clean slate
996
{
997
  KEY_CACHE *new_key_cache= check_opt->key_cache;
998
  const char *errmsg= 0;
999
  int error= HA_ADMIN_OK;
327.2.4 by Brian Aker
Refactoring table.h
1000
  TableList *table_list= table->pos_in_table_list;
1 by brian
clean slate
1001
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
1002
  table->keys_in_use_for_query.reset();
1 by brian
clean slate
1003
1004
  if (table_list->process_index_hints(table))
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1005
    return(HA_ADMIN_FAILED);
1 by brian
clean slate
1006
993.1.23 by Padraig O'Sullivan
Removing an unused parameter in a function in the MyISAM storage engine.
1007
  if ((error= mi_assign_to_key_cache(file, new_key_cache)))
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1008
  {
1 by brian
clean slate
1009
    char buf[STRING_BUFFER_USUAL_SIZE];
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1010
    snprintf(buf, sizeof(buf),
1 by brian
clean slate
1011
		"Failed to flush to index file (errno: %d)", error);
1012
    errmsg= buf;
1013
    error= HA_ADMIN_CORRUPT;
1014
  }
1015
1016
  if (error != HA_ADMIN_OK)
1017
  {
1018
    /* Send error to user */
1019
    MI_CHECK param;
1020
    myisamchk_init(&param);
520.1.22 by Brian Aker
Second pass of thd cleanup
1021
    param.session= session;
1 by brian
clean slate
1022
    param.op_name=    "assign_to_keycache";
1023
    param.db_name=    table->s->db.str;
1024
    param.table_name= table->s->table_name.str;
1025
    param.testflag= 0;
1026
    mi_check_print_error(&param, errmsg);
1027
  }
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1028
  return(error);
1 by brian
clean slate
1029
}
1030
1031
1032
/*
1033
  Disable indexes, making it persistent if requested.
1034
1035
  SYNOPSIS
1036
    disable_indexes()
1037
    mode        mode of operation:
1038
                HA_KEY_SWITCH_NONUNIQ      disable all non-unique keys
1039
                HA_KEY_SWITCH_ALL          disable all keys
1040
                HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent
1041
                HA_KEY_SWITCH_ALL_SAVE     dis. all keys and make persistent
1042
1043
  IMPLEMENTATION
1044
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
1045
    HA_KEY_SWITCH_ALL_SAVE      is not implemented.
1046
1047
  RETURN
1048
    0  ok
1049
    HA_ERR_WRONG_COMMAND  mode not implemented.
1050
*/
1051
482 by Brian Aker
Remove uint.
1052
int ha_myisam::disable_indexes(uint32_t mode)
1 by brian
clean slate
1053
{
1054
  int error;
1055
1056
  if (mode == HA_KEY_SWITCH_ALL)
1057
  {
1058
    /* call a storage engine function to switch the key map */
1059
    error= mi_disable_indexes(file);
1060
  }
1061
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1062
  {
1063
    mi_extra(file, HA_EXTRA_NO_KEYS, 0);
1064
    info(HA_STATUS_CONST);                        // Read new key info
1065
    error= 0;
1066
  }
1067
  else
1068
  {
1069
    /* mode not implemented */
1070
    error= HA_ERR_WRONG_COMMAND;
1071
  }
1072
  return error;
1073
}
1074
1075
1076
/*
1077
  Enable indexes, making it persistent if requested.
1078
1079
  SYNOPSIS
1080
    enable_indexes()
1081
    mode        mode of operation:
1082
                HA_KEY_SWITCH_NONUNIQ      enable all non-unique keys
1083
                HA_KEY_SWITCH_ALL          enable all keys
1084
                HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent
1085
                HA_KEY_SWITCH_ALL_SAVE     en. all keys and make persistent
1086
1087
  DESCRIPTION
1088
    Enable indexes, which might have been disabled by disable_index() before.
1089
    The modes without _SAVE work only if both data and indexes are empty,
1090
    since the MyISAM repair would enable them persistently.
1091
    To be sure in these cases, call handler::delete_all_rows() before.
1092
1093
  IMPLEMENTATION
1094
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
1095
    HA_KEY_SWITCH_ALL_SAVE      is not implemented.
1096
1097
  RETURN
1098
    0  ok
1099
    !=0  Error, among others:
1100
    HA_ERR_CRASHED  data or index is non-empty. Delete all rows and retry.
1101
    HA_ERR_WRONG_COMMAND  mode not implemented.
1102
*/
1103
482 by Brian Aker
Remove uint.
1104
int ha_myisam::enable_indexes(uint32_t mode)
1 by brian
clean slate
1105
{
1106
  int error;
1107
1108
  if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys))
1109
  {
1110
    /* All indexes are enabled already. */
1111
    return 0;
1112
  }
1113
1114
  if (mode == HA_KEY_SWITCH_ALL)
1115
  {
1116
    error= mi_enable_indexes(file);
1117
    /*
1118
       Do not try to repair on error,
1119
       as this could make the enabled state persistent,
1120
       but mode==HA_KEY_SWITCH_ALL forbids it.
1121
    */
1122
  }
1123
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
1124
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1125
    Session *session=current_session;
1 by brian
clean slate
1126
    MI_CHECK param;
520.1.22 by Brian Aker
Second pass of thd cleanup
1127
    const char *save_proc_info= session->get_proc_info();
1128
    session->set_proc_info("Creating index");
1 by brian
clean slate
1129
    myisamchk_init(&param);
1130
    param.op_name= "recreating_index";
1131
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
1132
                     T_CREATE_MISSING_KEYS);
1133
    param.myf_rw&= ~MY_WAIT_IF_FULL;
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
1134
    param.sort_buffer_length=  (size_t)sort_buffer_size;
520.1.22 by Brian Aker
Second pass of thd cleanup
1135
    param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
1136
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1 by brian
clean slate
1137
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1138
      errmsg_printf(ERRMSG_LVL_WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
1 by brian
clean slate
1139
                        my_errno, param.db_name, param.table_name);
1140
      /* Repairing by sort failed. Now try standard repair method. */
1141
      param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
520.1.22 by Brian Aker
Second pass of thd cleanup
1142
      error= (repair(session,param,0) != HA_ADMIN_OK);
1 by brian
clean slate
1143
      /*
1144
        If the standard repair succeeded, clear all error messages which
1145
        might have been set by the first repair. They can still be seen
1146
        with SHOW WARNINGS then.
1147
      */
1148
      if (! error)
520.1.22 by Brian Aker
Second pass of thd cleanup
1149
        session->clear_error();
1 by brian
clean slate
1150
    }
1151
    info(HA_STATUS_CONST);
520.1.22 by Brian Aker
Second pass of thd cleanup
1152
    session->set_proc_info(save_proc_info);
1 by brian
clean slate
1153
  }
1154
  else
1155
  {
1156
    /* mode not implemented */
1157
    error= HA_ERR_WRONG_COMMAND;
1158
  }
1159
  return error;
1160
}
1161
1162
1163
/*
1164
  Test if indexes are disabled.
1165
1166
1167
  SYNOPSIS
1168
    indexes_are_disabled()
1169
      no parameters
1170
1171
1172
  RETURN
1173
    0  indexes are not disabled
1174
    1  all indexes are disabled
1175
   [2  non-unique indexes are disabled - NOT YET IMPLEMENTED]
1176
*/
1177
1178
int ha_myisam::indexes_are_disabled(void)
1179
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1180
1 by brian
clean slate
1181
  return mi_indexes_are_disabled(file);
1182
}
1183
1184
1185
/*
1186
  prepare for a many-rows insert operation
1187
  e.g. - disable indexes (if they can be recreated fast) or
1188
  activate special bulk-insert optimizations
1189
1190
  SYNOPSIS
1191
    start_bulk_insert(rows)
1192
    rows        Rows to be inserted
1193
                0 if we don't know
1194
1195
  NOTICE
1196
    Do not forget to call end_bulk_insert() later!
1197
*/
1198
1199
void ha_myisam::start_bulk_insert(ha_rows rows)
1200
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1201
  Session *session= current_session;
1202
  ulong size= cmin(session->variables.read_buff_size,
1 by brian
clean slate
1203
                  (ulong) (table->s->avg_row_length*rows));
1204
1205
  /* don't enable row cache if too few rows */
1206
  if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1207
    mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
1208
1209
  can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
1210
                                            file->s->base.keys);
1211
362 by Brian Aker
No more dead special flags...
1212
  /*
1213
    Only disable old index if the table was empty and we are inserting
1214
    a lot of rows.
1215
    We should not do this for only a few rows as this is slower and
1216
    we don't want to update the key statistics based of only a few rows.
1217
  */
1218
  if (file->state->records == 0 && can_enable_indexes &&
1219
      (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1220
    mi_disable_non_unique_index(file,rows);
1221
  else
1 by brian
clean slate
1222
    if (!file->bulk_insert &&
1223
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1224
    {
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
1225
      mi_init_bulk_insert(file,
1226
                          (size_t)session->variables.bulk_insert_buff_size,
1227
                          rows);
1 by brian
clean slate
1228
    }
362 by Brian Aker
No more dead special flags...
1229
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1230
  return;
1 by brian
clean slate
1231
}
1232
1233
/*
1234
  end special bulk-insert optimizations,
1235
  which have been activated by start_bulk_insert().
1236
1237
  SYNOPSIS
1238
    end_bulk_insert()
1239
    no arguments
1240
1241
  RETURN
1242
    0     OK
1243
    != 0  Error
1244
*/
1245
1246
int ha_myisam::end_bulk_insert()
1247
{
1248
  mi_end_bulk_insert(file);
1249
  int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0);
1250
  return err ? err : can_enable_indexes ?
1251
                     enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE) : 0;
1252
}
1253
1254
520.1.22 by Brian Aker
Second pass of thd cleanup
1255
bool ha_myisam::check_and_repair(Session *session)
1 by brian
clean slate
1256
{
1257
  int error=0;
1258
  int marked_crashed;
1259
  char *old_query;
482 by Brian Aker
Remove uint.
1260
  uint32_t old_query_length;
1 by brian
clean slate
1261
  HA_CHECK_OPT check_opt;
1262
1263
  check_opt.init();
1264
  check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
1265
  // Don't use quick if deleted rows
1266
  if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
1267
    check_opt.flags|=T_QUICK;
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1268
  errmsg_printf(ERRMSG_LVL_WARN, "Checking table:   '%s'",table->s->path.str);
1 by brian
clean slate
1269
520.1.22 by Brian Aker
Second pass of thd cleanup
1270
  old_query= session->query;
1271
  old_query_length= session->query_length;
1 by brian
clean slate
1272
  pthread_mutex_lock(&LOCK_thread_count);
520.1.22 by Brian Aker
Second pass of thd cleanup
1273
  session->query=        table->s->table_name.str;
1274
  session->query_length= table->s->table_name.length;
1 by brian
clean slate
1275
  pthread_mutex_unlock(&LOCK_thread_count);
1276
520.1.22 by Brian Aker
Second pass of thd cleanup
1277
  if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
1 by brian
clean slate
1278
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1279
    errmsg_printf(ERRMSG_LVL_WARN, "Recovering table: '%s'",table->s->path.str);
1 by brian
clean slate
1280
    check_opt.flags=
1281
      ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
1282
       (marked_crashed                             ? 0 : T_QUICK) |
1283
       (myisam_recover_options & HA_RECOVER_FORCE  ? 0 : T_SAFE_REPAIR) |
1284
       T_AUTO_REPAIR);
520.1.22 by Brian Aker
Second pass of thd cleanup
1285
    if (repair(session, &check_opt))
1 by brian
clean slate
1286
      error=1;
1287
  }
1288
  pthread_mutex_lock(&LOCK_thread_count);
520.1.22 by Brian Aker
Second pass of thd cleanup
1289
  session->query= old_query;
1290
  session->query_length= old_query_length;
1 by brian
clean slate
1291
  pthread_mutex_unlock(&LOCK_thread_count);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1292
  return(error);
1 by brian
clean slate
1293
}
1294
1295
bool ha_myisam::is_crashed() const
1296
{
1297
  return (file->s->state.changed & STATE_CRASHED ||
77.1.96 by Monty Taylor
Removed skip-external-locking.
1298
	  (file->s->state.open_count));
1 by brian
clean slate
1299
}
1300
481 by Brian Aker
Remove all of uchar.
1301
int ha_myisam::update_row(const unsigned char *old_data, unsigned char *new_data)
1 by brian
clean slate
1302
{
1303
  ha_statistic_increment(&SSV::ha_update_count);
1304
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1305
    table->timestamp_field->set_time();
1306
  return mi_update(file,old_data,new_data);
1307
}
1308
481 by Brian Aker
Remove all of uchar.
1309
int ha_myisam::delete_row(const unsigned char *buf)
1 by brian
clean slate
1310
{
1311
  ha_statistic_increment(&SSV::ha_delete_count);
1312
  return mi_delete(file,buf);
1313
}
1314
398.1.9 by Monty Taylor
Cleaned up stuff out of global.h.
1315
#ifdef __cplusplus
1316
extern "C" {
1317
#endif
1 by brian
clean slate
1318
281 by Brian Aker
Converted myisam away from my_bool
1319
bool index_cond_func_myisam(void *arg)
1 by brian
clean slate
1320
{
1321
  ha_myisam *h= (ha_myisam*)arg;
1322
  /*if (h->in_range_read)*/
1323
  if (h->end_range)
1324
  {
1325
    if (h->compare_key2(h->end_range) > 0)
1326
      return 2; /* caller should return HA_ERR_END_OF_FILE already */
1327
  }
281 by Brian Aker
Converted myisam away from my_bool
1328
  return (bool)h->pushed_idx_cond->val_int();
1 by brian
clean slate
1329
}
1330
398.1.9 by Monty Taylor
Cleaned up stuff out of global.h.
1331
#ifdef __cplusplus
1332
}
1333
#endif
1 by brian
clean slate
1334
1335
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1336
int ha_myisam::index_init(uint32_t idx, bool )
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1337
{
1 by brian
clean slate
1338
  active_index=idx;
163 by Brian Aker
Merge Monty's code.
1339
  //in_range_read= false;
1 by brian
clean slate
1340
  if (pushed_idx_cond_keyno == idx)
1341
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1342
  return 0;
1 by brian
clean slate
1343
}
1344
1345
1346
int ha_myisam::index_end()
1347
{
1348
  active_index=MAX_KEY;
1349
  //pushed_idx_cond_keyno= MAX_KEY;
1350
  mi_set_index_cond_func(file, NULL, 0);
163 by Brian Aker
Merge Monty's code.
1351
  in_range_check_pushed_down= false;
1 by brian
clean slate
1352
  ds_mrr.dsmrr_close();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1353
  return 0;
1 by brian
clean slate
1354
}
1355
1356
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1357
uint32_t ha_myisam::index_flags(uint32_t inx, uint32_t, bool) const
1358
{
1359
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
1360
          0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
1361
          HA_READ_ORDER | HA_KEYREAD_ONLY |
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
1362
          (keys_with_parts.test(inx)?0:HA_DO_INDEX_COND_PUSHDOWN));
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1363
}
1364
1365
481 by Brian Aker
Remove all of uchar.
1366
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
1367
                              key_part_map keypart_map,
1368
                              enum ha_rkey_function find_flag)
1369
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1370
  assert(inited==INDEX);
1 by brian
clean slate
1371
  ha_statistic_increment(&SSV::ha_read_key_count);
1372
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1373
  table->status=error ? STATUS_NOT_FOUND: 0;
1374
  return error;
1375
}
1376
482 by Brian Aker
Remove uint.
1377
int ha_myisam::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
1 by brian
clean slate
1378
                                  key_part_map keypart_map,
1379
                                  enum ha_rkey_function find_flag)
1380
{
1381
  ha_statistic_increment(&SSV::ha_read_key_count);
1382
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1383
  table->status=error ? STATUS_NOT_FOUND: 0;
1384
  return error;
1385
}
1386
481 by Brian Aker
Remove all of uchar.
1387
int ha_myisam::index_read_last_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
1388
                                   key_part_map keypart_map)
1389
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1390
  assert(inited==INDEX);
1 by brian
clean slate
1391
  ha_statistic_increment(&SSV::ha_read_key_count);
1392
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1393
                    HA_READ_PREFIX_LAST);
1394
  table->status=error ? STATUS_NOT_FOUND: 0;
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1395
  return(error);
1 by brian
clean slate
1396
}
1397
481 by Brian Aker
Remove all of uchar.
1398
int ha_myisam::index_next(unsigned char *buf)
1 by brian
clean slate
1399
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1400
  assert(inited==INDEX);
1 by brian
clean slate
1401
  ha_statistic_increment(&SSV::ha_read_next_count);
1402
  int error=mi_rnext(file,buf,active_index);
1403
  table->status=error ? STATUS_NOT_FOUND: 0;
1404
  return error;
1405
}
1406
481 by Brian Aker
Remove all of uchar.
1407
int ha_myisam::index_prev(unsigned char *buf)
1 by brian
clean slate
1408
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1409
  assert(inited==INDEX);
1 by brian
clean slate
1410
  ha_statistic_increment(&SSV::ha_read_prev_count);
1411
  int error=mi_rprev(file,buf, active_index);
1412
  table->status=error ? STATUS_NOT_FOUND: 0;
1413
  return error;
1414
}
1415
481 by Brian Aker
Remove all of uchar.
1416
int ha_myisam::index_first(unsigned char *buf)
1 by brian
clean slate
1417
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1418
  assert(inited==INDEX);
1 by brian
clean slate
1419
  ha_statistic_increment(&SSV::ha_read_first_count);
1420
  int error=mi_rfirst(file, buf, active_index);
1421
  table->status=error ? STATUS_NOT_FOUND: 0;
1422
  return error;
1423
}
1424
481 by Brian Aker
Remove all of uchar.
1425
int ha_myisam::index_last(unsigned char *buf)
1 by brian
clean slate
1426
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1427
  assert(inited==INDEX);
1 by brian
clean slate
1428
  ha_statistic_increment(&SSV::ha_read_last_count);
1429
  int error=mi_rlast(file, buf, active_index);
1430
  table->status=error ? STATUS_NOT_FOUND: 0;
1431
  return error;
1432
}
1433
481 by Brian Aker
Remove all of uchar.
1434
int ha_myisam::index_next_same(unsigned char *buf,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1435
			       const unsigned char *,
1436
			       uint32_t )
1 by brian
clean slate
1437
{
1438
  int error;
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1439
  assert(inited==INDEX);
1 by brian
clean slate
1440
  ha_statistic_increment(&SSV::ha_read_next_count);
1441
  do
1442
  {
1443
    error= mi_rnext_same(file,buf);
1444
  } while (error == HA_ERR_RECORD_DELETED);
1445
  table->status=error ? STATUS_NOT_FOUND: 0;
1446
  return error;
1447
}
1448
1449
int ha_myisam::read_range_first(const key_range *start_key,
1450
		 	        const key_range *end_key,
1451
			        bool eq_range_arg,
1452
                                bool sorted /* ignored */)
1453
{
1454
  int res;
1455
  //if (!eq_range_arg)
163 by Brian Aker
Merge Monty's code.
1456
  //  in_range_read= true;
1 by brian
clean slate
1457
1458
  res= handler::read_range_first(start_key, end_key, eq_range_arg, sorted);
1459
1460
  //if (res)
163 by Brian Aker
Merge Monty's code.
1461
  //  in_range_read= false;
1 by brian
clean slate
1462
  return res;
1463
}
1464
1465
1466
int ha_myisam::read_range_next()
1467
{
1468
  int res= handler::read_range_next();
1469
  //if (res)
163 by Brian Aker
Merge Monty's code.
1470
  //  in_range_read= false;
1 by brian
clean slate
1471
  return res;
1472
}
1473
1474
1475
int ha_myisam::rnd_init(bool scan)
1476
{
1477
  if (scan)
1478
    return mi_scan_init(file);
1479
  return mi_reset(file);                        // Free buffers
1480
}
1481
481 by Brian Aker
Remove all of uchar.
1482
int ha_myisam::rnd_next(unsigned char *buf)
1 by brian
clean slate
1483
{
1484
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1485
  int error=mi_scan(file, buf);
1486
  table->status=error ? STATUS_NOT_FOUND: 0;
1487
  return error;
1488
}
1489
481 by Brian Aker
Remove all of uchar.
1490
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
1 by brian
clean slate
1491
{
1492
  return rnd_pos(buf,pos);
1493
}
1494
481 by Brian Aker
Remove all of uchar.
1495
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
1 by brian
clean slate
1496
{
1497
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1498
  int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1499
  table->status=error ? STATUS_NOT_FOUND: 0;
1500
  return error;
1501
}
1502
1503
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1504
void ha_myisam::position(const unsigned char *)
1 by brian
clean slate
1505
{
1506
  my_off_t row_position= mi_position(file);
1507
  my_store_ptr(ref, ref_length, row_position);
1508
}
1509
482 by Brian Aker
Remove uint.
1510
int ha_myisam::info(uint32_t flag)
1 by brian
clean slate
1511
{
1512
  MI_ISAMINFO misam_info;
1513
  char name_buff[FN_REFLEN];
1514
1515
  (void) mi_status(file,&misam_info,flag);
1516
  if (flag & HA_STATUS_VARIABLE)
1517
  {
1518
    stats.records=           misam_info.records;
1519
    stats.deleted=           misam_info.deleted;
1520
    stats.data_file_length=  misam_info.data_file_length;
1521
    stats.index_file_length= misam_info.index_file_length;
1522
    stats.delete_length=     misam_info.delete_length;
1523
    stats.check_time=        misam_info.check_time;
1524
    stats.mean_rec_length=   misam_info.mean_reclength;
1525
  }
1526
  if (flag & HA_STATUS_CONST)
1527
  {
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
1528
    TableShare *share= table->s;
1 by brian
clean slate
1529
    stats.max_data_file_length=  misam_info.max_data_file_length;
1530
    stats.max_index_file_length= misam_info.max_index_file_length;
1531
    stats.create_time= misam_info.create_time;
1532
    ref_length= misam_info.reflength;
1533
    share->db_options_in_use= misam_info.options;
754 by Brian Aker
Make block_size for myisam fit into plugin.
1534
    stats.block_size= block_size;        /* record block size */
1 by brian
clean slate
1535
1536
    /* Update share */
1537
    if (share->tmp_table == NO_TMP_TABLE)
1538
      pthread_mutex_lock(&share->mutex);
993.1.7 by Padraig O'Sullivan
Made some tiny changes in the storage engines to reflect that key_map is now
1539
    set_prefix(share->keys_in_use, share->keys);
1540
    share->keys_in_use&= misam_info.key_map;
1541
    share->keys_for_keyread&= share->keys_in_use;
1 by brian
clean slate
1542
    share->db_record_offset= misam_info.record_offset;
1543
    if (share->key_parts)
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
1544
      memcpy(table->key_info[0].rec_per_key,
1545
	     misam_info.rec_per_key,
1 by brian
clean slate
1546
	     sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1547
    if (share->tmp_table == NO_TMP_TABLE)
1548
      pthread_mutex_unlock(&share->mutex);
1549
1550
   /*
1551
     Set data_file_name and index_file_name to point at the symlink value
1552
     if table is symlinked (Ie;  Real name is not same as generated name)
1553
   */
1554
    data_file_name= index_file_name= 0;
1555
    fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
1556
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1557
    if (strcmp(name_buff, misam_info.data_file_name))
1558
      data_file_name=misam_info.data_file_name;
1559
    fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
1560
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1561
    if (strcmp(name_buff, misam_info.index_file_name))
1562
      index_file_name=misam_info.index_file_name;
1563
  }
1564
  if (flag & HA_STATUS_ERRKEY)
1565
  {
1566
    errkey  = misam_info.errkey;
1567
    my_store_ptr(dup_ref, ref_length, misam_info.dupp_key_pos);
1568
  }
1569
  if (flag & HA_STATUS_TIME)
1570
    stats.update_time = misam_info.update_time;
1571
  if (flag & HA_STATUS_AUTO)
1572
    stats.auto_increment_value= misam_info.auto_increment;
1573
1574
  return 0;
1575
}
1576
1577
1578
int ha_myisam::extra(enum ha_extra_function operation)
1579
{
1580
  return mi_extra(file, operation, 0);
1581
}
1582
1583
int ha_myisam::reset(void)
1584
{
1585
  pushed_idx_cond= NULL;
1586
  pushed_idx_cond_keyno= MAX_KEY;
1587
  mi_set_index_cond_func(file, NULL, 0);
1588
  ds_mrr.dsmrr_close();
1589
  return mi_reset(file);
1590
}
1591
1592
/* To be used with WRITE_CACHE and EXTRA_CACHE */
1593
61 by Brian Aker
Conversion of handler type.
1594
int ha_myisam::extra_opt(enum ha_extra_function operation, uint32_t cache_size)
1 by brian
clean slate
1595
{
1596
  return mi_extra(file, operation, (void*) &cache_size);
1597
}
1598
1599
int ha_myisam::delete_all_rows()
1600
{
1601
  return mi_delete_all_rows(file);
1602
}
1603
1604
int ha_myisam::delete_table(const char *name)
1605
{
1606
  return mi_delete_table(name);
1607
}
1608
1609
520.1.22 by Brian Aker
Second pass of thd cleanup
1610
int ha_myisam::external_lock(Session *session, int lock_type)
1 by brian
clean slate
1611
{
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
1612
  file->in_use= session;
1 by brian
clean slate
1613
  return mi_lock_database(file, !table->s->tmp_table ?
1614
			  lock_type : ((lock_type == F_UNLCK) ?
1615
				       F_UNLCK : F_EXTRA_LCK));
1616
}
1617
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1618
THR_LOCK_DATA **ha_myisam::store_lock(Session *,
1 by brian
clean slate
1619
				      THR_LOCK_DATA **to,
1620
				      enum thr_lock_type lock_type)
1621
{
1622
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
1623
    file->lock.type=lock_type;
1624
  *to++= &file->lock;
1625
  return to;
1626
}
1627
1628
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
1629
{
1630
  ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
1631
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
1632
  {
1633
    create_info->auto_increment_value= stats.auto_increment_value;
1634
  }
1635
  create_info->data_file_name=data_file_name;
1636
  create_info->index_file_name=index_file_name;
1637
}
1638
1639
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1640
int ha_myisam::create(const char *name, register Table *table_arg,
1 by brian
clean slate
1641
		      HA_CREATE_INFO *ha_create_info)
1642
{
1643
  int error;
779.3.10 by Monty Taylor
Turned on -Wshadow.
1644
  uint32_t create_flags= 0, create_records;
1 by brian
clean slate
1645
  char buff[FN_REFLEN];
1646
  MI_KEYDEF *keydef;
1647
  MI_COLUMNDEF *recinfo;
1648
  MI_CREATE_INFO create_info;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
1649
  TableShare *share= table_arg->s;
482 by Brian Aker
Remove uint.
1650
  uint32_t options= share->db_options_in_use;
779.3.10 by Monty Taylor
Turned on -Wshadow.
1651
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &create_records)))
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1652
    return(error); /* purecov: inspected */
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
1653
  memset(&create_info, 0, sizeof(create_info));
1 by brian
clean slate
1654
  create_info.max_rows= share->max_rows;
1655
  create_info.reloc_rows= share->min_rows;
1656
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1657
  create_info.auto_increment= (ha_create_info->auto_increment_value ?
1658
                               ha_create_info->auto_increment_value -1 :
1659
                               (uint64_t) 0);
1660
  create_info.data_file_length= ((uint64_t) share->max_rows *
1661
                                 share->avg_row_length);
1662
  create_info.data_file_name= ha_create_info->data_file_name;
1663
  create_info.index_file_name= ha_create_info->index_file_name;
1664
  create_info.language= share->table_charset->number;
1665
1666
  if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
1667
    create_flags|= HA_CREATE_TMP_TABLE;
1668
  if (ha_create_info->options & HA_CREATE_KEEP_FILES)
1669
    create_flags|= HA_CREATE_KEEP_FILES;
1670
  if (options & HA_OPTION_PACK_RECORD)
1671
    create_flags|= HA_PACK_RECORD;
1672
  if (options & HA_OPTION_CHECKSUM)
1673
    create_flags|= HA_CREATE_CHECKSUM;
1674
  if (options & HA_OPTION_DELAY_KEY_WRITE)
1675
    create_flags|= HA_CREATE_DELAY_KEY_WRITE;
1676
1677
  /* TODO: Check that the following fn_format is really needed */
1678
  error= mi_create(fn_format(buff, name, "", "",
1679
                             MY_UNPACK_FILENAME|MY_APPEND_EXT),
1680
                   share->keys, keydef,
779.3.10 by Monty Taylor
Turned on -Wshadow.
1681
                   create_records, recinfo,
1 by brian
clean slate
1682
                   0, (MI_UNIQUEDEF*) 0,
1683
                   &create_info, create_flags);
481 by Brian Aker
Remove all of uchar.
1684
  free((unsigned char*) recinfo);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1685
  return(error);
1 by brian
clean slate
1686
}
1687
1688
1689
int ha_myisam::rename_table(const char * from, const char * to)
1690
{
1691
  return mi_rename(from,to);
1692
}
1693
1694
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1695
void ha_myisam::get_auto_increment(uint64_t ,
1696
                                   uint64_t ,
1697
                                   uint64_t ,
1 by brian
clean slate
1698
                                   uint64_t *first_value,
1699
                                   uint64_t *nb_reserved_values)
1700
{
1701
  uint64_t nr;
1702
  int error;
481 by Brian Aker
Remove all of uchar.
1703
  unsigned char key[MI_MAX_KEY_LENGTH];
1 by brian
clean slate
1704
1705
  if (!table->s->next_number_key_offset)
1706
  {						// Autoincrement at key-start
1707
    ha_myisam::info(HA_STATUS_AUTO);
1708
    *first_value= stats.auto_increment_value;
1709
    /* MyISAM has only table-level lock, so reserves to +inf */
163 by Brian Aker
Merge Monty's code.
1710
    *nb_reserved_values= UINT64_MAX;
1 by brian
clean slate
1711
    return;
1712
  }
1713
1714
  /* it's safe to call the following if bulk_insert isn't on */
1715
  mi_flush_bulk_insert(file, table->s->next_number_index);
1716
1717
  (void) extra(HA_EXTRA_KEYREAD);
1718
  key_copy(key, table->record[0],
1719
           table->key_info + table->s->next_number_index,
1720
           table->s->next_number_key_offset);
1721
  error= mi_rkey(file, table->record[1], (int) table->s->next_number_index,
1722
                 key, make_prev_keypart_map(table->s->next_number_keypart),
1723
                 HA_READ_PREFIX_LAST);
1724
  if (error)
1725
    nr= 1;
1726
  else
1727
  {
1728
    /* Get data from record[1] */
1729
    nr= ((uint64_t) table->next_number_field->
1730
         val_int_offset(table->s->rec_buff_length)+1);
1731
  }
1732
  extra(HA_EXTRA_NO_KEYREAD);
1733
  *first_value= nr;
1734
  /*
1735
    MySQL needs to call us for next row: assume we are inserting ("a",null)
1736
    here, we return 3, and next this statement will want to insert ("b",null):
1737
    there is no reason why ("b",3+1) would be the good row to insert: maybe it
1738
    already exists, maybe 3+1 is too large...
1739
  */
1740
  *nb_reserved_values= 1;
1741
}
1742
1743
1744
/*
1745
  Find out how many rows there is in the given range
1746
1747
  SYNOPSIS
1748
    records_in_range()
1749
    inx			Index to use
1750
    min_key		Start of range.  Null pointer if from first key
1751
    max_key		End of range. Null pointer if to last key
1752
1753
  NOTES
1754
    min_key.flag can have one of the following values:
1755
      HA_READ_KEY_EXACT		Include the key in the range
1756
      HA_READ_AFTER_KEY		Don't include key in range
1757
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1758
    max_key.flag can have one of the following values:
1 by brian
clean slate
1759
      HA_READ_BEFORE_KEY	Don't include key in range
1760
      HA_READ_AFTER_KEY		Include all 'end_key' values in the range
1761
1762
  RETURN
1763
   HA_POS_ERROR		Something is wrong with the index tree.
1764
   0			There is no matching keys in the given range
1765
   number > 0		There is approximately 'number' matching rows in
1766
			the range.
1767
*/
1768
482 by Brian Aker
Remove uint.
1769
ha_rows ha_myisam::records_in_range(uint32_t inx, key_range *min_key,
1 by brian
clean slate
1770
                                    key_range *max_key)
1771
{
1772
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1773
}
1774
1775
482 by Brian Aker
Remove uint.
1776
uint32_t ha_myisam::checksum() const
1 by brian
clean slate
1777
{
1778
  return (uint)file->state->checksum;
1779
}
1780
971.1.51 by Monty Taylor
New-style plugin registration now works.
1781
static MyisamEngine *engine= NULL;
1782
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
1783
static int myisam_init(PluginRegistry &registry)
971.1.51 by Monty Taylor
New-style plugin registration now works.
1784
{
1785
  engine= new MyisamEngine(engine_name);
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
1786
  registry.add(engine);
971.1.51 by Monty Taylor
New-style plugin registration now works.
1787
1788
  pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
1789
1790
  return 0;
1791
}
1792
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
1793
int myisam_deinit(PluginRegistry &registry)
971.1.51 by Monty Taylor
New-style plugin registration now works.
1794
{
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
1795
  registry.remove(engine);
960.2.33 by Monty Taylor
Converted MyISAM.
1796
  delete engine;
1797
598 by Brian Aker
Removed mutex which are myisam from global to just engine.
1798
  pthread_mutex_destroy(&THR_LOCK_myisam);
1799
224.2.3 by Brian Aker
Fix for memory leak in shutdown/restart of an engine (not fixed in 5.1)
1800
  return mi_panic(HA_PANIC_CLOSE);
1 by brian
clean slate
1801
}
1802
1803
1804
/****************************************************************************
1805
 * MyISAM MRR implementation: use DS-MRR
1806
 ***************************************************************************/
1807
1808
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1809
                                     uint32_t n_ranges, uint32_t mode,
1 by brian
clean slate
1810
                                     HANDLER_BUFFER *buf)
1811
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1812
  return ds_mrr.dsmrr_init(this, &table->key_info[active_index],
1 by brian
clean slate
1813
                           seq, seq_init_param, n_ranges, mode, buf);
1814
}
1815
1816
int ha_myisam::multi_range_read_next(char **range_info)
1817
{
1818
  return ds_mrr.dsmrr_next(this, range_info);
1819
}
1820
482 by Brian Aker
Remove uint.
1821
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1822
                                               void *seq_init_param,
482 by Brian Aker
Remove uint.
1823
                                               uint32_t n_ranges, uint32_t *bufsz,
1824
                                               uint32_t *flags, COST_VECT *cost)
1 by brian
clean slate
1825
{
1826
  /*
1827
    This call is here because there is no location where this->table would
1828
    already be known.
1829
    TODO: consider moving it into some per-query initialization call.
1830
  */
1831
  ds_mrr.init(this, table);
1832
  return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
1833
                                 flags, cost);
1834
}
1835
482 by Brian Aker
Remove uint.
1836
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1837
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1 by brian
clean slate
1838
{
1839
  ds_mrr.init(this, table);
1840
  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1841
}
1842
1843
/* MyISAM MRR implementation ends */
1844
1845
1846
/* Index condition pushdown implementation*/
1847
1848
482 by Brian Aker
Remove uint.
1849
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
1 by brian
clean slate
1850
{
1851
  pushed_idx_cond_keyno= keyno_arg;
1852
  pushed_idx_cond= idx_cond_arg;
163 by Brian Aker
Merge Monty's code.
1853
  in_range_check_pushed_down= true;
1 by brian
clean slate
1854
  if (active_index == pushed_idx_cond_keyno)
1855
    mi_set_index_cond_func(file, index_cond_func_myisam, this);
1856
  return NULL;
1857
}
1858
754 by Brian Aker
Make block_size for myisam fit into plugin.
1859
static DRIZZLE_SYSVAR_UINT(block_size, block_size,
1860
                           PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1861
                           N_("Block size to be used for MyISAM index pages."),
1862
                           NULL, NULL, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, 
1863
                           MI_MAX_KEY_BLOCK_LENGTH, 0);
1864
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1865
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
754 by Brian Aker
Make block_size for myisam fit into plugin.
1866
                           PLUGIN_VAR_RQCMDARG,
1867
                           N_("Number of threads to use when repairing MyISAM tables. The value of "
1868
                              "1 disables parallel repair."),
1869
                           NULL, NULL, 1, 1, UINT32_MAX, 0);
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1870
788 by Brian Aker
Move MyISAM bits to myisam plugin
1871
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
789 by Brian Aker
MyISAM fix.
1872
                                PLUGIN_VAR_RQCMDARG,
1873
                                N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
1874
                                NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
1875
1876
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
1877
                                PLUGIN_VAR_RQCMDARG,
1878
                                N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
1879
                                NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
788 by Brian Aker
Move MyISAM bits to myisam plugin
1880
790 by Brian Aker
More myisam plugin conversion.
1881
extern uint32_t data_pointer_size;
1882
static DRIZZLE_SYSVAR_UINT(data_pointer_size, data_pointer_size,
1883
                           PLUGIN_VAR_RQCMDARG,
1884
                           N_("Default pointer size to be used for MyISAM tables."),
1885
                           NULL, NULL, 6, 2, 7, 0);
1886
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1887
static struct st_mysql_sys_var* system_variables[]= {
754 by Brian Aker
Make block_size for myisam fit into plugin.
1888
  DRIZZLE_SYSVAR(block_size),
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1889
  DRIZZLE_SYSVAR(repair_threads),
788 by Brian Aker
Move MyISAM bits to myisam plugin
1890
  DRIZZLE_SYSVAR(max_sort_file_size),
789 by Brian Aker
MyISAM fix.
1891
  DRIZZLE_SYSVAR(sort_buffer_size),
790 by Brian Aker
More myisam plugin conversion.
1892
  DRIZZLE_SYSVAR(data_pointer_size),
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1893
  NULL
1894
};
1895
1 by brian
clean slate
1896
813.2.1 by Toru Maesaka
Renamed mysql_declare_plugin to drizzle_declare_plugin
1897
drizzle_declare_plugin(myisam)
1 by brian
clean slate
1898
{
1899
  "MyISAM",
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
1900
  "1.0",
1 by brian
clean slate
1901
  "MySQL AB",
1902
  "Default engine as of MySQL 3.23 with great performance",
1903
  PLUGIN_LICENSE_GPL,
1904
  myisam_init, /* Plugin Init */
224.2.3 by Brian Aker
Fix for memory leak in shutdown/restart of an engine (not fixed in 5.1)
1905
  myisam_deinit, /* Plugin Deinit */
1 by brian
clean slate
1906
  NULL,                       /* status variables                */
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
1907
  system_variables,           /* system variables */
1 by brian
clean slate
1908
  NULL                        /* config options                  */
1909
}
813.2.2 by Toru Maesaka
Renamed mysql_declare_plugin_end to drizzle_declare_plugin_end
1910
drizzle_declare_plugin_end;