~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_check.c

Cleanup around SAFEMALLOC

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
  only. And it is sufficient to calculate the checksum once only.
41
41
*/
42
42
 
43
 
#include "myisam_priv.h"
44
 
#include "drizzled/internal/m_string.h"
 
43
#include "myisamdef.h"
45
44
#include <stdarg.h>
46
 
#include "drizzled/option.h"
 
45
#include <mysys/my_getopt.h>
47
46
#ifdef HAVE_SYS_VADVISE_H
48
47
#include <sys/vadvise.h>
49
48
#endif
50
 
#ifdef HAVE_SYS_TYPES
51
 
#include <sys/types.h>
52
 
#endif
53
49
#ifdef HAVE_SYS_MMAN_H
54
50
#include <sys/mman.h>
55
51
#endif
56
 
#include <drizzled/util/test.h>
57
 
#include "drizzled/error.h"
58
 
 
59
 
#include <algorithm>
60
 
 
61
 
using namespace std;
62
 
using namespace drizzled;
63
 
using namespace drizzled::internal;
64
 
 
65
 
 
66
 
#define my_off_t2double(A)  ((double) (my_off_t) (A))
67
 
 
68
 
/* Functions defined in this file */
69
 
 
70
 
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint32_t nr);
 
52
 
 
53
#ifndef USE_RAID
 
54
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
 
55
#define my_raid_delete(A,B,C) my_delete(A,B)
 
56
#endif
 
57
 
 
58
        /* Functions defined in this file */
 
59
 
 
60
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr);
71
61
static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
72
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
73
 
                     ha_checksum *key_checksum, uint32_t level);
74
 
static uint32_t isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
 
62
                     my_off_t page, uchar *buff, ha_rows *keys,
 
63
                     ha_checksum *key_checksum, uint level);
 
64
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
75
65
static ha_checksum calc_checksum(ha_rows count);
76
66
static int writekeys(MI_SORT_PARAM *sort_param);
77
67
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
78
 
                          my_off_t pagepos, int new_file);
79
 
int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
80
 
int sort_get_next_record(MI_SORT_PARAM *sort_param);
81
 
int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
82
 
int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
83
 
my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
84
 
                            unsigned char *key);
85
 
int sort_insert_key(MI_SORT_PARAM  *sort_param,
86
 
                    register SORT_KEY_BLOCKS *key_block,
87
 
                    unsigned char *key, my_off_t prev_block);
88
 
int sort_delete_record(MI_SORT_PARAM *sort_param);
89
 
 
 
68
                          my_off_t pagepos, File new_file);
 
69
static int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
 
70
static int sort_get_next_record(MI_SORT_PARAM *sort_param);
 
71
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
 
72
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
 
73
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
 
74
                                uchar *key);
 
75
static int sort_insert_key(MI_SORT_PARAM  *sort_param,
 
76
                           register SORT_KEY_BLOCKS *key_block,
 
77
                           uchar *key, my_off_t prev_block);
 
78
static int sort_delete_record(MI_SORT_PARAM *sort_param);
90
79
/*static int flush_pending_blocks(MI_CHECK *param);*/
91
 
static SORT_KEY_BLOCKS  *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
92
 
                                          uint32_t buffer_length);
93
 
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length);
 
80
static SORT_KEY_BLOCKS  *alloc_key_blocks(MI_CHECK *param, uint blocks,
 
81
                                          uint buffer_length);
 
82
static ha_checksum mi_byte_checksum(const uchar *buf, uint length);
94
83
static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
95
84
 
96
85
void myisamchk_init(MI_CHECK *param)
128
117
  if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0))
129
118
  {
130
119
    /* Don't count this as a real warning, as check can correct this ! */
131
 
    uint32_t save=param->warning_printed;
 
120
    uint save=param->warning_printed;
132
121
    mi_check_print_warning(param,
133
 
                           share->state.open_count==1 ?
134
 
                           "%d client is using or hasn't closed the table properly" :
 
122
                           share->state.open_count==1 ? 
 
123
                           "%d client is using or hasn't closed the table properly" : 
135
124
                           "%d clients are using or haven't closed the table properly",
136
125
                           share->state.open_count);
137
126
    /* If this will be fixed by the check, forget the warning */
143
132
 
144
133
        /* Check delete links */
145
134
 
146
 
int chk_del(MI_CHECK *param, register MI_INFO *info, uint32_t test_flag)
 
135
int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
147
136
{
148
137
  register ha_rows i;
149
 
  uint32_t delete_link_length;
 
138
  uint delete_link_length;
150
139
  my_off_t empty, next_link, old_link= 0;
151
140
  char buff[22],buff2[22];
152
141
 
178
167
        printf(" %9s",llstr(next_link,buff));
179
168
      if (next_link >= info->state->data_file_length)
180
169
        goto wrong;
181
 
      if (my_pread(info->dfile, (unsigned char*) buff,delete_link_length,
 
170
      if (my_pread(info->dfile, (uchar*) buff,delete_link_length,
182
171
                   next_link,MYF(MY_NABP)))
183
172
      {
184
173
        if (test_flag & T_VERBOSE) puts("");
209
198
      else
210
199
      {
211
200
        param->record_checksum+=(ha_checksum) next_link;
212
 
        next_link=_mi_rec_pos(info->s,(unsigned char*) buff+1);
 
201
        next_link=_mi_rec_pos(info->s,(uchar*) buff+1);
213
202
        empty+=info->s->base.pack_reclength;
214
203
      }
215
204
    }
250
239
 
251
240
        /* Check delete links in index file */
252
241
 
253
 
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint32_t nr)
 
242
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
254
243
{
255
244
  my_off_t next_link;
256
 
  uint32_t block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
 
245
  uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
257
246
  ha_rows records;
258
247
  char llbuff[21], llbuff2[21];
259
 
  unsigned char *buff;
 
248
  uchar *buff;
260
249
 
261
250
  if (param->testflag & T_VERBOSE)
262
 
    printf("block_size %4u:", block_size);
 
251
    printf("block_size %4u:", block_size); /* purecov: tested */
263
252
 
264
253
  next_link=info->s->state.key_del[nr];
265
254
  records= (ha_rows) (info->state->key_file_length / block_size);
273
262
    /* Key blocks must lay within the key file length entirely. */
274
263
    if (next_link + block_size > info->state->key_file_length)
275
264
    {
 
265
      /* purecov: begin tested */
276
266
      mi_check_print_error(param, "Invalid key block position: %s  "
277
267
                           "key block size: %u  file_length: %s",
278
268
                           llstr(next_link, llbuff), block_size,
279
269
                           llstr(info->state->key_file_length, llbuff2));
280
270
      return(1);
 
271
      /* purecov: end */
281
272
    }
282
273
 
283
274
    /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */
284
275
    if (next_link & (MI_MIN_KEY_BLOCK_LENGTH - 1))
285
276
    {
 
277
      /* purecov: begin tested */
286
278
      mi_check_print_error(param, "Mis-aligned key block: %s  "
287
279
                           "minimum key block length: %u",
288
280
                           llstr(next_link, llbuff), MI_MIN_KEY_BLOCK_LENGTH);
289
281
      return(1);
 
282
      /* purecov: end */
290
283
    }
291
284
 
292
285
    /*
296
289
    */
297
290
    if (!(buff=key_cache_read(info->s->key_cache,
298
291
                              info->s->kfile, next_link, DFLT_INIT_HITS,
299
 
                              (unsigned char*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
 
292
                              (uchar*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
300
293
                              MI_MIN_KEY_BLOCK_LENGTH, 1)))
301
294
    {
 
295
      /* purecov: begin tested */
302
296
      mi_check_print_error(param, "key cache read error for block: %s",
303
297
                           llstr(next_link,llbuff));
304
298
      return(1);
 
299
      /* purecov: end */
305
300
    }
306
301
    next_link=mi_sizekorr(buff);
307
302
    records--;
332
327
  flush_key_blocks(info->s->key_cache,
333
328
                   info->s->kfile, FLUSH_FORCE_WRITE);
334
329
 
335
 
  size= lseek(info->s->kfile, 0, SEEK_END);
 
330
  size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
336
331
  if ((skr=(my_off_t) info->state->key_file_length) != size)
337
332
  {
338
333
    /* Don't give error if file generated by myisampack */
356
351
                           llstr(info->state->key_file_length,buff),
357
352
                           llstr(info->s->base.max_key_file_length-1,buff));
358
353
 
359
 
  size=lseek(info->dfile,0L,SEEK_END);
 
354
  size=my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
360
355
  skr=(my_off_t) info->state->data_file_length;
361
356
  if (info->s->options & HA_OPTION_COMPRESS_RECORD)
362
357
    skr+= MEMMAP_EXTRA_MARGIN;
397
392
 
398
393
int chk_key(MI_CHECK *param, register MI_INFO *info)
399
394
{
400
 
  uint32_t key,found_keys=0,full_text_keys=0,result=0;
 
395
  uint key,found_keys=0,full_text_keys=0,result=0;
401
396
  ha_rows keys;
402
397
  ha_checksum old_record_checksum,init_checksum;
403
398
  my_off_t all_keydata,all_totaldata,key_totlength,length;
445
440
    found_keys++;
446
441
 
447
442
    param->record_checksum=init_checksum;
448
 
 
 
443
    
449
444
    memset(&param->unique_count, 0, sizeof(param->unique_count));
450
445
    memset(&param->notnull_count, 0, sizeof(param->notnull_count));
451
446
 
525
520
      /* Check that there isn't a row with auto_increment = 0 in the table */
526
521
      mi_extra(info,HA_EXTRA_KEYREAD,0);
527
522
      memset(info->lastkey, 0, keyinfo->seg->length);
528
 
      if (!mi_rkey(info, info->rec_buff, key, (const unsigned char*) info->lastkey,
 
523
      if (!mi_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey,
529
524
                   (key_part_map)1, HA_READ_KEY_EXACT))
530
525
      {
531
526
        /* Don't count this as a real warning, as myisamchk can't correct it */
532
 
        uint32_t save=param->warning_printed;
 
527
        uint save=param->warning_printed;
533
528
        mi_check_print_warning(param, "Found row where the auto_increment "
534
529
                               "column has the value 0");
535
530
        param->warning_printed=save;
551
546
    if (param->testflag & T_STATISTICS)
552
547
      update_key_parts(keyinfo, rec_per_key_part, param->unique_count,
553
548
                       param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
554
 
                       param->notnull_count: NULL,
 
549
                       param->notnull_count: NULL, 
555
550
                       (uint64_t)info->state->records);
556
551
  }
557
552
  if (param->testflag & T_INFO)
578
573
 
579
574
 
580
575
static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
581
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
582
 
                     ha_checksum *key_checksum, uint32_t level)
 
576
                     my_off_t page, uchar *buff, ha_rows *keys,
 
577
                     ha_checksum *key_checksum, uint level)
583
578
{
584
579
  char llbuff[22],llbuff2[22];
585
580
 
586
581
  /* Key blocks must lay within the key file length entirely. */
587
582
  if (page + keyinfo->block_length > info->state->key_file_length)
588
583
  {
 
584
    /* purecov: begin tested */
589
585
    /* Give it a chance to fit in the real file size. */
590
 
    my_off_t max_length= lseek(info->s->kfile, 0, SEEK_END);
 
586
    my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END,
 
587
                                 MYF(MY_THREADSAFE));
591
588
    mi_check_print_error(param, "Invalid key block position: %s  "
592
589
                         "key block size: %u  file_length: %s",
593
590
                         llstr(page, llbuff), keyinfo->block_length,
597
594
    /* Fix the remebered key file length. */
598
595
    info->state->key_file_length= (max_length &
599
596
                                   ~ (my_off_t) (keyinfo->block_length - 1));
 
597
    /* purecov: end */
600
598
  }
601
599
 
602
600
  /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */
603
601
  if (page & (MI_MIN_KEY_BLOCK_LENGTH - 1))
604
602
  {
 
603
    /* purecov: begin tested */
605
604
    mi_check_print_error(param, "Mis-aligned key block: %s  "
606
605
                         "minimum key block length: %u",
607
606
                         llstr(page, llbuff), MI_MIN_KEY_BLOCK_LENGTH);
608
607
    goto err;
 
608
    /* purecov: end */
609
609
  }
610
610
 
611
611
  if (!_mi_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0))
620
620
 
621
621
  return(0);
622
622
 
 
623
  /* purecov: begin tested */
623
624
err:
624
625
  return(1);
 
626
  /* purecov: end */
625
627
}
626
628
 
627
629
 
642
644
 
643
645
static
644
646
void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, uint64_t *notnull,
645
 
                                    unsigned char *key)
 
647
                                    uchar *key)
646
648
{
647
 
  uint32_t first_null, kp;
 
649
  uint first_null, kp;
648
650
  first_null= ha_find_null(keyseg, key) - keyseg;
649
651
  /*
650
652
    All prefix tuples that don't include keypart_{first_null} are not-null
671
673
    1. Find out which prefix tuples of last_key don't contain NULLs, and
672
674
       update the array of notnull counters accordingly.
673
675
    2. Find the first keypart number where the prev_key and last_key tuples
674
 
       are different(A), or last_key has NULL value(B), and return it, so the
675
 
       caller can count number of unique tuples for each key prefix. We don't
676
 
       need (B) to be counted, and that is compensated back in
 
676
       are different(A), or last_key has NULL value(B), and return it, so the 
 
677
       caller can count number of unique tuples for each key prefix. We don't 
 
678
       need (B) to be counted, and that is compensated back in 
677
679
       update_key_parts().
678
680
 
679
681
  RETURN
682
684
 
683
685
static
684
686
int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, uint64_t *notnull,
685
 
                                  unsigned char *prev_key, unsigned char *last_key)
 
687
                                  uchar *prev_key, uchar *last_key)
686
688
{
687
 
  uint32_t diffs[2];
688
 
  uint32_t first_null_seg, kp;
 
689
  uint diffs[2];
 
690
  uint first_null_seg, kp;
689
691
  HA_KEYSEG *seg;
690
692
 
691
 
  /*
 
693
  /* 
692
694
     Find the first keypart where values are different or either of them is
693
695
     NULL. We get results in diffs array:
694
696
     diffs[0]= 1 + number of first different keypart
696
698
                      last_key that is NULL or different from corresponding
697
699
                      value in prev_key.
698
700
  */
699
 
  ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY,
 
701
  ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, 
700
702
             SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs);
701
703
  seg= keyseg + diffs[0] - 1;
702
704
 
705
707
  for (kp= 0; kp < first_null_seg; kp++)
706
708
    notnull[kp]++;
707
709
 
708
 
  /*
 
710
  /* 
709
711
    Return 1+ number of first key part where values differ. Don't care if
710
712
    these were NULLs and not .... We compensate for that in
711
713
    update_key_parts.
717
719
        /* Check if index is ok */
718
720
 
719
721
static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
720
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
721
 
                     ha_checksum *key_checksum, uint32_t level)
 
722
                     my_off_t page, uchar *buff, ha_rows *keys,
 
723
                     ha_checksum *key_checksum, uint level)
722
724
{
723
725
  int flag;
724
 
  uint32_t used_length,comp_flag,nod_flag,key_length=0;
725
 
  unsigned char key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
 
726
  uint used_length,comp_flag,nod_flag,key_length=0;
 
727
  uchar key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
726
728
  my_off_t next_page,record;
727
729
  char llbuff[22];
728
 
  uint32_t diff_pos[2];
 
730
  uint diff_pos[2];
729
731
 
730
 
  if (!(temp_buff=(unsigned char*) malloc(keyinfo->block_length)))
 
732
  if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
731
733
  {
732
734
    mi_check_print_error(param,"Not enough memory for keyblock");
733
735
    return(-1);
796
798
                     diff_pos);
797
799
        else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
798
800
        {
799
 
          diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg,
 
801
          diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg, 
800
802
                                                  param->notnull_count,
801
803
                                                  info->lastkey, key);
802
804
        }
803
805
        param->unique_count[diff_pos[0]-1]++;
804
806
      }
