~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_check.c

  • Committer: Jay Pipes
  • Date: 2008-07-21 17:52:33 UTC
  • mto: (201.2.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: jay@mysql.com-20080721175233-mtyz298j8xl3v63y
cleanup of FAQ file

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
*/
42
42
 
43
43
#include "myisamdef.h"
 
44
#include <m_ctype.h>
44
45
#include <stdarg.h>
45
 
#include <mysys/my_getopt.h>
 
46
#include <my_getopt.h>
46
47
#ifdef HAVE_SYS_VADVISE_H
47
48
#include <sys/vadvise.h>
48
49
#endif
49
 
#ifdef HAVE_SYS_TYPES
50
 
#include <sys/types.h>
51
 
#endif
52
50
#ifdef HAVE_SYS_MMAN_H
53
51
#include <sys/mman.h>
54
52
#endif
55
 
#include <drizzled/util/test.h>
56
 
 
57
 
 
58
 
/* Functions defined in this file */
59
 
 
60
 
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint32_t nr);
 
53
 
 
54
#ifndef USE_RAID
 
55
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
 
56
#define my_raid_delete(A,B,C) my_delete(A,B)
 
57
#endif
 
58
 
 
59
        /* Functions defined in this file */
 
60
 
 
61
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr);
61
62
static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
62
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
63
 
                     ha_checksum *key_checksum, uint32_t level);
64
 
static uint32_t isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
 
63
                     my_off_t page, uchar *buff, ha_rows *keys,
 
64
                     ha_checksum *key_checksum, uint level);
 
65
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
65
66
static ha_checksum calc_checksum(ha_rows count);
66
67
static int writekeys(MI_SORT_PARAM *sort_param);
67
68
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
71
72
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
72
73
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
73
74
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
74
 
                                unsigned char *key);
 
75
                                uchar *key);
75
76
static int sort_insert_key(MI_SORT_PARAM  *sort_param,
76
77
                           register SORT_KEY_BLOCKS *key_block,
77
 
                           unsigned char *key, my_off_t prev_block);
 
78
                           uchar *key, my_off_t prev_block);
78
79
static int sort_delete_record(MI_SORT_PARAM *sort_param);
79
80
/*static int flush_pending_blocks(MI_CHECK *param);*/
80
 
static SORT_KEY_BLOCKS  *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
81
 
                                          uint32_t buffer_length);
82
 
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length);
 
81
static SORT_KEY_BLOCKS  *alloc_key_blocks(MI_CHECK *param, uint blocks,
 
82
                                          uint buffer_length);
 
83
static ha_checksum mi_byte_checksum(const uchar *buf, uint length);
83
84
static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
84
85
 
85
86
void myisamchk_init(MI_CHECK *param)
86
87
{
87
 
  memset(param, 0, sizeof(*param));
 
88
  bzero((uchar*) param,sizeof(*param));
88
89
  param->opt_follow_links=1;
89
90
  param->keys_in_use= ~(uint64_t) 0;
90
91
  param->search_after_block=HA_OFFSET_ERROR;
117
118
  if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0))
