~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
/* open a isam-database */
17
1130.3.28 by Monty Taylor
Moved heapdef.h and myisamdef.h to *_priv.h for easier filtering for include guard check.
18
#include "myisam_priv.h"
1 by brian
clean slate
19
612.2.13 by Monty Taylor
Work on removing global.h from headers that should be installed.
20
#include <string.h>
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
21
#include <algorithm>
1929.1.5 by Stewart Smith
Fix large stack usage in MyISAM mi_open():
22
#include <memory>
1929.1.40 by Monty Taylor
Replaced auto_ptr with scoped_ptr.
23
#include <boost/scoped_ptr.hpp>
1929.1.42 by Monty Taylor
You really want to use scoped_array with new[].
24
#include <boost/scoped_array.hpp>
612.2.13 by Monty Taylor
Work on removing global.h from headers that should be installed.
25
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
26
#include <drizzled/internal/m_string.h>
27
#include <drizzled/util/test.h>
28
#include <drizzled/charset.h>
29
#include <drizzled/memory/multi_malloc.h>
2241.4.14 by Stewart Smith
remove some includes from my_sys.h and instead only include where needed. This helps reduce the number of files that have to be rebuilt when you change some of the more widely included header files (such as the drizzled::identifier ones)
30
#include <drizzled/identifier.h>
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
31
32
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
33
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
34
using namespace drizzled;
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
35
1 by brian
clean slate
36
static void setup_key_functions(MI_KEYDEF *keyinfo);
1165.1.131 by Stewart Smith
make mi_keydef_read() static to myisam/mi_open.cc
37
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
1165.1.132 by Stewart Smith
make static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)() static to myisam/mi_open.cc
38
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
1165.1.133 by Stewart Smith
make mi_recinfo_read() static to myisam/mi_open.cc
39
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
1165.1.134 by Stewart Smith
make mi_safe_mul() static to myisam/mi_open.cc
40
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
1165.1.135 by Stewart Smith
make mi_state_info_read() static to myisam/mi_open.cc
41
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
1165.1.136 by Stewart Smith
make mi_uniquedef_read() static to myisam/mi_open.cc
42
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
1165.1.137 by Stewart Smith
make my_n_base_info_read() static to myisam/mi_open.cc
43
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base);
1 by brian
clean slate
44
45
#define disk_pos_assert(pos, end_pos) \
46
if (pos > end_pos)             \
47
{                              \
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
48
  errno=HA_ERR_CRASHED;     \
1 by brian
clean slate
49
  goto err;                    \
50
}
51
52
53
/******************************************************************************
54
** Return the shared struct if the table is already open.
55
** In MySQL the server will handle version issues.
56
******************************************************************************/
57
58
MI_INFO *test_if_reopen(char *filename)
59
{
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
60
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
61
  while (it != myisam_open_list.end())
1 by brian
clean slate
62
  {
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
63
    MI_INFO *info= *it;
916.1.31 by Padraig O'Sullivan
Reverting some refactoring changes I made to MyISAM that didn't really work
64
    MYISAM_SHARE *share=info->s;
1 by brian
clean slate
65
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
66
      return info;
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
67
    ++it;
1 by brian
clean slate
68
  }
69
  return 0;
70
}
71
72
73
/******************************************************************************
74
  open a MyISAM database.
75
  See my_base.h for the handle_locking argument
76
  if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table
77
  is marked crashed or if we are not using locking and the table doesn't
78
  have an open count of 0.
79
******************************************************************************/
80
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
81
MI_INFO *mi_open(const drizzled::identifier::Table &identifier, int mode, uint32_t open_flags)
1 by brian
clean slate
82
{
83
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
482 by Brian Aker
Remove uint.
84
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
2253.1.1 by Andrew Hutchings
Fix Drizzle to compile in GCC 4.6 (which fires warnings and therefore errors if a variable is set and not read)
85
    key_parts,unique_key_parts,uniques;
1 by brian
clean slate
86
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
1060.2.5 by Eric Lambert
-removed my_realpath from my_symlink and replaced it with calls to posix realpath
87
       data_name[FN_REFLEN], rp_buff[PATH_MAX];
481 by Brian Aker
Remove all of uchar.
88
  unsigned char *disk_cache= NULL;
89
  unsigned char *disk_pos, *end_pos;
1 by brian
clean slate
90
  MI_INFO info,*m_info,*old_info;
1929.1.40 by Monty Taylor
Replaced auto_ptr with scoped_ptr.
91
  boost::scoped_ptr<MYISAM_SHARE> share_buff_ap(new MYISAM_SHARE);
1929.1.5 by Stewart Smith
Fix large stack usage in MyISAM mi_open():
92
  MYISAM_SHARE &share_buff= *share_buff_ap.get();
93
  MYISAM_SHARE *share;
1929.1.42 by Monty Taylor
You really want to use scoped_array with new[].
94
  boost::scoped_array<ulong> rec_per_key_part_ap(new ulong[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]);
1929.1.5 by Stewart Smith
Fix large stack usage in MyISAM mi_open():
95
  ulong *rec_per_key_part= rec_per_key_part_ap.get();
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
96
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
151 by Brian Aker
Ulonglong to uint64_t
97
  uint64_t max_key_file_length, max_data_file_length;
1 by brian
clean slate
98
99
  kfile= -1;
100
  lock_error=1;
101
  errpos=0;
102
  head_length=sizeof(share_buff.state.header);
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
103
  memset(&info, 0, sizeof(info));
1 by brian
clean slate
104
1749.3.20 by Brian Aker
Updated myisam for identifier.
105
  (void)internal::fn_format(org_name,
106
                            identifier.getPath().c_str(), 
107
                            "",
108
                            MI_NAME_IEXT,
109
                            MY_UNPACK_FILENAME);
1060.2.5 by Eric Lambert
-removed my_realpath from my_symlink and replaced it with calls to posix realpath
110
  if (!realpath(org_name,rp_buff))
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
111
    internal::my_load_path(rp_buff,org_name, NULL);
1060.2.5 by Eric Lambert
-removed my_realpath from my_symlink and replaced it with calls to posix realpath
112
  rp_buff[FN_REFLEN-1]= '\0';
113
  strcpy(name_buff,rp_buff);
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
114
  THR_LOCK_myisam.lock();
1 by brian
clean slate
115
  if (!(old_info=test_if_reopen(name_buff)))
116
  {
117
    share= &share_buff;
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
118
    memset(&share_buff, 0, sizeof(share_buff));
1 by brian
clean slate
119
    share_buff.state.rec_per_key_part=rec_per_key_part;
120
    share_buff.state.key_root=key_root;
121
    share_buff.state.key_del=key_del;
1689.2.15 by Brian Aker
Encapsulate the key cache object in myisam.
122
    share_buff.setKeyCache();
1 by brian
clean slate
123
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
124
    if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
1 by brian
clean slate
125
    {
126
      if ((errno != EROFS && errno != EACCES) ||
127
	  mode != O_RDONLY ||
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
128
	  (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
1 by brian
clean slate
129
	goto err;
130
    }
131
    share->mode=open_mode;
132
    errpos=1;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
133
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
1 by brian
clean slate
134
		MYF(MY_NABP)))
135
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
136
      errno= HA_ERR_NOT_A_TABLE;
1 by brian
clean slate
137
      goto err;
138
    }
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
139
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
1 by brian
clean slate
140
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
141
      errno=HA_ERR_NOT_A_TABLE;
1 by brian
clean slate
142
      goto err;
143
    }