805
807
      else
806
 
      {
 
808
      {  
807
809
        if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
808
810
          mi_collect_stats_nonulls_first(keyinfo->seg, param->notnull_count,
809
811
                                         key);
810
812
      }
811
813
    }
812
 
    (*key_checksum)+= mi_byte_checksum((unsigned char*) key,
 
814
    (*key_checksum)+= mi_byte_checksum((uchar*) key,
813
815
                                       key_length- info->s->rec_reflength);
814
816
    record= _mi_dpos(info,0,key+key_length);
815
817
    if (record >= info->state->data_file_length)
825
827
                llstr(page,llbuff), used_length, (keypos - buff));
826
828
    goto err;
827
829
  }
828
 
  free(temp_buff);
 
830
  my_afree((uchar*) temp_buff);
829
831
  return(0);
830
832
 err:
831
 
  free(temp_buff);
 
833
  my_afree((uchar*) temp_buff);
832
834
  return(1);
833
835
} /* chk_index */
834
836
 
857
859
 
858
860
        /* Calc length of key in normal isam */
859
861
 
860
 
static uint32_t isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
 
862
static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
861
863
{
862
 
  uint32_t length;
 
864
  uint length;
863
865
  HA_KEYSEG *keyseg;
864
866
 
865
867
  length= info->s->rec_reflength;
879
881
  ha_rows records, del_blocks;
880
882
  my_off_t used, empty, pos, splits, start_recpos= 0,
881
883
           del_length, link_used, start_block;
882
 
  unsigned char *record= NULL, *to= NULL;
 
884
  uchar *record= NULL, *to= NULL;
883
885
  char llbuff[22],llbuff2[22],llbuff3[22];
884
886
  ha_checksum intern_record_checksum;
885
887
  ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY];
929
931
      goto err2;
930
932
    switch (info->s->data_file_type) {
931
933
    case STATIC_RECORD:
932
 
      if (my_b_read(&param->read_cache,(unsigned char*) record,
 
934
      if (my_b_read(&param->read_cache,(uchar*) record,
933
935
                    info->s->base.pack_reclength))
934
936
        goto err;
935
937
      start_recpos=pos;
949
951
      block_info.next_filepos=pos;
950
952
      do
951
953
      {
952
 
        if (_mi_read_cache(&param->read_cache,(unsigned char*) block_info.header,
 
954
        if (_mi_read_cache(&param->read_cache,(uchar*) block_info.header,
953
955
                           (start_block=block_info.next_filepos),
954
956
                           sizeof(block_info.header),
955
957
                           (flag ? 0 : READING_NEXT) | READING_HEADER))
1053
1055
          got_error=1;
1054
1056
          break;
1055
1057
        }
1056
 
        if (_mi_read_cache(&param->read_cache,(unsigned char*) to,block_info.filepos,
 
1058
        if (_mi_read_cache(&param->read_cache,(uchar*) to,block_info.filepos,
1057
1059
                           (uint) block_info.data_len,
1058
1060
                           flag == 1 ? READING_NEXT : 0))
1059
1061
          goto err;
1123
1125
      records++;
1124
1126
      if (param->testflag & T_WRITE_LOOP && records % WRITE_COUNT == 0)
1125
1127
      {
1126
 
        printf("%s\r", llstr(records,llbuff)); fflush(stdout);
 
1128
        printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout));
1127
1129
      }
1128
1130
 
1129
1131
      /* Check if keys match the record */
1134
1136
        if (mi_is_key_active(info->s->state.key_map, key))
1135
1137
        {
1136
1138
          {
1137
 
            uint32_t key_length=_mi_make_key(info,key,info->lastkey,record,
 
1139
            uint key_length=_mi_make_key(info,key,info->lastkey,record,
1138
1140
                                         start_recpos);
1139
1141
            if (extend)
1140
1142
            {
1154
1156
              }
1155
1157
            }
1156
1158
            else
1157
 
              key_checksum[key]+=mi_byte_checksum((unsigned char*) info->lastkey,
 
1159
              key_checksum[key]+=mi_byte_checksum((uchar*) info->lastkey,
1158
1160
                                                  key_length);
1159
1161
          }
1160
1162
        }
1170
1172
  }
1171
1173
  if (param->testflag & T_WRITE_LOOP)
1172
1174
  {
1173
 
    fputs("          \r",stdout); fflush(stdout);
 
1175
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1174
1176
  }
1175
1177
  if (records != info->state->records)
1176
1178
  {
1187
1189
  }
1188
1190
  else if (param->glob_crc != info->state->checksum &&
1189
1191
           (info->s->options &
1190
 
            (HA_OPTION_COMPRESS_RECORD)))
 
1192
            (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
1191
1193
  {
1192
1194
    mi_check_print_warning(param,
1193
1195
                           "Record checksum is not the same as checksum stored in the index file\n");
1263
1265
    printf("Lost space:   %12s    Linkdata:     %10s\n",
1264
1266
           llstr(empty,llbuff),llstr(link_used,llbuff2));
1265
1267
  }
1266
 
  free(mi_get_rec_buff_ptr(info, record));
 
1268
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1267
1269
  return (error);
1268
1270
 err:
1269
 
  mi_check_print_error(param,"got error: %d when reading datafile at record: %s",errno, llstr(records,llbuff));
 
1271
  mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
1270
1272
 err2:
1271
 
  free(mi_get_rec_buff_ptr(info, record));
 
1273
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1272
1274
  param->testflag|=T_RETRY_WITHOUT_QUICK;
1273
1275
  return(1);
1274
1276
} /* chk_data_link */
1314
1316
 
1315
1317
    However, there is an exception. Sometimes MySQL disables non-unique
1316
1318
    indexes when the table is empty (e.g. when copying a table in
1317
 
    drizzled::alter_table()). When enabling the non-unique indexes, they
 
1319
    mysql_alter_table()). When enabling the non-unique indexes, they
1318
1320
    are still empty. So there is no index block that can be lost. This
1319
1321
    optimization is implemented in this function.
1320
1322
 
1331
1333
{
1332
1334
  MYISAM_SHARE *share= info->s;
1333
1335
  MI_STATE_INFO *state= &share->state;
1334
 
  uint32_t i;
 
1336
  uint i;
1335
1337
  int error;
1336
1338
 
1337
1339
  /*
1378
1380
  /* Remove all key blocks of this index file from key cache. */
1379
1381
  if ((error= flush_key_blocks(share->key_cache, share->kfile,
1380
1382
                               FLUSH_IGNORE_CHANGED)))
1381
 
    goto end;
 
1383
    goto end; /* purecov: inspected */
1382
1384
 
1383
1385
  /* Clear index root block pointers. */
1384
1386
  for (i= 0; i < share->base.keys; i++)
1407
1409
  int error,got_error;
1408
1410
  ha_rows start_records,new_header_length;
1409
1411
  my_off_t del;
1410
 
  int new_file;
 
1412
  File new_file;
1411
1413
  MYISAM_SHARE *share=info->s;
1412
1414
  char llbuff[22],llbuff2[22];
1413
1415
  SORT_INFO sort_info;
1429
1431
  }
1430
1432
  param->testflag|=T_REP; /* for easy checking */
1431
1433
 
1432
 
  if (info->s->options & (HA_OPTION_COMPRESS_RECORD))
 
1434
  if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
1433
1435
    param->testflag|=T_CALC_CHECKSUM;
1434
1436
 
1435
1437
  if (!param->using_global_keycache)
1436
 
    init_key_cache(dflt_key_cache, param->key_cache_block_size,
1437
 
                   (size_t)param->use_buffers, 0, 0);
 
1438
    VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
 
1439
                        param->use_buffers, 0, 0));
1438
1440
 
1439
1441
  if (init_io_cache(&param->read_cache,info->dfile,
1440
1442
                    (uint) param->read_buffer_length,
1459
1461
  if (!rep_quick)
1460
1462
  {
1461
1463
    /* Get real path for data file */
1462
 
    if ((new_file=my_create(internal::fn_format(param->temp_filename,
1463
 
                                      share->data_file_name, "",
1464
 
                                      DATA_TMP_EXT, 2+4),
1465
 
                            0,param->tmpfile_createflag,
1466
 
                            MYF(0))) < 0)
 
1464
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
1465
                                           share->data_file_name, "",
 
1466
                                           DATA_TMP_EXT, 2+4),
 
1467
                                 0,param->tmpfile_createflag,
 
1468
                                 share->base.raid_type,
 
1469
                                 share->base.raid_chunks,
 
1470
                                 share->base.raid_chunksize,
 
1471
                                 MYF(0))) < 0)
1467
1472
    {
1468
1473
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
1469
 
                           param->temp_filename);
 
1474
                           param->temp_filename);
