~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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
17
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
18
#include <config.h>
19
#include <drizzled/internal/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"
1130.3.28 by Monty Taylor
Moved heapdef.h and myisamdef.h to *_priv.h for easier filtering for include guard check.
22
#include "myisam_priv.h"
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
23
#include <drizzled/option.h>
24
#include <drizzled/internal/my_bit.h>
25
#include <drizzled/internal/m_string.h>
26
#include <drizzled/util/test.h>
27
#include <drizzled/error.h>
28
#include <drizzled/errmsg_print.h>
29
#include <drizzled/gettext.h>
30
#include <drizzled/session.h>
31
#include <drizzled/plugin.h>
32
#include <drizzled/plugin/client.h>
33
#include <drizzled/table.h>
34
#include <drizzled/memory/multi_malloc.h>
35
#include <drizzled/plugin/daemon.h>
2241.2.6 by Olaf van der Spek
Refactor
36
#include <drizzled/session/table_messages.h>
2148.7.12 by Brian Aker
Merge in header fixes.
37
#include <drizzled/plugin/storage_engine.h>
2198.1.1 by Olaf van der Spek
Remove unnecessary alter* includes
38
#include <drizzled/key.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
39
#include <drizzled/statistics_variables.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
40
#include <drizzled/system_variables.h>
2148.7.12 by Brian Aker
Merge in header fixes.
41
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
42
#include <boost/algorithm/string.hpp>
1929.1.40 by Monty Taylor
Replaced auto_ptr with scoped_ptr.
43
#include <boost/scoped_ptr.hpp>
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
44
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
45
#include <string>
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
46
#include <sstream>
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
47
#include <map>
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
48
#include <algorithm>
1929.1.4 by Stewart Smith
fix large stack usage in MyISAM:
49
#include <memory>
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
50
#include <boost/program_options.hpp>
51
#include <drizzled/module/option_map.h>
52
53
namespace po= boost::program_options;
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
54
55
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
56
using namespace drizzled;
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
57
58
static const string engine_name("MyISAM");
59
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
60
boost::mutex THR_LOCK_myisam;
1 by brian
clean slate
61
1689.2.21 by Brian Aker
Remove outward sign of Key Cache
62
static uint32_t myisam_key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
1251.2.7 by Jay Pipes
Why on Earth key_buffer_size was a 64-bit integer when the resize_key_cache() expected a 32-bit integer is beyond me.
63
static uint32_t myisam_key_cache_size;
1251.2.2 by Jay Pipes
Pulls MyISAM-specific server variables into the MyISAM
64
static uint32_t myisam_key_cache_division_limit;
65
static uint32_t myisam_key_cache_age_threshold;
788 by Brian Aker
Move MyISAM bits to myisam plugin
66
static uint64_t max_sort_file_size;
1897.4.13 by Monty Taylor
MyISAM.
67
typedef constrained_check<size_t, SIZE_MAX, 1024, 1024> sort_buffer_constraint;
68
static sort_buffer_constraint sort_buffer_size;
753 by Brian Aker
Converted myisam_repair_threads to being in module for MyISAM
69
1689.2.16 by Brian Aker
This places keycache directly into the table (ie it is now mapped 1=1).
70
void st_mi_isam_share::setKeyCache()
71
{
72
  (void)init_key_cache(&key_cache,
73
                       myisam_key_cache_block_size,
74
                       myisam_key_cache_size,
75
                       myisam_key_cache_division_limit, 
76
                       myisam_key_cache_age_threshold);
77
}
78
1 by brian
clean slate
79
/*****************************************************************************
80
** MyISAM tables
81
*****************************************************************************/
82
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
83
static const char *ha_myisam_exts[] = {
84
  ".MYI",
85
  ".MYD",
86
  NULL
87
};
88
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
89
class MyisamEngine : public plugin::StorageEngine
1 by brian
clean slate
90
{
1324.2.19 by Monty Taylor
Fixed up myisam just a little bit.
91
  MyisamEngine();
92
  MyisamEngine(const MyisamEngine&);
93
  MyisamEngine& operator=(const MyisamEngine&);
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
94
public:
1324.2.14 by Monty Taylor
Removed MyisamCleanup... encorporated into Engine destructor.
95
  explicit MyisamEngine(string name_arg) :
96
    plugin::StorageEngine(name_arg,
97
                          HTON_CAN_INDEX_BLOBS |
98
                          HTON_STATS_RECORDS_IS_EXACT |
99
                          HTON_TEMPORARY_ONLY |
100
                          HTON_NULL_IN_KEY |
101
                          HTON_HAS_RECORDS |
102
                          HTON_DUPLICATE_POS |
103
                          HTON_AUTO_PART_KEY |
1461.1.1 by Stewart Smith
remove HTON_FILE_BASED: it's unused now.
104
                          HTON_SKIP_STORE_LOCK)
1324.2.14 by Monty Taylor
Removed MyisamCleanup... encorporated into Engine destructor.
105
  {
106
  }
107
108
  virtual ~MyisamEngine()
109
  { 
110
    mi_panic(HA_PANIC_CLOSE);
111
  }
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
112
1869.1.4 by Brian Aker
TableShare is no longer in the house (i.e. we no longer directly have a copy
113
  virtual Cursor *create(Table &table)
960.2.33 by Monty Taylor
Converted MyISAM.
114
  {
1680.6.1 by Brian Aker
Remove call for using special new for a cursor.
115
    return new ha_myisam(*this, table);
960.2.33 by Monty Taylor
Converted MyISAM.
116
  }
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
117
118
  const char **bas_ext() const {
119
    return ha_myisam_exts;
120
  }
1039.3.3 by Stewart Smith
Move handler::create to StorageEngine::create_table
121
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
122
  int doCreateTable(Session&,
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
123
                    Table& table_arg,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
124
                    const identifier::Table &identifier,
2224.4.2 by Brian Aker
Merge in work around making all passing of table as const.
125
                    const message::Table&);
1095.3.29 by Stewart Smith
s/Impl/Implementation/
126
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
127
  int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
1095.3.29 by Stewart Smith
s/Impl/Implementation/
128
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
129
  int doDropTable(Session&, const identifier::Table &identifier);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
130
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
131
  int doGetTableDefinition(Session& session,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
132
                           const identifier::Table &identifier,
1354.1.1 by Brian Aker
Modify ptr to reference.
133
                           message::Table &table_message);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
134
1233.1.9 by Brian Aker
Move max key stuff up to engine.
135
  uint32_t max_supported_keys()          const { return MI_MAX_KEY; }
136
  uint32_t max_supported_key_length()    const { return MI_MAX_KEY_LENGTH; }
137
  uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
1235.1.13 by Brian Aker
Next pass through interface to move index flag bits up to engine.
138
139
  uint32_t index_flags(enum  ha_key_alg) const
140
  {
141
    return (HA_READ_NEXT |
142
            HA_READ_PREV |
143
            HA_READ_RANGE |
144
            HA_READ_ORDER |
145
            HA_KEYREAD_ONLY);
146
  }
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
147
  bool doDoesTableExist(Session& session, const identifier::Table &identifier);
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
148
149
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
2087.4.1 by Brian Aker
Merge in schema identifier.
150
                             const drizzled::identifier::Schema &schema_identifier,
2252.1.9 by Olaf van der Spek
Common fwd
151
                             drizzled::identifier::table::vector &set_of_identifiers);
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
152
  bool validateCreateTableOption(const std::string &key, const std::string &state)
153
  {
154
    (void)state;
155
    if (boost::iequals(key, "ROW_FORMAT"))
156
    {
157
      return true;
158
    }
159
160
    return false;
161
  }
960.2.33 by Monty Taylor
Converted MyISAM.
162
};
1 by brian
clean slate
163
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
164
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
2087.4.1 by Brian Aker
Merge in schema identifier.
165
                                         const drizzled::identifier::Schema&,
2252.1.9 by Olaf van der Spek
Common fwd
166
                                         drizzled::identifier::table::vector&)
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
167
{
168
}
169
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
170
bool MyisamEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
171
{
1923.1.4 by Brian Aker
Encapsulate up the cache we use in Session for tracking table proto for temp
172
  return session.getMessageCache().doesTableMessageExist(identifier);
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
173
}
174
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
175
int MyisamEngine::doGetTableDefinition(Session &session,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
176
                                       const identifier::Table &identifier,
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
177
                                       message::Table &table_message)
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
178
{
1923.1.4 by Brian Aker
Encapsulate up the cache we use in Session for tracking table proto for temp
179
  if (session.getMessageCache().getTableMessage(identifier, table_message))
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
180
    return EEXIST;
181
  return ENOENT;
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
182
}
183
1126.2.2 by Brian Aker
Remove need for protocol from myisam
184
/* 
185
  Convert to push_Warnings if you ever care about this, otherwise, it is a no-op.
186
*/
1 by brian
clean slate
187
1126.2.2 by Brian Aker
Remove need for protocol from myisam
188
static void mi_check_print_msg(MI_CHECK *,	const char* ,
189
                               const char *, va_list )