144
    share->options= mi_uint2korr(share->state.header.options);
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
145
    static const uint64_t OLD_FILE_OPTIONS= HA_OPTION_PACK_RECORD |
146
	    HA_OPTION_PACK_KEYS |
147
	    HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
148
	    HA_OPTION_TEMP_COMPRESS_RECORD |
149
	    HA_OPTION_TMP_TABLE;
150
    if (share->options & ~OLD_FILE_OPTIONS)
1 by brian
clean slate
151
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
152
      errno=HA_ERR_OLD_FILE;
1 by brian
clean slate
153
      goto err;
154
    }
1115.1.7 by Brian Aker
Remove dead myisam program
155
1 by brian
clean slate
156
    /* Don't call realpath() if the name can't be a link */
1060.2.1 by Eric Lambert
-replace calls to my_readlink with readlink
157
    ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
158
    if (sym_link_size >= 0 )
159
      index_name[sym_link_size]= '\0';
160
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
161
      (void) strcpy(index_name, org_name);
1 by brian
clean slate
162
    *strrchr(org_name, '.')= '\0';
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
163
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
1 by brian
clean slate
164
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
165
166
    info_length=mi_uint2korr(share->state.header.header_length);
167
    base_pos=mi_uint2korr(share->state.header.base_pos);
481 by Brian Aker
Remove all of uchar.
168
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
1 by brian
clean slate
169
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
170
      errno=ENOMEM;
1 by brian
clean slate
171
      goto err;
172
    }
173
    end_pos=disk_cache+info_length;
174
    errpos=2;
175
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
176
    lseek(kfile,0,SEEK_SET);
1 by brian
clean slate
177
    errpos=3;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
178
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
1 by brian
clean slate
179
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
180
      errno=HA_ERR_CRASHED;
1 by brian
clean slate
181
      goto err;
182
    }
183
    len=mi_uint2korr(share->state.header.state_info_length);
184
    keys=    (uint) share->state.header.keys;
185
    uniques= (uint) share->state.header.uniques;
186
    key_parts= mi_uint2korr(share->state.header.key_parts);
187
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
188
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
189
190
    mi_state_info_read(disk_cache, &share->state);
191
    len= mi_uint2korr(share->state.header.base_info_length);
192
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
193
    share->state.state_length=base_pos;
194
1237.6.2 by Brian Aker
Minor cleanup for dead code.
195
    if (share->state.changed & STATE_CRASHED)
1 by brian
clean slate
196
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
197
      errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
1 by brian
clean slate
198
		HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
199
      goto err;
200
    }
201
202
    /* sanity check */
203
    if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
204
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
205
      errno=HA_ERR_CRASHED;
1 by brian
clean slate
206
      goto err;
207
    }
208
209
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
210
	key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
211
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
212
      errno=HA_ERR_UNSUPPORTED;
1 by brian
clean slate
213
      goto err;
214
    }
215
216
    /* Correct max_file_length based on length of sizeof(off_t) */
217
    max_data_file_length=
218
      (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
151 by Brian Aker
Ulonglong to uint64_t
219
      (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
1 by brian
clean slate
220
      (mi_safe_mul(share->base.pack_reclength,
151 by Brian Aker
Ulonglong to uint64_t
221
		   (uint64_t) 1 << (share->base.rec_reflength*8))-1);
1 by brian
clean slate
222
    max_key_file_length=
223
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
151 by Brian Aker
Ulonglong to uint64_t
224
		  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
1 by brian
clean slate
225
#if SIZEOF_OFF_T == 4
590.2.23 by Monty Taylor
Fixed a few things for solaris builds.
226
    set_if_smaller(max_data_file_length, INT32_MAX);
227
    set_if_smaller(max_key_file_length, INT32_MAX);
1 by brian
clean slate
228
#endif
229
    if (share->base.raid_type)
230
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
231
      errno=HA_ERR_UNSUPPORTED;
1 by brian
clean slate
232
      goto err;
233
    }
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
234
    share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
235
    share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
1 by brian
clean slate
236
237
    if (share->options & HA_OPTION_COMPRESS_RECORD)
238
      share->base.max_key_length+=2;	/* For safety */
239
240
    /* Add space for node pointer */
241
    share->base.max_key_length+= share->base.key_reflength;
242
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
243
    if (!drizzled::memory::multi_malloc(false,
244
           &share,sizeof(*share),
245
           &share->state.rec_per_key_part,sizeof(long)*key_parts,
246
           &share->keyinfo,keys*sizeof(MI_KEYDEF),
247
           &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
248
           &share->keyparts,
249
           (key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
250
           &share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
251
           &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
252
           &share->unique_file_name,strlen(name_buff)+1,
253
           &share->index_file_name,strlen(index_name)+1,
254
           &share->data_file_name,strlen(data_name)+1,
255
           &share->state.key_root,keys*sizeof(uint64_t),
256
           &share->state.key_del,
257
           (share->state.header.max_block_size_index*sizeof(uint64_t)),
258
           NULL))
1 by brian
clean slate
259
      goto err;
260
    errpos=4;
261
    *share=share_buff;
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
262
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
263
           sizeof(long)*key_parts);
264
    memcpy(share->state.key_root, key_root,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
265
           sizeof(internal::my_off_t)*keys);
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
266
    memcpy(share->state.key_del, key_del,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
267
           sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
268
    strcpy(share->unique_file_name, name_buff);
1 by brian
clean slate
269
    share->unique_name_length= strlen(name_buff);
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
270
    strcpy(share->index_file_name,  index_name);
271
    strcpy(share->data_file_name,   data_name);
1 by brian
clean slate
272
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
273
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
1 by brian
clean slate
274
    {
275
      HA_KEYSEG *pos=share->keyparts;
276
      for (i=0 ; i < keys ; i++)
277
      {
278
        share->keyinfo[i].share= share;
279
	disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
280
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
281
 			end_pos);
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
282
	set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
1 by brian
clean slate
283
	share->keyinfo[i].seg=pos;
284
	for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
285
	{
286
	  disk_pos=mi_keyseg_read(disk_pos, pos);
287
          if (pos->flag & HA_BLOB_PART &&
288
              ! (share->options & (HA_OPTION_COMPRESS_RECORD |
289
                                   HA_OPTION_PACK_RECORD)))
290
          {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
291
            errno= HA_ERR_CRASHED;
1 by brian
clean slate
292
            goto err;
293
          }
294
	  if (pos->type == HA_KEYTYPE_TEXT ||
295
              pos->type == HA_KEYTYPE_VARTEXT1 ||
296
              pos->type == HA_KEYTYPE_VARTEXT2)
297
	  {
298
	    if (!pos->language)
299
	      pos->charset=default_charset_info;
862 by Brian Aker
Remove charset directory code.
300
	    else if (!(pos->charset= get_charset(pos->language)))
1 by brian
clean slate
301
	    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
302
	      errno=HA_ERR_UNKNOWN_CHARSET;
1 by brian
clean slate
303
	      goto err;
304
	    }
305
	  }
306
	  else if (pos->type == HA_KEYTYPE_BINARY)
307
	    pos->charset= &my_charset_bin;
308
	}
309
        setup_key_functions(share->keyinfo+i);
310
	share->keyinfo[i].end=pos;
311
	pos->type=HA_KEYTYPE_END;			/* End */
312
	pos->length=share->base.rec_reflength;
313
	pos->null_bit=0;
314
	pos->flag=0;					/* For purify */
315
	pos++;
316
      }
317
      for (i=0 ; i < uniques ; i++)
318
      {
319
	disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
320
        disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs *
321
			HA_KEYSEG_SIZE, end_pos);
322
	share->uniqueinfo[i].seg=pos;
323
	for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
324
	{
325
	  disk_pos=mi_keyseg_read(disk_pos, pos);
326
	  if (pos->type == HA_KEYTYPE_TEXT ||
327
              pos->type == HA_KEYTYPE_VARTEXT1 ||
328
              pos->type == HA_KEYTYPE_VARTEXT2)
329
	  {
330
	    if (!pos->language)
331
	      pos->charset=default_charset_info;
862 by Brian Aker
Remove charset directory code.
332
	    else if (!(pos->charset= get_charset(pos->language)))
1 by brian
clean slate
333
	    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
334
	      errno=HA_ERR_UNKNOWN_CHARSET;
1 by brian
clean slate
335
	      goto err;
336
	    }
337
	  }
338
	}