1470
1475
      goto err;
1471
1476
    }
1472
1477
    if (new_header_length &&
1473
1478
        filecopy(param,new_file,info->dfile,0L,new_header_length,
1474
 
                 "datafile-header"))
 
1479
                 "datafile-header"))
1475
1480
      goto err;
1476
1481
    info->s->state.dellink= HA_OFFSET_ERROR;
1477
1482
    info->rec_cache.file=new_file;
1487
1492
  sort_param.pos=sort_param.max_pos=share->pack.header_length;
1488
1493
  sort_param.filepos=new_header_length;
1489
1494
  param->read_cache.end_of_file=sort_info.filelength=
1490
 
    lseek(info->dfile,0L,SEEK_END);
 
1495
    my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
1491
1496
  sort_info.dupp=0;
1492
1497
  sort_param.fix_datafile= (bool) (! rep_quick);
1493
1498
  sort_param.master=1;
1515
1520
  {
1516
1521
    if (writekeys(&sort_param))
1517
1522
    {
1518
 
      if (errno != HA_ERR_FOUND_DUPP_KEY)
 
1523
      if (my_errno != HA_ERR_FOUND_DUPP_KEY)
1519
1524
        goto err;
1520
1525
      mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
1521
1526
                          info->errkey+1,
1523
1528
                          llstr(info->dupp_key_pos,llbuff2));
1524
1529
      if (param->testflag & T_VERBOSE)
1525
1530
      {
1526
 
        _mi_make_key(info,(uint) info->errkey,info->lastkey,
1527
 
                     sort_param.record,0L);
 
1531
        VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
 
1532
                          sort_param.record,0L));
1528
1533
      }
1529
1534
      sort_info.dupp++;
1530
1535
      if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
1544
1549
 
1545
1550
  if (param->testflag & T_WRITE_LOOP)
1546
1551
  {
1547
 
    fputs("          \r",stdout); fflush(stdout);
 
1552
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1548
1553
  }
1549
1554
  if (ftruncate(share->kfile, info->state->key_file_length))
1550
1555
  {
1551
1556
    mi_check_print_warning(param,
1552
1557
                           "Can't change size of indexfile, error: %d",
1553
 
                           errno);
 
1558
                           my_errno);
1554
1559
    goto err;
1555
1560
  }
1556
1561
 
1576
1581
 
1577
1582
  if (!rep_quick)
1578
1583
  {
1579
 
    internal::my_close(info->dfile,MYF(0));
 
1584
    my_close(info->dfile,MYF(0));
1580
1585
    info->dfile=new_file;
1581
1586
    info->state->data_file_length=sort_param.filepos;
1582
1587
    share->state.version=(ulong) time((time_t*) 0);     /* Force reopen */
1609
1614
    /* Replace the actual file with the temporary file */
1610
1615
    if (new_file >= 0)
1611
1616
    {
1612
 
      internal::my_close(new_file,MYF(0));
 
1617
      my_close(new_file,MYF(0));
1613
1618
      info->dfile=new_file= -1;
1614
1619
      if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
1615
1620
                            DATA_TMP_EXT, share->base.raid_chunks,
1622
1627
  if (got_error)
1623
1628
  {
1624
1629
    if (! param->error_printed)
1625
 
      mi_check_print_error(param,"%d for record at pos %s",errno,
 
1630
      mi_check_print_error(param,"%d for record at pos %s",my_errno,
1626
1631
                  llstr(sort_param.start_recpos,llbuff));
1627
1632
    if (new_file >= 0)
1628
1633
    {
1629
 
      internal::my_close(new_file,MYF(0));
1630
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
1634
      VOID(my_close(new_file,MYF(0)));
 
1635
      VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
 
1636
                          MYF(MY_WME)));
1631
1637
      info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
1632
1638
    }
1633
1639
    mi_mark_crashed_on_repair(info);
1634
1640
  }
1635
 
 
1636
 
  void * rec_buff_ptr= NULL;
1637
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
1638
 
  if (rec_buff_ptr != NULL)
1639
 
    free(rec_buff_ptr);
1640
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1641
 
  if (rec_buff_ptr != NULL)
1642
 
    free(rec_buff_ptr);
1643
 
  rec_buff_ptr= NULL;
1644
 
 
1645
 
  free(sort_info.buff);
1646
 
  end_io_cache(&param->read_cache);
 
1641
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
1642
                            MYF(MY_ALLOW_ZERO_PTR));
 
1643
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
1644
          MYF(MY_ALLOW_ZERO_PTR));
 
1645
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
1646
  VOID(end_io_cache(&param->read_cache));
1647
1647
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1648
 
  end_io_cache(&info->rec_cache);
 
1648
  VOID(end_io_cache(&info->rec_cache));
1649
1649
  got_error|=flush_blocks(param, share->key_cache, share->kfile);
1650
1650
  if (!got_error && param->testflag & T_UNPACK)
1651
1651
  {
1652
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
1652
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
1653
1653
    share->pack.header_length=0;
1654
1654
    share->data_file_type=sort_info.new_data_file_type;
1655
1655
  }
1663
1663
 