1 by brian
clean slate
190
{
191
}
192
193
194
/*
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
195
  Convert Table object to MyISAM key and column definition
1 by brian
clean slate
196
197
  SYNOPSIS
198
    table2myisam()
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
199
      table_arg   in     Table object.
1 by brian
clean slate
200
      keydef_out  out    MyISAM key definition.
201
      recinfo_out out    MyISAM column definition.
202
      records_out out    Number of fields.
203
204
  DESCRIPTION
205
    This function will allocate and initialize MyISAM key and column
206
    definition for further use in mi_create or for a check for underlying
207
    table conformance in merge engine.
208
209
    The caller needs to free *recinfo_out after use. Since *recinfo_out
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
210
    and *keydef_out are allocated with a multi_malloc, *keydef_out
1 by brian
clean slate
211
    is freed automatically when *recinfo_out is freed.
212
213
  RETURN VALUE
214
    0  OK
215
    !0 error code
216
*/
217
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
218
static int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
219
                        MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
1 by brian
clean slate
220
{
482 by Brian Aker
Remove uint.
221
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
1 by brian
clean slate
222
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
481 by Brian Aker
Remove all of uchar.
223
  unsigned char *record;
1 by brian
clean slate
224
  MI_KEYDEF *keydef;
225
  MI_COLUMNDEF *recinfo, *recinfo_pos;
226
  HA_KEYSEG *keyseg;
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
227
  TableShare *share= table_arg->getMutableShare();
482 by Brian Aker
Remove uint.
228
  uint32_t options= share->db_options_in_use;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
229
  if (!(memory::multi_malloc(false,
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
230
          recinfo_out, (share->sizeFields() * 2 + 2) * sizeof(MI_COLUMNDEF),
231
          keydef_out, share->sizeKeys() * sizeof(MI_KEYDEF),
232
          &keyseg, (share->key_parts + share->sizeKeys()) * sizeof(HA_KEYSEG),
461 by Monty Taylor
Removed NullS. bu-bye.
233
          NULL)))
971.6.11 by Eric Day
Removed purecov messages.
234
    return(HA_ERR_OUT_OF_MEM);
1 by brian
clean slate
235
  keydef= *keydef_out;
236
  recinfo= *recinfo_out;
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
237
  for (i= 0; i < share->sizeKeys(); i++)
1 by brian
clean slate
238
  {
1574.1.1 by Brian Aker
Small touchup for using array, not increment.
239
    KeyInfo *pos= &table_arg->key_info[i];
249 by Brian Aker
Random key cleanup (it is a friday...)
240
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
241
    keydef[i].key_alg= HA_KEY_ALG_BTREE;
1 by brian
clean slate
242
    keydef[i].block_length= pos->block_size;
243
    keydef[i].seg= keyseg;
244
    keydef[i].keysegs= pos->key_parts;
245
    for (j= 0; j < pos->key_parts; j++)
246
    {
247
      Field *field= pos->key_part[j].field;
248
      type= field->key_type();
249
      keydef[i].seg[j].flag= pos->key_part[j].key_part_flag;
250
251
      if (options & HA_OPTION_PACK_KEYS ||
252
          (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY |
253
                         HA_SPACE_PACK_USED)))
254
      {
255
        if (pos->key_part[j].length > 8 &&
256
            (type == HA_KEYTYPE_TEXT ||
257
             (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
258
        {
259
          /* No blobs here */
260
          if (j == 0)
261
            keydef[i].flag|= HA_PACK_KEY;
241 by Brian Aker
First pass of CHAR removal.
262
          if ((((int) (pos->key_part[j].length - field->decimals())) >= 4))
1 by brian
clean slate
263
            keydef[i].seg[j].flag|= HA_SPACE_PACK;
264
        }
265
        else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
266
          keydef[i].flag|= HA_BINARY_PACK_KEY;
267
      }
268
      keydef[i].seg[j].type= (int) type;
269
      keydef[i].seg[j].start= pos->key_part[j].offset;
270
      keydef[i].seg[j].length= pos->key_part[j].length;
271
      keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end=
272
        keydef[i].seg[j].bit_length= 0;
273
      keydef[i].seg[j].bit_pos= 0;
274
      keydef[i].seg[j].language= field->charset()->number;
275
276
      if (field->null_ptr)
277
      {
278
        keydef[i].seg[j].null_bit= field->null_bit;
279
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
1672.3.6 by Brian Aker
First pass in encapsulating row
280
                                           (unsigned char*) table_arg->getInsertRecord());
1 by brian
clean slate
281
      }
282
      else
283
      {
284
        keydef[i].seg[j].null_bit= 0;
285
        keydef[i].seg[j].null_pos= 0;
286
      }
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
287
      if (field->type() == DRIZZLE_TYPE_BLOB)
1 by brian
clean slate
288
      {
289
        keydef[i].seg[j].flag|= HA_BLOB_PART;
290
        /* save number of bytes used to pack length */
291
        keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
2134.1.4 by Brian Aker
Simple encapsulation for table.
292
                                            share->sizeBlobPtr());
1 by brian
clean slate
293
      }
294
    }
295
    keyseg+= pos->key_parts;
296
  }
297
  if (table_arg->found_next_number_field)
298
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
1672.3.6 by Brian Aker
First pass in encapsulating row
299
  record= table_arg->getInsertRecord();
1 by brian
clean slate
300
  recpos= 0;
301
  recinfo_pos= recinfo;
2134.1.4 by Brian Aker
Simple encapsulation for table.
302
303
  while (recpos < (uint) share->sizeStoredRecord())
1 by brian
clean slate
304
  {
305
    Field **field, *found= 0;
1578.2.8 by Brian Aker
Encapsulate record length.
306
    minpos= share->getRecordLength();
1 by brian
clean slate
307
    length= 0;
308
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
309
    for (field= table_arg->getFields(); *field; field++)
1 by brian
clean slate
310
    {
311
      if ((fieldpos= (*field)->offset(record)) >= recpos &&
312
          fieldpos <= minpos)
313
      {
314
        /* skip null fields */
315
        if (!(temp_length= (*field)->pack_length_in_rec()))
316
          continue; /* Skip null-fields */
2134.1.4 by Brian Aker
Simple encapsulation for table.
317
1 by brian
clean slate
318
        if (! found || fieldpos < minpos ||
319
            (fieldpos == minpos && temp_length < length))
320
        {
321
          minpos= fieldpos;
322
          found= *field;
323
          length= temp_length;
324
        }
325
      }
326
    }
327
    if (recpos != minpos)
328
    { // Reserved space (Null bits?)
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
329
      memset(recinfo_pos, 0, sizeof(*recinfo_pos));
1 by brian
clean slate
330
      recinfo_pos->type= (int) FIELD_NORMAL;
206 by Brian Aker
Removed final uint dead types.
331
      recinfo_pos++->length= (uint16_t) (minpos - recpos);
1 by brian
clean slate
332
    }
333
    if (!found)
334
      break;
335
336
    if (found->flags & BLOB_FLAG)
337
      recinfo_pos->type= (int) FIELD_BLOB;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
338
    else if (found->type() == DRIZZLE_TYPE_VARCHAR)
1 by brian
clean slate
339
      recinfo_pos->type= FIELD_VARCHAR;
340
    else if (!(options & HA_OPTION_PACK_RECORD))
341
      recinfo_pos->type= (int) FIELD_NORMAL;
342
    else if (found->zero_pack())
343
      recinfo_pos->type= (int) FIELD_SKIP_ZERO;
344
    else
241 by Brian Aker
First pass of CHAR removal.
345
      recinfo_pos->type= (int) ((length <= 3) ?  FIELD_NORMAL : FIELD_SKIP_PRESPACE);
1 by brian
clean slate
346
    if (found->null_ptr)
347
    {
348
      recinfo_pos->null_bit= found->null_bit;
349
      recinfo_pos->null_pos= (uint) (found->null_ptr -
1672.3.6 by Brian Aker
First pass in encapsulating row
350
                                     (unsigned char*) table_arg->getInsertRecord());
1 by brian
clean slate
351
    }
352
    else
353
    {
354
      recinfo_pos->null_bit= 0;
355
      recinfo_pos->null_pos= 0;
356
    }
206 by Brian Aker
Removed final uint dead types.
357
    (recinfo_pos++)->length= (uint16_t) length;
1 by brian
clean slate
358
    recpos= minpos + length;
359
  }
360
  *records_out= (uint) (recinfo_pos - recinfo);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
361
  return(0);
1 by brian
clean slate
362
}
363
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
364
int ha_myisam::reset_auto_increment(uint64_t value)
365
{
1210 by Brian Aker
Merge new Truncate
366
  file->s->state.auto_increment= value;
367
  return 0;
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
368
}
1 by brian
clean slate
369
370
/*
371
  Check for underlying table conformance
372
373
  SYNOPSIS
374
    check_definition()
375
      t1_keyinfo       in    First table key definition
376
      t1_recinfo       in    First table record definition
377
      t1_keys          in    Number of keys in first table
378
      t1_recs          in    Number of records in first table
379
      t2_keyinfo       in    Second table key definition
380
      t2_recinfo       in    Second table record definition
381
      t2_keys          in    Number of keys in second table
382
      t2_recs          in    Number of records in second table
383
      strict           in    Strict check switch
384
385
  DESCRIPTION
386
    This function compares two MyISAM definitions. By intention it was done
387
    to compare merge table definition against underlying table definition.
388
    It may also be used to compare dot-frm and MYI definitions of MyISAM
389
    table as well to compare different MyISAM table definitions.
390
391
    For merge table it is not required that number of keys in merge table
392
    must exactly match number of keys in underlying table. When calling this
393
    function for underlying table conformance check, 'strict' flag must be
394
    set to false, and converted merge definition must be passed as t1_*.
395
396
    Otherwise 'strict' flag must be set to 1 and it is not required to pass
397
    converted dot-frm definition as t1_*.
398
399
  RETURN VALUE
400
    0 - Equal definitions.
401
    1 - Different definitions.
402
403
  TODO
404
    - compare FULLTEXT keys;
405
    - compare SPATIAL keys;
406
    - compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
407
      (should be corretly detected in table2myisam).
408
*/
409
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
410
static int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
411
                            uint32_t t1_keys, uint32_t t1_recs,