118
119
  {
119
120
    /* Don't count this as a real warning, as check can correct this ! */
120
 
    uint32_t save=param->warning_printed;
 
121
    uint save=param->warning_printed;
121
122
    mi_check_print_warning(param,
122
123
                           share->state.open_count==1 ? 
123
124
                           "%d client is using or hasn't closed the table properly" : 
132
133
 
133
134
        /* Check delete links */
134
135
 
135
 
int chk_del(MI_CHECK *param, register MI_INFO *info, uint32_t test_flag)
 
136
int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
136
137
{
137
138
  register ha_rows i;
138
 
  uint32_t delete_link_length;
 
139
  uint delete_link_length;
139
140
  my_off_t empty, next_link, old_link= 0;
140
141
  char buff[22],buff2[22];
141
142
 
167
168
        printf(" %9s",llstr(next_link,buff));
168
169
      if (next_link >= info->state->data_file_length)
169
170
        goto wrong;
170
 
      if (my_pread(info->dfile, (unsigned char*) buff,delete_link_length,
 
171
      if (my_pread(info->dfile, (uchar*) buff,delete_link_length,
171
172
                   next_link,MYF(MY_NABP)))
172
173
      {
173
174
        if (test_flag & T_VERBOSE) puts("");
198
199
      else
199
200
      {
200
201
        param->record_checksum+=(ha_checksum) next_link;
201
 
        next_link=_mi_rec_pos(info->s,(unsigned char*) buff+1);
 
202
        next_link=_mi_rec_pos(info->s,(uchar*) buff+1);
202
203
        empty+=info->s->base.pack_reclength;
203
204
      }
204
205
    }
239
240
 
240
241
        /* Check delete links in index file */
241
242
 
242
 
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint32_t nr)
 
243
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
243
244
{
244
245
  my_off_t next_link;
245
 
  uint32_t block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
 
246
  uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
246
247
  ha_rows records;
247
248
  char llbuff[21], llbuff2[21];
248
 
  unsigned char *buff;
 
249
  uchar *buff;
249
250
 
250
251
  if (param->testflag & T_VERBOSE)
251
252
    printf("block_size %4u:", block_size); /* purecov: tested */
289
290
    */
290
291
    if (!(buff=key_cache_read(info->s->key_cache,
291
292
                              info->s->kfile, next_link, DFLT_INIT_HITS,
292
 
                              (unsigned char*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
 
293
                              (uchar*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
293
294
                              MI_MIN_KEY_BLOCK_LENGTH, 1)))
294
295
    {
295
296
      /* purecov: begin tested */
392
393
 
393
394
int chk_key(MI_CHECK *param, register MI_INFO *info)
394
395
{
395
 
  uint32_t key,found_keys=0,full_text_keys=0,result=0;
 
396
  uint key,found_keys=0,full_text_keys=0,result=0;
396
397
  ha_rows keys;
397
398
  ha_checksum old_record_checksum,init_checksum;
398
399
  my_off_t all_keydata,all_totaldata,key_totlength,length;
430
431
    if (! mi_is_key_active(share->state.key_map, key))
431
432
    {
432
433
      /* Remember old statistics for key */
433
 
      assert(rec_per_key_part >= param->rec_per_key_part);
434
 
      memcpy(rec_per_key_part,
435
 
             (share->state.rec_per_key_part +
436
 
              (rec_per_key_part - param->rec_per_key_part)),
 
434
      memcpy((char*) rec_per_key_part,
 
435
             (char*) (share->state.rec_per_key_part +
 
436
                      (uint) (rec_per_key_part - param->rec_per_key_part)),
437
437
             keyinfo->keysegs*sizeof(*rec_per_key_part));
438
438
      continue;
439
439
    }
441
441
 
442
442
    param->record_checksum=init_checksum;
443
443
    
444
 
    memset(&param->unique_count, 0, sizeof(param->unique_count));
445
 
    memset(&param->notnull_count, 0, sizeof(param->notnull_count));
 
444
    bzero((char*) &param->unique_count,sizeof(param->unique_count));
 
445
    bzero((char*) &param->notnull_count,sizeof(param->notnull_count));
446
446
 
447
447
    if ((!(param->testflag & T_SILENT)))
448
448
      printf ("- check data record references index: %d\n",key+1);
449
 
    if (share->state.key_root[key] == HA_OFFSET_ERROR && (info->state->records == 0))
 
449
    if (share->state.key_root[key] == HA_OFFSET_ERROR &&
 
450
        (info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
450
451
      goto do_stat;
451
452
    if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],
452
453
                           DFLT_INIT_HITS,info->buff,0))
466
467
    if (chk_index(param,info,keyinfo,share->state.key_root[key],info->buff,
467
468
                  &keys, param->key_crc+key,1))
468
469
      return(-1);
469
 
    if(!(0))
 
470
    if(!(keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL)))
470
471
    {
471
472
      if (keys != info->state->records)
472
473
      {
519
520
 
520
521
      /* Check that there isn't a row with auto_increment = 0 in the table */
521
522
      mi_extra(info,HA_EXTRA_KEYREAD,0);
522
 
      memset(info->lastkey, 0, keyinfo->seg->length);
523
 
      if (!mi_rkey(info, info->rec_buff, key, (const unsigned char*) info->lastkey,
 
523
      bzero(info->lastkey,keyinfo->seg->length);
 
524
      if (!mi_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey,
524
525
                   (key_part_map)1, HA_READ_KEY_EXACT))
525
526
      {
526
527
        /* Don't count this as a real warning, as myisamchk can't correct it */
527
 
        uint32_t save=param->warning_printed;
 
528
        uint save=param->warning_printed;
528
529
        mi_check_print_warning(param, "Found row where the auto_increment "
529
530
                               "column has the value 0");
530
531
        param->warning_printed=save;
573
574
 
574
575
 
575
576
static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
576
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
577
 
                     ha_checksum *key_checksum, uint32_t level)
 
577
                     my_off_t page, uchar *buff, ha_rows *keys,
 
578
                     ha_checksum *key_checksum, uint level)
578
579
{
579
580
  char llbuff[22],llbuff2[22];
580
581
 
644
645
 
645
646
static
646
647
void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, uint64_t *notnull,
647
 
                                    unsigned char *key)
 
648
                                    uchar *key)
648
649
{
649
 
  uint32_t first_null, kp;
 
650
  uint first_null, kp;
650
651
  first_null= ha_find_null(keyseg, key) - keyseg;
651
652
  /*
652
653
    All prefix tuples that don't include keypart_{first_null} are not-null
684
685
 
685
686
static
686
687
int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, uint64_t *notnull,
687
 
                                  unsigned char *prev_key, unsigned char *last_key)
 
688
                                  uchar *prev_key, uchar *last_key)
688
689
{
689
 
  uint32_t diffs[2];
690
 
  uint32_t first_null_seg, kp;
 
690
  uint diffs[2];
 
691
  uint first_null_seg, kp;
691
692
  HA_KEYSEG *seg;
692
693
 
693
694
  /* 
719
720
        /* Check if index is ok */
720
721
 
721
722
static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
722
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
723
 
                     ha_checksum *key_checksum, uint32_t level)
 
723
                     my_off_t page, uchar *buff, ha_rows *keys,
 
724
                     ha_checksum *key_checksum, uint level)
724
725
{
725
726
  int flag;
726
 
  uint32_t used_length,comp_flag,nod_flag,key_length=0;
727
 
  unsigned char key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
 
727
  uint used_length,comp_flag,nod_flag,key_length=0;
 
728
  uchar key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
728
729
  my_off_t next_page,record;
729
730
  char llbuff[22];
730
 
  uint32_t diff_pos[2];
 
731
  uint diff_pos[2];
731
732
 
732
 
  if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
 
733
  if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
733
734
  {
734
735
    mi_check_print_error(param,"Not enough memory for keyblock");
735
736
    return(-1);
759
760
  {
760
761
    if (*killed_ptr(param))
761
762
      goto err;
762
 
    memcpy(info->lastkey,key,key_length);
 
763
    memcpy((char*) info->lastkey,(char*) key,key_length);
763
764
    info->lastkey_length=key_length;
764
765
    if (nod_flag)
765
766
    {
811
812
                                         key);
812
813
      }
813
814
    }
814
 
    (*key_checksum)+= mi_byte_checksum((unsigned char*) key,
 
815
    (*key_checksum)+= mi_byte_checksum((uchar*) key,
815
816
                                       key_length- info->s->rec_reflength);
816
817
    record= _mi_dpos(info,0,key+key_length);
817
818
    if (record >= info->state->data_file_length)
827
828
                llstr(page,llbuff), used_length, (keypos - buff));
828
829
    goto err;
829
830
  }
830
 
  my_afree((unsigned char*) temp_buff);
 
831
  my_afree((uchar*) temp_buff);
831
832
  return(0);
832
833
 err:
833
 
  my_afree((unsigned char*) temp_buff);
 
834
  my_afree((uchar*) temp_buff);
834
835
  return(1);
835
836
} /* chk_index */
836
837
 
859
860
 
860
861
        /* Calc length of key in normal isam */
861
862
 
862
 
static uint32_t isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
 
863
static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
863
864
{
864
 
  uint32_t length;
 
865
  uint length;
865
866
  HA_KEYSEG *keyseg;
866
867
 
867
868
  length= info->s->rec_reflength;
881
882
  ha_rows records, del_blocks;
882
883
  my_off_t used, empty, pos, splits, start_recpos= 0,
883
884
           del_length, link_used, start_block;
884
 
  unsigned char *record= NULL, *to= NULL;
 
885
  uchar *record= NULL, *to= NULL;
885
886
  char llbuff[22],llbuff2[22],llbuff3[22];
886
887
  ha_checksum intern_record_checksum;
887
888
  ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY];
888
 
  bool static_row_size;
 
889
  my_bool static_row_size;
889
890
  MI_KEYDEF *keyinfo;
890
891
  MI_BLOCK_INFO block_info;
891
892
 
924
925
  }
925
926
 
926
927
  pos=my_b_tell(&param->read_cache);
927
 
  memset(key_checksum, 0, info->s->base.keys * sizeof(key_checksum[0]));
 
928
  bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
928
929
  while (pos < info->state->data_file_length)
929
930
  {
930
931
    if (*killed_ptr(param))
931
932
      goto err2;
932
933
    switch (info->s->data_file_type) {
933
934
    case STATIC_RECORD:
934
 
      if (my_b_read(&param->read_cache,(unsigned char*) record,
 
935
      if (my_b_read(&param->read_cache,(uchar*) record,
935
936
                    info->s->base.pack_reclength))
936
937
        goto err;
937
938
      start_recpos=pos;
951
952
      block_info.next_filepos=pos;
952
953
      do
953
954
      {
954
 
        if (_mi_read_cache(&param->read_cache,(unsigned char*) block_info.header,
 
955
        if (_mi_read_cache(&param->read_cache,(uchar*) block_info.header,
955
956
                           (start_block=block_info.next_filepos),
956
957
                           sizeof(block_info.header),
957
958
                           (flag ? 0 : READING_NEXT) | READING_HEADER))
1055
1056
          got_error=1;
1056
1057
          break;
1057
1058
        }
1058
 
        if (_mi_read_cache(&param->read_cache,(unsigned char*) to,block_info.filepos,
 
1059
        if (_mi_read_cache(&param->read_cache,(uchar*) to,block_info.filepos,
1059
1060
                           (uint) block_info.data_len,
1060
1061
                           flag == 1 ? READING_NEXT : 0))
1061
1062
          goto err;
1116
1117
        pos=block_info.filepos+block_info.block_len;
1117
1118
      break;
1118
1119
    case COMPRESSED_RECORD:
 
1120
      if (_mi_read_cache(&param->read_cache,(uchar*) block_info.header, pos,
 
1121
                         info->s->pack.ref_length, READING_NEXT))
 
1122
        goto err;
 
1123
      start_recpos=pos;
 
1124
      splits++;
 
1125
      VOID(_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
 
1126
                                   &info->rec_buff, -1, start_recpos));
 
1127
      pos=block_info.filepos+block_info.rec_len;
 
1128
      if (block_info.rec_len < (uint) info->s->min_pack_length ||
 
1129
          block_info.rec_len > (uint) info->s->max_pack_length)
 
1130
      {
 
1131
        mi_check_print_error(param,
 
1132
                             "Found block with wrong recordlength: %d at %s",
 
1133
                             block_info.rec_len, llstr(start_recpos,llbuff));
 
1134
        got_error=1;
 
1135
        break;
 
1136
      }
 
1137
      if (_mi_read_cache(&param->read_cache,(uchar*) info->rec_buff,
 
1138
                        block_info.filepos, block_info.rec_len, READING_NEXT))
 
1139
        goto err;
 
1140
      if (_mi_pack_rec_unpack(info, &info->bit_buff, record,
 
1141
                              info->rec_buff, block_info.rec_len))
 
1142
      {
 
1143
        mi_check_print_error(param,"Found wrong record at %s",
 
1144
                             llstr(start_recpos,llbuff));
 
1145
        got_error=1;
 
1146
      }
 
1147
      if (static_row_size)
 
1148
        param->glob_crc+= mi_static_checksum(info,record);
 
1149
      else
 
1150
        param->glob_crc+= mi_checksum(info,record);
 
1151
      link_used+= (block_info.filepos - start_recpos);
 
1152
      used+= (pos-start_recpos);
1119
1153
    case BLOCK_RECORD:
1120
1154
      assert(0);                                /* Impossible */
1121
1155
    } /* switch */
1125
1159
      records++;
1126
1160
      if (param->testflag & T_WRITE_LOOP && records % WRITE_COUNT == 0)
1127
1161
      {
1128
 
        printf("%s\r", llstr(records,llbuff)); fflush(stdout);
 
1162
        printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout));
1129
1163
      }
1130
1164
 
1131
1165
      /* Check if keys match the record */
1135
1169
      {
1136
1170
        if (mi_is_key_active(info->s->state.key_map, key))
1137
1171
        {
 
1172
          if(!(keyinfo->flag & HA_FULLTEXT))
1138
1173
          {
1139
 
            uint32_t key_length=_mi_make_key(info,key,info->lastkey,record,
 
1174
            uint key_length=_mi_make_key(info,key,info->lastkey,record,
1140
1175
                                         start_recpos);
1141
1176
            if (extend)
1142
1177
            {
1156
1191
              }
1157
1192
            }
1158
1193
            else
1159
 
              key_checksum[key]+=mi_byte_checksum((unsigned char*) info->lastkey,
 
1194
              key_checksum[key]+=mi_byte_checksum((uchar*) info->lastkey,
1160
1195
                                                  key_length);
1161
1196
          }
1162
1197
        }
1172
1207
  }
1173
1208
  if (param->testflag & T_WRITE_LOOP)
1174
1209
  {
1175
 
    fputs("          \r",stdout); fflush(stdout);
 
1210
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1176
1211
  }
1177
1212
  if (records != info->state->records)
1178
1213
  {
1199
1234
  {
1200
1235
    for (key=0 ; key < info->s->base.keys;  key++)
1201
1236
    {
1202
 
      if (key_checksum[key] != param->key_crc[key])
 
1237
      if (key_checksum[key] != param->key_crc[key] &&
 
1238
          !(info->s->keyinfo[key].flag & (HA_FULLTEXT | HA_SPATIAL)))
1203
1239
      {
1204
1240
        mi_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records",
1205
1241
                    key+1);
1265
1301
    printf("Lost space:   %12s    Linkdata:     %10s\n",
1266
1302
           llstr(empty,llbuff),llstr(link_used,llbuff2));
1267
1303
  }
1268
 
  free(mi_get_rec_buff_ptr(info, record));
 
1304
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1269
1305
  return (error);
1270
1306
 err:
1271
1307
  mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
1272
1308
 err2:
1273
 
  free(mi_get_rec_buff_ptr(info, record));
 
1309
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1274
1310
  param->testflag|=T_RETRY_WITHOUT_QUICK;
1275
1311
  return(1);
1276
1312
} /* chk_data_link */
1329
1365
    then recrate all indexes.
1330
1366
*/
1331
1367
 
1332
 
static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, bool force)
 
1368
static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, my_bool force)
1333
1369
{
1334
1370
  MYISAM_SHARE *share= info->s;
1335
1371
  MI_STATE_INFO *state= &share->state;
1336
 
  uint32_t i;
 
1372
  uint i;
1337
1373
  int error;
1338
1374
 
1339
1375
  /*
1415
1451
  SORT_INFO sort_info;
1416
1452
  MI_SORT_PARAM sort_param;
1417
1453
 
1418
 
  memset(&sort_info, 0, sizeof(sort_info));
1419
 
  memset(&sort_param, 0, sizeof(sort_param));
 
1454
  bzero((char *)&sort_info, sizeof(sort_info));
 
1455
  bzero((char *)&sort_param, sizeof(sort_param));
1420
1456
  start_records=info->state->records;
1421
1457
  new_header_length=(param->testflag & T_UNPACK) ? 0L :
1422
1458
    share->pack.header_length;
1435
1471
    param->testflag|=T_CALC_CHECKSUM;
1436
1472
 
1437
1473
  if (!param->using_global_keycache)
1438
 
    init_key_cache(dflt_key_cache, param->key_cache_block_size,
1439
 
                   param->use_buffers, 0, 0);
 
1474
    VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
 
1475
                        param->use_buffers, 0, 0));
1440
1476
 
1441
1477
  if (init_io_cache(&param->read_cache,info->dfile,
1442
1478
                    (uint) param->read_buffer_length,
1443
1479
                    READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
1444
1480
  {
1445
 
    memset(&info->rec_cache, 0, sizeof(info->rec_cache));
 
1481
    bzero(&info->rec_cache,sizeof(info->rec_cache));
1446
1482
    goto err;
1447
1483
  }
1448
1484
  if (!rep_quick)
1461
1497
  if (!rep_quick)
1462
1498
  {
1463
1499
    /* Get real path for data file */
1464
 
    if ((new_file=my_create(fn_format(param->temp_filename,
1465
 
                                      share->data_file_name, "",
1466
 
                                      DATA_TMP_EXT, 2+4),
1467
 
                            0,param->tmpfile_createflag,
1468
 
                            MYF(0))) < 0)
 
1500
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
1501
                                           share->data_file_name, "",
 
1502
                                           DATA_TMP_EXT, 2+4),
 
1503
                                 0,param->tmpfile_createflag,
 
1504
                                 share->base.raid_type,
 
1505
                                 share->base.raid_chunks,
 
1506
                                 share->base.raid_chunksize,
 
1507
                                 MYF(0))) < 0)
1469
1508
    {
1470
1509
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
1471
 
                           param->temp_filename);
 
1510
                           param->temp_filename);
1472
1511
      goto err;
1473
1512
    }
1474
1513
    if (new_header_length &&
1475
1514
        filecopy(param,new_file,info->dfile,0L,new_header_length,
1476
 
                 "datafile-header"))
 
1515
                 "datafile-header"))
1477
1516
      goto err;
1478
1517
    info->s->state.dellink= HA_OFFSET_ERROR;
1479
1518
    info->rec_cache.file=new_file;
1491
1530
  param->read_cache.end_of_file=sort_info.filelength=
1492
1531
    my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
1493
1532
  sort_info.dupp=0;
1494
 
  sort_param.fix_datafile= (bool) (! rep_quick);
 
1533
  sort_param.fix_datafile= (my_bool) (! rep_quick);
1495
1534
  sort_param.master=1;
1496
1535
  sort_info.max_records= ~(ha_rows) 0;
1497
1536
 
1525
1564
                          llstr(info->dupp_key_pos,llbuff2));
1526
1565
      if (param->testflag & T_VERBOSE)
1527
1566
      {
1528
 
        _mi_make_key(info,(uint) info->errkey,info->lastkey,
1529
 
                     sort_param.record,0L);
 
1567
        VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
 
1568
                          sort_param.record,0L));
1530
1569
      }