339
	share->uniqueinfo[i].end=pos;
340
	pos->type=HA_KEYTYPE_END;			/* End */
341
	pos->null_bit=0;
342
	pos->flag=0;
343
	pos++;
344
      }
345
    }
346
347
    disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
348
    for (i=j=offset=0 ; i < share->base.fields ; i++)
349
    {
350
      disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
351
      share->rec[i].pack_type=0;
352
      share->rec[i].huff_tree=0;
353
      share->rec[i].offset=offset;
354
      if (share->rec[i].type == (int) FIELD_BLOB)
355
      {
356
	share->blobs[j].pack_length=
357
	  share->rec[i].length-portable_sizeof_char_ptr;
358
	share->blobs[j].offset=offset;
359
	j++;
360
      }
361
      offset+=share->rec[i].length;
362
    }
363
    share->rec[i].type=(int) FIELD_LAST;	/* End marker */
364
    if (offset > share->base.reclength)
365
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
366
      errno= HA_ERR_CRASHED;
1 by brian
clean slate
367
      goto err;
368
    }
369
370
    if (! lock_error)
371
    {
372
      lock_error=1;			/* Database unlocked */
373
    }
374
375
    if (mi_open_datafile(&info, share, -1))
376
      goto err;
377
    errpos=5;
378
379
    share->kfile=kfile;
380
    share->this_process=(ulong) getpid();
381
    share->last_process= share->state.process;
382
    share->base.key_parts=key_parts;
383
    share->base.all_key_parts=key_parts+unique_key_parts;
384
    if (!(share->last_version=share->state.version))
385
      share->last_version=1;			/* Safety */
386
    share->rec_reflength=share->base.rec_reflength; /* May be changed */
387
    share->base.margin_key_file_length=(share->base.max_key_file_length -
388
					(keys ? MI_INDEX_BLOCK_MARGIN *
389
					 share->blocksize * keys : 0));
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
390
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
1 by brian
clean slate
391
    share->data_file_type=STATIC_RECORD;
311 by Brian Aker
Sqlech issues with pack
392
    if (share->options & HA_OPTION_PACK_RECORD)
1 by brian
clean slate
393
      share->data_file_type = DYNAMIC_RECORD;
478 by Monty Taylor
Made my_alloc actually always use malloc.
394
    free(disk_cache);
395
    disk_cache= NULL;
1 by brian
clean slate
396
    mi_setup_functions(share);
163 by Brian Aker
Merge Monty's code.
397
    share->is_log_table= false;
