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