1664
1664
static int writekeys(MI_SORT_PARAM *sort_param)
1665
1665
{
1666
 
  register uint32_t i;
1667
 
  unsigned char    *key;
 
1666
  register uint i;
 
1667
  uchar    *key;
1668
1668
  MI_INFO  *info=   sort_param->sort_info->info;
1669
 
  unsigned char    *buff=   sort_param->record;
 
1669
  uchar    *buff=   sort_param->record;
1670
1670
  my_off_t filepos= sort_param->filepos;
1671
1671
 
1672
1672
  key=info->lastkey+info->s->base.max_key_length;
1675
1675
    if (mi_is_key_active(info->s->state.key_map, i))
1676
1676
    {
1677
1677
      {
1678
 
        uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1678
        uint key_length=_mi_make_key(info,i,key,buff,filepos);
1679
1679
        if (_mi_ck_write(info,i,key,key_length))
1680
1680
          goto err;
1681
1681
      }
1684
1684
  return(0);
1685
1685
 
1686
1686
 err:
1687
 
  if (errno == HA_ERR_FOUND_DUPP_KEY)
 
1687
  if (my_errno == HA_ERR_FOUND_DUPP_KEY)
1688
1688
  {
1689
1689
    info->errkey=(int) i;                       /* This key was found */
1690
1690
    while ( i-- > 0 )
1692
1692
      if (mi_is_key_active(info->s->state.key_map, i))
1693
1693
      {
1694
1694
        {
1695
 
          uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1695
          uint key_length=_mi_make_key(info,i,key,buff,filepos);
1696
1696
          if (_mi_ck_delete(info,i,key,key_length))
1697
1697
            break;
1698
1698
        }
1708
1708
 
1709
1709
        /* Change all key-pointers that points to a records */
1710
1710
 
1711
 
int movepoint(register MI_INFO *info, unsigned char *record, my_off_t oldpos,
1712
 
              my_off_t newpos, uint32_t prot_key)
 
1711
int movepoint(register MI_INFO *info, uchar *record, my_off_t oldpos,
 
1712
              my_off_t newpos, uint prot_key)
1713
1713
{
1714
 
  register uint32_t i;
1715
 
  unsigned char *key;
1716
 
  uint32_t key_length;
 
1714
  register uint i;
 
1715
  uchar *key;
 
1716
  uint key_length;
1717
1717
 
1718
1718
  key=info->lastkey+info->s->base.max_key_length;
1719
1719
  for (i=0 ; i < info->s->base.keys; i++)
1723
1723
      key_length=_mi_make_key(info,i,key,record,oldpos);
1724
1724
      if (info->s->keyinfo[i].flag & HA_NOSAME)
1725
1725
      {                                 /* Change pointer direct */
1726
 
        uint32_t nod_flag;
 
1726
        uint nod_flag;
1727
1727
        MI_KEYDEF *keyinfo;
1728
1728
        keyinfo=info->s->keyinfo+i;
1729
1729
        if (_mi_search(info,keyinfo,key,USE_WHOLE_KEY,
1753
1753
 
1754
1754
        /* Tell system that we want all memory for our cache */
1755
1755
 
1756
 
void lock_memory(MI_CHECK *)
 
1756
void lock_memory(MI_CHECK *param __attribute__((unused)))
1757
1757
{
 
1758
#ifdef SUN_OS                           /* Key-cacheing thrases on sun 4.1 */
 
1759
  if (param->opt_lock_memory)
 
1760
  {
 
1761
    int success = mlockall(MCL_CURRENT);        /* or plock(DATLOCK); */
 
1762
    if (geteuid() == 0 && success != 0)
 
1763
      mi_check_print_warning(param,
 
1764
                             "Failed to lock memory. errno %d",my_errno);
 
1765
  }
 
1766
#endif
1758
1767
} /* lock_memory */
1759
1768
 
1760
1769
 
1761
1770
        /* Flush all changed blocks to disk */
1762
1771
 
1763
 
int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, int file)
 
1772
int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file)
1764
1773
{
1765
1774
  if (flush_key_blocks(key_cache, file, FLUSH_RELEASE))
1766
1775
  {
1767
 
    mi_check_print_error(param,"%d when trying to write bufferts",errno);
 
1776
    mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
1768
1777
    return(1);
1769
1778
  }
1770
1779
  if (!param->using_global_keycache)
1777
1786
 
1778
1787
int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name)
1779
1788
{
1780
 
  register uint32_t key;
 
1789
  register uint key;
1781
1790
  register MI_KEYDEF *keyinfo;
1782
 
  int new_file;
 
1791
  File new_file;
1783
1792
  my_off_t index_pos[HA_MAX_POSSIBLE_KEY];
1784
 
  uint32_t r_locks,w_locks;
 
1793
  uint r_locks,w_locks;
1785
1794
  int old_lock;
1786
1795
  MYISAM_SHARE *share=info->s;
1787
1796
  MI_STATE_INFO old_state;
1794
1803
    printf("- Sorting index for MyISAM-table '%s'\n",name);
1795
1804
 
1796
1805
  /* Get real path for index file */
1797
 
  internal::fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32);
1798
 
  if ((new_file=my_create(internal::fn_format(param->temp_filename,param->temp_filename,
 
1806
  fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32);
 
1807
  if ((new_file=my_create(fn_format(param->temp_filename,param->temp_filename,
1799
1808
                                    "", INDEX_TMP_EXT,2+4),
1800
1809
                          0,param->tmpfile_createflag,MYF(0))) <= 0)
1801
1810
  {
1837
1846
        /* Put same locks as old file */
1838
1847
  share->r_locks= share->w_locks= share->tot_locks= 0;
1839
1848
  (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
1840
 
  internal::my_close(share->kfile,MYF(MY_WME));
 
1849
  VOID(my_close(share->kfile,MYF(MY_WME)));
1841
1850
  share->kfile = -1;
1842
 
  internal::my_close(new_file,MYF(MY_WME));
 
1851
  VOID(my_close(new_file,MYF(MY_WME)));
1843
1852
  if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
1844
1853
                        MYF(0)) ||
1845
1854
      mi_open_keyfile(share))
1863
1872
  return(0);
1864
1873
 
1865
1874
err:
1866
 
  internal::my_close(new_file,MYF(MY_WME));
 
1875
  VOID(my_close(new_file,MYF(MY_WME)));
1867
1876
err2:
1868
 
  my_delete(param->temp_filename,MYF(MY_WME));
 
1877
  VOID(my_delete(param->temp_filename,MYF(MY_WME)));
1869
1878
  return(-1);
1870
1879
} /* mi_sort_index */
1871
1880
 
1873
1882
         /* Sort records recursive using one index */
1874
1883
 
1875
1884
static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
1876
 
                          my_off_t pagepos, int new_file)
 
1885
                          my_off_t pagepos, File new_file)
1877
1886
{
1878
 
  uint32_t length,nod_flag,used_length, key_length;
1879
 
  unsigned char *buff,*keypos,*endpos;
1880
 
  unsigned char key[HA_MAX_POSSIBLE_KEY_BUFF];
 
1887
  uint length,nod_flag,used_length, key_length;
 
1888
  uchar *buff,*keypos,*endpos;
 
1889
  uchar key[HA_MAX_POSSIBLE_KEY_BUFF];
1881
1890
  my_off_t new_page_pos,next_page;
1882
1891
  char llbuff[22];
1883
1892
 
1884
1893
  new_page_pos=param->new_file_pos;
1885
1894
  param->new_file_pos+=keyinfo->block_length;
1886
1895
 
1887
 
  if (!(buff=(unsigned char*) malloc(keyinfo->block_length)))
 
1896
  if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
1888
1897
  {
1889
1898
    mi_check_print_error(param,"Not enough memory for key block");
1890
1899
    return(-1);
1921
1930
  /* Fill block with zero and write it to the new index file */
1922
1931
  length=mi_getint(buff);
1923
1932
  memset(buff+length, 0, keyinfo->block_length-length);
1924
 
  if (my_pwrite(new_file,(unsigned char*) buff,(uint) keyinfo->block_length,
 
1933
  if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
1925
1934
                new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
1926
1935
  {
1927
 
    mi_check_print_error(param,"Can't write indexblock, error: %d",errno);
 
1936
    mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
1928
1937
    goto err;
1929
1938
  }
1930
 
  free(buff);
 
1939
  my_afree((uchar*) buff);
1931
1940
  return(0);
1932
1941
err:
1933
 
  free(buff);
 
1942
  my_afree((uchar*) buff);
1934
1943
  return(1);
1935
1944
} /* sort_one_index */
1936
1945
 
1946
1955
 
1947
1956
int change_to_newfile(const char * filename, const char * old_ext,
1948
1957
                      const char * new_ext,
1949
 
                      uint32_t raid_chunks,
 
1958
                      uint raid_chunks __attribute__((unused)),
1950
1959
                      myf MyFlags)
1951
1960
{
1952
 
  (void)raid_chunks;
1953
1961
  char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
1954
1962
  /* Get real path to filename */
1955
 
  (void) internal::fn_format(old_filename,filename,"",old_ext,2+4+32);
 
1963
  (void) fn_format(old_filename,filename,"",old_ext,2+4+32);
1956
1964
  return my_redel(old_filename,
1957
 
                  internal::fn_format(new_filename,old_filename,"",new_ext,2+4),
 
1965
                  fn_format(new_filename,old_filename,"",new_ext,2+4),
1958
1966
                  MYF(MY_WME | MY_LINK_WARNING | MyFlags));
1959
1967
} /* change_to_newfile */
1960
1968
 
1962
1970
 
1963
1971
        /* Copy a block between two files */
1964
1972
 
1965
 
int filecopy(MI_CHECK *param, int to,int from,my_off_t start,
 
1973
int filecopy(MI_CHECK *param, File to,File from,my_off_t start,
1966
1974
             my_off_t length, const char *type)
1967
1975
{
1968
1976
  char tmp_buff[IO_SIZE],*buff;
1969
1977
  ulong buff_length;
1970
1978
 
1971
 
  buff_length=(ulong) min(param->write_buffer_length, (size_t)length);
1972
 
  if (!(buff=(char *)malloc(buff_length)))
 
1979
  buff_length=(ulong) min(param->write_buffer_length,length);
 
1980
  if (!(buff=my_malloc(buff_length,MYF(0))))
1973
1981
  {
1974
1982
    buff=tmp_buff; buff_length=IO_SIZE;
1975
1983
  }
1976
1984
 
1977
 
  lseek(from,start,SEEK_SET);
 
1985
  VOID(my_seek(from,start,MY_SEEK_SET,MYF(0)));
1978
1986
  while (length > buff_length)
1979
1987
  {
1980
 
    if (my_read(from,(unsigned char*) buff,buff_length,MYF(MY_NABP)) ||
1981
 
        my_write(to,(unsigned char*) buff,buff_length,param->myf_rw))
 
1988
    if (my_read(from,(uchar*) buff,buff_length,MYF(MY_NABP)) ||
 
1989
        my_write(to,(uchar*) buff,buff_length,param->myf_rw))
1982
1990
      goto err;
1983
1991
    length-= buff_length;
1984
1992
  }
1985
 
  if (my_read(from,(unsigned char*) buff,(uint) length,MYF(MY_NABP)) ||
1986
 
      my_write(to,(unsigned char*) buff,(uint) length,param->myf_rw))
 
1993
  if (my_read(from,(uchar*) buff,(uint) length,MYF(MY_NABP)) ||
 
1994
      my_write(to,(uchar*) buff,(uint) length,param->myf_rw))
1987
1995
    goto err;
1988
1996
  if (buff != tmp_buff)
1989
 
    free(buff);
 
1997
    my_free(buff,MYF(0));
1990
1998
  return(0);
1991
1999
err:
1992
2000
  if (buff != tmp_buff)
1993
 
    free(buff);
 
2001
    my_free(buff,MYF(0));
1994
2002
  mi_check_print_error(param,"Can't copy %s to tempfile, error %d",
1995
 
                       type,errno);
 
2003
                       type,my_errno);
1996
2004
  return(1);
1997
2005
}
1998
2006
 
2016
2024
                      const char * name, int rep_quick)
2017
2025
{
2018
2026
  int got_error;
2019
 
  uint32_t i;
 
2027
  uint i;
2020
2028
  ulong length;
2021
2029
  ha_rows start_records;
2022
2030
  my_off_t new_header_length,del;
2023
 
  int new_file;
 
2031
  File new_file;
2024
2032
  MI_SORT_PARAM sort_param;
2025
2033
  MYISAM_SHARE *share=info->s;
2026
2034
  HA_KEYSEG *keyseg;
2041
2049
  }
2042
2050
  param->testflag|=T_REP; /* for easy checking */
2043
2051
 
2044
 
  if (info->s->options & (HA_OPTION_COMPRESS_RECORD))
 
2052
  if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
2045
2053
    param->testflag|=T_CALC_CHECKSUM;
2046
2054
 
2047
2055
  memset(&sort_info, 0, sizeof(sort_info));
2072
2080
  if (!rep_quick)
2073
2081
  {
2074
2082
    /* Get real path for data file */
2075
 
    if ((new_file=my_create(internal::fn_format(param->temp_filename,
2076
 
                                      share->data_file_name, "",
2077
 
                                      DATA_TMP_EXT, 2+4),
2078
 
                            0,param->tmpfile_createflag,
2079
 
                            MYF(0))) < 0)
 
2083
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2084
                                           share->data_file_name, "",
 
2085
                                           DATA_TMP_EXT, 2+4),
 
2086
                                 0,param->tmpfile_createflag,
 
2087
                                 share->base.raid_type,
 
2088
                                 share->base.raid_chunks,
 
2089
                                 share->base.raid_chunksize,
 
2090
                                 MYF(0))) < 0)
2080
2091
    {
2081
2092
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2082
 
                           param->temp_filename);
 
2093
                           param->temp_filename);
2083
2094
      goto err;
2084
2095
    }
2085
2096
    if (new_header_length &&
2114
2125
  sort_info.dupp=0;
2115
2126
  sort_info.buff=0;
2116
2127
  param->read_cache.end_of_file=sort_info.filelength=
2117
 
    lseek(param->read_cache.file,0L,SEEK_END);
 
2128
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2118
2129
 
2119
2130
  sort_param.wordlist=NULL;
2120
2131
 
2129
2140
     (ha_rows) (sort_info.filelength/length+1));
2130
2141
  sort_param.key_cmp=sort_key_cmp;
2131
2142
  sort_param.lock_in_memory=lock_memory;
 
2143
  sort_param.tmpdir=param->tmpdir;
2132
2144
  sort_param.sort_info=&sort_info;
2133
2145
  sort_param.fix_datafile= (bool) (! rep_quick);
2134
2146
  sort_param.master =1;
2135
 
 
 
2147
  
2136
2148
  del=info->state->del;
2137
2149
  param->glob_crc=0;
2138
2150
  if (param->testflag & T_CALC_CHECKSUM)
2224
2236
        sort_param.filepos;
2225
2237
      /* Only whole records */
2226
2238
      share->state.version=(ulong) time((time_t*) 0);
2227
 
      internal::my_close(info->dfile,MYF(0));
 
2239
      my_close(info->dfile,MYF(0));
2228
2240
      info->dfile=new_file;
2229
2241
      share->data_file_type=sort_info.new_data_file_type;
2230
2242
      share->pack.header_length=(ulong) new_header_length;
2240
2252
 
2241
2253
  if (param->testflag & T_WRITE_LOOP)
2242
2254
  {
2243
 
    fputs("          \r",stdout); fflush(stdout);
 
2255
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
2244
2256
  }
2245
2257
 
2246
2258
  if (rep_quick && del+sort_info.dupp != info->state->del)
2267
2279
      if (ftruncate(info->dfile, skr))
2268
2280
        mi_check_print_warning(param,
2269
2281
                               "Can't change size of datafile,  error: %d",
2270
 
                               errno);
 
2282
                               my_errno);
2271
2283
  }
2272
2284
  if (param->testflag & T_CALC_CHECKSUM)
2273
2285
    info->state->checksum=param->glob_crc;
2275
2287
  if (ftruncate(share->kfile, info->state->key_file_length))
2276
2288
    mi_check_print_warning(param,
2277
2289
                           "Can't change size of indexfile, error: %d",
2278
 
                           errno);
 
2290
                           my_errno);