412
                            MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
413
                            uint32_t t2_keys, uint32_t t2_recs, bool strict)
1 by brian
clean slate
414
{
482 by Brian Aker
Remove uint.
415
  uint32_t i, j;
1 by brian
clean slate
416
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
417
  {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
418
    return(1);
1 by brian
clean slate
419
  }
420
  if (t1_recs != t2_recs)
421
  {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
422
    return(1);
1 by brian
clean slate
423
  }
424
  for (i= 0; i < t1_keys; i++)
425
  {
426
    HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
427
    HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
428
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
429
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
430
    {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
431
      return(1);
1 by brian
clean slate
432
    }
433
    for (j=  t1_keyinfo[i].keysegs; j--;)
434
    {
206 by Brian Aker
Removed final uint dead types.
435
      uint8_t t1_keysegs_j__type= t1_keysegs[j].type;
1 by brian
clean slate
436
437
      /*
438
        Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
439
        always HA_KEYTYPE_VARTEXT2. In 4.1 we had only the equivalent of
440
        HA_KEYTYPE_VARTEXT1. Since we treat both the same on MyISAM
441
        level, we can ignore a mismatch between these types.
442
      */
443
      if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
444
          (t2_keysegs[j].flag & HA_BLOB_PART))
445
      {
446
        if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
447
            (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
971.6.11 by Eric Day
Removed purecov messages.
448
          t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1;
1 by brian
clean slate
449
        else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
450
                 (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
971.6.11 by Eric Day
Removed purecov messages.
451
          t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1;
1 by brian
clean slate
452
      }
453
454
      if (t1_keysegs_j__type != t2_keysegs[j].type ||
455
          t1_keysegs[j].language != t2_keysegs[j].language ||
456
          t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
457
          t1_keysegs[j].length != t2_keysegs[j].length)
458
      {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
459
        return(1);
1 by brian
clean slate
460
      }
461
    }
462
  }
463
  for (i= 0; i < t1_recs; i++)
464
  {
465
    MI_COLUMNDEF *t1_rec= &t1_recinfo[i];
466
    MI_COLUMNDEF *t2_rec= &t2_recinfo[i];
467
    /*
468
      FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in mi_create,
469
      see NOTE1 in mi_create.c
470
    */
471
    if ((t1_rec->type != t2_rec->type &&
472
         !(t1_rec->type == (int) FIELD_SKIP_ZERO &&
473
           t1_rec->length == 1 &&
474
           t2_rec->type == (int) FIELD_NORMAL)) ||
475
        t1_rec->length != t2_rec->length ||
476
        t1_rec->null_bit != t2_rec->null_bit)
477
    {
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
478
      return(1);
1 by brian
clean slate
479
    }
480
  }
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
481
  return(0);
1 by brian
clean slate
482
}
483
484
485
volatile int *killed_ptr(MI_CHECK *param)
486
{
487
  /* In theory Unsafe conversion, but should be ok for now */
1910.2.8 by Brian Aker
Enapsulate Kill.
488
  return (int*) (((Session *)(param->session))->getKilledPtr());
1 by brian
clean slate
489
}
490
491
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
492
{
493
  param->error_printed|=1;
494
  param->out_flag|= O_DATA_LOST;
495
  va_list args;
496
  va_start(args, fmt);
497
  mi_check_print_msg(param, "error", fmt, args);
498
  va_end(args);
499
}
500
501
void mi_check_print_info(MI_CHECK *param, const char *fmt,...)
502
{
503
  va_list args;
504
  va_start(args, fmt);
505
  mi_check_print_msg(param, "info", fmt, args);
506
  va_end(args);
507
}
508
509
void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
510
{
511
  param->warning_printed=1;
512
  param->out_flag|= O_DATA_LOST;
513
  va_list args;
514
  va_start(args, fmt);
515
  mi_check_print_msg(param, "warning", fmt, args);
516
  va_end(args);
517
}
518
519
/**
520
  Report list of threads (and queries) accessing a table, thread_id of a
521
  thread that detected corruption, ource file name and line number where
522
  this corruption was detected, optional extra information (string).
523
524
  This function is intended to be used when table corruption is detected.
525
526
  @param[in] file      MI_INFO object.
527
  @param[in] message   Optional error message.
528
  @param[in] sfile     Name of source file.
529
  @param[in] sline     Line number in source file.
530
531
  @return void
532
*/
533
534
void _mi_report_crashed(MI_INFO *file, const char *message,
482 by Brian Aker
Remove uint.
535
                        const char *sfile, uint32_t sline)
1 by brian
clean slate
536
{
520.1.22 by Brian Aker
Second pass of thd cleanup
537
  Session *cur_session;
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
538
  if ((cur_session= file->in_use))
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
539
  {
540
    errmsg_printf(error::ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
553 by Monty Taylor
Changed my_thread_id type.
541
                    cur_session->thread_id,
1 by brian
clean slate
542
                    sfile, sline);
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
543
  }
1 by brian
clean slate
544
  else
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
545
  {
546
    errmsg_printf(error::ERROR, _("Got an error from unknown thread, %s:%d"), sfile, sline);
547
  }
548
1 by brian
clean slate
549
  if (message)
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
550
    errmsg_printf(error::ERROR, "%s", message);
551
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
552
  list<Session *>::iterator it= file->s->in_use->begin();
553
  while (it != file->s->in_use->end())
1 by brian
clean slate
554
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
555
    errmsg_printf(error::ERROR, "%s", _("Unknown thread accessing table"));
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
556
    ++it;
1 by brian
clean slate
557
  }
558
}
559
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
560
ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
1869.1.4 by Brian Aker
TableShare is no longer in the house (i.e. we no longer directly have a copy
561
                     Table &table_arg)
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
562
  : Cursor(engine_arg, table_arg),
1220.1.12 by Brian Aker
Small cleanup from something Jay noticed.
563
  file(0),
564
  can_enable_indexes(true),
565
  is_ordered(true)