1531
1570
      sort_info.dupp++;
1532
1571
      if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
1540
1579
    if (sort_write_record(&sort_param))
1541
1580
      goto err;
1542
1581
  }
1543
 
  if (error > 0 || write_data_suffix(&sort_info, (bool)!rep_quick) ||
 
1582
  if (error > 0 || write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
1544
1583
      flush_io_cache(&info->rec_cache) || param->read_cache.error < 0)
1545
1584
    goto err;
1546
1585
 
1547
1586
  if (param->testflag & T_WRITE_LOOP)
1548
1587
  {
1549
 
    fputs("          \r",stdout); fflush(stdout);
 
1588
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1550
1589
  }
1551
1590
  if (ftruncate(share->kfile, info->state->key_file_length))
1552
1591
  {
1628
1667
                  llstr(sort_param.start_recpos,llbuff));
1629
1668
    if (new_file >= 0)
1630
1669
    {
1631
 
      my_close(new_file,MYF(0));
1632
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
1670
      VOID(my_close(new_file,MYF(0)));
 
1671
      VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
 
1672
                          MYF(MY_WME)));
1633
1673
      info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
1634
1674
    }
1635
1675
    mi_mark_crashed_on_repair(info);
1636
1676
  }
1637
 
 
1638
 
  void * rec_buff_ptr= NULL;
1639
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
1640
 
  if (rec_buff_ptr != NULL)
1641
 
    free(rec_buff_ptr);
1642
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1643
 
  if (rec_buff_ptr != NULL)
1644
 
    free(rec_buff_ptr);
1645
 
  rec_buff_ptr= NULL;
1646
 
 
1647
 
  free(sort_info.buff);
1648
 
  end_io_cache(&param->read_cache);
 
1677
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
1678
                            MYF(MY_ALLOW_ZERO_PTR));
 
1679
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
1680
          MYF(MY_ALLOW_ZERO_PTR));
 
1681
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
1682
  VOID(end_io_cache(&param->read_cache));
1649
1683
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1650
 
  end_io_cache(&info->rec_cache);
 
1684
  VOID(end_io_cache(&info->rec_cache));
1651
1685
  got_error|=flush_blocks(param, share->key_cache, share->kfile);
1652
1686
  if (!got_error && param->testflag & T_UNPACK)
1653
1687
  {
1654
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
1688
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
1655
1689
    share->pack.header_length=0;
1656
1690
    share->data_file_type=sort_info.new_data_file_type;
1657
1691
  }
1665
1699
 