2279
2291
 
2280
2292
  if (!(param->testflag & T_SILENT))
2281
2293
  {
2293
2305
 
2294
2306
err:
2295
2307
  got_error|= flush_blocks(param, share->key_cache, share->kfile);
2296
 
  end_io_cache(&info->rec_cache);
 
2308
  VOID(end_io_cache(&info->rec_cache));
2297
2309
  if (!got_error)
2298
2310
  {
2299
2311
    /* Replace the actual file with the temporary file */
2300
2312
    if (new_file >= 0)
2301
2313
    {
2302
 
      internal::my_close(new_file,MYF(0));
 
2314
      my_close(new_file,MYF(0));
2303
2315
      info->dfile=new_file= -1;
2304
2316
      if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
2305
2317
                            DATA_TMP_EXT, share->base.raid_chunks,
2312
2324
  if (got_error)
2313
2325
  {
2314
2326
    if (! param->error_printed)
2315
 
      mi_check_print_error(param,"%d when fixing table",errno);
 
2327
      mi_check_print_error(param,"%d when fixing table",my_errno);
2316
2328
    if (new_file >= 0)
2317
2329
    {
2318
 
      internal::my_close(new_file,MYF(0));
2319
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2330
      VOID(my_close(new_file,MYF(0)));
 
2331
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2332
                          MYF(MY_WME)));
2320
2333
      if (info->dfile == new_file)
2321
 
        info->dfile= -1;
 
2334
        info->dfile= -1;
2322
2335
    }
2323
2336
    mi_mark_crashed_on_repair(info);
2324
2337
  }
2326
2339
    share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
2327
2340
  share->state.changed|=STATE_NOT_SORTED_PAGES;
2328
2341
 
2329
 
  void * rec_buff_ptr= NULL;
2330
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
2331
 
  if (rec_buff_ptr != NULL)
2332
 
    free(rec_buff_ptr);
2333
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
2334
 
  if (rec_buff_ptr != NULL)
2335
 
    free(rec_buff_ptr);
2336
 
  rec_buff_ptr= NULL;
2337
 
 
2338
 
  free((unsigned char*) sort_info.key_block);
2339
 
  free(sort_info.buff);
2340
 
  end_io_cache(&param->read_cache);
 
2342
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
2343
                            MYF(MY_ALLOW_ZERO_PTR));
 
2344
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
2345
          MYF(MY_ALLOW_ZERO_PTR));
 
2346
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2347
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2348
  VOID(end_io_cache(&param->read_cache));
2341
2349
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2342
2350
  if (!got_error && (param->testflag & T_UNPACK))
2343
2351
  {
2344
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2352
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2345
2353
    share->pack.header_length=0;
2346
2354
  }
2347
2355
  return(got_error);
2393
2401
                        const char * name, int rep_quick)
2394
2402
{
2395
2403
  int got_error;
2396
 
  uint32_t i,key, total_key_length, istep;
 
2404
  uint i,key, total_key_length, istep;
2397
2405
  ulong rec_length;
2398
2406
  ha_rows start_records;
2399
2407
  my_off_t new_header_length,del;
2400
 
  int new_file;
 
2408
  File new_file;
2401
2409
  MI_SORT_PARAM *sort_param=0;
2402
2410
  MYISAM_SHARE *share=info->s;
2403
2411
  ulong   *rec_per_key_part;
2422
2430
  }
2423
2431
  param->testflag|=T_REP; /* for easy checking */
2424
2432
 
2425
 
  if (info->s->options & (HA_OPTION_COMPRESS_RECORD))
 
2433
  if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
2426
2434
    param->testflag|=T_CALC_CHECKSUM;
2427
2435
 
2428
2436
  /*
2481
2489
  if (!rep_quick)
2482
2490
  {
2483
2491
    /* Get real path for data file */
2484
 
    if ((new_file=my_create(internal::fn_format(param->temp_filename,
2485
 
                                      share->data_file_name, "",
2486
 
                                      DATA_TMP_EXT,
2487
 
                                      2+4),
2488
 
                            0,param->tmpfile_createflag,
2489
 
                            MYF(0))) < 0)
 
2492
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2493
                                           share->data_file_name, "",
 
2494
                                           DATA_TMP_EXT,
 
2495
                                           2+4),
 
2496
                                 0,param->tmpfile_createflag,
 
2497
                                 share->base.raid_type,
 
2498
                                 share->base.raid_chunks,
 
2499
                                 share->base.raid_chunksize,
 
2500
                                 MYF(0))) < 0)
2490
2501
    {
2491
2502
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2492
2503
                           param->temp_filename);
2523
2534
  sort_info.dupp=0;
2524
2535
  sort_info.buff=0;
2525
2536
  param->read_cache.end_of_file=sort_info.filelength=
2526
 
    lseek(param->read_cache.file,0L,SEEK_END);
 
2537
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2527
2538
 
2528
2539
  if (share->data_file_type == DYNAMIC_RECORD)
2529
2540
    rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
2554
2565
  if (share->options & HA_OPTION_COMPRESS_RECORD)
2555
2566
    set_if_bigger(max_pack_reclength, share->max_pack_length);
2556
2567
  if (!(sort_param=(MI_SORT_PARAM *)
2557
 
        malloc(share->base.keys *
2558
 
               (sizeof(MI_SORT_PARAM) + max_pack_reclength))))
 
2568
        my_malloc((uint) share->base.keys *
 
2569
                  (sizeof(MI_SORT_PARAM) + max_pack_reclength),
 
2570
                  MYF(MY_ZEROFILL))))
2559
2571
  {
2560
2572
    mi_check_print_error(param,"Not enough memory for key!");
2561
2573
    goto err;
2562
2574
  }
2563
 
  memset(sort_param, 0, share->base.keys *
2564
 
                        (sizeof(MI_SORT_PARAM) + max_pack_reclength));
2565
2575
  total_key_length=0;
2566
2576
  rec_per_key_part= param->rec_per_key_part;
2567
2577
  info->state->records=info->state->del=share->state.split=0;
2597
2607
    }
2598
2608
    sort_param[i].key_cmp=sort_key_cmp;
2599
2609
    sort_param[i].lock_in_memory=lock_memory;
 
2610
    sort_param[i].tmpdir=param->tmpdir;
2600
2611
    sort_param[i].sort_info=&sort_info;
2601
2612
    sort_param[i].master=0;
2602
2613
    sort_param[i].fix_datafile=0;
2605
2616
    sort_param[i].filepos=new_header_length;
2606
2617
    sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
2607
2618
 
2608
 
    sort_param[i].record= (((unsigned char *)(sort_param+share->base.keys))+
 
2619
    sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+
2609
2620
                           (max_pack_reclength * i));
2610
2621
    if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
2611
2622
    {
2733
2744
      Exchange the data file descriptor of the table, so that we use the
2734
2745
      new file from now on.
2735
2746
     */
2736
 
    internal::my_close(info->dfile,MYF(0));
 
2747
    my_close(info->dfile,MYF(0));
2737
2748
    info->dfile=new_file;
2738
2749
 
2739
2750
    share->data_file_type=sort_info.new_data_file_type;
2765
2776
      if (ftruncate(info->dfile, skr))
2766
2777
        mi_check_print_warning(param,
2767
2778
                               "Can't change size of datafile,  error: %d",
2768
 
                               errno);
 
2779
                               my_errno);
2769
2780
  }
2770
2781
  if (param->testflag & T_CALC_CHECKSUM)
2771
2782
    info->state->checksum=param->glob_crc;
2772
2783
 
2773
2784
  if (ftruncate(share->kfile, info->state->key_file_length))
2774
2785
    mi_check_print_warning(param,
2775
 
                           "Can't change size of indexfile, error: %d", errno);
 
2786
                           "Can't change size of indexfile, error: %d", my_errno);
2776
2787
 
2777
2788
  if (!(param->testflag & T_SILENT))