1685.2.1 by Brian Aker
This removes custom myisam lock code from the kernel (and removes the
398
    if (myisam_concurrent_insert)
1 by brian
clean slate
399
    {
400
      share->concurrent_insert=
401
	((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
402
			   HA_OPTION_COMPRESS_RECORD |
403
			   HA_OPTION_TEMP_COMPRESS_RECORD)) ||
74 by Brian Aker
More removal of FT from MyISAM
404
	 (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
1 by brian
clean slate
405
      if (share->concurrent_insert)
406
      {
1685.2.1 by Brian Aker
This removes custom myisam lock code from the kernel (and removes the
407
        assert(0);
1 by brian
clean slate
408
      }
409
    }
410
  }
411
  else
412
  {
413
    share= old_info->s;
414
    if (mode == O_RDWR && share->mode == O_RDONLY)
415
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
416
      errno=EACCES;				/* Can't open in write mode */
1 by brian
clean slate
417
      goto err;
418
    }
419
    if (mi_open_datafile(&info, share, old_info->dfile))
420
      goto err;
421
    errpos=5;
422
    have_rtree= old_info->rtree_recursion_state != NULL;
423
  }
424
425
  /* alloc and set up private structure parts */
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
426
  if (!drizzled::memory::multi_malloc(MY_WME,
427
         &m_info,sizeof(MI_INFO),
428
         &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
429
         &info.buff,(share->base.max_key_block_length*2+
430
                     share->base.max_key_length),
431
         &info.lastkey,share->base.max_key_length*3+1,
432
         &info.first_mbr_key, share->base.max_key_length,
1749.3.20 by Brian Aker
Updated myisam for identifier.
433
         &info.filename, identifier.getPath().length()+1,
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
434
         &info.rtree_recursion_state,have_rtree ? 1024 : 0,
435
         NULL))
1 by brian
clean slate
436
    goto err;
437
  errpos=6;
438
439
  if (!have_rtree)
440
    info.rtree_recursion_state= NULL;
441
1749.3.20 by Brian Aker
Updated myisam for identifier.
442
  strcpy(info.filename, identifier.getPath().c_str());
1 by brian
clean slate
443
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
444
  info.lastkey2=info.lastkey+share->base.max_key_length;
445
446
  info.s=share;
447
  info.lastpos= HA_OFFSET_ERROR;
448
  info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
449
  info.opt_flag=READ_CHECK_USED;
450
  info.this_unique= (ulong) info.dfile; /* Uniq number in process */
451
  if (share->data_file_type == COMPRESSED_RECORD)
452
    info.this_unique= share->state.unique;
453
  info.this_loop=0;				/* Update counter */
454
  info.last_unique= share->state.unique;
455
  info.last_loop=   share->state.update_count;
456
  if (mode == O_RDONLY)
457
    share->options|=HA_OPTION_READ_ONLY_DATA;
458
  info.lock_type=F_UNLCK;
459
  info.quick_mode=0;
460
  info.bulk_insert=0;
461
  info.errkey= -1;
462
  info.page_changed=1;
463
  info.read_record=share->read_record;
464
  share->reopen++;
465
  share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
466
  if (share->options & HA_OPTION_READ_ONLY_DATA)
467
  {
468
    info.lock_type=F_RDLCK;
469
    share->r_locks++;
470
    share->tot_locks++;
471
  }
472
  if ((open_flags & HA_OPEN_TMP_TABLE) ||
473
      (share->options & HA_OPTION_TMP_TABLE))
474
  {
475
    share->temporary=share->delay_key_write=1;
476
    share->write_flag=MYF(MY_NABP);
1085.2.1 by Stewart Smith
Fix BUG lp:387627: UPDATE can be TRUNCATE on TEMPORARY TABLE. Some special case code in MyISAM for 'if temporary table' was making (the included) test case fail. Root cause of what we've messed up in MyISAM was not found (after much investigation).
477
    /*
478
     * The following two statements are commented out as a fix of
479
     * bug https://bugs.launchpad.net/drizzle/+bug/387627
480
     *
481
     * UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
482
     * The root cause of why this makes a difference hasn't
483
     * been found, but this fixes things for now.
484
     */
485
//    share->w_locks++;			// We don't have to update status
486
//    share->tot_locks++;
1 by brian
clean slate
487
    info.lock_type=F_WRLCK;
488
  }
1115.1.2 by Brian Aker
Taylor the defaults for MyISAM for its "tmp" behavior.
489
490
  share->delay_key_write= 1;
1 by brian
clean slate
491
  info.state= &share->state.state;	/* Change global values by default */
492
493
  /* Allocate buffer for one record */
494
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
495
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
496
  if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
1 by brian
clean slate
497
    goto err;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
498
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
1 by brian
clean slate
499
500
  *m_info=info;
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
501
  myisam_open_list.push_front(m_info);
1 by brian
clean slate
502
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
503
  THR_LOCK_myisam.unlock();
51.1.103 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
504
  return(m_info);
1 by brian
clean slate
505
506
err:
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
507
  free(disk_cache);
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
508
  save_errno=errno ? errno : HA_ERR_END_OF_FILE;
1 by brian
clean slate
509
  if ((save_errno == HA_ERR_CRASHED) ||
510
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
511
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
1749.3.20 by Brian Aker
Updated myisam for identifier.
512
    mi_report_error(save_errno, identifier.getPath().c_str());
1 by brian
clean slate
513
  switch (errpos) {
514
  case 6:
481 by Brian Aker
Remove all of uchar.
515
    free((unsigned char*) m_info);
1 by brian
clean slate
516
    /* fall through */
517
  case 5:
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
518
    internal::my_close(info.dfile,MYF(0));
1 by brian
clean slate
519
    if (old_info)
520
      break;					/* Don't remove open table */
521
    /* fall through */
522
  case 4:
481 by Brian Aker
Remove all of uchar.
523
    free((unsigned char*) share);
1 by brian
clean slate
524
    /* fall through */
525
  case 3:
526
    /* fall through */
527
  case 1:
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
528
    internal::my_close(kfile,MYF(0));
1 by brian
clean slate
529
    /* fall through */
530
  case 0:
531
  default:
532
    break;
533
  }
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
534
  THR_LOCK_myisam.unlock();
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
535
  errno=save_errno;
51.1.103 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
536
  return (NULL);
1 by brian
clean slate
537
} /* mi_open */
538
539
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
540
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
1 by brian
clean slate
541
{
482 by Brian Aker
Remove uint.
542
  uint32_t extra;
205 by Brian Aker
uint32 -> uin32_t
543
  uint32_t old_length= 0;
1 by brian
clean slate
544
545
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
546
  {
481 by Brian Aker
Remove all of uchar.
547
    unsigned char *newptr = *buf;
1 by brian
clean slate
548
549
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
550
    if (length == SIZE_MAX)
1 by brian
clean slate
551
    {
552
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
553
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
1 by brian
clean slate
554
      else
555
        length= info->s->base.pack_reclength;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
556
      length= max((uint32_t)length, info->s->base.max_key_length);
1 by brian
clean slate
557
      /* Avoid unnecessary realloc */
558
      if (newptr && length == old_length)
559
	return newptr;
560
    }
561
562
    extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
563
	    ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
564
	    MI_REC_BUFF_OFFSET : 0);
565
    if (extra && newptr)
566
      newptr-= MI_REC_BUFF_OFFSET;
656.1.44 by Monty Taylor
Added some return checking.
567
    void *tmpnewptr= NULL;
568
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
1 by brian
clean slate
569
      return newptr;
960.2.2 by Monty Taylor
Moved MyISAM files to C++ so we can continue to consolidate code.
570
    newptr= (unsigned char *)tmpnewptr;
205 by Brian Aker
uint32 -> uin32_t
571
    *((uint32_t *) newptr)= (uint32_t) length;
1 by brian
clean slate
572
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
573
  }
574
  return *buf;
575
}
576
577
1165.1.134 by Stewart Smith
make mi_safe_mul() static to myisam/mi_open.cc
578
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
1 by brian
clean slate
579
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
580
  uint64_t max_val= ~ (uint64_t) 0;		/* internal::my_off_t is unsigned */
1 by brian
clean slate
581
582
  if (!a || max_val / a < b)