1666
1700
static int writekeys(MI_SORT_PARAM *sort_param)
1667
1701
{
1668
 
  register uint32_t i;
1669
 
  unsigned char    *key;
 
1702
  register uint i;
 
1703
  uchar    *key;
1670
1704
  MI_INFO  *info=   sort_param->sort_info->info;
1671
 
  unsigned char    *buff=   sort_param->record;
 
1705
  uchar    *buff=   sort_param->record;
1672
1706
  my_off_t filepos= sort_param->filepos;
1673
1707
 
1674
1708
  key=info->lastkey+info->s->base.max_key_length;
1677
1711
    if (mi_is_key_active(info->s->state.key_map, i))
1678
1712
    {
1679
1713
      {
1680
 
        uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1714
        uint key_length=_mi_make_key(info,i,key,buff,filepos);
1681
1715
        if (_mi_ck_write(info,i,key,key_length))
1682
1716
          goto err;
1683
1717
      }
1694
1728
      if (mi_is_key_active(info->s->state.key_map, i))
1695
1729
      {
1696
1730
        {
1697
 
          uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1731
          uint key_length=_mi_make_key(info,i,key,buff,filepos);
1698
1732
          if (_mi_ck_delete(info,i,key,key_length))
1699
1733
            break;
1700
1734
        }
1710
1744
 
1711
1745
        /* Change all key-pointers that points to a records */
1712
1746
 
1713
 
int movepoint(register MI_INFO *info, unsigned char *record, my_off_t oldpos,
1714
 
              my_off_t newpos, uint32_t prot_key)
 
1747
int movepoint(register MI_INFO *info, uchar *record, my_off_t oldpos,
 
1748
              my_off_t newpos, uint prot_key)
1715
1749
{
1716
 
  register uint32_t i;
1717
 
  unsigned char *key;
1718
 
  uint32_t key_length;
 
1750
  register uint i;
 
1751
  uchar *key;
 
1752
  uint key_length;
1719
1753
 
1720
1754
  key=info->lastkey+info->s->base.max_key_length;
1721
1755
  for (i=0 ; i < info->s->base.keys; i++)
1725
1759
      key_length=_mi_make_key(info,i,key,record,oldpos);
1726
1760
      if (info->s->keyinfo[i].flag & HA_NOSAME)
1727
1761
      {                                 /* Change pointer direct */
1728
 
        uint32_t nod_flag;
 
1762
        uint nod_flag;
1729
1763
        MI_KEYDEF *keyinfo;
1730
1764
        keyinfo=info->s->keyinfo+i;
1731
1765
        if (_mi_search(info,keyinfo,key,USE_WHOLE_KEY,
1788
1822
 
1789
1823
int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name)
1790
1824
{
1791
 
  register uint32_t key;
 
1825
  register uint key;
1792
1826
  register MI_KEYDEF *keyinfo;
1793
1827
  File new_file;
1794
1828
  my_off_t index_pos[HA_MAX_POSSIBLE_KEY];
1795
 
  uint32_t r_locks,w_locks;
 
1829
  uint r_locks,w_locks;
1796
1830
  int old_lock;
1797
1831
  MYISAM_SHARE *share=info->s;
1798
1832
  MI_STATE_INFO old_state;
1848
1882
        /* Put same locks as old file */
1849
1883
  share->r_locks= share->w_locks= share->tot_locks= 0;
1850
1884
  (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
1851
 
  my_close(share->kfile,MYF(MY_WME));
 
1885
  VOID(my_close(share->kfile,MYF(MY_WME)));
1852
1886
  share->kfile = -1;
1853
 
  my_close(new_file,MYF(MY_WME));
 
1887
  VOID(my_close(new_file,MYF(MY_WME)));
1854
1888
  if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
1855
1889
                        MYF(0)) ||
1856
1890
      mi_open_keyfile(share))
1874
1908
  return(0);
1875
1909
 
1876
1910
err:
1877
 
  my_close(new_file,MYF(MY_WME));
 
1911
  VOID(my_close(new_file,MYF(MY_WME)));
1878
1912
err2:
1879
 
  my_delete(param->temp_filename,MYF(MY_WME));
 
1913
  VOID(my_delete(param->temp_filename,MYF(MY_WME)));
1880
1914
  return(-1);
1881
1915
} /* mi_sort_index */
1882
1916
 
1886
1920
static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
1887
1921
                          my_off_t pagepos, File new_file)
1888
1922
{
1889
 
  uint32_t length,nod_flag,used_length, key_length;
1890
 
  unsigned char *buff,*keypos,*endpos;
1891
 
  unsigned char key[HA_MAX_POSSIBLE_KEY_BUFF];
 
1923
  uint length,nod_flag,used_length, key_length;
 
1924
  uchar *buff,*keypos,*endpos;
 
1925
  uchar key[HA_MAX_POSSIBLE_KEY_BUFF];
1892
1926
  my_off_t new_page_pos,next_page;
1893
1927
  char llbuff[22];
1894
1928
 
1895
1929
  new_page_pos=param->new_file_pos;
1896
1930
  param->new_file_pos+=keyinfo->block_length;
1897
1931
 
1898
 
  if (!(buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
 
1932
  if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
1899
1933
  {
1900
1934
    mi_check_print_error(param,"Not enough memory for key block");
1901
1935
    return(-1);
1906
1940
                llstr(pagepos,llbuff));
1907
1941
    goto err;
1908
1942
  }
1909
 
  if ((nod_flag=mi_test_if_nod(buff)))
 
1943
  if ((nod_flag=mi_test_if_nod(buff)) || keyinfo->flag & HA_FULLTEXT)
1910
1944
  {
1911
1945
    used_length=mi_getint(buff);
1912
1946
    keypos=buff+2+nod_flag;
1931
1965
 
1932
1966
  /* Fill block with zero and write it to the new index file */
1933
1967
  length=mi_getint(buff);
1934
 
  memset(buff+length, 0, keyinfo->block_length-length);
1935
 
  if (my_pwrite(new_file,(unsigned char*) buff,(uint) keyinfo->block_length,
 
1968
  bzero((uchar*) buff+length,keyinfo->block_length-length);
 
1969
  if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
1936
1970
                new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
1937
1971
  {
1938
1972
    mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
1939
1973
    goto err;
1940
1974
  }
1941
 
  my_afree((unsigned char*) buff);
 
1975
  my_afree((uchar*) buff);
1942
1976
  return(0);
1943
1977
err:
1944
 
  my_afree((unsigned char*) buff);
 
1978
  my_afree((uchar*) buff);
1945
1979
  return(1);
1946
1980
} /* sort_one_index */
1947
1981
 
1957
1991
 
1958
1992
int change_to_newfile(const char * filename, const char * old_ext,
1959
1993
                      const char * new_ext,
1960
 
                      uint32_t raid_chunks __attribute__((unused)),
 
1994
                      uint raid_chunks __attribute__((unused)),
1961
1995
                      myf MyFlags)
1962
1996
{
1963
1997
  char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
1978
2012
  char tmp_buff[IO_SIZE],*buff;
1979
2013
  ulong buff_length;
1980
2014
 
1981
 
  buff_length=(ulong) cmin(param->write_buffer_length,length);
 
2015
  buff_length=(ulong) min(param->write_buffer_length,length);
1982
2016
  if (!(buff=my_malloc(buff_length,MYF(0))))
1983
2017
  {
1984
2018
    buff=tmp_buff; buff_length=IO_SIZE;
1985
2019
  }
1986
2020
 
1987
 
  my_seek(from,start,MY_SEEK_SET,MYF(0));
 
2021
  VOID(my_seek(from,start,MY_SEEK_SET,MYF(0)));
1988
2022
  while (length > buff_length)
1989
2023
  {
1990
 
    if (my_read(from,(unsigned char*) buff,buff_length,MYF(MY_NABP)) ||
1991
 
        my_write(to,(unsigned char*) buff,buff_length,param->myf_rw))
 
2024
    if (my_read(from,(uchar*) buff,buff_length,MYF(MY_NABP)) ||
 
2025
        my_write(to,(uchar*) buff,buff_length,param->myf_rw))
1992
2026
      goto err;
1993
2027
    length-= buff_length;
1994
2028
  }
1995
 
  if (my_read(from,(unsigned char*) buff,(uint) length,MYF(MY_NABP)) ||
1996
 
      my_write(to,(unsigned char*) buff,(uint) length,param->myf_rw))
 
2029
  if (my_read(from,(uchar*) buff,(uint) length,MYF(MY_NABP)) ||
 
2030
      my_write(to,(uchar*) buff,(uint) length,param->myf_rw))
1997
2031
    goto err;
1998
2032
  if (buff != tmp_buff)
1999
 
    free(buff);
 
2033
    my_free(buff,MYF(0));
2000
2034
  return(0);
2001
2035
err:
2002
2036
  if (buff != tmp_buff)
2003
 
    free(buff);
 
2037
    my_free(buff,MYF(0));
2004
2038
  mi_check_print_error(param,"Can't copy %s to tempfile, error %d",
2005
2039
                       type,my_errno);
2006
2040
  return(1);
2026
2060
                      const char * name, int rep_quick)
2027
2061
{
2028
2062
  int got_error;
2029
 
  uint32_t i;
 
2063
  uint i;
2030
2064
  ulong length;
2031
2065
  ha_rows start_records;
2032
2066
  my_off_t new_header_length,del;
2054
2088
  if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
2055
2089
    param->testflag|=T_CALC_CHECKSUM;
2056
2090
 
2057
 
  memset(&sort_info, 0, sizeof(sort_info));
2058
 
  memset(&sort_param, 0, sizeof(sort_param));
 
2091
  bzero((char*)&sort_info,sizeof(sort_info));
 
2092
  bzero((char *)&sort_param, sizeof(sort_param));
2059
2093
  if (!(sort_info.key_block=
2060
2094
        alloc_key_blocks(param,
2061
2095
                         (uint) param->sort_key_blocks,
2082
2116
  if (!rep_quick)
2083
2117
  {
2084
2118
    /* Get real path for data file */
2085
 
    if ((new_file=my_create(fn_format(param->temp_filename,
2086
 
                                      share->data_file_name, "",
2087
 
                                      DATA_TMP_EXT, 2+4),
2088
 
                            0,param->tmpfile_createflag,
2089
 
                            MYF(0))) < 0)
 
2119
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2120
                                           share->data_file_name, "",
 
2121
                                           DATA_TMP_EXT, 2+4),
 
2122
                                 0,param->tmpfile_createflag,
 
2123
                                 share->base.raid_type,
 
2124
                                 share->base.raid_chunks,
 
2125
                                 share->base.raid_chunksize,
 
2126
                                 MYF(0))) < 0)
2090
2127
    {
2091
2128
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2092
 
                           param->temp_filename);
 
2129
                           param->temp_filename);
2093
2130
      goto err;
2094
2131
    }
2095
2132
    if (new_header_length &&
2129
2166
  sort_param.wordlist=NULL;
2130
2167
 
2131
2168
  if (share->data_file_type == DYNAMIC_RECORD)
2132
 
    length=cmax(share->base.min_pack_length+1,share->base.min_block_length);
 
2169
    length=max(share->base.min_pack_length+1,share->base.min_block_length);
2133
2170
  else if (share->data_file_type == COMPRESSED_RECORD)
2134
2171
    length=share->base.min_block_length;
2135
2172
  else
2141
2178
  sort_param.lock_in_memory=lock_memory;
2142
2179
  sort_param.tmpdir=param->tmpdir;
2143
2180
  sort_param.sort_info=&sort_info;
2144
 
  sort_param.fix_datafile= (bool) (! rep_quick);
 
2181
  sort_param.fix_datafile= (my_bool) (! rep_quick);
2145
2182
  sort_param.master =1;
2146
2183
  
2147
2184
  del=info->state->del;
2163
2200
    if (! mi_is_key_active(key_map, sort_param.key))
2164
2201
    {
2165
2202
      /* Remember old statistics for key */
2166
 
      assert(rec_per_key_part >= param->rec_per_key_part);
2167
 
      memcpy(rec_per_key_part,
2168
 
             (share->state.rec_per_key_part +
2169
 
              (rec_per_key_part - param->rec_per_key_part)),
 
2203
      memcpy((char*) rec_per_key_part,
 
2204
             (char*) (share->state.rec_per_key_part +
 
2205
                      (uint) (rec_per_key_part - param->rec_per_key_part)),
2170
2206
             sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
2171
2207
      continue;
2172
2208
    }
2175
2211
      printf ("- Fixing index %d\n",sort_param.key+1);
2176
2212
    sort_param.max_pos=sort_param.pos=share->pack.header_length;
2177
2213
    keyseg=sort_param.seg;
2178
 
    memset(sort_param.unique, 0, sizeof(sort_param.unique));
 
2214
    bzero((char*) sort_param.unique,sizeof(sort_param.unique));
2179
2215
    sort_param.key_length=share->rec_reflength;
2180
2216
    for (i=0 ; keyseg[i].type != HA_KEYTYPE_END; i++)
2181
2217
    {
2196
2232
    }
2197
2233
 
2198
2234
    if (_create_index_by_sort(&sort_param,
2199
 
                              (bool) (!(param->testflag & T_VERBOSE)),
 
2235
                              (my_bool) (!(param->testflag & T_VERBOSE)),
2200
2236
                              (uint) param->sort_buffer_length))
2201
2237
    {
2202
2238
      param->retry_repair=1;
2251
2287
 
2252
2288
  if (param->testflag & T_WRITE_LOOP)
2253
2289
  {
2254
 
    fputs("          \r",stdout); fflush(stdout);
 
2290
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
2255
2291
  }
2256
2292
 
2257
2293
  if (rep_quick && del+sort_info.dupp != info->state->del)
2304
2340
 
2305
2341
err:
2306
2342
  got_error|= flush_blocks(param, share->key_cache, share->kfile);
2307
 
  end_io_cache(&info->rec_cache);
 
2343
  VOID(end_io_cache(&info->rec_cache));
2308
2344
  if (!got_error)
2309
2345
  {
2310
2346
    /* Replace the actual file with the temporary file */
2326
2362
      mi_check_print_error(param,"%d when fixing table",my_errno);
2327
2363
    if (new_file >= 0)
2328
2364
    {
2329
 
      my_close(new_file,MYF(0));
2330
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2365
      VOID(my_close(new_file,MYF(0)));
 
2366
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2367
                          MYF(MY_WME)));
2331
2368
      if (info->dfile == new_file)
2332
 
        info->dfile= -1;
 
2369
        info->dfile= -1;
2333
2370
    }
2334
2371
    mi_mark_crashed_on_repair(info);
2335
2372
  }
2337
2374
    share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
2338
2375
  share->state.changed|=STATE_NOT_SORTED_PAGES;
2339
2376
 
2340
 
  void * rec_buff_ptr= NULL;
2341
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
2342
 
  if (rec_buff_ptr != NULL)
2343
 
    free(rec_buff_ptr);
2344
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
2345
 
  if (rec_buff_ptr != NULL)
2346
 
    free(rec_buff_ptr);
2347
 
  rec_buff_ptr= NULL;
2348
 
 
2349
 
  free((unsigned char*) sort_info.key_block);
2350
 
  free(sort_info.buff);
2351
 
  end_io_cache(&param->read_cache);
 
2377
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
2378
                            MYF(MY_ALLOW_ZERO_PTR));
 
2379
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
2380
          MYF(MY_ALLOW_ZERO_PTR));
 
2381
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2382
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2383
  VOID(end_io_cache(&param->read_cache));
2352
2384
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2353
2385
  if (!got_error && (param->testflag & T_UNPACK))
2354
2386
  {
2355
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2387
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2356
2388
    share->pack.header_length=0;
2357
2389
  }
2358
2390
  return(got_error);
2404
2436
                        const char * name, int rep_quick)
2405
2437
{
2406
2438
  int got_error;
2407
 
  uint32_t i,key, total_key_length, istep;
 
2439
  uint i,key, total_key_length, istep;
2408
2440
  ulong rec_length;
2409
2441
  ha_rows start_records;
2410
2442
  my_off_t new_header_length,del;
2464
2496
      position 'new_header_length'.
2465
2497
    }
2466
2498
  */
2467
 
  memset(&sort_info, 0, sizeof(sort_info));
 
2499
  bzero((char*)&sort_info,sizeof(sort_info));
2468
2500
  /* Initialize pthread structures before goto err. */
2469
2501
  pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
2470
2502
  pthread_cond_init(&sort_info.cond, 0);
2492
2524
  if (!rep_quick)
2493
2525
  {
2494
2526
    /* Get real path for data file */
2495
 
    if ((new_file=my_create(fn_format(param->temp_filename,
2496
 
                                      share->data_file_name, "",
2497
 
                                      DATA_TMP_EXT,
2498
 
                                      2+4),
2499
 
                            0,param->tmpfile_createflag,
2500
 
                            MYF(0))) < 0)
 
2527
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2528
                                           share->data_file_name, "",
 
2529
                                           DATA_TMP_EXT,
 
2530
                                           2+4),
 
2531
                                 0,param->tmpfile_createflag,
 
2532
                                 share->base.raid_type,
 
2533
                                 share->base.raid_chunks,
 
2534
                                 share->base.raid_chunksize,
 
2535
                                 MYF(0))) < 0)
2501
2536
    {
2502
2537
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2503
2538
                           param->temp_filename);
2537
2572
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2538
2573
 
2539
2574
  if (share->data_file_type == DYNAMIC_RECORD)
2540
 
    rec_length=cmax(share->base.min_pack_length+1,share->base.min_block_length);
 
2575
    rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
2541
2576
  else if (share->data_file_type == COMPRESSED_RECORD)
2542
2577
    rec_length=share->base.min_block_length;
2543
2578
  else
2590
2625
    if (! mi_is_key_active(key_map, key))
2591
2626
    {
2592
2627
      /* Remember old statistics for key */
2593
 
      assert(rec_per_key_part >= param->rec_per_key_part);
2594
 
      memcpy(rec_per_key_part,
2595
 
             (share->state.rec_per_key_part +
2596
 
              (rec_per_key_part - param->rec_per_key_part)),
 
2628
      memcpy((char*) rec_per_key_part,
 
2629
             (char*) (share->state.rec_per_key_part+
 
2630
                      (uint) (rec_per_key_part - param->rec_per_key_part)),
2597
2631
             sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part));
2598
2632
      istep=0;
2599
2633
      continue;
2616
2650
    sort_param[i].filepos=new_header_length;
2617
2651
    sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
2618
2652
 
2619
 
    sort_param[i].record= (((unsigned char *)(sort_param+share->base.keys))+
 
2653
    sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+
2620
2654
                           (max_pack_reclength * i));
2621
2655
    if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
2622
2656
    {
2640
2674
  }
2641
2675
  sort_info.total_keys=i;
2642
2676
  sort_param[0].master= 1;
2643
 
  sort_param[0].fix_datafile= (bool)(! rep_quick);
 
2677
  sort_param[0].fix_datafile= (my_bool)(! rep_quick);
2644
2678
  sort_param[0].calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
2645
2679
 
2646
2680
  sort_info.got_error=0;
2806
2840
    the share by remove_io_thread() or it was not yet started (if the
2807
2841
    error happend before creating the thread).
2808
2842
  */
2809
 
  end_io_cache(&info->rec_cache);
 
2843
  VOID(end_io_cache(&info->rec_cache));
2810
2844
  /*
2811
2845
    Destroy the new data cache in case of non-quick repair. All slave
2812
2846
    threads did either detach from the share by remove_io_thread()
2814
2848
    creating the threads).
2815
2849
  */
2816
2850
  if (!rep_quick)
2817
 
    end_io_cache(&new_data_cache);
 
2851
    VOID(end_io_cache(&new_data_cache));
2818
2852
  if (!got_error)
2819
2853
  {
2820
2854
    /* Replace the actual file with the temporary file */
2836
2870
      mi_check_print_error(param,"%d when fixing table",my_errno);
2837
2871
    if (new_file >= 0)
2838
2872
    {
2839
 
      my_close(new_file,MYF(0));
2840
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2873
      VOID(my_close(new_file,MYF(0)));
 
2874
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2875
                          MYF(MY_WME)));
2841
2876
      if (info->dfile == new_file)
2842
 
        info->dfile= -1;
 
2877
        info->dfile= -1;
2843
2878
    }
2844
2879
    mi_mark_crashed_on_repair(info);
2845
2880
  }
2850
2885
  pthread_cond_destroy (&sort_info.cond);
2851
2886
  pthread_mutex_destroy(&sort_info.mutex);
2852
2887
 
2853
 
  free((unsigned char*) sort_info.key_block);
2854
 
  free((unsigned char*) sort_param);
2855
 
  free(sort_info.buff);
2856
 
  end_io_cache(&param->read_cache);
 
2888
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2889
  my_free((uchar*) sort_param,MYF(MY_ALLOW_ZERO_PTR));
 
2890
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2891
  VOID(end_io_cache(&param->read_cache));
2857
2892
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2858
2893
  if (!got_error && (param->testflag & T_UNPACK))
2859
2894
  {
2860
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2895
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2861
2896
    share->pack.header_length=0;
2862
2897
  }
2863
2898
  return(got_error);
2882
2917
  }
2883
2918
  sort_param->real_key_length=
2884
2919
    (info->s->rec_reflength+
2885
 
     _mi_make_key(info, sort_param->key, (unsigned char*) key,
 
2920
     _mi_make_key(info, sort_param->key, (uchar*) key,
2886
2921
                  sort_param->record, sort_param->filepos));
2887
2922
#ifdef HAVE_purify
2888
 
  memset(key+sort_param->real_key_length, 0,
2889
 
         (sort_param->key_length-sort_param->real_key_length));
 
2923
  bzero(key+sort_param->real_key_length,
 
2924
        (sort_param->key_length-sort_param->real_key_length));
2890
2925
#endif
2891
2926
  return(sort_write_record(sort_param));
2892
2927
} /* sort_key_read */
2927
2962
{
2928
2963
  int searching;
2929
2964
  int parallel_flag;
2930
 
  uint32_t found_record,b_type,left_length;
 
2965
  uint found_record,b_type,left_length;
2931
2966
  my_off_t pos;
2932
 
  unsigned char *to= NULL;
 
2967
  uchar *to= NULL;
2933
2968
  MI_BLOCK_INFO block_info;
2934
2969
  SORT_INFO *sort_info=sort_param->sort_info;
2935
2970
  MI_CHECK *param=sort_info->param;
3005
3040
                     llstr(param->search_after_block,llbuff),
3006
3041
                     llstr(sort_param->start_recpos,llbuff2));
3007
3042
        if (_mi_read_cache(&sort_param->read_cache,
3008
 
                           (unsigned char*) block_info.header,pos,
 
3043
                           (uchar*) block_info.header,pos,
3009
3044
                           MI_BLOCK_INFO_HEADER_LENGTH,
3010
3045
                           (! found_record ? READING_NEXT : 0) |
3011
3046
                           parallel_flag | READING_HEADER))
3032
3067
             (block_info.rec_len < (uint) share->base.min_pack_length ||
3033
3068
              block_info.rec_len > (uint) share->base.max_pack_length)))