2778
2789
  {
2795
2806
    the share by remove_io_thread() or it was not yet started (if the
2796
2807
    error happend before creating the thread).
2797
2808
  */
2798
 
  end_io_cache(&info->rec_cache);
 
2809
  VOID(end_io_cache(&info->rec_cache));
2799
2810
  /*
2800
2811
    Destroy the new data cache in case of non-quick repair. All slave
2801
2812
    threads did either detach from the share by remove_io_thread()
2803
2814
    creating the threads).
2804
2815
  */
2805
2816
  if (!rep_quick)
2806
 
    end_io_cache(&new_data_cache);
 
2817
    VOID(end_io_cache(&new_data_cache));
2807
2818
  if (!got_error)
2808
2819
  {
2809
2820
    /* Replace the actual file with the temporary file */
2810
2821
    if (new_file >= 0)
2811
2822
    {
2812
 
      internal::my_close(new_file,MYF(0));
 
2823
      my_close(new_file,MYF(0));
2813
2824
      info->dfile=new_file= -1;
2814
2825
      if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
2815
2826
                            DATA_TMP_EXT, share->base.raid_chunks,
2822
2833
  if (got_error)
2823
2834
  {
2824
2835
    if (! param->error_printed)
2825
 
      mi_check_print_error(param,"%d when fixing table",errno);
 
2836
      mi_check_print_error(param,"%d when fixing table",my_errno);
2826
2837
    if (new_file >= 0)
2827
2838
    {
2828
 
      internal::my_close(new_file,MYF(0));
2829
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2839
      VOID(my_close(new_file,MYF(0)));
 
2840
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2841
                          MYF(MY_WME)));
2830
2842
      if (info->dfile == new_file)
2831
 
        info->dfile= -1;
 
2843
        info->dfile= -1;
2832
2844
    }
2833
2845
    mi_mark_crashed_on_repair(info);
2834
2846
  }
2839
2851
  pthread_cond_destroy (&sort_info.cond);
2840
2852
  pthread_mutex_destroy(&sort_info.mutex);
2841
2853
 
2842
 
  free((unsigned char*) sort_info.key_block);
2843
 
  free((unsigned char*) sort_param);
2844
 
  free(sort_info.buff);
2845
 
  end_io_cache(&param->read_cache);
 
2854
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2855
  my_free((uchar*) sort_param,MYF(MY_ALLOW_ZERO_PTR));
 
2856
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2857
  VOID(end_io_cache(&param->read_cache));
2846
2858
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2847
2859
  if (!got_error && (param->testflag & T_UNPACK))
2848
2860
  {
2849
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2861
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2850
2862
    share->pack.header_length=0;
2851
2863
  }
2852
2864
  return(got_error);
2854
2866
 
2855
2867
        /* Read next record and return next key */
2856
2868
 
2857
 
int sort_key_read(MI_SORT_PARAM *sort_param, void *key)
 
2869
static int sort_key_read(MI_SORT_PARAM *sort_param, void *key)
2858
2870
{
2859
2871
  int error;
2860
2872
  SORT_INFO *sort_info=sort_param->sort_info;
2871
2883
  }
2872
2884
  sort_param->real_key_length=
2873
2885
    (info->s->rec_reflength+
2874
 
     _mi_make_key(info, sort_param->key, (unsigned char*) key,
 
2886
     _mi_make_key(info, sort_param->key, (uchar*) key,
2875
2887
                  sort_param->record, sort_param->filepos));
2876
2888
#ifdef HAVE_purify
2877
 
  memset((unsigned char *)key+sort_param->real_key_length, 0,
 
2889
  memset(key+sort_param->real_key_length, 0,
2878
2890
         (sort_param->key_length-sort_param->real_key_length));
2879
2891
#endif
2880
2892
  return(sort_write_record(sort_param));
2912
2924
    > 0         error
2913
2925
*/
2914
2926
 
2915
 
int sort_get_next_record(MI_SORT_PARAM *sort_param)
 
2927
static int sort_get_next_record(MI_SORT_PARAM *sort_param)
2916
2928
{
2917
2929
  int searching;
2918
2930
  int parallel_flag;
2919
 
  uint32_t found_record,b_type,left_length;
 
2931
  uint found_record,b_type,left_length;
2920
2932
  my_off_t pos;
2921
 
  unsigned char *to= NULL;
 
2933
  uchar *to= NULL;
2922
2934
  MI_BLOCK_INFO block_info;
2923
2935
  SORT_INFO *sort_info=sort_param->sort_info;
2924
2936
  MI_CHECK *param=sort_info->param;
2994
3006
                     llstr(param->search_after_block,llbuff),
2995
3007
                     llstr(sort_param->start_recpos,llbuff2));
2996
3008
        if (_mi_read_cache(&sort_param->read_cache,
2997
 
                           (unsigned char*) block_info.header,pos,
 
3009
                           (uchar*) block_info.header,pos,
2998
3010
                           MI_BLOCK_INFO_HEADER_LENGTH,
2999
3011
                           (! found_record ? READING_NEXT : 0) |
3000
3012
                           parallel_flag | READING_HEADER))
3021
3033
             (block_info.rec_len < (uint) share->base.min_pack_length ||
3022
3034
              block_info.rec_len > (uint) share->base.max_pack_length)))
3023
3035
        {
3024
 
          uint32_t i;
 
3036
          uint i;
3025
3037
          if (param->testflag & T_VERBOSE || searching == 0)
3026
3038
            mi_check_print_info(param,
3027
3039
                                "Wrong bytesec: %3d-%3d-%3d at %10s; Skipped",
3180
3192
          streched over the end of the previous buffer contents.
3181
3193
        */
3182
3194
        {
3183
 
          uint32_t header_len= (uint) (block_info.filepos - pos);
3184
 
          uint32_t prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
 
3195
          uint header_len= (uint) (block_info.filepos - pos);
 
3196
          uint prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
3185
3197
 
3186
3198
          if (prefetch_len > block_info.data_len)
3187
3199
            prefetch_len= block_info.data_len;
3202
3214
        {
3203
3215
          mi_check_print_info(param,
3204
3216
                              "Read error for block at: %s (error: %d); Skipped",
3205
 
                              llstr(block_info.filepos,llbuff),errno);
 
3217
                              llstr(block_info.filepos,llbuff),my_errno);
3206
3218
          goto try_next;
3207
3219
        }
3208
3220
        left_length-=block_info.data_len;
3282
3294
{
3283
3295
  int flag;
3284
3296
  ulong block_length,reclength;
3285
 
  unsigned char *from;
 
3297
  uchar *from;
3286
3298
  SORT_INFO *sort_info=sort_param->sort_info;
3287
3299
  MI_CHECK *param=sort_info->param;
3288
3300
  MI_INFO *info=sort_info->info;
3295
3307
      if (my_b_write(&info->rec_cache,sort_param->record,
3296
3308
                     share->base.pack_reclength))
3297
3309
      {
3298
 
        mi_check_print_error(param,"%d when writing to datafile",errno);
 
3310
        mi_check_print_error(param,"%d when writing to datafile",my_errno);
3299
3311
        return(1);
3300
3312
      }
3301
3313
      sort_param->filepos+=share->base.pack_reclength;
3314
3326
          MI_DYN_DELETE_BLOCK_HEADER;
3315
3327
        if (sort_info->buff_length < reclength)
3316
3328
        {
3317
 
          void *tmpptr= NULL;
3318
 
          tmpptr= realloc(sort_info->buff, reclength);
3319
 
          if(tmpptr)
3320
 
          {
3321
 
            sort_info->buff_length=reclength;
3322
 
            sort_info->buff= (unsigned char *)tmpptr;
3323
 
          }
3324
 
          else
3325
 
          {
3326
 
            mi_check_print_error(param,"Could not realloc() sort_info->buff "
3327
 
                                 " to %ul bytes", reclength);
3328
 
            return(1);
3329
 
          }
 
3329
          if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength,
 
3330
                                           MYF(MY_FREE_ON_ERROR |
 
3331
                                               MY_ALLOW_ZERO_PTR))))
 
3332
            return(1);
 
3333
          sort_info->buff_length=reclength;
3330
3334
        }
3331
3335
        from= sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
3332
3336
      }
3349
3353
                                  sort_param->filepos+block_length,
3350
3354
                                  &from,&reclength,&flag))
3351
3355
        {
3352
 
          mi_check_print_error(param,"%d when writing to datafile",errno);
 
3356
          mi_check_print_error(param,"%d when writing to datafile",my_errno);
3353
3357
          return(1);
3354
3358
        }
3355
3359
        sort_param->filepos+=block_length;
3370
3374
    {
3371
3375
      char llbuff[22];
3372
3376
      printf("%s\r", llstr(info->state->records,llbuff));
3373
 
      fflush(stdout);
 
3377
      VOID(fflush(stdout));
3374
3378
    }
3375
3379
  }
3376
3380
  return(0);
3379
3383
 
3380
3384
        /* Compare two keys from _create_index_by_sort */
3381
3385
 
3382
 
int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a, const void *b)
 
3386
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
 
3387
                        const void *b)
3383
3388
{
3384
 
  uint32_t not_used[2];
3385
 
  return (ha_key_cmp(sort_param->seg, *((unsigned char* const *) a), *((unsigned char* const *) b),
 
3389
  uint not_used[2];
 
3390
  return (ha_key_cmp(sort_param->seg, *((uchar* const *) a), *((uchar* const *) b),
3386
3391
                     USE_WHOLE_KEY, SEARCH_SAME, not_used));
3387
3392
} /* sort_key_cmp */
3388
3393
 
3389
3394
 
3390
 
int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
 
3395
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
3391
3396
{
3392
 
  uint32_t diff_pos[2];
 
3397
  uint diff_pos[2];
3393
3398
  char llbuff[22],llbuff2[22];
3394
3399
  SORT_INFO *sort_info=sort_param->sort_info;
3395
3400
  MI_CHECK *param= sort_info->param;
3398
3403
  if (sort_info->key_block->inited)
3399
3404
  {
3400
3405
    cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3401
 
                   (unsigned char*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
 
3406
                   (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3402
3407
                   diff_pos);
3403
3408
    if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3404
3409
      ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3405
 
                 (unsigned char*) a, USE_WHOLE_KEY,
 
3410
                 (uchar*) a, USE_WHOLE_KEY, 
3406
3411
                 SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3407
3412
    else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3408
3413
    {
3409
3414
      diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
3410
3415
                                                 sort_param->notnull,
3411
3416
                                                 sort_info->key_block->lastkey,
3412
 
                                                 (unsigned char*)a);
 
3417
                                                 (uchar*)a);
3413
3418
    }
3414
3419
    sort_param->unique[diff_pos[0]-1]++;
3415
3420
  }
3418
3423
    cmp= -1;
3419
3424
    if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3420
3425
      mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull,
3421
 
                                     (unsigned char*)a);
 
3426
                                     (uchar*)a);
3422
3427
  }
3423
3428
  if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
3424
3429
  {
3425
3430
    sort_info->dupp++;
3426
3431
    sort_info->info->lastpos=get_record_for_key(sort_info->info,
3427
3432
                                                sort_param->keyinfo,
3428
 
                                                (unsigned char*) a);
 
3433
                                                (uchar*) a);