566
{ }
1 by brian
clean slate
567
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
568
Cursor *ha_myisam::clone(memory::Root *mem_root)
1 by brian
clean slate
569
{
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
570
  ha_myisam *new_handler= static_cast <ha_myisam *>(Cursor::clone(mem_root));
1 by brian
clean slate
571
  if (new_handler)
572
    new_handler->file->state= file->state;
573
  return new_handler;
574
}
575
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
576
const char *ha_myisam::index_type(uint32_t )
1 by brian
clean slate
577
{
74 by Brian Aker
More removal of FT from MyISAM
578
  return "BTREE";
1 by brian
clean slate
579
}
580
581
/* Name is here without an extension */
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
582
int ha_myisam::doOpen(const drizzled::identifier::Table &identifier, int mode, uint32_t test_if_locked)
1 by brian
clean slate
583
{
584
  MI_KEYDEF *keyinfo;
585
  MI_COLUMNDEF *recinfo= 0;
482 by Brian Aker
Remove uint.
586
  uint32_t recs;
587
  uint32_t i;
1 by brian
clean slate
588
589
  /*
590
    If the user wants to have memory mapped data files, add an
591
    open_flag. Do not memory map temporary tables because they are
592
    expected to be inserted and thus extended a lot. Memory mapping is
593
    efficient for files that keep their size, but very inefficient for
594
    growing files. Using an open_flag instead of calling mi_extra(...
595
    HA_EXTRA_MMAP ...) after mi_open() has the advantage that the
596
    mapping is not repeated for every open, but just done on the initial
597
    open, when the MyISAM share is created. Everytime the server
598
    requires to open a new instance of a table it calls this method. We
599
    will always supply HA_OPEN_MMAP for a permanent table. However, the
600
    MyISAM storage engine will ignore this flag if this is a secondary
601
    open of a table that is in use by other threads already (if the
602
    MyISAM share exists already).
603
  */
1749.3.20 by Brian Aker
Updated myisam for identifier.
604
  if (!(file= mi_open(identifier, mode, test_if_locked)))
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
605
    return (errno ? errno : -1);
1115.1.7 by Brian Aker
Remove dead myisam program
606
1869.1.5 by Brian Aker
getTable()
607
  if (!getTable()->getShare()->getType()) /* No need to perform a check for tmp table */
1 by brian
clean slate
608
  {
1869.1.5 by Brian Aker
getTable()
609
    if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
1 by brian
clean slate
610
    {
611
      goto err;
612
    }
1869.1.5 by Brian Aker
getTable()
613
    if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
1 by brian
clean slate
614
                         file->s->keyinfo, file->s->rec,
615
                         file->s->base.keys, file->s->base.fields, true))
616
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
617
      errno= HA_ERR_CRASHED;
1 by brian
clean slate
618
      goto err;
619
    }
620
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
621
1578.2.9 by Brian Aker
Simplify ha_open.
622
  assert(test_if_locked);
1 by brian
clean slate
623
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
398.1.10 by Monty Taylor
Actually removed VOID() this time.
624
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
1 by brian
clean slate
625
626
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
627
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
398.1.10 by Monty Taylor
Actually removed VOID() this time.
628
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
1869.1.5 by Brian Aker
getTable()
629
  if (!getTable()->getShare()->db_record_offset)
1220.2.1 by Brian Aker
Move cursor flags up to storage engine flags. These need to be merged.
630
    is_ordered= false;
631
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
632
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
633
  keys_with_parts.reset();
1869.1.5 by Brian Aker
getTable()
634
  for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
1 by brian
clean slate
635
  {
1869.1.5 by Brian Aker
getTable()
636
    getTable()->key_info[i].block_size= file->s->keyinfo[i].block_length;
1 by brian
clean slate
637
1869.1.5 by Brian Aker
getTable()
638
    KeyPartInfo *kp= getTable()->key_info[i].key_part;
639
    KeyPartInfo *kp_end= kp + getTable()->key_info[i].key_parts;
1 by brian
clean slate
640
    for (; kp != kp_end; kp++)
641
    {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
642
      if (!kp->field->part_of_key.test(i))
1 by brian
clean slate
643
      {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
644
        keys_with_parts.set(i);
1 by brian
clean slate
645
        break;
646
      }
647
    }
648
  }
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
649
  errno= 0;
1 by brian
clean slate
650
  goto end;
651
 err:
652
  this->close();
653
 end:
654
  /*
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
655
    Both recinfo and keydef are allocated by multi_malloc(), thus only
1 by brian
clean slate
656
    recinfo must be freed.
657
  */
658
  if (recinfo)
481 by Brian Aker
Remove all of uchar.
659
    free((unsigned char*) recinfo);
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
660
  return errno;
1 by brian
clean slate
661
}
662
663
int ha_myisam::close(void)
664
{
665
  MI_INFO *tmp=file;
666
  file=0;
667
  return mi_close(tmp);
668
}
669
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
670
int ha_myisam::doInsertRecord(unsigned char *buf)
1 by brian
clean slate
671
{
672
  /*
673
    If we have an auto_increment column and we are writing a changed row
674
    or a new row, then update the auto_increment value in the record.
675
  */
1869.1.5 by Brian Aker
getTable()
676
  if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
1 by brian
clean slate
677
  {
678
    int error;
679
    if ((error= update_auto_increment()))
680
      return error;
681
  }
682
  return mi_write(file,buf);
683
}
684
685
520.1.22 by Brian Aker
Second pass of thd cleanup
686
int ha_myisam::repair(Session *session, MI_CHECK &param, bool do_optimize)
1 by brian
clean slate
687
{
688
  int error=0;
789 by Brian Aker
MyISAM fix.
689
  uint32_t local_testflag= param.testflag;
1 by brian
clean slate
690
  bool optimize_done= !do_optimize, statistics_done=0;
520.1.22 by Brian Aker
Second pass of thd cleanup
691
  const char *old_proc_info= session->get_proc_info();
1 by brian
clean slate
692
  char fixed_name[FN_REFLEN];
693
  MYISAM_SHARE* share = file->s;
694
  ha_rows rows= file->state->records;
695
696
  /*
697
    Normally this method is entered with a properly opened table. If the
698
    repair fails, it can be repeated with more elaborate options. Under
699
    special circumstances it can happen that a repair fails so that it
700
    closed the data file and cannot re-open it. In this case file->dfile
701
    is set to -1. We must not try another repair without an open data
702
    file. (Bug #25289)
703
  */
704
  if (file->dfile == -1)
705
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
706
    errmsg_printf(error::INFO, "Retrying repair of: '%s' failed. "
707
		  "Please try REPAIR EXTENDED or myisamchk",
708
		  getTable()->getShare()->getPath());
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
709
    return(HA_ADMIN_FAILED);
1 by brian
clean slate
710
  }
711
1869.1.5 by Brian Aker
getTable()
712
  param.db_name=    getTable()->getShare()->getSchemaName();
713
  param.table_name= getTable()->getAlias();
1 by brian
clean slate
714
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
715
  param.using_global_keycache = 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
716
  param.session= session;
1 by brian
clean slate
717
  param.out_flag= 0;
1897.4.13 by Monty Taylor
MyISAM.
718
  param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
719
  strcpy(fixed_name,file->filename);
1 by brian
clean slate
720
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
721
  // Don't lock tables if we have used LOCK Table
1869.1.5 by Brian Aker
getTable()
722
  if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
1 by brian
clean slate
723
  {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
724
    mi_check_print_error(&param,ER(ER_CANT_LOCK),errno);
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
725
    return(HA_ADMIN_FAILED);
1 by brian
clean slate
726
  }
727
728
  if (!do_optimize ||
729
      ((file->state->del || share->state.split != file->state->records) &&
730
       (!(param.testflag & T_QUICK) ||
731
	!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
732
  {
733
    uint64_t key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
734
			mi_get_mask_all_keys_active(share->base.keys) :
735
			share->state.key_map);
482 by Brian Aker
Remove uint.
736
    uint32_t testflag=param.testflag;
1 by brian
clean slate
737
    if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
738
	(local_testflag & T_REP_BY_SORT))
739
    {
740
      local_testflag|= T_STATISTICS;
741
      param.testflag|= T_STATISTICS;		// We get this for free
742
      statistics_done=1;
743
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
744
        session->set_proc_info("Repair by sorting");
1 by brian
clean slate
745
        error = mi_repair_by_sort(&param, file, fixed_name,
746
            param.testflag & T_QUICK);
747
      }
748
    }
749
    else
750
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
751
      session->set_proc_info("Repair with keycache");
1 by brian
clean slate
752
      param.testflag &= ~T_REP_BY_SORT;
753
      error=  mi_repair(&param, file, fixed_name,
754
			param.testflag & T_QUICK);
755
    }
756
    param.testflag=testflag;
757
    optimize_done=1;
758
  }
759
  if (!error)