3034
3069
        {
3035
 
          uint32_t i;
 
3070
          uint i;
3036
3071
          if (param->testflag & T_VERBOSE || searching == 0)
3037
3072
            mi_check_print_info(param,
3038
3073
                                "Wrong bytesec: %3d-%3d-%3d at %10s; Skipped",
3055
3090
        }
3056
3091
        if (b_type & BLOCK_DELETED)
3057
3092
        {
3058
 
          bool error=0;
 
3093
          my_bool error=0;
3059
3094
          if (block_info.block_len+ (uint) (block_info.filepos-pos) <
3060
3095
              share->base.min_block_length)
3061
3096
          {
3191
3226
          streched over the end of the previous buffer contents.
3192
3227
        */
3193
3228
        {
3194
 
          uint32_t header_len= (uint) (block_info.filepos - pos);
3195
 
          uint32_t prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
 
3229
          uint header_len= (uint) (block_info.filepos - pos);
 
3230
          uint prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
3196
3231
 
3197
3232
          if (prefetch_len > block_info.data_len)
3198
3233
            prefetch_len= block_info.data_len;
3267
3302
      searching=1;
3268
3303
    }
3269
3304
  case COMPRESSED_RECORD:
 
3305
    for (searching=0 ;; searching=1, sort_param->pos++)
 
3306
    {
 
3307
      if (_mi_read_cache(&sort_param->read_cache,(uchar*) block_info.header,
 
3308
                         sort_param->pos,
 
3309
                         share->pack.ref_length,READING_NEXT))
 
3310
        return(-1);
 
3311
      if (searching && ! sort_param->fix_datafile)
 
3312
      {
 
3313
        param->error_printed=1;
 
3314
        param->retry_repair=1;
 
3315
        param->testflag|=T_RETRY_WITHOUT_QUICK;
 
3316
        return(1);              /* Something wrong with data */
 
3317
      }
 
3318
      sort_param->start_recpos=sort_param->pos;
 
3319
      if (_mi_pack_get_block_info(info, &sort_param->bit_buff, &block_info,
 
3320
                                  &sort_param->rec_buff, -1, sort_param->pos))
 
3321
        return(-1);
 
3322
      if (!block_info.rec_len &&
 
3323
          sort_param->pos + MEMMAP_EXTRA_MARGIN ==
 
3324
          sort_param->read_cache.end_of_file)
 
3325
        return(-1);
 
3326
      if (block_info.rec_len < (uint) share->min_pack_length ||
 
3327
          block_info.rec_len > (uint) share->max_pack_length)
 
3328
      {
 
3329
        if (! searching)
 
3330
          mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
 
3331
                              block_info.rec_len,
 
3332
                              llstr(sort_param->pos,llbuff));
 
3333
        continue;
 
3334
      }
 
3335
      if (_mi_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
 
3336
                         block_info.filepos, block_info.rec_len,
 
3337
                         READING_NEXT))
 
3338
      {
 
3339
        if (! searching)
 
3340
          mi_check_print_info(param,"Couldn't read whole record from %s",
 
3341
                              llstr(sort_param->pos,llbuff));
 
3342
        continue;
 
3343
      }
 
3344
      if (_mi_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
 
3345
                              sort_param->rec_buff, block_info.rec_len))
 
3346
      {
 
3347
        if (! searching)
 
3348
          mi_check_print_info(param,"Found wrong record at %s",
 
3349
                              llstr(sort_param->pos,llbuff));
 
3350
        continue;
 
3351
      }
 
3352
      if (!sort_param->fix_datafile)
 
3353
      {
 
3354
        sort_param->filepos=sort_param->pos;
 
3355
        if (sort_param->master)
 
3356
          share->state.split++;
 
3357
      }
 
3358
      sort_param->max_pos=(sort_param->pos=block_info.filepos+
 
3359
                         block_info.rec_len);
 
3360
      info->packed_length=block_info.rec_len;
 
3361
      if (sort_param->calc_checksum)
 
3362
        param->glob_crc+= (info->checksum=
 
3363
                           mi_checksum(info, sort_param->record));
 
3364
      return(0);
 
3365
    }