3429
3434
    mi_check_print_warning(param,
3430
3435
                           "Duplicate key for record at %10s against record at %10s",
3431
3436
                           llstr(sort_info->info->lastpos,llbuff),
3438
3443
    return (sort_delete_record(sort_param));
3439
3444
  }
3440
3445
  return (sort_insert_key(sort_param,sort_info->key_block,
3441
 
                          (unsigned char*) a, HA_OFFSET_ERROR));
 
3446
                          (uchar*) a, HA_OFFSET_ERROR));
3442
3447
} /* sort_key_write */
3443
3448
 
3444
3449
 
3445
3450
        /* get pointer to record from a key */
3446
3451
 
3447
 
my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
3448
 
                            unsigned char *key) {
 
3452
static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
 
3453
                                   uchar *key)
 
3454
{
3449
3455
  return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key));
3450
3456
} /* get_record_for_key */
3451
3457
 
3452
3458
 
3453
3459
        /* Insert a key in sort-key-blocks */
3454
3460
 
3455
 
int sort_insert_key(MI_SORT_PARAM *sort_param,
3456
 
                    register SORT_KEY_BLOCKS *key_block, unsigned char *key,
3457
 
                    my_off_t prev_block)
 
3461
static int sort_insert_key(MI_SORT_PARAM *sort_param,
 
3462
                           register SORT_KEY_BLOCKS *key_block, uchar *key,
 
3463
                           my_off_t prev_block)
3458
3464
{
3459
 
  uint32_t a_length,t_length,nod_flag;
 
3465
  uint a_length,t_length,nod_flag;
3460
3466
  my_off_t filepos,key_file_length;
3461
 
  unsigned char *anc_buff,*lastkey;
 
3467
  uchar *anc_buff,*lastkey;
3462
3468
  MI_KEY_PARAM s_temp;
3463
3469
  MI_INFO *info;
3464
3470
  MI_KEYDEF *keyinfo=sort_param->keyinfo;
3491
3497
    _mi_kpointer(info,key_block->end_pos,prev_block);
3492
3498
 
3493
3499
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
3494
 
                                (unsigned char*) 0,lastkey,lastkey,key,
 
3500
                                (uchar*) 0,lastkey,lastkey,key,
3495
3501
                                 &s_temp);
3496
3502
  (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
3497
3503
  a_length+=t_length;
3499
3505
  key_block->end_pos+=t_length;
3500
3506
  if (a_length <= keyinfo->block_length)
3501
3507
  {
3502
 
    _mi_move_key(keyinfo,key_block->lastkey,key);
 
3508
    VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
3503
3509
    key_block->last_length=a_length-t_length;
3504
3510
    return(0);
3505
3511
  }
3518
3524
    if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
3519
3525
      return(1);
3520
3526
  }
3521
 
  else if (my_pwrite(info->s->kfile,(unsigned char*) anc_buff,
 
3527
  else if (my_pwrite(info->s->kfile,(uchar*) anc_buff,
3522
3528
                     (uint) keyinfo->block_length,filepos, param->myf_rw))
3523
3529
    return(1);
3524
3530
 
3534
3540
 
3535
3541
        /* Delete record when we found a duplicated key */
3536
3542
 
3537
 
int sort_delete_record(MI_SORT_PARAM *sort_param)
 
3543
static int sort_delete_record(MI_SORT_PARAM *sort_param)
3538
3544
{
3539
 
  uint32_t i;
 
3545
  uint i;
3540
3546
  int old_file,error;
3541
 
  unsigned char *key;
 
3547
  uchar *key;
3542
3548
  SORT_INFO *sort_info=sort_param->sort_info;
3543
3549
  MI_CHECK *param=sort_info->param;
3544
3550
  MI_INFO *info=sort_info->info;
3571
3577
 
3572
3578
    for (i=0 ; i < sort_info->current_key ; i++)
3573
3579
    {
3574
 
      uint32_t key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
 
3580
      uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
3575
3581
      if (_mi_ck_delete(info,i,key,key_length))
3576
3582
      {
3577
3583
        mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
3592
3598
 
3593
3599
int flush_pending_blocks(MI_SORT_PARAM *sort_param)
3594
3600
{
3595
 
  uint32_t nod_flag,length;
 
3601
  uint nod_flag,length;
3596
3602
  my_off_t filepos,key_file_length;
3597
3603
  SORT_KEY_BLOCKS *key_block;
3598
3604
  SORT_INFO *sort_info= sort_param->sort_info;
3620
3626
                            DFLT_INIT_HITS, key_block->buff))
3621
3627
        return(1);
3622
3628
    }
3623
 
    else if (my_pwrite(info->s->kfile,(unsigned char*) key_block->buff,
 
3629
    else if (my_pwrite(info->s->kfile,(uchar*) key_block->buff,
3624
3630
                       (uint) keyinfo->block_length,filepos, myf_rw))
3625
3631
      return(1);
3626
3632
    nod_flag=1;
3631
3637
 
3632
3638
        /* alloc space and pointers for key_blocks */
3633
3639
 
3634
 
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
3635
 
                                         uint32_t buffer_length)
 
3640
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
 
3641
                                         uint buffer_length)
3636
3642
{
3637
 
  register uint32_t i;
 
3643
  register uint i;
3638
3644
  SORT_KEY_BLOCKS *block;
3639
3645
 
3640
 
  if (!(block=(SORT_KEY_BLOCKS*) malloc((sizeof(SORT_KEY_BLOCKS)+
3641
 
                                        buffer_length+IO_SIZE)*blocks)))
 
3646
  if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
 
3647
                                            buffer_length+IO_SIZE)*blocks,
 
3648
                                           MYF(0))))
3642
3649
  {
3643
3650
    mi_check_print_error(param,"Not enough memory for sort-key-blocks");
3644
3651
    return(0);
3646
3653
  for (i=0 ; i < blocks ; i++)
3647
3654
  {
3648
3655
    block[i].inited=0;
3649
 
    block[i].buff=(unsigned char*) (block+blocks)+(buffer_length+IO_SIZE)*i;
 
3656
    block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i;
3650
3657
  }
3651
3658
  return(block);
3652
3659
} /* alloc_key_blocks */
3658
3665
{
3659
3666
  if (info->s->options & HA_OPTION_COMPRESS_RECORD)
3660
3667
    return 0;
3661
 
  return (my_off_t)(lseek(info->s->kfile, 0L, SEEK_END) / 10 * 9) >
 
3668
  return my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)) / 10 * 9 >
3662
3669
         (my_off_t) info->s->base.max_key_file_length ||
3663
 
         (my_off_t)(lseek(info->dfile, 0L, SEEK_END) / 10 * 9) >
 
3670
         my_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
3664
3671
         (my_off_t) info->s->base.max_data_file_length;
3665
3672
}
3666
3673
 
3676
3683
  MI_COLUMNDEF *recdef,*rec,*end;
3677
3684
  MI_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
3678
3685
  MI_STATUS_INFO status_info;
3679
 
  uint32_t unpack,key_parts;
 
3686
  uint unpack,key_parts;
3680
3687
  ha_rows max_records;
3681
3688
  uint64_t file_length,tmp_length;
3682
3689
  MI_CREATE_INFO create_info;
3688
3695
  share= *(*org_info)->s;
3689
3696
  unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
3690
3697
    (param->testflag & T_UNPACK);
3691
 
  if (!(keyinfo=(MI_KEYDEF*) malloc(sizeof(MI_KEYDEF)*share.base.keys)))
 
3698
  if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
3692
3699
    return(0);
3693
3700
  memcpy(keyinfo,share.keyinfo,sizeof(MI_KEYDEF)*share.base.keys);
3694
3701
 
3695
3702
  key_parts= share.base.all_key_parts;
3696
 
  if (!(keysegs=(HA_KEYSEG*) malloc(sizeof(HA_KEYSEG)*
3697
 
                                    (key_parts+share.base.keys))))
 
3703
  if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
 
3704
                                       (key_parts+share.base.keys))))
3698
3705
  {
3699
 
    free(keyinfo);
 
3706
    my_afree((uchar*) keyinfo);
3700
3707
    return(1);
3701
3708
  }