760
  {
761
    if ((local_testflag & T_SORT_INDEX) &&
762
	(share->state.changed & STATE_NOT_SORTED_PAGES))
763
    {
764
      optimize_done=1;
520.1.22 by Brian Aker
Second pass of thd cleanup
765
      session->set_proc_info("Sorting index");
1 by brian
clean slate
766
      error=mi_sort_index(&param,file,fixed_name);
767
    }
768
    if (!statistics_done && (local_testflag & T_STATISTICS))
769
    {
770
      if (share->state.changed & STATE_NOT_ANALYZED)
771
      {
772
	optimize_done=1;
520.1.22 by Brian Aker
Second pass of thd cleanup
773
	session->set_proc_info("Analyzing");
1 by brian
clean slate
774
	error = chk_key(&param, file);
775
      }
776
      else
777
	local_testflag&= ~T_STATISTICS;		// Don't update statistics
778
    }
779
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
780
  session->set_proc_info("Saving state");
1 by brian
clean slate
781
  if (!error)
782
  {
783
    if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
784
    {
785
      share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
786
			       STATE_CRASHED_ON_REPAIR);
787
      file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
788
    }
789
    /*
790
      the following 'if', thought conceptually wrong,
791
      is a useful optimization nevertheless.
792
    */
793
    if (file->state != &file->s->state.state)
794
      file->s->state.state = *file->state;
795
    if (file->s->base.auto_key)
796
      update_auto_increment_key(&param, file, 1);
797
    if (optimize_done)
798
      error = update_state_info(&param, file,
799
				UPDATE_TIME | UPDATE_OPEN_COUNT |
800
				(local_testflag &
801
				 T_STATISTICS ? UPDATE_STAT : 0));
802
    info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
803
	 HA_STATUS_CONST);
804
    if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT))
805
    {
806
      char llbuff[22],llbuff2[22];
807
      mi_check_print_warning(&param,"Number of rows changed from %s to %s",
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
808
			     internal::llstr(rows,llbuff),
809
			     internal::llstr(file->state->records,llbuff2));
1 by brian
clean slate
810
    }
811
  }
812
  else
813
  {
814
    mi_mark_crashed_on_repair(file);
815
    file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
816
    update_state_info(&param, file, 0);
817
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
818
  session->set_proc_info(old_proc_info);
1054.1.8 by Brian Aker
Remove lock_tables list from session.
819
  mi_lock_database(file,F_UNLCK);
820
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
821
  return(error ? HA_ADMIN_FAILED :
1 by brian
clean slate
822
	      !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
823
}
824
825
826
/*
827
  Disable indexes, making it persistent if requested.
828
829
  SYNOPSIS
830
    disable_indexes()
831
    mode        mode of operation:
832
                HA_KEY_SWITCH_NONUNIQ      disable all non-unique keys
833
                HA_KEY_SWITCH_ALL          disable all keys
834
                HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent
835
                HA_KEY_SWITCH_ALL_SAVE     dis. all keys and make persistent
836
837
  IMPLEMENTATION
838
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
839
    HA_KEY_SWITCH_ALL_SAVE      is not implemented.
840
841
  RETURN
842
    0  ok
843
    HA_ERR_WRONG_COMMAND  mode not implemented.
844
*/
845
482 by Brian Aker
Remove uint.
846
int ha_myisam::disable_indexes(uint32_t mode)
1 by brian
clean slate
847
{
848
  int error;
849
850
  if (mode == HA_KEY_SWITCH_ALL)
851
  {
852
    /* call a storage engine function to switch the key map */
853
    error= mi_disable_indexes(file);
854
  }
855
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
856
  {
857
    mi_extra(file, HA_EXTRA_NO_KEYS, 0);
858
    info(HA_STATUS_CONST);                        // Read new key info
859
    error= 0;
860
  }
861
  else
862
  {
863
    /* mode not implemented */
864
    error= HA_ERR_WRONG_COMMAND;
865
  }
866
  return error;
867
}
868
869
870
/*
871
  Enable indexes, making it persistent if requested.
872
873
  SYNOPSIS
874
    enable_indexes()
875
    mode        mode of operation:
876
                HA_KEY_SWITCH_NONUNIQ      enable all non-unique keys
877
                HA_KEY_SWITCH_ALL          enable all keys
878
                HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent
879
                HA_KEY_SWITCH_ALL_SAVE     en. all keys and make persistent
880
881
  DESCRIPTION
882
    Enable indexes, which might have been disabled by disable_index() before.
883
    The modes without _SAVE work only if both data and indexes are empty,
884
    since the MyISAM repair would enable them persistently.
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
885
    To be sure in these cases, call Cursor::delete_all_rows() before.
1 by brian
clean slate
886
887
  IMPLEMENTATION
888
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
889
    HA_KEY_SWITCH_ALL_SAVE      is not implemented.
890
891
  RETURN
892
    0  ok
893
    !=0  Error, among others:
894
    HA_ERR_CRASHED  data or index is non-empty. Delete all rows and retry.
895
    HA_ERR_WRONG_COMMAND  mode not implemented.
896
*/
897
482 by Brian Aker
Remove uint.
898
int ha_myisam::enable_indexes(uint32_t mode)
1 by brian
clean slate
899
{
900
  int error;
901
902
  if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys))
903
  {
904
    /* All indexes are enabled already. */
905
    return 0;
906
  }
907
908
  if (mode == HA_KEY_SWITCH_ALL)
909
  {
910
    error= mi_enable_indexes(file);
911
    /*
912
       Do not try to repair on error,
913
       as this could make the enabled state persistent,
914
       but mode==HA_KEY_SWITCH_ALL forbids it.
915
    */
916
  }
917
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
918
  {
1869.1.5 by Brian Aker
getTable()
919
    Session *session= getTable()->in_use;
1929.1.40 by Monty Taylor
Replaced auto_ptr with scoped_ptr.
920
    boost::scoped_ptr<MI_CHECK> param_ap(new MI_CHECK);
1929.1.4 by Stewart Smith
fix large stack usage in MyISAM:
921
    MI_CHECK &param= *param_ap.get();
520.1.22 by Brian Aker
Second pass of thd cleanup
922
    const char *save_proc_info= session->get_proc_info();
923
    session->set_proc_info("Creating index");
1 by brian
clean slate
924
    myisamchk_init(&param);
925
    param.op_name= "recreating_index";
926
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
927
                     T_CREATE_MISSING_KEYS);
928
    param.myf_rw&= ~MY_WAIT_IF_FULL;
1897.4.13 by Monty Taylor
MyISAM.
929
    param.sort_buffer_length=  static_cast<size_t>(sort_buffer_size);
1115.1.3 by Brian Aker
Remove final bits of "myisam" specific from drizzled.cc
930
    param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
520.1.22 by Brian Aker
Second pass of thd cleanup
931
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1 by brian
clean slate
932
    {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
933
      errmsg_printf(error::WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
934
                        errno, param.db_name, param.table_name);
1 by brian
clean slate
935
      /* Repairing by sort failed. Now try standard repair method. */
936
      param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
520.1.22 by Brian Aker
Second pass of thd cleanup
937
      error= (repair(session,param,0) != HA_ADMIN_OK);
1 by brian
clean slate
938
      /*
939
        If the standard repair succeeded, clear all error messages which
940
        might have been set by the first repair. They can still be seen
941
        with SHOW WARNINGS then.
942
      */
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
943
      if (not error)
520.1.22 by Brian Aker
Second pass of thd cleanup
944
        session->clear_error();
1 by brian
clean slate
945
    }
946
    info(HA_STATUS_CONST);
520.1.22 by Brian Aker
Second pass of thd cleanup
947
    session->set_proc_info(save_proc_info);
1 by brian
clean slate
948
  }
949
  else
950
  {
951
    /* mode not implemented */
952
    error= HA_ERR_WRONG_COMMAND;
953
  }
954
  return error;
955
}
956
957
958
/*
959
  Test if indexes are disabled.
960
961
962
  SYNOPSIS
963
    indexes_are_disabled()
964
      no parameters
965
966
967
  RETURN
968
    0  indexes are not disabled
969
    1  all indexes are disabled
970
   [2  non-unique indexes are disabled - NOT YET IMPLEMENTED]
971
*/
972
973
int ha_myisam::indexes_are_disabled(void)
974
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
975
1 by brian
clean slate
976
  return mi_indexes_are_disabled(file);
977
}
978
979
980
/*
981
  prepare for a many-rows insert operation
982
  e.g. - disable indexes (if they can be recreated fast) or
983
  activate special bulk-insert optimizations
984
985
  SYNOPSIS
986
    start_bulk_insert(rows)
987
    rows        Rows to be inserted
988
                0 if we don't know
989
990
  NOTICE
991
    Do not forget to call end_bulk_insert() later!
992
*/
993
994
void ha_myisam::start_bulk_insert(ha_rows rows)
995
{
1869.1.5 by Brian Aker
getTable()
996
  Session *session= getTable()->in_use;
1116.1.2 by Brian Aker
Remove options which are just for internal optimizations.
997
  ulong size= session->variables.read_buff_size;
1 by brian
clean slate
998
999
  /* don't enable row cache if too few rows */
1000
  if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1001
    mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
1002
1003
  can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
1004
                                            file->s->base.keys);