3270
3366
  case BLOCK_RECORD:
3271
3367
    assert(0);                                  /* Impossible */
3272
3368
  }
3292
3388
int sort_write_record(MI_SORT_PARAM *sort_param)
3293
3389
{
3294
3390
  int flag;
 
3391
  uint length;
3295
3392
  ulong block_length,reclength;
3296
 
  unsigned char *from;
 
3393
  uchar *from;
 
3394
  uchar block_buff[8];
3297
3395
  SORT_INFO *sort_info=sort_param->sort_info;
3298
3396
  MI_CHECK *param=sort_info->param;
3299
3397
  MI_INFO *info=sort_info->info;
3361
3459
      /* sort_info->param->glob_crc+=info->checksum; */
3362
3460
      break;
3363
3461
    case COMPRESSED_RECORD:
 
3462
      reclength=info->packed_length;
 
3463
      length= save_pack_length((uint) share->pack.version, block_buff,
 
3464
                               reclength);
 
3465
      if (info->s->base.blobs)
 
3466
        length+= save_pack_length((uint) share->pack.version,
 
3467
                                  block_buff + length, info->blob_length);
 
3468
      if (my_b_write(&info->rec_cache,block_buff,length) ||
 
3469
          my_b_write(&info->rec_cache,(uchar*) sort_param->rec_buff,reclength))
 
3470
      {
 
3471
        mi_check_print_error(param,"%d when writing to datafile",my_errno);
 
3472
        return(1);
 
3473
      }
 
3474
      /* sort_info->param->glob_crc+=info->checksum; */
 
3475
      sort_param->filepos+=reclength+length;
 
3476
      info->s->state.split++;
 
3477
      break;
3364
3478
    case BLOCK_RECORD:
3365
3479
      assert(0);                                  /* Impossible */
3366
3480
    }
3373
3487
    {
3374
3488
      char llbuff[22];
3375
3489
      printf("%s\r", llstr(info->state->records,llbuff));
3376
 
      fflush(stdout);
 
3490
      VOID(fflush(stdout));
3377
3491
    }
3378
3492
  }
3379
3493
  return(0);
3385
3499
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
3386
3500
                        const void *b)
3387
3501
{
3388
 
  uint32_t not_used[2];
3389
 
  return (ha_key_cmp(sort_param->seg, *((unsigned char* const *) a), *((unsigned char* const *) b),
 
3502
  uint not_used[2];
 
3503
  return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b),
3390
3504
                     USE_WHOLE_KEY, SEARCH_SAME, not_used));
3391
3505
} /* sort_key_cmp */
3392
3506
 
3393
3507
 
3394
3508
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
3395
3509
{
3396
 
  uint32_t diff_pos[2];
 
3510
  uint diff_pos[2];
3397
3511
  char llbuff[22],llbuff2[22];
3398
3512
  SORT_INFO *sort_info=sort_param->sort_info;
3399
3513
  MI_CHECK *param= sort_info->param;
3402
3516
  if (sort_info->key_block->inited)
3403
3517
  {
3404
3518
    cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3405
 
                   (unsigned char*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
 
3519
                   (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3406
3520
                   diff_pos);
3407
3521
    if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3408
3522
      ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3409
 
                 (unsigned char*) a, USE_WHOLE_KEY, 
 
3523
                 (uchar*) a, USE_WHOLE_KEY, 
3410
3524
                 SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3411
3525
    else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3412
3526
    {
3413
3527
      diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
3414
3528
                                                 sort_param->notnull,
3415
3529
                                                 sort_info->key_block->lastkey,
3416
 
                                                 (unsigned char*)a);
 
3530
                                                 (uchar*)a);
3417
3531
    }
3418
3532
    sort_param->unique[diff_pos[0]-1]++;
3419
3533
  }