3702
3709
  if (!(recdef=(MI_COLUMNDEF*)
3703
 
        malloc(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
 
3710
        my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3704
3711
  {
3705
 
    free(keyinfo);
3706
 
    free(keysegs);
 
3712
    my_afree((uchar*) keyinfo);
 
3713
    my_afree((uchar*) keysegs);
3707
3714
    return(1);
3708
3715
  }
3709
3716
  if (!(uniquedef=(MI_UNIQUEDEF*)
3710
 
        malloc(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
 
3717
        my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
3711
3718
  {
3712
 
    free(recdef);
3713
 
    free(keyinfo);
3714
 
    free(keysegs);
 
3719
    my_afree((uchar*) recdef);
 
3720
    my_afree((uchar*) keyinfo);
 
3721
    my_afree((uchar*) keysegs);
3715
3722
    return(1);
3716
3723
  }
3717
3724
 
3755
3762
  if (share.options & HA_OPTION_COMPRESS_RECORD)
3756
3763
    share.base.records=max_records=info.state->records;
3757
3764
  else if (share.base.min_pack_length)
3758
 
    max_records=(ha_rows) (lseek(info.dfile,0L,SEEK_END) /
 
3765
    max_records=(ha_rows) (my_seek(info.dfile,0L,MY_SEEK_END,MYF(0)) /
3759
3766
                           (ulong) share.base.min_pack_length);
3760
3767
  else
3761
3768
    max_records=0;
3763
3770
    (param->testflag & T_UNPACK);
3764
3771
  share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
3765
3772
 
3766
 
  file_length=(uint64_t) lseek(info.dfile,0L,SEEK_END);
 
3773
  file_length=(uint64_t) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
3767
3774
  tmp_length= file_length+file_length/10;
3768
3775
  set_if_bigger(file_length,param->max_data_file_length);
3769
3776
  set_if_bigger(file_length,tmp_length);
3770
3777
  set_if_bigger(file_length,(uint64_t) share.base.max_data_file_length);
3771
3778
 
3772
 
  mi_close(*org_info);
 
3779
  VOID(mi_close(*org_info));
3773
3780
  memset(&create_info, 0, sizeof(create_info));
3774
3781
  create_info.max_rows=max(max_records,share.base.records);
3775
3782
  create_info.reloc_rows=share.base.reloc;
3795
3802
                &create_info,
3796
3803
                HA_DONT_TOUCH_DATA))
3797
3804
  {
3798
 
    mi_check_print_error(param,"Got error %d when trying to recreate indexfile",errno);
 
3805
    mi_check_print_error(param,"Got error %d when trying to recreate indexfile",my_errno);
3799
3806
    goto end;
3800
3807
  }
3801
3808
  *org_info=mi_open(filename,O_RDWR,
3805
3812
  if (!*org_info)
3806
3813
  {
3807
3814
    mi_check_print_error(param,"Got error %d when trying to open re-created indexfile",
3808
 
                errno);
 
3815
                my_errno);
3809
3816
    goto end;
3810
3817
  }
3811
3818
  /* We are modifing */
3812
3819
  (*org_info)->s->options&= ~HA_OPTION_READ_ONLY_DATA;
3813
 
  _mi_readinfo(*org_info,F_WRLCK,0);
 
3820
  VOID(_mi_readinfo(*org_info,F_WRLCK,0));
3814
3821
  (*org_info)->state->records=info.state->records;
3815
3822
  if (share.state.create_time)
3816
3823
    (*org_info)->s->state.create_time=share.state.create_time;
3826
3833
    goto end;
3827
3834
  error=0;
3828
3835
end:
3829
 
  free(uniquedef);
3830
 
  free(keyinfo);
3831
 
  free(recdef);
3832
 
  free(keysegs);
 
3836
  my_afree((uchar*) uniquedef);
 
3837
  my_afree((uchar*) keyinfo);
 
3838
  my_afree((uchar*) recdef);
 
3839
  my_afree((uchar*) keysegs);
3833
3840
  return(error);
3834
3841
}
3835
3842
 
3842
3849
 
3843
3850
  if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
3844
3851
  {
3845
 
    unsigned char buff[MEMMAP_EXTRA_MARGIN];
 
3852
    uchar buff[MEMMAP_EXTRA_MARGIN];
3846
3853
    memset(buff, 0, sizeof(buff));
3847
3854
    if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
3848
3855
    {
3849
3856
      mi_check_print_error(sort_info->param,
3850
 
                           "%d when writing to datafile",errno);
 
3857
                           "%d when writing to datafile",my_errno);
3851
3858
      return 1;
3852
3859
    }
3853
3860
    sort_info->param->read_cache.end_of_file+=sizeof(buff);
3857
3864
 
3858
3865
        /* Update state and myisamchk_time of indexfile */
3859
3866
 
3860
 
int update_state_info(MI_CHECK *param, MI_INFO *info,uint32_t update)
 
3867
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
3861
3868
{
3862
3869
  MYISAM_SHARE *share=info->s;
3863
3870
 
3868
3875
  }
3869
3876
  if (update & UPDATE_STAT)
3870
3877
  {
3871
 
    uint32_t i, key_parts= mi_uint2korr(share->state.header.key_parts);
 
3878
    uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
3872
3879
    share->state.rec_per_key_rows=info->state->records;
3873
3880
    share->state.changed&= ~STATE_NOT_ANALYZED;
3874
3881
    if (info->state->records)
3902
3909
  }
3903
3910
  {                                             /* Force update of status */
3904
3911
    int error;
3905
 
    uint32_t r_locks=share->r_locks,w_locks=share->w_locks;
 
3912
    uint r_locks=share->r_locks,w_locks=share->w_locks;
3906
3913
    share->r_locks= share->w_locks= share->tot_locks= 0;
3907
3914
    error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK);
3908
3915
    share->r_locks=r_locks;
3912
3919
      return 0;
3913
3920
  }
3914
3921
err:
3915
 
  mi_check_print_error(param,"%d when updating keyfile",errno);
 
3922
  mi_check_print_error(param,"%d when updating keyfile",my_errno);
3916
3923
  return 1;
3917
3924
}
3918
3925
 
3932
3939
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
3933
3940
                               bool repair_only)
3934
3941
{
3935
 
  unsigned char *record= 0;
 
3942
  uchar *record= 0;
3936
3943
 
3937
3944
  if (!info->s->base.auto_key ||
3938
3945
      ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1))
3947
3954
      !(param->testflag & T_REP))
3948
3955
    printf("Updating MyISAM file: %s\n", param->isam_file_name);
3949
3956
  /*
3950
 
    We have to use an allocated buffer instead of info->rec_buff as
 
3957
    We have to use an allocated buffer instead of info->rec_buff as 
3951
3958
    _mi_put_key_in_record() may use info->rec_buff
3952
3959
  */
3953
3960
  if (!mi_alloc_rec_buff(info, -1, &record))
3959
3966
  mi_extra(info,HA_EXTRA_KEYREAD,0);
3960
3967
  if (mi_rlast(info, record, info->s->base.auto_key-1))
3961
3968
  {
3962
 
    if (errno != HA_ERR_END_OF_FILE)
 
3969
    if (my_errno != HA_ERR_END_OF_FILE)
3963
3970
    {
3964
3971
      mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3965
 
      free(mi_get_rec_buff_ptr(info, record));
3966
 
      mi_check_print_error(param,"%d when reading last record",errno);
 
3972
      my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
 
3973
      mi_check_print_error(param,"%d when reading last record",my_errno);
3967
3974
      return;
3968
3975
    }
3969
3976
    if (!repair_only)
3977
3984
      set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
3978
3985
  }
3979
3986
  mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3980
 
  free(mi_get_rec_buff_ptr(info, record));
 
3987
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3981
3988
  update_state_info(param, info, UPDATE_AUTO_INC);
3982
3989
  return;
3983
3990
}
3995
4002
      records               Number of records in the table
3996
4003
 
3997
4004
  DESCRIPTION
3998
 
    This function is called produce index statistics values from unique and
 
4005
    This function is called produce index statistics values from unique and 
3999
4006
    notnull_tuples arrays after these arrays were produced with sequential
4000
4007
    index scan (the scan is done in two places: chk_index() and
4001
4008
    sort_key_write()).
4009
4016
 
4010
4017
    For MI_STATS_METHOD_IGNORE_NULLS method, notnull_tuples is an array too:
4011
4018
      notnull_tuples[0]= (#of {keypart1} tuples such that keypart1 is not NULL)
4012
 
      notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all
 
4019
      notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all 
4013
4020
                          keypart{i} are not NULL)
4014
4021
      ...
4015
4022
    For all other statistics collection methods notnull_tuples==NULL.
4016
4023
 
4017
4024
    Output is an array:
4018
 
    rec_per_key_part[k] =
4019
 
     = E(#records in the table such that keypart_1=c_1 AND ... AND
4020
 
         keypart_k=c_k for arbitrary constants c_1 ... c_k)
4021
 
 
 
4025
    rec_per_key_part[k] = 
 
4026
     = E(#records in the table such that keypart_1=c_1 AND ... AND 
 
4027
         keypart_k=c_k for arbitrary constants c_1 ... c_k) 
 
4028
     
4022
4029
     = {assuming that values have uniform distribution and index contains all
4023
4030
        tuples from the domain (or that {c_1, ..., c_k} tuple is choosen from
4024
4031
        index tuples}
4025
 
 
 
4032
     
4026
4033
     = #tuples-in-the-index / #distinct-tuples-in-the-index.
4027
 
 
4028
 
    The #tuples-in-the-index and #distinct-tuples-in-the-index have different
 
4034
    
 
4035
    The #tuples-in-the-index and #distinct-tuples-in-the-index have different 
4029
4036
    meaning depending on which statistics collection method is used:
4030
 
 
 
4037
    
4031
4038
    MI_STATS_METHOD_*  how are nulls compared?  which tuples are counted?
4032
4039
     NULLS_EQUAL            NULL == NULL           all tuples in table
4033
4040
     NULLS_NOT_EQUAL        NULL != NULL           all tuples in table
4040
4047
{
4041
4048
  uint64_t count=0,tmp, unique_tuples;
4042
4049
  uint64_t tuples= records;
4043
 
  uint32_t parts;
 
4050
  uint parts;
4044
4051
  for (parts=0 ; parts < keyinfo->keysegs  ; parts++)
4045
4052
  {
4046
4053
    count+=unique[parts];
4047
 
    unique_tuples= count + 1;
 
4054
    unique_tuples= count + 1;    
4048
4055
    if (notnull)
4049
4056
    {
4050
4057
      tuples= notnull[parts];
4051
 
      /*
4052
 
        #(unique_tuples not counting tuples with NULLs) =
4053
 
          #(unique_tuples counting tuples with NULLs as different) -
 
4058
      /* 
 
4059
        #(unique_tuples not counting tuples with NULLs) = 
 
4060
          #(unique_tuples counting tuples with NULLs as different) - 
4054
4061
          #(tuples with NULLs)
4055
4062
      */
4056
4063
      unique_tuples -= (records - notnull[parts]);
4057
4064
    }
4058
 
 
 
4065
    
4059
4066
    if (unique_tuples == 0)
4060
4067
      tmp= 1;
4061
4068
    else if (count == 0)
4063
4070
    else
4064
4071
      tmp= (tuples + unique_tuples/2) / unique_tuples;
4065
4072
 
4066
 
    /*
4067
 
      for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
 
4073
    /* 
 
4074
      for some weird keys (e.g. FULLTEXT) tmp can be <1 here. 
4068
4075
      let's ensure it is not
4069
4076
    */
4070
 
    if (tmp < 1)
4071
 
      tmp= 1;
 
4077
    set_if_bigger(tmp,1);
4072
4078
    if (tmp >= (uint64_t) ~(ulong) 0)
4073
4079
      tmp=(uint64_t) ~(ulong) 0;
4074
4080
 
4078
4084
}
4079
4085
 
4080
4086
 
4081
 
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length)
 
4087
static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
4082
4088
{
4083
4089
  ha_checksum crc;
4084
 
  const unsigned char *end=buf+length;
 
4090
  const uchar *end=buf+length;
4085
4091
  for (crc=0; buf != end; buf++)
4086
 
    crc=((crc << 1) + *((unsigned char*) buf)) +
 
4092
    crc=((crc << 1) + *((uchar*) buf)) +
4087
4093
      test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1)));
4088
4094
  return crc;
4089
4095
}
4090
4096
 
4091
4097
static bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
4092
4098
{
4093
 
  uint32_t key_maxlength=key->maxlength;
 
4099
  uint key_maxlength=key->maxlength;
4094
4100
  return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY) &&
4095
4101
          ((uint64_t) rows * key_maxlength >
4096
 
           (uint64_t) MAX_FILE_SIZE));
 
4102
           (uint64_t) myisam_max_temp_length));
4097
4103
}
4098
4104
 
4099
4105
/*
4109
4115
{
4110
4116
  MYISAM_SHARE *share=info->s;
4111
4117
  MI_KEYDEF    *key=share->keyinfo;
4112
 
  uint32_t          i;
 
4118
  uint          i;
4113
4119
 
4114
4120
  assert(info->state->records == 0 &&
4115
4121
              (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES));
4136
4142
{
4137
4143
  MYISAM_SHARE *share=info->s;
4138
4144
  MI_KEYDEF *key=share->keyinfo;
4139
 
  uint32_t i;
 
4145
  uint i;
4140
4146
 
4141
4147
  /*
4142
4148
    mi_repair_by_sort only works if we have at least one key. If we don't