1005
362 by Brian Aker
No more dead special flags...
1006
  /*
1007
    Only disable old index if the table was empty and we are inserting
1008
    a lot of rows.
1009
    We should not do this for only a few rows as this is slower and
1010
    we don't want to update the key statistics based of only a few rows.
1011
  */
1012
  if (file->state->records == 0 && can_enable_indexes &&
1013
      (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1014
    mi_disable_non_unique_index(file,rows);
1015
  else
1 by brian
clean slate
1016
    if (!file->bulk_insert &&
1017
        (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1018
    {
779.3.20 by Monty Taylor
Fixed Solaris warnings for MyISAM.
1019
      mi_init_bulk_insert(file,
1020
                          (size_t)session->variables.bulk_insert_buff_size,
1021
                          rows);
1 by brian
clean slate
1022
    }
1023
}
1024
1025
/*
1026
  end special bulk-insert optimizations,
1027
  which have been activated by start_bulk_insert().
1028
1029
  SYNOPSIS
1030
    end_bulk_insert()
1031
    no arguments
1032
1033
  RETURN
1034
    0     OK
1035
    != 0  Error
1036
*/
1037
1038
int ha_myisam::end_bulk_insert()
1039
{
1040
  mi_end_bulk_insert(file);
1041
  int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0);
1042
  return err ? err : can_enable_indexes ?
1043
                     enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE) : 0;
1044
}
1045
1046
1047
1491.1.3 by Jay Pipes
Cursor::update_row() changed to doUpdateRecord() and updateRecord()
1048
int ha_myisam::doUpdateRecord(const unsigned char *old_data, unsigned char *new_data)
1 by brian
clean slate
1049
{
1050
  return mi_update(file,old_data,new_data);
1051
}
1052
1491.1.4 by Jay Pipes
delete_row() is now deleteRecord() and doDeleteRecord() in Cursor
1053
int ha_myisam::doDeleteRecord(const unsigned char *buf)
1 by brian
clean slate
1054
{
1055
  return mi_delete(file,buf);
1056
}
1057
1058
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1059
int ha_myisam::doStartIndexScan(uint32_t idx, bool )
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1060
{
1 by brian
clean slate
1061
  active_index=idx;
163 by Brian Aker
Merge Monty's code.
1062
  //in_range_read= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1063
  return 0;
1 by brian
clean slate
1064
}
1065
1066
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1067
int ha_myisam::doEndIndexScan()
1 by brian
clean slate
1068
{
1069
  active_index=MAX_KEY;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1070
  return 0;
1 by brian
clean slate
1071
}
1072
1073
481 by Brian Aker
Remove all of uchar.
1074
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
1075
                              key_part_map keypart_map,
1076
                              enum ha_rkey_function find_flag)
1077
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1078
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1079
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1 by brian
clean slate
1080
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1869.1.5 by Brian Aker
getTable()
1081
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1082
  return error;
1083
}
1084
482 by Brian Aker
Remove uint.
1085
int ha_myisam::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
1 by brian
clean slate
1086
                                  key_part_map keypart_map,
1087
                                  enum ha_rkey_function find_flag)
1088
{
1273.16.8 by Brian Aker
Remove typedef.
1089
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1 by brian
clean slate
1090
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1869.1.5 by Brian Aker
getTable()
1091
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1092
  return error;
1093
}
1094
481 by Brian Aker
Remove all of uchar.
1095
int ha_myisam::index_read_last_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
1096
                                   key_part_map keypart_map)
1097
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1098
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1099
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1 by brian
clean slate
1100
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1101
                    HA_READ_PREFIX_LAST);
1869.1.5 by Brian Aker
getTable()
1102
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1103
  return(error);
1 by brian
clean slate
1104
}
1105
481 by Brian Aker
Remove all of uchar.
1106
int ha_myisam::index_next(unsigned char *buf)
1 by brian
clean slate
1107
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1108
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1109
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1 by brian
clean slate
1110
  int error=mi_rnext(file,buf,active_index);
1869.1.5 by Brian Aker
getTable()
1111
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1112
  return error;
1113
}
1114
481 by Brian Aker
Remove all of uchar.
1115
int ha_myisam::index_prev(unsigned char *buf)
1 by brian
clean slate
1116
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1117
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1118
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
1 by brian
clean slate
1119
  int error=mi_rprev(file,buf, active_index);
1869.1.5 by Brian Aker
getTable()
1120
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1121
  return error;
1122
}
1123
481 by Brian Aker
Remove all of uchar.
1124
int ha_myisam::index_first(unsigned char *buf)
1 by brian
clean slate
1125
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1126
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1127
  ha_statistic_increment(&system_status_var::ha_read_first_count);
1 by brian
clean slate
1128
  int error=mi_rfirst(file, buf, active_index);
1869.1.5 by Brian Aker
getTable()
1129
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1130
  return error;
1131
}
1132
481 by Brian Aker
Remove all of uchar.
1133
int ha_myisam::index_last(unsigned char *buf)
1 by brian
clean slate
1134
{
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1135
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1136
  ha_statistic_increment(&system_status_var::ha_read_last_count);
1 by brian
clean slate
1137
  int error=mi_rlast(file, buf, active_index);
1869.1.5 by Brian Aker
getTable()
1138
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1139
  return error;
1140
}
1141
481 by Brian Aker
Remove all of uchar.
1142
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.
1143
			       const unsigned char *,
1144
			       uint32_t )
1 by brian
clean slate
1145
{
1146
  int error;
51.1.89 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
1147
  assert(inited==INDEX);
1273.16.8 by Brian Aker
Remove typedef.
1148
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1 by brian
clean slate
1149
  do
1150
  {
1151
    error= mi_rnext_same(file,buf);
1152
  } while (error == HA_ERR_RECORD_DELETED);
1869.1.5 by Brian Aker
getTable()
1153
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1154
  return error;
1155
}
1156
1157
int ha_myisam::read_range_first(const key_range *start_key,
1158
		 	        const key_range *end_key,
1159
			        bool eq_range_arg,
1160
                                bool sorted /* ignored */)
1161
{
1162
  int res;
1163
  //if (!eq_range_arg)
163 by Brian Aker
Merge Monty's code.
1164
  //  in_range_read= true;
1 by brian
clean slate
1165
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1166
  res= Cursor::read_range_first(start_key, end_key, eq_range_arg, sorted);
1 by brian
clean slate
1167
1168
  //if (res)
163 by Brian Aker
Merge Monty's code.
1169
  //  in_range_read= false;
1 by brian
clean slate
1170
  return res;
1171
}
1172
1173
1174
int ha_myisam::read_range_next()
1175
{
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1176
  int res= Cursor::read_range_next();
1 by brian
clean slate
1177
  //if (res)
163 by Brian Aker
Merge Monty's code.
1178
  //  in_range_read= false;
1 by brian
clean slate
1179
  return res;
1180
}
1181
1182
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1183
int ha_myisam::doStartTableScan(bool scan)
1 by brian
clean slate
1184
{
1185
  if (scan)
1186
    return mi_scan_init(file);
1187
  return mi_reset(file);                        // Free buffers
1188
}
1189
481 by Brian Aker
Remove all of uchar.
1190
int ha_myisam::rnd_next(unsigned char *buf)
1 by brian
clean slate
1191
{
1273.16.8 by Brian Aker
Remove typedef.
1192
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1 by brian
clean slate
1193
  int error=mi_scan(file, buf);
1869.1.5 by Brian Aker
getTable()
1194
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1195
  return error;
1196
}
1197
481 by Brian Aker
Remove all of uchar.
1198
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
1 by brian
clean slate
1199
{
1273.16.8 by Brian Aker
Remove typedef.
1200
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1201
  int error=mi_rrnd(file, buf, internal::my_get_ptr(pos,ref_length));
1869.1.5 by Brian Aker
getTable()
1202
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
1 by brian
clean slate
1203
  return error;
1204
}
1205
1206
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1207
void ha_myisam::position(const unsigned char *)
1 by brian
clean slate
1208
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1209
  internal::my_off_t row_position= mi_position(file);
1210
  internal::my_store_ptr(ref, ref_length, row_position);