3422
3536
    cmp= -1;
3423
3537
    if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3424
3538
      mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull,
3425
 
                                     (unsigned char*)a);
 
3539
                                     (uchar*)a);
3426
3540
  }
3427
3541
  if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
3428
3542
  {
3429
3543
    sort_info->dupp++;
3430
3544
    sort_info->info->lastpos=get_record_for_key(sort_info->info,
3431
3545
                                                sort_param->keyinfo,
3432
 
                                                (unsigned char*) a);
 
3546
                                                (uchar*) a);
3433
3547
    mi_check_print_warning(param,
3434
3548
                           "Duplicate key for record at %10s against record at %10s",
3435
3549
                           llstr(sort_info->info->lastpos,llbuff),
3442
3556
    return (sort_delete_record(sort_param));
3443
3557
  }
3444
3558
  return (sort_insert_key(sort_param,sort_info->key_block,
3445
 
                          (unsigned char*) a, HA_OFFSET_ERROR));
 
3559
                          (uchar*) a, HA_OFFSET_ERROR));
3446
3560
} /* sort_key_write */
3447
3561
 
3448
3562
 
3449
3563
        /* get pointer to record from a key */
3450
3564
 
3451
3565
static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
3452
 
                                   unsigned char *key)
 
3566
                                   uchar *key)
3453
3567
{
3454
3568
  return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key));
3455
3569
} /* get_record_for_key */
3458
3572
        /* Insert a key in sort-key-blocks */
3459
3573
 
3460
3574
static int sort_insert_key(MI_SORT_PARAM *sort_param,
3461
 
                           register SORT_KEY_BLOCKS *key_block, unsigned char *key,
 
3575
                           register SORT_KEY_BLOCKS *key_block, uchar *key,
3462
3576
                           my_off_t prev_block)
3463
3577
{
3464
 
  uint32_t a_length,t_length,nod_flag;
 
3578
  uint a_length,t_length,nod_flag;
3465
3579
  my_off_t filepos,key_file_length;
3466
 
  unsigned char *anc_buff,*lastkey;
 
3580
  uchar *anc_buff,*lastkey;
3467
3581
  MI_KEY_PARAM s_temp;
3468
3582
  MI_INFO *info;
3469
3583
  MI_KEYDEF *keyinfo=sort_param->keyinfo;
3496
3610
    _mi_kpointer(info,key_block->end_pos,prev_block);
3497
3611
 
3498
3612
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
3499
 
                                (unsigned char*) 0,lastkey,lastkey,key,
 
3613
                                (uchar*) 0,lastkey,lastkey,key,
3500
3614
                                 &s_temp);
3501
3615
  (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
3502
3616
  a_length+=t_length;
3504
3618
  key_block->end_pos+=t_length;
3505
3619
  if (a_length <= keyinfo->block_length)
3506
3620
  {
3507
 
    _mi_move_key(keyinfo,key_block->lastkey,key);
 
3621
    VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
3508
3622
    key_block->last_length=a_length-t_length;
3509
3623
    return(0);
3510
3624
  }
3511
3625
 
3512
3626
        /* Fill block with end-zero and write filled block */
3513
3627
  mi_putint(anc_buff,key_block->last_length,nod_flag);
3514
 
  memset(anc_buff+key_block->last_length, 0,
3515
 
         keyinfo->block_length - key_block->last_length);
 
3628
  bzero((uchar*) anc_buff+key_block->last_length,
 
3629
        keyinfo->block_length- key_block->last_length);
3516
3630
  key_file_length=info->state->key_file_length;
3517
3631
  if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3518
3632
    return(1);
3523
3637
    if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
3524
3638
      return(1);
3525
3639
  }
3526
 
  else if (my_pwrite(info->s->kfile,(unsigned char*) anc_buff,
 
3640
  else if (my_pwrite(info->s->kfile,(uchar*) anc_buff,
3527
3641
                     (uint) keyinfo->block_length,filepos, param->myf_rw))
3528
3642
    return(1);
3529
3643
 
3541
3655
 
3542
3656
static int sort_delete_record(MI_SORT_PARAM *sort_param)
3543
3657
{
3544
 
  uint32_t i;
 
3658
  uint i;
3545
3659
  int old_file,error;
3546
 
  unsigned char *key;
 
3660
  uchar *key;
3547
3661
  SORT_INFO *sort_info=sort_param->sort_info;
3548
3662
  MI_CHECK *param=sort_info->param;
3549
3663
  MI_INFO *info=sort_info->info;
3576
3690
 
3577
3691
    for (i=0 ; i < sort_info->current_key ; i++)
3578
3692
    {
3579
 
      uint32_t key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
 
3693
      uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
3580
3694
      if (_mi_ck_delete(info,i,key,key_length))
3581
3695
      {
3582
3696
        mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
3597
3711
 
3598
3712
int flush_pending_blocks(MI_SORT_PARAM *sort_param)
3599
3713
{
3600
 
  uint32_t nod_flag,length;
 
3714
  uint nod_flag,length;
3601
3715
  my_off_t filepos,key_file_length;
3602
3716
  SORT_KEY_BLOCKS *key_block;
3603
3717
  SORT_INFO *sort_info= sort_param->sort_info;
3614
3728
    if (nod_flag)
3615
3729
      _mi_kpointer(info,key_block->end_pos,filepos);
3616
3730
    key_file_length=info->state->key_file_length;
3617
 
    memset(key_block->buff+length, 0, keyinfo->block_length-length);
 
3731
    bzero((uchar*) key_block->buff+length, keyinfo->block_length-length);
3618
3732
    if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3619
3733
      return(1);
3620
3734
 
3625
3739
                            DFLT_INIT_HITS, key_block->buff))
3626
3740
        return(1);
3627
3741
    }
3628
 
    else if (my_pwrite(info->s->kfile,(unsigned char*) key_block->buff,
 
3742
    else if (my_pwrite(info->s->kfile,(uchar*) key_block->buff,
3629
3743
                       (uint) keyinfo->block_length,filepos, myf_rw))
3630
3744
      return(1);
3631
3745
    nod_flag=1;
3636
3750
 
3637
3751
        /* alloc space and pointers for key_blocks */
3638
3752
 
3639
 
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
3640
 
                                         uint32_t buffer_length)
 
3753
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
 
3754
                                         uint buffer_length)
3641
3755
{
3642
 
  register uint32_t i;
 
3756
  register uint i;
3643
3757
  SORT_KEY_BLOCKS *block;
3644
3758
 
3645
3759
  if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
3652
3766
  for (i=0 ; i < blocks ; i++)
3653
3767
  {
3654
3768
    block[i].inited=0;
3655
 
    block[i].buff=(unsigned char*) (block+blocks)+(buffer_length+IO_SIZE)*i;
 
3769
    block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i;
3656
3770
  }
3657
3771
  return(block);
3658
3772
} /* alloc_key_blocks */
3682
3796
  MI_COLUMNDEF *recdef,*rec,*end;
3683
3797
  MI_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
3684
3798
  MI_STATUS_INFO status_info;
3685
 
  uint32_t unpack,key_parts;
 
3799
  uint unpack,key_parts;
3686
3800
  ha_rows max_records;
3687
3801
  uint64_t file_length,tmp_length;
3688
3802
  MI_CREATE_INFO create_info;
3696
3810
    (param->testflag & T_UNPACK);
3697
3811
  if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
3698
3812
    return(0);
3699
 
  memcpy(keyinfo,share.keyinfo,sizeof(MI_KEYDEF)*share.base.keys);
 
3813
  memcpy((uchar*) keyinfo,(uchar*) share.keyinfo,
 
3814
         (size_t) (sizeof(MI_KEYDEF)*share.base.keys));
3700
3815
 
3701
3816
  key_parts= share.base.all_key_parts;
3702
3817
  if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
3703
3818
                                       (key_parts+share.base.keys))))
3704
3819
  {
3705
 
    my_afree((unsigned char*) keyinfo);
 
3820
    my_afree((uchar*) keyinfo);
3706
3821
    return(1);
3707
3822
  }