583
    return max_val;
584
  return a*b;
585
}
586
587
	/* Set up functions in structs */
588
589
void mi_setup_functions(register MYISAM_SHARE *share)
590
{
311 by Brian Aker
Sqlech issues with pack
591
  if (share->options & HA_OPTION_PACK_RECORD)
1 by brian
clean slate
592
  {
593
    share->read_record=_mi_read_dynamic_record;
594
    share->read_rnd=_mi_read_rnd_dynamic_record;
595
    share->delete_record=_mi_delete_dynamic_record;
596
    share->compare_record=_mi_cmp_dynamic_record;
597
    share->compare_unique=_mi_cmp_dynamic_unique;
598
    share->calc_checksum= mi_checksum;
599
600
    /* add bits used to pack data to pack_reclength for faster allocation */
601
    share->base.pack_reclength+= share->base.pack_bits;
602
    if (share->base.blobs)
603
    {
604
      share->update_record=_mi_update_blob_record;
605
      share->write_record=_mi_write_blob_record;
606
    }
607
    else
608
    {
609
      share->write_record=_mi_write_dynamic_record;
610
      share->update_record=_mi_update_dynamic_record;
611
    }
612
  }
613
  else
614
  {
615
    share->read_record=_mi_read_static_record;
616
    share->read_rnd=_mi_read_rnd_static_record;
617
    share->delete_record=_mi_delete_static_record;
618
    share->compare_record=_mi_cmp_static_record;
619
    share->update_record=_mi_update_static_record;
620
    share->write_record=_mi_write_static_record;
621
    share->compare_unique=_mi_cmp_static_unique;
622
    share->calc_checksum= mi_static_checksum;
623
  }
624
  share->file_read= mi_nommap_pread;
625
  share->file_write= mi_nommap_pwrite;
1117.1.2 by Brian Aker
Remove CHECKSUM option in create table.
626
  share->calc_checksum=0;
1 by brian
clean slate
627
}
628
629
630
static void setup_key_functions(register MI_KEYDEF *keyinfo)
631
{
632
  {
633
    keyinfo->ck_insert = _mi_ck_write;
634
    keyinfo->ck_delete = _mi_ck_delete;
635
  }
636
  if (keyinfo->flag & HA_BINARY_PACK_KEY)
637
  {						/* Simple prefix compression */
638
    keyinfo->bin_search=_mi_seq_search;
639
    keyinfo->get_key=_mi_get_binary_pack_key;
640
    keyinfo->pack_key=_mi_calc_bin_pack_key_length;
641
    keyinfo->store_key=_mi_store_bin_pack_key;
642
  }
643
  else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
644
  {
645
    keyinfo->get_key= _mi_get_pack_key;
646
    if (keyinfo->seg[0].flag & HA_PACK_KEY)
647
    {						/* Prefix compression */
648
      /*
649
        _mi_prefix_search() compares end-space against ASCII blank (' ').
650
        It cannot be used for character sets, that do not encode the
651
        blank character like ASCII does. UCS2 is an example. All
652
        character sets with a fixed width > 1 or a mimimum width > 1
653
        cannot represent blank like ASCII does. In these cases we have
654
        to use _mi_seq_search() for the search.
655
      */
656
      if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
657
          (keyinfo->seg->flag & HA_NULL_PART) ||
658
          (keyinfo->seg->charset->mbminlen > 1))
659
        keyinfo->bin_search=_mi_seq_search;
660
      else
661
        keyinfo->bin_search=_mi_prefix_search;
662
      keyinfo->pack_key=_mi_calc_var_pack_key_length;
663
      keyinfo->store_key=_mi_store_var_pack_key;
664
    }
665
    else
666
    {
667
      keyinfo->bin_search=_mi_seq_search;
668
      keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
669
      keyinfo->store_key=_mi_store_static_key;
670
    }
671
  }
672
  else
673
  {
674
    keyinfo->bin_search=_mi_bin_search;
675
    keyinfo->get_key=_mi_get_static_key;
676
    keyinfo->pack_key=_mi_calc_static_key_length;
677
    keyinfo->store_key=_mi_store_static_key;
678
  }
679
  return;
680
}
681
682
683
/*
684
   Function to save and store the header in the index file (.MYI)
685
*/
686
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
687
uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite)
1 by brian
clean slate
688
{
481 by Brian Aker
Remove all of uchar.
689
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
690
  unsigned char *ptr=buff;
1 by brian
clean slate
691
  uint	i, keys= (uint) state->header.keys,
692
	key_blocks=state->header.max_block_size_index;
693
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
694
  memcpy(ptr,&state->header,sizeof(state->header));
1 by brian
clean slate
695
  ptr+=sizeof(state->header);
696
697
  /* open_count must be first because of _mi_mark_file_changed ! */
698
  mi_int2store(ptr,state->open_count);		ptr +=2;
481 by Brian Aker
Remove all of uchar.
699
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
1 by brian
clean slate
700
  mi_rowstore(ptr,state->state.records);	ptr +=8;
701
  mi_rowstore(ptr,state->state.del);		ptr +=8;
702
  mi_rowstore(ptr,state->split);		ptr +=8;
703
  mi_sizestore(ptr,state->dellink);		ptr +=8;
704
  mi_sizestore(ptr,state->state.key_file_length);	ptr +=8;
705
  mi_sizestore(ptr,state->state.data_file_length);	ptr +=8;
706
  mi_sizestore(ptr,state->state.empty);		ptr +=8;
707
  mi_sizestore(ptr,state->state.key_empty);	ptr +=8;
708
  mi_int8store(ptr,state->auto_increment);	ptr +=8;
151 by Brian Aker
Ulonglong to uint64_t
709
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
1 by brian
clean slate
710
  mi_int4store(ptr,state->process);		ptr +=4;
711
  mi_int4store(ptr,state->unique);		ptr +=4;
712
  mi_int4store(ptr,state->status);		ptr +=4;
713
  mi_int4store(ptr,state->update_count);	ptr +=4;
714
715
  ptr+=state->state_diff_length;
716
717
  for (i=0; i < keys; i++)
718
  {
719
    mi_sizestore(ptr,state->key_root[i]);	ptr +=8;
720
  }
721
  for (i=0; i < key_blocks; i++)
722
  {
723
    mi_sizestore(ptr,state->key_del[i]);	ptr +=8;
724
  }
725
  if (pWrite & 2)				/* From isamchk */
726
  {
482 by Brian Aker
Remove uint.
727
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
1 by brian
clean slate
728
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
729
    mi_int4store(ptr,state->sec_index_used);	ptr +=4;
730
    mi_int4store(ptr,state->version);		ptr +=4;
731
    mi_int8store(ptr,state->key_map);		ptr +=8;
151 by Brian Aker
Ulonglong to uint64_t
732
    mi_int8store(ptr,(uint64_t) state->create_time);	ptr +=8;
733
    mi_int8store(ptr,(uint64_t) state->recover_time);	ptr +=8;
734
    mi_int8store(ptr,(uint64_t) state->check_time);	ptr +=8;
1 by brian
clean slate
735
    mi_sizestore(ptr,state->rec_per_key_rows);	ptr+=8;
736
    for (i=0 ; i < key_parts ; i++)
737
    {
738
      mi_int4store(ptr,state->rec_per_key_part[i]);  ptr+=4;
739
    }
740
  }
741
742
  if (pWrite & 1)
51.1.103 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
743
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
1 by brian
clean slate
744
			  MYF(MY_NABP | MY_THREADSAFE)) != 0);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