1 by brian
clean slate
1211
}
1212
482 by Brian Aker
Remove uint.
1213
int ha_myisam::info(uint32_t flag)
1 by brian
clean slate
1214
{
1215
  MI_ISAMINFO misam_info;
1216
  char name_buff[FN_REFLEN];
1217
1218
  (void) mi_status(file,&misam_info,flag);
1219
  if (flag & HA_STATUS_VARIABLE)
1220
  {
1221
    stats.records=           misam_info.records;
1222
    stats.deleted=           misam_info.deleted;
1223
    stats.data_file_length=  misam_info.data_file_length;
1224
    stats.index_file_length= misam_info.index_file_length;
1225
    stats.delete_length=     misam_info.delete_length;
1226
    stats.check_time=        misam_info.check_time;
1227
    stats.mean_rec_length=   misam_info.mean_reclength;
1228
  }
1229
  if (flag & HA_STATUS_CONST)
1230
  {
1869.1.5 by Brian Aker
getTable()
1231
    TableShare *share= getTable()->getMutableShare();
1 by brian
clean slate
1232
    stats.max_data_file_length=  misam_info.max_data_file_length;
1233
    stats.max_index_file_length= misam_info.max_index_file_length;
1234
    stats.create_time= misam_info.create_time;
1235
    ref_length= misam_info.reflength;
1236
    share->db_options_in_use= misam_info.options;
1251.2.2 by Jay Pipes
Pulls MyISAM-specific server variables into the MyISAM
1237
    stats.block_size= myisam_key_cache_block_size;        /* record block size */
1 by brian
clean slate
1238
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
1239
    set_prefix(share->keys_in_use, share->sizeKeys());
1095.6.1 by Padraig O'Sullivan
Fix for 32 bit Solaris builds. Issue was with conversion of 64-bit unsigned
1240
    /*
1241
     * Due to bug 394932 (32-bit solaris build failure), we need
1242
     * to convert the uint64_t key_map member of the misam_info
1243
     * structure in to a std::bitset so that we can logically and
1244
     * it with the share->key_in_use key_map.
1245
     */
1246
    ostringstream ostr;
1247
    string binary_key_map;
1248
    uint64_t num= misam_info.key_map;
1249
    /*
1250
     * Convert the uint64_t to a binary
1251
     * string representation of it.
1252
     */
1253
    while (num > 0)
1254
    {
1255
      uint64_t bin_digit= num % 2;
1256
      ostr << bin_digit;
1257
      num/= 2;
1258
    }
1259
    binary_key_map.append(ostr.str());
1260
    /*
1261
     * Now we have the binary string representation of the
1262
     * flags, we need to fill that string representation out
1263
     * with the appropriate number of bits. This is needed
1264
     * since key_map is declared as a std::bitset of a certain bit
1265
     * width that depends on the MAX_INDEXES variable. 
1266
     */
1267
    if (MAX_INDEXES <= 64)
1268
    {
1269
      size_t len= 72 - binary_key_map.length();
1270
      string all_zeros(len, '0');
1271
      binary_key_map.insert(binary_key_map.begin(),
1272
                            all_zeros.begin(),
1273
                            all_zeros.end());
1274
    }
1275
    else
1276
    {
1277
      size_t len= (MAX_INDEXES + 7) / 8 * 8;
1278
      string all_zeros(len, '0');
1279
      binary_key_map.insert(binary_key_map.begin(),
1280
                            all_zeros.begin(),
1281
                            all_zeros.end());
1282
    }
1283
    key_map tmp_map(binary_key_map);
1284
    share->keys_in_use&= tmp_map;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1285
    share->keys_for_keyread&= share->keys_in_use;
1 by brian
clean slate
1286
    share->db_record_offset= misam_info.record_offset;
1287
    if (share->key_parts)
1869.1.5 by Brian Aker
getTable()
1288
      memcpy(getTable()->key_info[0].rec_per_key,
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
1289
	     misam_info.rec_per_key,
1869.1.5 by Brian Aker
getTable()
1290
	     sizeof(getTable()->key_info[0].rec_per_key)*share->key_parts);
1685.2.2 by Brian Aker
Remove wait condition.
1291
    assert(share->getType() != message::Table::STANDARD);
1 by brian
clean slate
1292
1293
   /*
1294
     Set data_file_name and index_file_name to point at the symlink value
1295
     if table is symlinked (Ie;  Real name is not same as generated name)
1296
   */
1297
    data_file_name= index_file_name= 0;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1298
    internal::fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
1 by brian
clean slate
1299
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1300
    if (strcmp(name_buff, misam_info.data_file_name))
1301
      data_file_name=misam_info.data_file_name;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1302
    internal::fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
1 by brian
clean slate
1303
              MY_APPEND_EXT | MY_UNPACK_FILENAME);
1304
    if (strcmp(name_buff, misam_info.index_file_name))
1305
      index_file_name=misam_info.index_file_name;
1306
  }
1307
  if (flag & HA_STATUS_ERRKEY)
1308
  {
1309
    errkey  = misam_info.errkey;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1310
    internal::my_store_ptr(dup_ref, ref_length, misam_info.dupp_key_pos);
1 by brian
clean slate
1311
  }
1312
  if (flag & HA_STATUS_TIME)
1313
    stats.update_time = misam_info.update_time;
1314
  if (flag & HA_STATUS_AUTO)
1315
    stats.auto_increment_value= misam_info.auto_increment;
1316
1317
  return 0;
1318
}
1319
1320
1321
int ha_myisam::extra(enum ha_extra_function operation)
1322
{
1323
  return mi_extra(file, operation, 0);
1324
}
1325
1326
int ha_myisam::reset(void)
1327
{
1328
  return mi_reset(file);
1329
}
1330
1331
/* To be used with WRITE_CACHE and EXTRA_CACHE */
1332
61 by Brian Aker
Conversion of handler type.
1333
int ha_myisam::extra_opt(enum ha_extra_function operation, uint32_t cache_size)
1 by brian
clean slate
1334
{
1335
  return mi_extra(file, operation, (void*) &cache_size);
1336
}
1337
1338
int ha_myisam::delete_all_rows()
1339
{
1340
  return mi_delete_all_rows(file);
1341
}
1342
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
1343
int MyisamEngine::doDropTable(Session &session,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
1344
                              const identifier::Table &identifier)
1 by brian
clean slate
1345
{
1923.1.4 by Brian Aker
Encapsulate up the cache we use in Session for tracking table proto for temp
1346
  session.getMessageCache().removeTableMessage(identifier);
1183.1.30 by Brian Aker
Added engine internal locks (instead of the session based....)
1347
1358.1.9 by Brian Aker
Update for std::string
1348
  return mi_delete_table(identifier.getPath().c_str());
1 by brian
clean slate
1349
}
1350
1351
520.1.22 by Brian Aker
Second pass of thd cleanup
1352
int ha_myisam::external_lock(Session *session, int lock_type)
1 by brian
clean slate
1353
{
916.1.35 by Padraig O'Sullivan
Removing the last of LIST from the MyISAM storage engine.
1354
  file->in_use= session;
1869.1.5 by Brian Aker
getTable()
1355
  return mi_lock_database(file, !getTable()->getShare()->getType() ?
1 by brian
clean slate
1356
			  lock_type : ((lock_type == F_UNLCK) ?
1357
				       F_UNLCK : F_EXTRA_LCK));
1358
}
1359
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
1360
int MyisamEngine::doCreateTable(Session &session,
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
1361
                                Table& table_arg,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
1362
                                const identifier::Table &identifier,
2224.4.2 by Brian Aker
Merge in work around making all passing of table as const.
1363
                                const message::Table& create_proto)
1 by brian
clean slate
1364
{
1365
  int error;
779.3.10 by Monty Taylor
Turned on -Wshadow.
1366
  uint32_t create_flags= 0, create_records;
1 by brian
clean slate
1367
  char buff[FN_REFLEN];
1368
  MI_KEYDEF *keydef;
1369
  MI_COLUMNDEF *recinfo;
1370
  MI_CREATE_INFO create_info;
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
1371
  TableShare *share= table_arg.getMutableShare();
482 by Brian Aker
Remove uint.
1372
  uint32_t options= share->db_options_in_use;
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
1373
  if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
971.6.11 by Eric Day
Removed purecov messages.
1374
    return(error);
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
1375
  memset(&create_info, 0, sizeof(create_info));
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
1376
  create_info.max_rows= create_proto.options().max_rows();
1377
  create_info.reloc_rows= create_proto.options().min_rows();
1 by brian
clean slate
1378
  create_info.with_auto_increment= share->next_number_key_offset == 0;
1222.1.5 by Brian Aker
Remove dependency in engines for auto_increment primer to be passed in by
1379
  create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
1380
                               create_proto.options().auto_increment_value() -1 :
1 by brian
clean slate
1381
                               (uint64_t) 0);
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
1382
  create_info.data_file_length= (create_proto.options().max_rows() *
1383
                                 create_proto.options().avg_row_length());