3708
3823
  if (!(recdef=(MI_COLUMNDEF*)
3709
3824
        my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3710
3825
  {
3711
 
    my_afree((unsigned char*) keyinfo);
3712
 
    my_afree((unsigned char*) keysegs);
 
3826
    my_afree((uchar*) keyinfo);
 
3827
    my_afree((uchar*) keysegs);
3713
3828
    return(1);
3714
3829
  }
3715
3830
  if (!(uniquedef=(MI_UNIQUEDEF*)
3716
3831
        my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
3717
3832
  {
3718
 
    my_afree((unsigned char*) recdef);
3719
 
    my_afree((unsigned char*) keyinfo);
3720
 
    my_afree((unsigned char*) keysegs);
 
3833
    my_afree((uchar*) recdef);
 
3834
    my_afree((uchar*) keyinfo);
 
3835
    my_afree((uchar*) keysegs);
3721
3836
    return(1);
3722
3837
  }
3723
3838
 
3724
3839
  /* Copy the column definitions */
3725
 
  memcpy(recdef, share.rec, sizeof(MI_COLUMNDEF)*(share.base.fields+1));
 
3840
  memcpy((uchar*) recdef,(uchar*) share.rec,
 
3841
         (size_t) (sizeof(MI_COLUMNDEF)*(share.base.fields+1)));
3726
3842
  for (rec=recdef,end=recdef+share.base.fields; rec != end ; rec++)
3727
3843
  {
3728
3844
    if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
3733
3849
  }
3734
3850
 
3735
3851
  /* Change the new key to point at the saved key segments */
3736
 
  memcpy(keysegs,share.keyparts,
3737
 
         sizeof(HA_KEYSEG)*(key_parts+share.base.keys+
3738
 
                            share.state.header.uniques));
 
3852
  memcpy((uchar*) keysegs,(uchar*) share.keyparts,
 
3853
         (size_t) (sizeof(HA_KEYSEG)*(key_parts+share.base.keys+
 
3854
                                      share.state.header.uniques)));
3739
3855
  keyseg=keysegs;
3740
3856
  for (key=keyinfo,key_end=keyinfo+share.base.keys; key != key_end ; key++)
3741
3857
  {
3750
3866
 
3751
3867
  /* Copy the unique definitions and change them to point at the new key
3752
3868
     segments*/
3753
 
  memcpy(uniquedef,share.uniqueinfo,
3754
 
         sizeof(MI_UNIQUEDEF)*(share.state.header.uniques));
 
3869
  memcpy((uchar*) uniquedef,(uchar*) share.uniqueinfo,
 
3870
         (size_t) (sizeof(MI_UNIQUEDEF)*(share.state.header.uniques)));
3755
3871
  for (u_ptr=uniquedef,u_end=uniquedef+share.state.header.uniques;
3756
3872
       u_ptr != u_end ; u_ptr++)
3757
3873
  {
3775
3891
  set_if_bigger(file_length,tmp_length);
3776
3892
  set_if_bigger(file_length,(uint64_t) share.base.max_data_file_length);
3777
3893
 
3778
 
  mi_close(*org_info);
3779
 
  memset(&create_info, 0, sizeof(create_info));
3780
 
  create_info.max_rows=cmax(max_records,share.base.records);
 
3894
  VOID(mi_close(*org_info));
 
3895
  bzero((char*) &create_info,sizeof(create_info));
 
3896
  create_info.max_rows=max(max_records,share.base.records);
3781
3897
  create_info.reloc_rows=share.base.reloc;
3782
3898
  create_info.old_options=(share.options |
3783
3899
                           (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
3816
3932
  }
3817
3933
  /* We are modifing */
3818
3934
  (*org_info)->s->options&= ~HA_OPTION_READ_ONLY_DATA;
3819
 
  _mi_readinfo(*org_info,F_WRLCK,0);
 
3935
  VOID(_mi_readinfo(*org_info,F_WRLCK,0));
3820
3936
  (*org_info)->state->records=info.state->records;
3821
3937
  if (share.state.create_time)
3822
3938
    (*org_info)->s->state.create_time=share.state.create_time;
3832
3948
    goto end;
3833
3949
  error=0;
3834
3950
end:
3835
 
  my_afree((unsigned char*) uniquedef);
3836
 
  my_afree((unsigned char*) keyinfo);
3837
 
  my_afree((unsigned char*) recdef);
3838
 
  my_afree((unsigned char*) keysegs);
 
3951
  my_afree((uchar*) uniquedef);
 
3952
  my_afree((uchar*) keyinfo);
 
3953
  my_afree((uchar*) recdef);
 
3954
  my_afree((uchar*) keysegs);
3839
3955
  return(error);
3840
3956
}
3841
3957
 
3842
3958
 
3843
3959
        /* write suffix to data file if neaded */
3844
3960
 
3845
 
int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile)
 
3961
int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
3846
3962
{
3847
3963
  MI_INFO *info=sort_info->info;
3848
3964
 
3849
3965
  if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
3850
3966
  {
3851
 
    unsigned char buff[MEMMAP_EXTRA_MARGIN];
3852
 
    memset(buff, 0, sizeof(buff));
 
3967
    uchar buff[MEMMAP_EXTRA_MARGIN];
 
3968
    bzero(buff,sizeof(buff));
3853
3969
    if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
3854
3970
    {
3855
3971
      mi_check_print_error(sort_info->param,
3863
3979
 
3864
3980
        /* Update state and myisamchk_time of indexfile */
3865
3981
 
3866
 
int update_state_info(MI_CHECK *param, MI_INFO *info,uint32_t update)
 
3982
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
3867
3983
{
3868
3984
  MYISAM_SHARE *share=info->s;
3869
3985
 
3874
3990
  }
3875
3991
  if (update & UPDATE_STAT)
3876
3992
  {
3877
 
    uint32_t i, key_parts= mi_uint2korr(share->state.header.key_parts);
 
3993
    uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
3878
3994
    share->state.rec_per_key_rows=info->state->records;
3879
3995
    share->state.changed&= ~STATE_NOT_ANALYZED;
3880
3996
    if (info->state->records)
3908
4024
  }
3909
4025
  {                                             /* Force update of status */
3910
4026
    int error;
3911
 
    uint32_t r_locks=share->r_locks,w_locks=share->w_locks;
 
4027
    uint r_locks=share->r_locks,w_locks=share->w_locks;
3912
4028
    share->r_locks= share->w_locks= share->tot_locks= 0;
3913
4029
    error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK);
3914
4030
    share->r_locks=r_locks;
3936
4052
        */
3937
4053
 
3938
4054
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
3939
 
                               bool repair_only)
 
4055
                               my_bool repair_only)
3940
4056
{
3941
 
  unsigned char *record= 0;
 
4057
  uchar *record= 0;
3942
4058
 
3943
4059
  if (!info->s->base.auto_key ||
3944
4060
      ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1))
3968
4084
    if (my_errno != HA_ERR_END_OF_FILE)
3969
4085
    {
3970
4086
      mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3971
 
      free(mi_get_rec_buff_ptr(info, record));
 
4087
      my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3972
4088
      mi_check_print_error(param,"%d when reading last record",my_errno);
3973
4089
      return;
3974
4090
    }
3983
4099
      set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
3984
4100
  }
3985
4101
  mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3986
 
  free(mi_get_rec_buff_ptr(info, record));
 
4102
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3987
4103
  update_state_info(param, info, UPDATE_AUTO_INC);
3988
4104
  return;
3989
4105
}
4046
4162
{
4047
4163
  uint64_t count=0,tmp, unique_tuples;
4048
4164
  uint64_t tuples= records;
4049
 
  uint32_t parts;
 
4165
  uint parts;
4050
4166
  for (parts=0 ; parts < keyinfo->keysegs  ; parts++)
4051
4167
  {
4052
4168
    count+=unique[parts];
4083
4199
}
4084
4200
 
4085
4201
 
4086
 
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length)
 
4202
static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
4087
4203
{
4088
4204
  ha_checksum crc;
4089
 
  const unsigned char *end=buf+length;
 
4205
  const uchar *end=buf+length;
4090
4206
  for (crc=0; buf != end; buf++)
4091
 
    crc=((crc << 1) + *((unsigned char*) buf)) +
 
4207
    crc=((crc << 1) + *((uchar*) buf)) +
4092
4208
      test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1)));
4093
4209
  return crc;
4094
4210
}
4095
4211
 
4096
 
static bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
 
4212
static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
4097
4213
{
4098
 
  uint32_t key_maxlength=key->maxlength;
4099
 
  return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY) &&
 
4214
  uint key_maxlength=key->maxlength;
 
4215
  return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
4100
4216
          ((uint64_t) rows * key_maxlength >
4101
4217
           (uint64_t) myisam_max_temp_length));
4102
4218
}
4114
4230
{
4115
4231
  MYISAM_SHARE *share=info->s;
4116
4232
  MI_KEYDEF    *key=share->keyinfo;
4117
 
  uint32_t          i;
 
4233
  uint          i;
4118
4234
 
4119
4235
  assert(info->state->records == 0 &&
4120
4236
              (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES));
4121
4237
  for (i=0 ; i < share->base.keys ; i++,key++)
4122
4238
  {
4123
 
    if (!(key->flag & (HA_NOSAME | HA_AUTO_KEY)) &&
 
4239
    if (!(key->flag & (HA_NOSAME | HA_SPATIAL | HA_AUTO_KEY)) &&
4124
4240
        ! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1)
4125
4241
    {
4126
4242
      mi_clear_key_active(share->state.key_map, i);
4136
4252
  even if the temporary file would be quite big!
4137
4253
*/
4138
4254
 
4139
 
bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
4140
 
                            uint64_t key_map, bool force)
 
4255
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
 
4256
                            uint64_t key_map, my_bool force)
4141
4257
{
4142
4258
  MYISAM_SHARE *share=info->s;
4143
4259
  MI_KEYDEF *key=share->keyinfo;
4144
 
  uint32_t i;
 
4260
  uint i;
4145
4261
 
4146
4262
  /*
4147
4263
    mi_repair_by_sort only works if we have at least one key. If we don't
4172
4288
      sort_info->new_data_file_type = STATIC_RECORD;
4173
4289
 
4174
4290
    /* Set delete_function for sort_delete_record() */
4175
 
    memcpy(&tmp, share, sizeof(*share));
 
4291
    memcpy((char*) &tmp, share, sizeof(*share));
4176
4292
    tmp.options= ~HA_OPTION_COMPRESS_RECORD;
4177
4293
    mi_setup_functions(&tmp);
4178
4294
    share->delete_record=tmp.delete_record;