745
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
1 by brian
clean slate
746
		       MYF(MY_NABP)) != 0);
747
}
748
749
1165.1.135 by Stewart Smith
make mi_state_info_read() static to myisam/mi_open.cc
750
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
1 by brian
clean slate
751
{
482 by Brian Aker
Remove uint.
752
  uint32_t i,keys,key_parts,key_blocks;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
753
  memcpy(&state->header,ptr, sizeof(state->header));
1 by brian
clean slate
754
  ptr +=sizeof(state->header);
755
  keys=(uint) state->header.keys;
756
  key_parts=mi_uint2korr(state->header.key_parts);
757
  key_blocks=state->header.max_block_size_index;
758
759
  state->open_count = mi_uint2korr(ptr);	ptr +=2;
760
  state->changed= *ptr++;
761
  state->sortkey = (uint) *ptr++;
762
  state->state.records= mi_rowkorr(ptr);	ptr +=8;
763
  state->state.del = mi_rowkorr(ptr);		ptr +=8;
764
  state->split	= mi_rowkorr(ptr);		ptr +=8;
765
  state->dellink= mi_sizekorr(ptr);		ptr +=8;
766
  state->state.key_file_length = mi_sizekorr(ptr);	ptr +=8;
767
  state->state.data_file_length= mi_sizekorr(ptr);	ptr +=8;
768
  state->state.empty	= mi_sizekorr(ptr);	ptr +=8;
769
  state->state.key_empty= mi_sizekorr(ptr);	ptr +=8;
770
  state->auto_increment=mi_uint8korr(ptr);	ptr +=8;
2241.4.37 by Stewart Smith
remove the drizzled::internal namespace prefix from teh typedef for ha_checksum - it's just for myisam now
771
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);	ptr +=8;
1 by brian
clean slate
772
  state->process= mi_uint4korr(ptr);		ptr +=4;
773
  state->unique = mi_uint4korr(ptr);		ptr +=4;
774
  state->status = mi_uint4korr(ptr);		ptr +=4;
775
  state->update_count=mi_uint4korr(ptr);	ptr +=4;
776
777
  ptr+= state->state_diff_length;
778
779
  for (i=0; i < keys; i++)
780
  {
781
    state->key_root[i]= mi_sizekorr(ptr);	ptr +=8;
782
  }
783
  for (i=0; i < key_blocks; i++)
784
  {
785
    state->key_del[i] = mi_sizekorr(ptr);	ptr +=8;
786
  }
787
  state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
788
  state->sec_index_used =    mi_uint4korr(ptr); ptr +=4;
789
  state->version     = mi_uint4korr(ptr);	ptr +=4;
790
  state->key_map     = mi_uint8korr(ptr);	ptr +=8;
791
  state->create_time = (time_t) mi_sizekorr(ptr);	ptr +=8;
792
  state->recover_time =(time_t) mi_sizekorr(ptr);	ptr +=8;
793
  state->check_time =  (time_t) mi_sizekorr(ptr);	ptr +=8;
794
  state->rec_per_key_rows=mi_sizekorr(ptr);	ptr +=8;
795
  for (i=0 ; i < key_parts ; i++)
796
  {
797
    state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
798
  }
799
  return ptr;