1121.1.2 by Brian Aker
Fix storing data/index path
1384
  create_info.data_file_name= NULL;
1385
  create_info.index_file_name=  NULL;
1 by brian
clean slate
1386
  create_info.language= share->table_charset->number;
1387
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1388
  if (create_proto.type() == message::Table::TEMPORARY)
1 by brian
clean slate
1389
    create_flags|= HA_CREATE_TMP_TABLE;
1390
  if (options & HA_OPTION_PACK_RECORD)
1391
    create_flags|= HA_PACK_RECORD;
1392
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1393
  /* TODO: Check that the following internal::fn_format is really needed */
1358.1.9 by Brian Aker
Update for std::string
1394
  error= mi_create(internal::fn_format(buff, identifier.getPath().c_str(), "", "",
1395
                                       MY_UNPACK_FILENAME|MY_APPEND_EXT),
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
1396
                   share->sizeKeys(), keydef,
779.3.10 by Monty Taylor
Turned on -Wshadow.
1397
                   create_records, recinfo,
1 by brian
clean slate
1398
                   0, (MI_UNIQUEDEF*) 0,
1399
                   &create_info, create_flags);
481 by Brian Aker
Remove all of uchar.
1400
  free((unsigned char*) recinfo);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
1401
1923.1.4 by Brian Aker
Encapsulate up the cache we use in Session for tracking table proto for temp
1402
  session.getMessageCache().storeTableMessage(identifier, create_proto);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
1403
1404
  return error;
1 by brian
clean slate
1405
}
1406
1407
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
1408
int MyisamEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
1 by brian
clean slate
1409
{
1923.1.4 by Brian Aker
Encapsulate up the cache we use in Session for tracking table proto for temp
1410
  session.getMessageCache().renameTableMessage(from, to);
1391 by Brian Aker
Updating interface.
1411
1390 by Brian Aker
Update interface to use Identifiers directly.
1412
  return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1 by brian
clean slate
1413
}
1414
1415
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1416
void ha_myisam::get_auto_increment(uint64_t ,
1417
                                   uint64_t ,
1418
                                   uint64_t ,
1 by brian
clean slate
1419
                                   uint64_t *first_value,
1420
                                   uint64_t *nb_reserved_values)
1421
{
1422
  uint64_t nr;
1423
  int error;
481 by Brian Aker
Remove all of uchar.
1424
  unsigned char key[MI_MAX_KEY_LENGTH];
1 by brian
clean slate
1425
1869.1.5 by Brian Aker
getTable()
1426
  if (!getTable()->getShare()->next_number_key_offset)
1 by brian
clean slate
1427
  {						// Autoincrement at key-start
1428
    ha_myisam::info(HA_STATUS_AUTO);
1429
    *first_value= stats.auto_increment_value;
1430
    /* MyISAM has only table-level lock, so reserves to +inf */
163 by Brian Aker
Merge Monty's code.
1431
    *nb_reserved_values= UINT64_MAX;
1 by brian
clean slate
1432
    return;
1433
  }
1434
1435
  /* it's safe to call the following if bulk_insert isn't on */
1869.1.5 by Brian Aker
getTable()
1436
  mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
1 by brian
clean slate
1437
1438
  (void) extra(HA_EXTRA_KEYREAD);
1869.1.5 by Brian Aker
getTable()
1439
  key_copy(key, getTable()->getInsertRecord(),
1440
           &getTable()->key_info[getTable()->getShare()->next_number_index],
1441
           getTable()->getShare()->next_number_key_offset);
1442
  error= mi_rkey(file, getTable()->getUpdateRecord(), (int) getTable()->getShare()->next_number_index,
1443
                 key, make_prev_keypart_map(getTable()->getShare()->next_number_keypart),
1 by brian
clean slate
1444
                 HA_READ_PREFIX_LAST);
1445
  if (error)
1446
    nr= 1;
1447
  else
1448
  {
1672.3.6 by Brian Aker
First pass in encapsulating row
1449
    /* Get data from getUpdateRecord() */
1869.1.5 by Brian Aker
getTable()
1450
    nr= ((uint64_t) getTable()->next_number_field->
1451
         val_int_offset(getTable()->getShare()->rec_buff_length)+1);
1 by brian
clean slate
1452
  }
1453
  extra(HA_EXTRA_NO_KEYREAD);
1454
  *first_value= nr;
1455
  /*
1456
    MySQL needs to call us for next row: assume we are inserting ("a",null)
1457
    here, we return 3, and next this statement will want to insert ("b",null):
1458
    there is no reason why ("b",3+1) would be the good row to insert: maybe it
1459
    already exists, maybe 3+1 is too large...
1460
  */
1461
  *nb_reserved_values= 1;
1462
}
1463
1464
1465
/*
1466
  Find out how many rows there is in the given range
1467
1468
  SYNOPSIS
1469
    records_in_range()
1470
    inx			Index to use
1471
    min_key		Start of range.  Null pointer if from first key
1472
    max_key		End of range. Null pointer if to last key
1473
1474
  NOTES
1475
    min_key.flag can have one of the following values:
1476
      HA_READ_KEY_EXACT		Include the key in the range
1477
      HA_READ_AFTER_KEY		Don't include key in range
1478
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1479
    max_key.flag can have one of the following values:
1 by brian
clean slate
1480
      HA_READ_BEFORE_KEY	Don't include key in range
1481
      HA_READ_AFTER_KEY		Include all 'end_key' values in the range
1482
1483
  RETURN
1484
   HA_POS_ERROR		Something is wrong with the index tree.
1485
   0			There is no matching keys in the given range
1486
   number > 0		There is approximately 'number' matching rows in
1487
			the range.
1488
*/
1489
482 by Brian Aker
Remove uint.
1490
ha_rows ha_myisam::records_in_range(uint32_t inx, key_range *min_key,
1 by brian
clean slate
1491
                                    key_range *max_key)
1492
{
1493
  return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1494
}
1495
1496
482 by Brian Aker
Remove uint.
1497
uint32_t ha_myisam::checksum() const
1 by brian
clean slate
1498
{
1499
  return (uint)file->state->checksum;
1500
}
1501
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
1502
static int myisam_init(module::Context &context)
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
1503
{ 
1897.4.13 by Monty Taylor
MyISAM.
1504
  context.add(new MyisamEngine(engine_name));
1505
  context.registerVariable(new sys_var_constrained_value<size_t>("sort-buffer-size",
1964.2.10 by Monty Taylor
Changed show SHOW_INT works ... man, trying to cast things as a method of data storage is lame.
1506
                                                                 sort_buffer_size));
1897.4.15 by Monty Taylor
Update MyISAM to use new sys_var.
1507
  context.registerVariable(new sys_var_uint64_t_ptr("max_sort_file_size",
1508
                                                    &max_sort_file_size,
1509
                                                    context.getOptions()["max-sort-file-size"].as<uint64_t>()));
971.1.51 by Monty Taylor
New-style plugin registration now works.
1510
1511
  return 0;
1512
}
1513
1 by brian
clean slate
1514
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
1515
static void init_options(drizzled::module::option_context &context)
1516
{
1517
  context("max-sort-file-size",
1682.2.5 by Monty Taylor
Fixed a typing issue.
1518
          po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
2068.4.1 by Andrew Hutchings
Fix intl domain
1519
          _("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
1520
  context("sort-buffer-size",
1897.4.13 by Monty Taylor
MyISAM.
1521
          po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
2068.4.1 by Andrew Hutchings
Fix intl domain
1522
          _("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
1523
}
1524
1 by brian
clean slate
1525
1228.1.5 by Monty Taylor
Merged in some naming things.
1526
DRIZZLE_DECLARE_PLUGIN
1 by brian
clean slate
1527
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
1528
  DRIZZLE_VERSION_ID,
1 by brian
clean slate
1529
  "MyISAM",
1689.2.21 by Brian Aker
Remove outward sign of Key Cache
1530
  "2.0",
1 by brian
clean slate
1531
  "MySQL AB",
1532
  "Default engine as of MySQL 3.23 with great performance",
1533
  PLUGIN_LICENSE_GPL,
1534
  myisam_init, /* Plugin Init */
2095.3.1 by Monty Taylor
Re-purpose the old plugin sysvar slot in the struct to be a depends list.
1535
  NULL,           /* depends */
1677.2.1 by Vijay Samuel
Merge refactored command line for myisam
1536
  init_options                        /* config options                  */
1 by brian
clean slate
1537
}
1228.1.5 by Monty Taylor
Merged in some naming things.
1538
DRIZZLE_DECLARE_PLUGIN_END;