~drizzle-trunk/drizzle/development

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