800
}
801
802
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
803
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
1 by brian
clean slate
804
{
481 by Brian Aker
Remove all of uchar.
805
  unsigned char	buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
1 by brian
clean slate
806
1115.1.2 by Brian Aker
Taylor the defaults for MyISAM for its "tmp" behavior.
807
  if (pRead)
1 by brian
clean slate
808
  {
1115.1.2 by Brian Aker
Taylor the defaults for MyISAM for its "tmp" behavior.
809
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
1 by brian
clean slate
810
      return 1;
811
  }
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
812
  else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
1115.1.2 by Brian Aker
Taylor the defaults for MyISAM for its "tmp" behavior.
813
    return 1;
814
  mi_state_info_read(buff, state);
815
1 by brian
clean slate
816
  return 0;
817
}
818
819
820
/****************************************************************************
821
**  store and read of MI_BASE_INFO
822
****************************************************************************/
823
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
824
uint32_t mi_base_info_write(int file, MI_BASE_INFO *base)
1 by brian
clean slate
825
{
481 by Brian Aker
Remove all of uchar.
826
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
1 by brian
clean slate
827
828
  mi_sizestore(ptr,base->keystart);			ptr +=8;
829
  mi_sizestore(ptr,base->max_data_file_length);		ptr +=8;
830
  mi_sizestore(ptr,base->max_key_file_length);		ptr +=8;
831
  mi_rowstore(ptr,base->records);			ptr +=8;
832
  mi_rowstore(ptr,base->reloc);				ptr +=8;
833
  mi_int4store(ptr,base->mean_row_length);		ptr +=4;
834
  mi_int4store(ptr,base->reclength);			ptr +=4;
835
  mi_int4store(ptr,base->pack_reclength);		ptr +=4;
836
  mi_int4store(ptr,base->min_pack_length);		ptr +=4;
837
  mi_int4store(ptr,base->max_pack_length);		ptr +=4;
838
  mi_int4store(ptr,base->min_block_length);		ptr +=4;
839
  mi_int4store(ptr,base->fields);			ptr +=4;
840
  mi_int4store(ptr,base->pack_fields);			ptr +=4;
841
  *ptr++=base->rec_reflength;
842
  *ptr++=base->key_reflength;
843
  *ptr++=base->keys;
844
  *ptr++=base->auto_key;
845
  mi_int2store(ptr,base->pack_bits);			ptr +=2;
846
  mi_int2store(ptr,base->blobs);			ptr +=2;
847
  mi_int2store(ptr,base->max_key_block_length);		ptr +=2;
848
  mi_int2store(ptr,base->max_key_length);		ptr +=2;
849
  mi_int2store(ptr,base->extra_alloc_bytes);		ptr +=2;
850
  *ptr++= base->extra_alloc_procent;
489.1.6 by Monty Taylor
Removed RAID garbage.
851
  /* old raid info  slots */
852
  *ptr++= 0;
853
  mi_int2store(ptr,UINT16_C(0));			ptr +=2;
854
  mi_int4store(ptr,UINT32_C(0));         		ptr +=4;
855
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
856
  memset(ptr, 0, 6);					ptr +=6; /* extra */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
857
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1 by brian
clean slate
858
}
859
860
1165.1.137 by Stewart Smith
make my_n_base_info_read() static to myisam/mi_open.cc
861
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
1 by brian
clean slate
862
{
863
  base->keystart = mi_sizekorr(ptr);			ptr +=8;
864
  base->max_data_file_length = mi_sizekorr(ptr);	ptr +=8;
865
  base->max_key_file_length = mi_sizekorr(ptr);		ptr +=8;
866
  base->records =  (ha_rows) mi_sizekorr(ptr);		ptr +=8;
867
  base->reloc = (ha_rows) mi_sizekorr(ptr);		ptr +=8;
868
  base->mean_row_length = mi_uint4korr(ptr);		ptr +=4;
869
  base->reclength = mi_uint4korr(ptr);			ptr +=4;
870
  base->pack_reclength = mi_uint4korr(ptr);		ptr +=4;
871
  base->min_pack_length = mi_uint4korr(ptr);		ptr +=4;
872
  base->max_pack_length = mi_uint4korr(ptr);		ptr +=4;
873
  base->min_block_length = mi_uint4korr(ptr);		ptr +=4;
874
  base->fields = mi_uint4korr(ptr);			ptr +=4;
875
  base->pack_fields = mi_uint4korr(ptr);		ptr +=4;
876
877
  base->rec_reflength = *ptr++;
878
  base->key_reflength = *ptr++;
879
  base->keys=		*ptr++;
880
  base->auto_key=	*ptr++;
881
  base->pack_bits = mi_uint2korr(ptr);			ptr +=2;
882
  base->blobs = mi_uint2korr(ptr);			ptr +=2;
883
  base->max_key_block_length= mi_uint2korr(ptr);	ptr +=2;
884
  base->max_key_length = mi_uint2korr(ptr);		ptr +=2;
885
  base->extra_alloc_bytes = mi_uint2korr(ptr);		ptr +=2;
886
  base->extra_alloc_procent = *ptr++;
489.1.6 by Monty Taylor
Removed RAID garbage.
887
888
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
889
  ptr+= 7;
1 by brian
clean slate
890
891
  ptr+=6;
892
  return ptr;
893
}
894
895
/*--------------------------------------------------------------------------
896
  mi_keydef
897
---------------------------------------------------------------------------*/
898
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
899
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
1 by brian
clean slate
900
{
481 by Brian Aker
Remove all of uchar.
901
  unsigned char buff[MI_KEYDEF_SIZE];
902
  unsigned char *ptr=buff;
1 by brian
clean slate
903
481 by Brian Aker
Remove all of uchar.
904
  *ptr++ = (unsigned char) keydef->keysegs;
1 by brian
clean slate
905
  *ptr++ = keydef->key_alg;			/* Rtree or Btree */
906
  mi_int2store(ptr,keydef->flag);		ptr +=2;
907
  mi_int2store(ptr,keydef->block_length);	ptr +=2;
908
  mi_int2store(ptr,keydef->keylength);		ptr +=2;
909
  mi_int2store(ptr,keydef->minlength);		ptr +=2;
910
  mi_int2store(ptr,keydef->maxlength);		ptr +=2;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
911
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1 by brian
clean slate
912
}
913
1165.1.131 by Stewart Smith
make mi_keydef_read() static to myisam/mi_open.cc
914
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
1 by brian
clean slate
915
{
916
   keydef->keysegs	= (uint) *ptr++;
917
   keydef->key_alg	= *ptr++;		/* Rtree or Btree */
918
919
   keydef->flag		= mi_uint2korr(ptr);	ptr +=2;
920
   keydef->block_length = mi_uint2korr(ptr);	ptr +=2;
921
   keydef->keylength	= mi_uint2korr(ptr);	ptr +=2;
922
   keydef->minlength	= mi_uint2korr(ptr);	ptr +=2;
923
   keydef->maxlength	= mi_uint2korr(ptr);	ptr +=2;
924
   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
925
   keydef->underflow_block_length=keydef->block_length/3;
926
   keydef->version	= 0;			/* Not saved */
927
   return ptr;
928
}
929
930
/***************************************************************************
931
**  mi_keyseg
932
***************************************************************************/
933
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
934
int mi_keyseg_write(int file, const HA_KEYSEG *keyseg)
1 by brian
clean slate
935
{
481 by Brian Aker
Remove all of uchar.
936
  unsigned char buff[HA_KEYSEG_SIZE];
937
  unsigned char *ptr=buff;
1 by brian
clean slate
938
  ulong pos;
939
940
  *ptr++= keyseg->type;
941
  *ptr++= keyseg->language;
942
  *ptr++= keyseg->null_bit;
943
  *ptr++= keyseg->bit_start;
944
  *ptr++= keyseg->bit_end;
945
  *ptr++= keyseg->bit_length;
946
  mi_int2store(ptr,keyseg->flag);	ptr+=2;
947
  mi_int2store(ptr,keyseg->length);	ptr+=2;
948
  mi_int4store(ptr,keyseg->start);	ptr+=4;
949
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
950
  mi_int4store(ptr, pos);
951
  ptr+=4;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
952
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
953
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1 by brian
clean slate
954
}
955
956
1165.1.132 by Stewart Smith
make static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)() static to myisam/mi_open.cc
957
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
1 by brian
clean slate
958
{
959
   keyseg->type		= *ptr++;
960
   keyseg->language	= *ptr++;
961
   keyseg->null_bit	= *ptr++;
962
   keyseg->bit_start	= *ptr++;
963
   keyseg->bit_end	= *ptr++;
964
   keyseg->bit_length   = *ptr++;
965
   keyseg->flag		= mi_uint2korr(ptr);  ptr +=2;
966
   keyseg->length	= mi_uint2korr(ptr);  ptr +=2;
967
   keyseg->start	= mi_uint4korr(ptr);  ptr +=4;
968
   keyseg->null_pos	= mi_uint4korr(ptr);  ptr +=4;
969
   keyseg->charset=0;				/* Will be filled in later */
970
   if (keyseg->null_bit)
206 by Brian Aker
Removed final uint dead types.
971
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
1 by brian
clean slate
972
   else
973
   {
206 by Brian Aker
Removed final uint dead types.
974
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
1 by brian
clean slate
975
     keyseg->null_pos= 0;
976
   }
977
   return ptr;
978
}
979
980
/*--------------------------------------------------------------------------
981
  mi_uniquedef
982
---------------------------------------------------------------------------*/
983
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
984
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
1 by brian
clean slate
985
{
481 by Brian Aker
Remove all of uchar.
986
  unsigned char buff[MI_UNIQUEDEF_SIZE];
987
  unsigned char *ptr=buff;
1 by brian
clean slate
988
989
  mi_int2store(ptr,def->keysegs);		ptr+=2;
481 by Brian Aker
Remove all of uchar.
990
  *ptr++=  (unsigned char) def->key;
991
  *ptr++ = (unsigned char) def->null_are_equal;
1 by brian
clean slate
992
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
993
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1 by brian
clean slate
994
}
995
1165.1.136 by Stewart Smith
make mi_uniquedef_read() static to myisam/mi_open.cc
996
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1 by brian
clean slate
997
{
998
   def->keysegs = mi_uint2korr(ptr);
999
   def->key	= ptr[2];
1000
   def->null_are_equal=ptr[3];
1001
   return ptr+4;				/* 1 extra byte */
1002
}
1003
1004
/***************************************************************************
1005
**  MI_COLUMNDEF
1006
***************************************************************************/
1007
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
1008
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
1 by brian
clean slate
1009
{
481 by Brian Aker
Remove all of uchar.
1010
  unsigned char buff[MI_COLUMNDEF_SIZE];
1011
  unsigned char *ptr=buff;
1 by brian
clean slate
1012
1013
  mi_int2store(ptr,recinfo->type);	ptr +=2;
1014
  mi_int2store(ptr,recinfo->length);	ptr +=2;
1015
  *ptr++ = recinfo->null_bit;
1016
  mi_int2store(ptr,recinfo->null_pos);	ptr+= 2;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1017
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1 by brian
clean slate
1018
}
1019
1165.1.133 by Stewart Smith
make mi_recinfo_read() static to myisam/mi_open.cc
1020
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1 by brian
clean slate
1021
{
1022
   recinfo->type=  mi_sint2korr(ptr);	ptr +=2;
1023
   recinfo->length=mi_uint2korr(ptr);	ptr +=2;
206 by Brian Aker
Removed final uint dead types.
1024
   recinfo->null_bit= (uint8_t) *ptr++;
1 by brian
clean slate
1025
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1026
   return ptr;
1027
}
1028
1029
/**************************************************************************
489.1.6 by Monty Taylor
Removed RAID garbage.
1030
Open data file
1 by brian
clean slate
1031
We can't use dup() here as the data file descriptors need to have different
1032
active seek-positions.
1033
1034
The argument file_to_dup is here for the future if there would on some OS
1035
exist a dup()-like call that would give us two different file descriptors.
1036
*************************************************************************/
1037
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
1038
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
1 by brian
clean slate
1039
{
779.3.1 by Monty Taylor
More cleanup.
1040
  (void)file_to_dup; 
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1041
  info->dfile=internal::my_open(share->data_file_name, share->mode,
779.3.1 by Monty Taylor
More cleanup.
1042
                      MYF(MY_WME));
1 by brian
clean slate
1043
  return info->dfile >= 0 ? 0 : 1;
1044
}
1045
1046
1047
int mi_open_keyfile(MYISAM_SHARE *share)
1048
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1049
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
1 by brian
clean slate
1050
                            MYF(MY_WME))) < 0)
1051
    return 1;
1052
  return 0;
1053
}
1054
1055
1056
/*
1057
  Disable all indexes.
1058
1059
  SYNOPSIS
1060
    mi_disable_indexes()
1061
    info        A pointer to the MyISAM storage engine MI_INFO struct.
1062
1063
  DESCRIPTION
1064
    Disable all indexes.
1065
1066
  RETURN
1067
    0  ok
1068
*/
1069
1070
int mi_disable_indexes(MI_INFO *info)
1071
{
1072
  MYISAM_SHARE *share= info->s;
1073
1074
  mi_clear_all_keys_active(share->state.key_map);
1075
  return 0;
1076
}
1077
1078
1079
/*
1080
  Enable all indexes
1081
1082
  SYNOPSIS
1083
    mi_enable_indexes()
1084
    info        A pointer to the MyISAM storage engine MI_INFO struct.
1085
1086
  DESCRIPTION
1087
    Enable all indexes. The indexes might have been disabled
1088
    by mi_disable_index() before.
1089
    The function works only if both data and indexes are empty,
1090
    otherwise a repair is required.
1091
    To be sure, call handler::delete_all_rows() before.
1092
1093
  RETURN
1094
    0  ok
1095
    HA_ERR_CRASHED data or index is non-empty.
1096
*/
1097
1098
int mi_enable_indexes(MI_INFO *info)
1099
{
1100
  int error= 0;
1101
  MYISAM_SHARE *share= info->s;
1102
1103
  if (share->state.state.data_file_length ||
1104
      (share->state.state.key_file_length != share->base.keystart))
1105
  {
1106
    mi_print_error(info->s, HA_ERR_CRASHED);
1107
    error= HA_ERR_CRASHED;
1108
  }
1109
  else
1110
    mi_set_all_keys_active(share->state.key_map, share->base.keys);
1111
  return error;
1112
}
1113
1114
1115
/*
1116
  Test if indexes are disabled.
1117
1118
  SYNOPSIS
1119
    mi_indexes_are_disabled()
1120
    info        A pointer to the MyISAM storage engine MI_INFO struct.
1121
1122
  DESCRIPTION
1123
    Test if indexes are disabled.
1124
1125
  RETURN
1126
    0  indexes are not disabled
1127
    1  all indexes are disabled
1128
    2  non-unique indexes are disabled
1129
*/
1130
1131
int mi_indexes_are_disabled(MI_INFO *info)
1132
{
1133
  MYISAM_SHARE *share= info->s;
1134
1135
  /*
1136
    No keys or all are enabled. keys is the number of keys. Left shifted
1137
    gives us only one bit set. When decreased by one, gives us all all bits
1138
    up to this one set and it gets unset.
1139
  */
1140
  if (!share->base.keys ||
1141
      (mi_is_all_keys_active(share->state.key_map, share->base.keys)))
1142
    return 0;
1143
1144
  /* All are disabled */
1145
  if (mi_is_any_key_active(share->state.key_map))
1146
    return 1;
1147
1148
  /*
1149
    We have keys. Some enabled, some disabled.
1150
    Don't check for any non-unique disabled but return directly 2
1151
  */
1152
  return 2;
1153
}
1154