~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_check.c

  • Committer: Monty Taylor
  • Date: 2008-08-09 02:24:34 UTC
  • mto: (266.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 279.
  • Revision ID: monty@inaugust.com-20080809022434-97na8pnugghskxip
Removed mystringslt conv lib and replaced it with a noinst lib.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
#ifdef HAVE_SYS_VADVISE_H
47
47
#include <sys/vadvise.h>
48
48
#endif
49
 
#ifdef HAVE_SYS_TYPES
50
 
#include <sys/types.h>
51
 
#endif
52
49
#ifdef HAVE_SYS_MMAN_H
53
50
#include <sys/mman.h>
54
51
#endif
60
57
 
61
58
        /* Functions defined in this file */
62
59
 
63
 
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint32_t nr);
 
60
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr);
64
61
static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
65
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
66
 
                     ha_checksum *key_checksum, uint32_t level);
67
 
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);
68
65
static ha_checksum calc_checksum(ha_rows count);
69
66
static int writekeys(MI_SORT_PARAM *sort_param);
70
67
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
74
71
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
75
72
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
76
73
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
77
 
                                unsigned char *key);
 
74
                                uchar *key);
78
75
static int sort_insert_key(MI_SORT_PARAM  *sort_param,
79
76
                           register SORT_KEY_BLOCKS *key_block,
80
 
                           unsigned char *key, my_off_t prev_block);
 
77
                           uchar *key, my_off_t prev_block);
81
78
static int sort_delete_record(MI_SORT_PARAM *sort_param);
82
79
/*static int flush_pending_blocks(MI_CHECK *param);*/
83
 
static SORT_KEY_BLOCKS  *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
84
 
                                          uint32_t buffer_length);
85
 
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);
86
83
static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
87
84
 
88
85
void myisamchk_init(MI_CHECK *param)
120
117
  if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0))
121
118
  {
122
119
    /* Don't count this as a real warning, as check can correct this ! */
123
 
    uint32_t save=param->warning_printed;
 
120
    uint save=param->warning_printed;
124
121
    mi_check_print_warning(param,
125
122
                           share->state.open_count==1 ? 
126
123
                           "%d client is using or hasn't closed the table properly" : 
135
132
 
136
133
        /* Check delete links */
137
134
 
138
 
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)
139
136
{
140
137
  register ha_rows i;
141
 
  uint32_t delete_link_length;
 
138
  uint delete_link_length;
142
139
  my_off_t empty, next_link, old_link= 0;
143
140
  char buff[22],buff2[22];
144
141
 
170
167
        printf(" %9s",llstr(next_link,buff));
171
168
      if (next_link >= info->state->data_file_length)
172
169
        goto wrong;
173
 
      if (my_pread(info->dfile, (unsigned char*) buff,delete_link_length,
 
170
      if (my_pread(info->dfile, (uchar*) buff,delete_link_length,
174
171
                   next_link,MYF(MY_NABP)))
175
172
      {
176
173
        if (test_flag & T_VERBOSE) puts("");
201
198
      else
202
199
      {
203
200
        param->record_checksum+=(ha_checksum) next_link;
204
 
        next_link=_mi_rec_pos(info->s,(unsigned char*) buff+1);
 
201
        next_link=_mi_rec_pos(info->s,(uchar*) buff+1);
205
202
        empty+=info->s->base.pack_reclength;
206
203
      }
207
204
    }
242
239
 
243
240
        /* Check delete links in index file */
244
241
 
245
 
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)
246
243
{
247
244
  my_off_t next_link;
248
 
  uint32_t block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
 
245
  uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
249
246
  ha_rows records;
250
247
  char llbuff[21], llbuff2[21];
251
 
  unsigned char *buff;
 
248
  uchar *buff;
252
249
 
253
250
  if (param->testflag & T_VERBOSE)
254
251
    printf("block_size %4u:", block_size); /* purecov: tested */
292
289
    */
293
290
    if (!(buff=key_cache_read(info->s->key_cache,
294
291
                              info->s->kfile, next_link, DFLT_INIT_HITS,
295
 
                              (unsigned char*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
 
292
                              (uchar*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
296
293
                              MI_MIN_KEY_BLOCK_LENGTH, 1)))
297
294
    {
298
295
      /* purecov: begin tested */
395
392
 
396
393
int chk_key(MI_CHECK *param, register MI_INFO *info)
397
394
{
398
 
  uint32_t key,found_keys=0,full_text_keys=0,result=0;
 
395
  uint key,found_keys=0,full_text_keys=0,result=0;
399
396
  ha_rows keys;
400
397
  ha_checksum old_record_checksum,init_checksum;
401
398
  my_off_t all_keydata,all_totaldata,key_totlength,length;
523
520
      /* Check that there isn't a row with auto_increment = 0 in the table */
524
521
      mi_extra(info,HA_EXTRA_KEYREAD,0);
525
522
      memset(info->lastkey, 0, keyinfo->seg->length);
526
 
      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,
527
524
                   (key_part_map)1, HA_READ_KEY_EXACT))
528
525
      {
529
526
        /* Don't count this as a real warning, as myisamchk can't correct it */
530
 
        uint32_t save=param->warning_printed;
 
527
        uint save=param->warning_printed;
531
528
        mi_check_print_warning(param, "Found row where the auto_increment "
532
529
                               "column has the value 0");
533
530
        param->warning_printed=save;
576
573
 
577
574
 
578
575
static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
579
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
580
 
                     ha_checksum *key_checksum, uint32_t level)
 
576
                     my_off_t page, uchar *buff, ha_rows *keys,
 
577
                     ha_checksum *key_checksum, uint level)
581
578
{
582
579
  char llbuff[22],llbuff2[22];
583
580
 
647
644
 
648
645
static
649
646
void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, uint64_t *notnull,
650
 
                                    unsigned char *key)
 
647
                                    uchar *key)
651
648
{
652
 
  uint32_t first_null, kp;
 
649
  uint first_null, kp;
653
650
  first_null= ha_find_null(keyseg, key) - keyseg;
654
651
  /*
655
652
    All prefix tuples that don't include keypart_{first_null} are not-null
687
684
 
688
685
static
689
686
int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, uint64_t *notnull,
690
 
                                  unsigned char *prev_key, unsigned char *last_key)
 
687
                                  uchar *prev_key, uchar *last_key)
691
688
{
692
 
  uint32_t diffs[2];
693
 
  uint32_t first_null_seg, kp;
 
689
  uint diffs[2];
 
690
  uint first_null_seg, kp;
694
691
  HA_KEYSEG *seg;
695
692
 
696
693
  /* 
722
719
        /* Check if index is ok */
723
720
 
724
721
static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
725
 
                     my_off_t page, unsigned char *buff, ha_rows *keys,
726
 
                     ha_checksum *key_checksum, uint32_t level)
 
722
                     my_off_t page, uchar *buff, ha_rows *keys,
 
723
                     ha_checksum *key_checksum, uint level)
727
724
{
728
725
  int flag;
729
 
  uint32_t used_length,comp_flag,nod_flag,key_length=0;
730
 
  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;
731
728
  my_off_t next_page,record;
732
729
  char llbuff[22];
733
 
  uint32_t diff_pos[2];
 
730
  uint diff_pos[2];
734
731
 
735
 
  if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
 
732
  if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
736
733
  {
737
734
    mi_check_print_error(param,"Not enough memory for keyblock");
738
735
    return(-1);
814
811
                                         key);
815
812
      }
816
813
    }
817
 
    (*key_checksum)+= mi_byte_checksum((unsigned char*) key,
 
814
    (*key_checksum)+= mi_byte_checksum((uchar*) key,
818
815
                                       key_length- info->s->rec_reflength);
819
816
    record= _mi_dpos(info,0,key+key_length);
820
817
    if (record >= info->state->data_file_length)
830
827
                llstr(page,llbuff), used_length, (keypos - buff));
831
828
    goto err;
832
829
  }
833
 
  my_afree((unsigned char*) temp_buff);
 
830
  my_afree((uchar*) temp_buff);
834
831
  return(0);
835
832
 err:
836
 
  my_afree((unsigned char*) temp_buff);
 
833
  my_afree((uchar*) temp_buff);
837
834
  return(1);
838
835
} /* chk_index */
839
836
 
862
859
 
863
860
        /* Calc length of key in normal isam */
864
861
 
865
 
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)
866
863
{
867
 
  uint32_t length;
 
864
  uint length;
868
865
  HA_KEYSEG *keyseg;
869
866
 
870
867
  length= info->s->rec_reflength;
884
881
  ha_rows records, del_blocks;
885
882
  my_off_t used, empty, pos, splits, start_recpos= 0,
886
883
           del_length, link_used, start_block;
887
 
  unsigned char *record= NULL, *to= NULL;
 
884
  uchar *record= NULL, *to= NULL;
888
885
  char llbuff[22],llbuff2[22],llbuff3[22];
889
886
  ha_checksum intern_record_checksum;
890
887
  ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY];
891
 
  bool static_row_size;
 
888
  my_bool static_row_size;
892
889
  MI_KEYDEF *keyinfo;
893
890
  MI_BLOCK_INFO block_info;
894
891
 
934
931
      goto err2;
935
932
    switch (info->s->data_file_type) {
936
933
    case STATIC_RECORD:
937
 
      if (my_b_read(&param->read_cache,(unsigned char*) record,
 
934
      if (my_b_read(&param->read_cache,(uchar*) record,
938
935
                    info->s->base.pack_reclength))
939
936
        goto err;
940
937
      start_recpos=pos;
954
951
      block_info.next_filepos=pos;
955
952
      do
956
953
      {
957
 
        if (_mi_read_cache(&param->read_cache,(unsigned char*) block_info.header,
 
954
        if (_mi_read_cache(&param->read_cache,(uchar*) block_info.header,
958
955
                           (start_block=block_info.next_filepos),
959
956
                           sizeof(block_info.header),
960
957
                           (flag ? 0 : READING_NEXT) | READING_HEADER))
1058
1055
          got_error=1;
1059
1056
          break;
1060
1057
        }
1061
 
        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,
1062
1059
                           (uint) block_info.data_len,
1063
1060
                           flag == 1 ? READING_NEXT : 0))
1064
1061
          goto err;
1119
1116
        pos=block_info.filepos+block_info.block_len;
1120
1117
      break;
1121
1118
    case COMPRESSED_RECORD:
 
1119
      if (_mi_read_cache(&param->read_cache,(uchar*) block_info.header, pos,
 
1120
                         info->s->pack.ref_length, READING_NEXT))
 
1121
        goto err;
 
1122
      start_recpos=pos;
 
1123
      splits++;
 
1124
      VOID(_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
 
1125
                                   &info->rec_buff, -1, start_recpos));
 
1126
      pos=block_info.filepos+block_info.rec_len;
 
1127
      if (block_info.rec_len < (uint) info->s->min_pack_length ||
 
1128
          block_info.rec_len > (uint) info->s->max_pack_length)
 
1129
      {
 
1130
        mi_check_print_error(param,
 
1131
                             "Found block with wrong recordlength: %d at %s",
 
1132
                             block_info.rec_len, llstr(start_recpos,llbuff));
 
1133
        got_error=1;
 
1134
        break;
 
1135
      }
 
1136
      if (_mi_read_cache(&param->read_cache,(uchar*) info->rec_buff,
 
1137
                        block_info.filepos, block_info.rec_len, READING_NEXT))
 
1138
        goto err;
 
1139
      if (_mi_pack_rec_unpack(info, &info->bit_buff, record,
 
1140
                              info->rec_buff, block_info.rec_len))
 
1141
      {
 
1142
        mi_check_print_error(param,"Found wrong record at %s",
 
1143
                             llstr(start_recpos,llbuff));
 
1144
        got_error=1;
 
1145
      }
 
1146
      if (static_row_size)
 
1147
        param->glob_crc+= mi_static_checksum(info,record);
 
1148
      else
 
1149
        param->glob_crc+= mi_checksum(info,record);
 
1150
      link_used+= (block_info.filepos - start_recpos);
 
1151
      used+= (pos-start_recpos);
1122
1152
    case BLOCK_RECORD:
1123
1153
      assert(0);                                /* Impossible */
1124
1154
    } /* switch */
1128
1158
      records++;
1129
1159
      if (param->testflag & T_WRITE_LOOP && records % WRITE_COUNT == 0)
1130
1160
      {
1131
 
        printf("%s\r", llstr(records,llbuff)); fflush(stdout);
 
1161
        printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout));
1132
1162
      }
1133
1163
 
1134
1164
      /* Check if keys match the record */
1139
1169
        if (mi_is_key_active(info->s->state.key_map, key))
1140
1170
        {
1141
1171
          {
1142
 
            uint32_t key_length=_mi_make_key(info,key,info->lastkey,record,
 
1172
            uint key_length=_mi_make_key(info,key,info->lastkey,record,
1143
1173
                                         start_recpos);
1144
1174
            if (extend)
1145
1175
            {
1159
1189
              }
1160
1190
            }
1161
1191
            else
1162
 
              key_checksum[key]+=mi_byte_checksum((unsigned char*) info->lastkey,
 
1192
              key_checksum[key]+=mi_byte_checksum((uchar*) info->lastkey,
1163
1193
                                                  key_length);
1164
1194
          }
1165
1195
        }
1175
1205
  }
1176
1206
  if (param->testflag & T_WRITE_LOOP)
1177
1207
  {
1178
 
    fputs("          \r",stdout); fflush(stdout);
 
1208
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1179
1209
  }
1180
1210
  if (records != info->state->records)
1181
1211
  {
1268
1298
    printf("Lost space:   %12s    Linkdata:     %10s\n",
1269
1299
           llstr(empty,llbuff),llstr(link_used,llbuff2));
1270
1300
  }
1271
 
  free(mi_get_rec_buff_ptr(info, record));
 
1301
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1272
1302
  return (error);
1273
1303
 err:
1274
1304
  mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
1275
1305
 err2:
1276
 
  free(mi_get_rec_buff_ptr(info, record));
 
1306
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
1277
1307
  param->testflag|=T_RETRY_WITHOUT_QUICK;
1278
1308
  return(1);
1279
1309
} /* chk_data_link */
1332
1362
    then recrate all indexes.
1333
1363
*/
1334
1364
 
1335
 
static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, bool force)
 
1365
static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, my_bool force)
1336
1366
{
1337
1367
  MYISAM_SHARE *share= info->s;
1338
1368
  MI_STATE_INFO *state= &share->state;
1339
 
  uint32_t i;
 
1369
  uint i;
1340
1370
  int error;
1341
1371
 
1342
1372
  /*
1438
1468
    param->testflag|=T_CALC_CHECKSUM;
1439
1469
 
1440
1470
  if (!param->using_global_keycache)
1441
 
    init_key_cache(dflt_key_cache, param->key_cache_block_size,
1442
 
                   param->use_buffers, 0, 0);
 
1471
    VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
 
1472
                        param->use_buffers, 0, 0));
1443
1473
 
1444
1474
  if (init_io_cache(&param->read_cache,info->dfile,
1445
1475
                    (uint) param->read_buffer_length,
1497
1527
  param->read_cache.end_of_file=sort_info.filelength=
1498
1528
    my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
1499
1529
  sort_info.dupp=0;
1500
 
  sort_param.fix_datafile= (bool) (! rep_quick);
 
1530
  sort_param.fix_datafile= (my_bool) (! rep_quick);
1501
1531
  sort_param.master=1;
1502
1532
  sort_info.max_records= ~(ha_rows) 0;
1503
1533
 
1531
1561
                          llstr(info->dupp_key_pos,llbuff2));
1532
1562
      if (param->testflag & T_VERBOSE)
1533
1563
      {
1534
 
        _mi_make_key(info,(uint) info->errkey,info->lastkey,
1535
 
                     sort_param.record,0L);
 
1564
        VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
 
1565
                          sort_param.record,0L));
1536
1566
      }
1537
1567
      sort_info.dupp++;
1538
1568
      if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
1546
1576
    if (sort_write_record(&sort_param))
1547
1577
      goto err;
1548
1578
  }
1549
 
  if (error > 0 || write_data_suffix(&sort_info, (bool)!rep_quick) ||
 
1579
  if (error > 0 || write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
1550
1580
      flush_io_cache(&info->rec_cache) || param->read_cache.error < 0)
1551
1581
    goto err;
1552
1582
 
1553
1583
  if (param->testflag & T_WRITE_LOOP)
1554
1584
  {
1555
 
    fputs("          \r",stdout); fflush(stdout);
 
1585
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
1556
1586
  }
1557
1587
  if (ftruncate(share->kfile, info->state->key_file_length))
1558
1588
  {
1634
1664
                  llstr(sort_param.start_recpos,llbuff));
1635
1665
    if (new_file >= 0)
1636
1666
    {
1637
 
      my_close(new_file,MYF(0));
1638
 
      my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
1639
 
                     MYF(MY_WME));
 
1667
      VOID(my_close(new_file,MYF(0)));
 
1668
      VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
 
1669
                          MYF(MY_WME)));
1640
1670
      info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
1641
1671
    }
1642
1672
    mi_mark_crashed_on_repair(info);
1643
1673
  }
1644
 
 
1645
 
  void * rec_buff_ptr= NULL;
1646
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
1647
 
  if (rec_buff_ptr != NULL)
1648
 
    free(rec_buff_ptr);
1649
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1650
 
  if (rec_buff_ptr != NULL)
1651
 
    free(rec_buff_ptr);
1652
 
  rec_buff_ptr= NULL;
1653
 
 
1654
 
  free(sort_info.buff);
1655
 
  end_io_cache(&param->read_cache);
 
1674
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
1675
                            MYF(MY_ALLOW_ZERO_PTR));
 
1676
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
1677
          MYF(MY_ALLOW_ZERO_PTR));
 
1678
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
1679
  VOID(end_io_cache(&param->read_cache));
1656
1680
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1657
 
  end_io_cache(&info->rec_cache);
 
1681
  VOID(end_io_cache(&info->rec_cache));
1658
1682
  got_error|=flush_blocks(param, share->key_cache, share->kfile);
1659
1683
  if (!got_error && param->testflag & T_UNPACK)
1660
1684
  {
1661
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
1685
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
1662
1686
    share->pack.header_length=0;
1663
1687
    share->data_file_type=sort_info.new_data_file_type;
1664
1688
  }
1672
1696
 
1673
1697
static int writekeys(MI_SORT_PARAM *sort_param)
1674
1698
{
1675
 
  register uint32_t i;
1676
 
  unsigned char    *key;
 
1699
  register uint i;
 
1700
  uchar    *key;
1677
1701
  MI_INFO  *info=   sort_param->sort_info->info;
1678
 
  unsigned char    *buff=   sort_param->record;
 
1702
  uchar    *buff=   sort_param->record;
1679
1703
  my_off_t filepos= sort_param->filepos;
1680
1704
 
1681
1705
  key=info->lastkey+info->s->base.max_key_length;
1684
1708
    if (mi_is_key_active(info->s->state.key_map, i))
1685
1709
    {
1686
1710
      {
1687
 
        uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1711
        uint key_length=_mi_make_key(info,i,key,buff,filepos);
1688
1712
        if (_mi_ck_write(info,i,key,key_length))
1689
1713
          goto err;
1690
1714
      }
1701
1725
      if (mi_is_key_active(info->s->state.key_map, i))
1702
1726
      {
1703
1727
        {
1704
 
          uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
 
1728
          uint key_length=_mi_make_key(info,i,key,buff,filepos);
1705
1729
          if (_mi_ck_delete(info,i,key,key_length))
1706
1730
            break;
1707
1731
        }
1717
1741
 
1718
1742
        /* Change all key-pointers that points to a records */
1719
1743
 
1720
 
int movepoint(register MI_INFO *info, unsigned char *record, my_off_t oldpos,
1721
 
              my_off_t newpos, uint32_t prot_key)
 
1744
int movepoint(register MI_INFO *info, uchar *record, my_off_t oldpos,
 
1745
              my_off_t newpos, uint prot_key)
1722
1746
{
1723
 
  register uint32_t i;
1724
 
  unsigned char *key;
1725
 
  uint32_t key_length;
 
1747
  register uint i;
 
1748
  uchar *key;
 
1749
  uint key_length;
1726
1750
 
1727
1751
  key=info->lastkey+info->s->base.max_key_length;
1728
1752
  for (i=0 ; i < info->s->base.keys; i++)
1732
1756
      key_length=_mi_make_key(info,i,key,record,oldpos);
1733
1757
      if (info->s->keyinfo[i].flag & HA_NOSAME)
1734
1758
      {                                 /* Change pointer direct */
1735
 
        uint32_t nod_flag;
 
1759
        uint nod_flag;
1736
1760
        MI_KEYDEF *keyinfo;
1737
1761
        keyinfo=info->s->keyinfo+i;
1738
1762
        if (_mi_search(info,keyinfo,key,USE_WHOLE_KEY,
1795
1819
 
1796
1820
int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name)
1797
1821
{
1798
 
  register uint32_t key;
 
1822
  register uint key;
1799
1823
  register MI_KEYDEF *keyinfo;
1800
1824
  File new_file;
1801
1825
  my_off_t index_pos[HA_MAX_POSSIBLE_KEY];
1802
 
  uint32_t r_locks,w_locks;
 
1826
  uint r_locks,w_locks;
1803
1827
  int old_lock;
1804
1828
  MYISAM_SHARE *share=info->s;
1805
1829
  MI_STATE_INFO old_state;
1855
1879
        /* Put same locks as old file */
1856
1880
  share->r_locks= share->w_locks= share->tot_locks= 0;
1857
1881
  (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
1858
 
  my_close(share->kfile,MYF(MY_WME));
 
1882
  VOID(my_close(share->kfile,MYF(MY_WME)));
1859
1883
  share->kfile = -1;
1860
 
  my_close(new_file,MYF(MY_WME));
 
1884
  VOID(my_close(new_file,MYF(MY_WME)));
1861
1885
  if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
1862
1886
                        MYF(0)) ||
1863
1887
      mi_open_keyfile(share))
1881
1905
  return(0);
1882
1906
 
1883
1907
err:
1884
 
  my_close(new_file,MYF(MY_WME));
 
1908
  VOID(my_close(new_file,MYF(MY_WME)));
1885
1909
err2:
1886
 
  my_delete(param->temp_filename,MYF(MY_WME));
 
1910
  VOID(my_delete(param->temp_filename,MYF(MY_WME)));
1887
1911
  return(-1);
1888
1912
} /* mi_sort_index */
1889
1913
 
1893
1917
static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
1894
1918
                          my_off_t pagepos, File new_file)
1895
1919
{
1896
 
  uint32_t length,nod_flag,used_length, key_length;
1897
 
  unsigned char *buff,*keypos,*endpos;
1898
 
  unsigned char key[HA_MAX_POSSIBLE_KEY_BUFF];
 
1920
  uint length,nod_flag,used_length, key_length;
 
1921
  uchar *buff,*keypos,*endpos;
 
1922
  uchar key[HA_MAX_POSSIBLE_KEY_BUFF];
1899
1923
  my_off_t new_page_pos,next_page;
1900
1924
  char llbuff[22];
1901
1925
 
1902
1926
  new_page_pos=param->new_file_pos;
1903
1927
  param->new_file_pos+=keyinfo->block_length;
1904
1928
 
1905
 
  if (!(buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
 
1929
  if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
1906
1930
  {
1907
1931
    mi_check_print_error(param,"Not enough memory for key block");
1908
1932
    return(-1);
1939
1963
  /* Fill block with zero and write it to the new index file */
1940
1964
  length=mi_getint(buff);
1941
1965
  memset(buff+length, 0, keyinfo->block_length-length);
1942
 
  if (my_pwrite(new_file,(unsigned char*) buff,(uint) keyinfo->block_length,
 
1966
  if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
1943
1967
                new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
1944
1968
  {
1945
1969
    mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
1946
1970
    goto err;
1947
1971
  }
1948
 
  my_afree((unsigned char*) buff);
 
1972
  my_afree((uchar*) buff);
1949
1973
  return(0);
1950
1974
err:
1951
 
  my_afree((unsigned char*) buff);
 
1975
  my_afree((uchar*) buff);
1952
1976
  return(1);
1953
1977
} /* sort_one_index */
1954
1978
 
1964
1988
 
1965
1989
int change_to_newfile(const char * filename, const char * old_ext,
1966
1990
                      const char * new_ext,
1967
 
                      uint32_t raid_chunks __attribute__((unused)),
 
1991
                      uint raid_chunks __attribute__((unused)),
1968
1992
                      myf MyFlags)
1969
1993
{
1970
1994
  char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
1985
2009
  char tmp_buff[IO_SIZE],*buff;
1986
2010
  ulong buff_length;
1987
2011
 
1988
 
  buff_length=(ulong) cmin(param->write_buffer_length,length);
 
2012
  buff_length=(ulong) min(param->write_buffer_length,length);
1989
2013
  if (!(buff=my_malloc(buff_length,MYF(0))))
1990
2014
  {
1991
2015
    buff=tmp_buff; buff_length=IO_SIZE;
1992
2016
  }
1993
2017
 
1994
 
  my_seek(from,start,MY_SEEK_SET,MYF(0));
 
2018
  VOID(my_seek(from,start,MY_SEEK_SET,MYF(0)));
1995
2019
  while (length > buff_length)
1996
2020
  {
1997
 
    if (my_read(from,(unsigned char*) buff,buff_length,MYF(MY_NABP)) ||
1998
 
        my_write(to,(unsigned char*) buff,buff_length,param->myf_rw))
 
2021
    if (my_read(from,(uchar*) buff,buff_length,MYF(MY_NABP)) ||
 
2022
        my_write(to,(uchar*) buff,buff_length,param->myf_rw))
1999
2023
      goto err;
2000
2024
    length-= buff_length;
2001
2025
  }
2002
 
  if (my_read(from,(unsigned char*) buff,(uint) length,MYF(MY_NABP)) ||
2003
 
      my_write(to,(unsigned char*) buff,(uint) length,param->myf_rw))
 
2026
  if (my_read(from,(uchar*) buff,(uint) length,MYF(MY_NABP)) ||
 
2027
      my_write(to,(uchar*) buff,(uint) length,param->myf_rw))
2004
2028
    goto err;
2005
2029
  if (buff != tmp_buff)
2006
 
    free(buff);
 
2030
    my_free(buff,MYF(0));
2007
2031
  return(0);
2008
2032
err:
2009
2033
  if (buff != tmp_buff)
2010
 
    free(buff);
 
2034
    my_free(buff,MYF(0));
2011
2035
  mi_check_print_error(param,"Can't copy %s to tempfile, error %d",
2012
2036
                       type,my_errno);
2013
2037
  return(1);
2033
2057
                      const char * name, int rep_quick)
2034
2058
{
2035
2059
  int got_error;
2036
 
  uint32_t i;
 
2060
  uint i;
2037
2061
  ulong length;
2038
2062
  ha_rows start_records;
2039
2063
  my_off_t new_header_length,del;
2139
2163
  sort_param.wordlist=NULL;
2140
2164
 
2141
2165
  if (share->data_file_type == DYNAMIC_RECORD)
2142
 
    length=cmax(share->base.min_pack_length+1,share->base.min_block_length);
 
2166
    length=max(share->base.min_pack_length+1,share->base.min_block_length);
2143
2167
  else if (share->data_file_type == COMPRESSED_RECORD)
2144
2168
    length=share->base.min_block_length;
2145
2169
  else
2151
2175
  sort_param.lock_in_memory=lock_memory;
2152
2176
  sort_param.tmpdir=param->tmpdir;
2153
2177
  sort_param.sort_info=&sort_info;
2154
 
  sort_param.fix_datafile= (bool) (! rep_quick);
 
2178
  sort_param.fix_datafile= (my_bool) (! rep_quick);
2155
2179
  sort_param.master =1;
2156
2180
  
2157
2181
  del=info->state->del;
2206
2230
    }
2207
2231
 
2208
2232
    if (_create_index_by_sort(&sort_param,
2209
 
                              (bool) (!(param->testflag & T_VERBOSE)),
 
2233
                              (my_bool) (!(param->testflag & T_VERBOSE)),
2210
2234
                              (uint) param->sort_buffer_length))
2211
2235
    {
2212
2236
      param->retry_repair=1;
2261
2285
 
2262
2286
  if (param->testflag & T_WRITE_LOOP)
2263
2287
  {
2264
 
    fputs("          \r",stdout); fflush(stdout);
 
2288
    VOID(fputs("          \r",stdout)); VOID(fflush(stdout));
2265
2289
  }
2266
2290
 
2267
2291
  if (rep_quick && del+sort_info.dupp != info->state->del)
2314
2338
 
2315
2339
err:
2316
2340
  got_error|= flush_blocks(param, share->key_cache, share->kfile);
2317
 
  end_io_cache(&info->rec_cache);
 
2341
  VOID(end_io_cache(&info->rec_cache));
2318
2342
  if (!got_error)
2319
2343
  {
2320
2344
    /* Replace the actual file with the temporary file */
2336
2360
      mi_check_print_error(param,"%d when fixing table",my_errno);
2337
2361
    if (new_file >= 0)
2338
2362
    {
2339
 
      my_close(new_file,MYF(0));
2340
 
      my_raid_delete(param->temp_filename,share->base.raid_chunks,
2341
 
                     MYF(MY_WME));
 
2363
      VOID(my_close(new_file,MYF(0)));
 
2364
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2365
                          MYF(MY_WME)));
2342
2366
      if (info->dfile == new_file)
2343
2367
        info->dfile= -1;
2344
2368
    }
2348
2372
    share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
2349
2373
  share->state.changed|=STATE_NOT_SORTED_PAGES;
2350
2374
 
2351
 
  void * rec_buff_ptr= NULL;
2352
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.rec_buff);
2353
 
  if (rec_buff_ptr != NULL)
2354
 
    free(rec_buff_ptr);
2355
 
  rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
2356
 
  if (rec_buff_ptr != NULL)
2357
 
    free(rec_buff_ptr);
2358
 
  rec_buff_ptr= NULL;
2359
 
 
2360
 
  free((unsigned char*) sort_info.key_block);
2361
 
  free(sort_info.buff);
2362
 
  end_io_cache(&param->read_cache);
 
2375
  my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
 
2376
                            MYF(MY_ALLOW_ZERO_PTR));
 
2377
  my_free(mi_get_rec_buff_ptr(info, sort_param.record),
 
2378
          MYF(MY_ALLOW_ZERO_PTR));
 
2379
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2380
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2381
  VOID(end_io_cache(&param->read_cache));
2363
2382
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2364
2383
  if (!got_error && (param->testflag & T_UNPACK))
2365
2384
  {
2366
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2385
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2367
2386
    share->pack.header_length=0;
2368
2387
  }
2369
2388
  return(got_error);
2415
2434
                        const char * name, int rep_quick)
2416
2435
{
2417
2436
  int got_error;
2418
 
  uint32_t i,key, total_key_length, istep;
 
2437
  uint i,key, total_key_length, istep;
2419
2438
  ulong rec_length;
2420
2439
  ha_rows start_records;
2421
2440
  my_off_t new_header_length,del;
2551
2570
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2552
2571
 
2553
2572
  if (share->data_file_type == DYNAMIC_RECORD)
2554
 
    rec_length=cmax(share->base.min_pack_length+1,share->base.min_block_length);
 
2573
    rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
2555
2574
  else if (share->data_file_type == COMPRESSED_RECORD)
2556
2575
    rec_length=share->base.min_block_length;
2557
2576
  else
2630
2649
    sort_param[i].filepos=new_header_length;
2631
2650
    sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
2632
2651
 
2633
 
    sort_param[i].record= (((unsigned char *)(sort_param+share->base.keys))+
 
2652
    sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+
2634
2653
                           (max_pack_reclength * i));
2635
2654
    if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
2636
2655
    {
2654
2673
  }
2655
2674
  sort_info.total_keys=i;
2656
2675
  sort_param[0].master= 1;
2657
 
  sort_param[0].fix_datafile= (bool)(! rep_quick);
 
2676
  sort_param[0].fix_datafile= (my_bool)(! rep_quick);
2658
2677
  sort_param[0].calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
2659
2678
 
2660
2679
  sort_info.got_error=0;
2820
2839
    the share by remove_io_thread() or it was not yet started (if the
2821
2840
    error happend before creating the thread).
2822
2841
  */
2823
 
  end_io_cache(&info->rec_cache);
 
2842
  VOID(end_io_cache(&info->rec_cache));
2824
2843
  /*
2825
2844
    Destroy the new data cache in case of non-quick repair. All slave
2826
2845
    threads did either detach from the share by remove_io_thread()
2828
2847
    creating the threads).
2829
2848
  */
2830
2849
  if (!rep_quick)
2831
 
    end_io_cache(&new_data_cache);
 
2850
    VOID(end_io_cache(&new_data_cache));
2832
2851
  if (!got_error)
2833
2852
  {
2834
2853
    /* Replace the actual file with the temporary file */
2850
2869
      mi_check_print_error(param,"%d when fixing table",my_errno);
2851
2870
    if (new_file >= 0)
2852
2871
    {
2853
 
      my_close(new_file,MYF(0));
2854
 
      my_raid_delete(param->temp_filename,share->base.raid_chunks,
2855
 
                     MYF(MY_WME));
 
2872
      VOID(my_close(new_file,MYF(0)));
 
2873
      VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2874
                          MYF(MY_WME)));
2856
2875
      if (info->dfile == new_file)
2857
2876
        info->dfile= -1;
2858
2877
    }
2865
2884
  pthread_cond_destroy (&sort_info.cond);
2866
2885
  pthread_mutex_destroy(&sort_info.mutex);
2867
2886
 
2868
 
  free((unsigned char*) sort_info.key_block);
2869
 
  free((unsigned char*) sort_param);
2870
 
  free(sort_info.buff);
2871
 
  end_io_cache(&param->read_cache);
 
2887
  my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
 
2888
  my_free((uchar*) sort_param,MYF(MY_ALLOW_ZERO_PTR));
 
2889
  my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
 
2890
  VOID(end_io_cache(&param->read_cache));
2872
2891
  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2873
2892
  if (!got_error && (param->testflag & T_UNPACK))
2874
2893
  {
2875
 
    share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
 
2894
    share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2876
2895
    share->pack.header_length=0;
2877
2896
  }
2878
2897
  return(got_error);
2897
2916
  }
2898
2917
  sort_param->real_key_length=
2899
2918
    (info->s->rec_reflength+
2900
 
     _mi_make_key(info, sort_param->key, (unsigned char*) key,
 
2919
     _mi_make_key(info, sort_param->key, (uchar*) key,
2901
2920
                  sort_param->record, sort_param->filepos));
2902
2921
#ifdef HAVE_purify
2903
2922
  memset(key+sort_param->real_key_length, 0,
2942
2961
{
2943
2962
  int searching;
2944
2963
  int parallel_flag;
2945
 
  uint32_t found_record,b_type,left_length;
 
2964
  uint found_record,b_type,left_length;
2946
2965
  my_off_t pos;
2947
 
  unsigned char *to= NULL;
 
2966
  uchar *to= NULL;
2948
2967
  MI_BLOCK_INFO block_info;
2949
2968
  SORT_INFO *sort_info=sort_param->sort_info;
2950
2969
  MI_CHECK *param=sort_info->param;
3020
3039
                     llstr(param->search_after_block,llbuff),
3021
3040
                     llstr(sort_param->start_recpos,llbuff2));
3022
3041
        if (_mi_read_cache(&sort_param->read_cache,
3023
 
                           (unsigned char*) block_info.header,pos,
 
3042
                           (uchar*) block_info.header,pos,
3024
3043
                           MI_BLOCK_INFO_HEADER_LENGTH,
3025
3044
                           (! found_record ? READING_NEXT : 0) |
3026
3045
                           parallel_flag | READING_HEADER))
3047
3066
             (block_info.rec_len < (uint) share->base.min_pack_length ||
3048
3067
              block_info.rec_len > (uint) share->base.max_pack_length)))
3049
3068
        {
3050
 
          uint32_t i;
 
3069
          uint i;
3051
3070
          if (param->testflag & T_VERBOSE || searching == 0)
3052
3071
            mi_check_print_info(param,
3053
3072
                                "Wrong bytesec: %3d-%3d-%3d at %10s; Skipped",
3070
3089
        }
3071
3090
        if (b_type & BLOCK_DELETED)
3072
3091
        {
3073
 
          bool error=0;
 
3092
          my_bool error=0;
3074
3093
          if (block_info.block_len+ (uint) (block_info.filepos-pos) <
3075
3094
              share->base.min_block_length)
3076
3095
          {
3206
3225
          streched over the end of the previous buffer contents.
3207
3226
        */
3208
3227
        {
3209
 
          uint32_t header_len= (uint) (block_info.filepos - pos);
3210
 
          uint32_t prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
 
3228
          uint header_len= (uint) (block_info.filepos - pos);
 
3229
          uint prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
3211
3230
 
3212
3231
          if (prefetch_len > block_info.data_len)
3213
3232
            prefetch_len= block_info.data_len;
3282
3301
      searching=1;
3283
3302
    }
3284
3303
  case COMPRESSED_RECORD:
 
3304
    for (searching=0 ;; searching=1, sort_param->pos++)
 
3305
    {
 
3306
      if (_mi_read_cache(&sort_param->read_cache,(uchar*) block_info.header,
 
3307
                         sort_param->pos,
 
3308
                         share->pack.ref_length,READING_NEXT))
 
3309
        return(-1);
 
3310
      if (searching && ! sort_param->fix_datafile)
 
3311
      {
 
3312
        param->error_printed=1;
 
3313
        param->retry_repair=1;
 
3314
        param->testflag|=T_RETRY_WITHOUT_QUICK;
 
3315
        return(1);              /* Something wrong with data */
 
3316
      }
 
3317
      sort_param->start_recpos=sort_param->pos;
 
3318
      if (_mi_pack_get_block_info(info, &sort_param->bit_buff, &block_info,
 
3319
                                  &sort_param->rec_buff, -1, sort_param->pos))
 
3320
        return(-1);
 
3321
      if (!block_info.rec_len &&
 
3322
          sort_param->pos + MEMMAP_EXTRA_MARGIN ==
 
3323
          sort_param->read_cache.end_of_file)
 
3324
        return(-1);
 
3325
      if (block_info.rec_len < (uint) share->min_pack_length ||
 
3326
          block_info.rec_len > (uint) share->max_pack_length)
 
3327
      {
 
3328
        if (! searching)
 
3329
          mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
 
3330
                              block_info.rec_len,
 
3331
                              llstr(sort_param->pos,llbuff));
 
3332
        continue;
 
3333
      }
 
3334
      if (_mi_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
 
3335
                         block_info.filepos, block_info.rec_len,
 
3336
                         READING_NEXT))
 
3337
      {
 
3338
        if (! searching)
 
3339
          mi_check_print_info(param,"Couldn't read whole record from %s",
 
3340
                              llstr(sort_param->pos,llbuff));
 
3341
        continue;
 
3342
      }
 
3343
      if (_mi_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
 
3344
                              sort_param->rec_buff, block_info.rec_len))
 
3345
      {
 
3346
        if (! searching)
 
3347
          mi_check_print_info(param,"Found wrong record at %s",
 
3348
                              llstr(sort_param->pos,llbuff));
 
3349
        continue;
 
3350
      }
 
3351
      if (!sort_param->fix_datafile)
 
3352
      {
 
3353
        sort_param->filepos=sort_param->pos;
 
3354
        if (sort_param->master)
 
3355
          share->state.split++;
 
3356
      }
 
3357
      sort_param->max_pos=(sort_param->pos=block_info.filepos+
 
3358
                         block_info.rec_len);
 
3359
      info->packed_length=block_info.rec_len;
 
3360
      if (sort_param->calc_checksum)
 
3361
        param->glob_crc+= (info->checksum=
 
3362
                           mi_checksum(info, sort_param->record));
 
3363
      return(0);
 
3364
    }
3285
3365
  case BLOCK_RECORD:
3286
3366
    assert(0);                                  /* Impossible */
3287
3367
  }
3307
3387
int sort_write_record(MI_SORT_PARAM *sort_param)
3308
3388
{
3309
3389
  int flag;
 
3390
  uint length;
3310
3391
  ulong block_length,reclength;
3311
 
  unsigned char *from;
 
3392
  uchar *from;
 
3393
  uchar block_buff[8];
3312
3394
  SORT_INFO *sort_info=sort_param->sort_info;
3313
3395
  MI_CHECK *param=sort_info->param;
3314
3396
  MI_INFO *info=sort_info->info;
3376
3458
      /* sort_info->param->glob_crc+=info->checksum; */
3377
3459
      break;
3378
3460
    case COMPRESSED_RECORD:
 
3461
      reclength=info->packed_length;
 
3462
      length= save_pack_length((uint) share->pack.version, block_buff,
 
3463
                               reclength);
 
3464
      if (info->s->base.blobs)
 
3465
        length+= save_pack_length((uint) share->pack.version,
 
3466
                                  block_buff + length, info->blob_length);
 
3467
      if (my_b_write(&info->rec_cache,block_buff,length) ||
 
3468
          my_b_write(&info->rec_cache,(uchar*) sort_param->rec_buff,reclength))
 
3469
      {
 
3470
        mi_check_print_error(param,"%d when writing to datafile",my_errno);
 
3471
        return(1);
 
3472
      }
 
3473
      /* sort_info->param->glob_crc+=info->checksum; */
 
3474
      sort_param->filepos+=reclength+length;
 
3475
      info->s->state.split++;
 
3476
      break;
3379
3477
    case BLOCK_RECORD:
3380
3478
      assert(0);                                  /* Impossible */
3381
3479
    }
3388
3486
    {
3389
3487
      char llbuff[22];
3390
3488
      printf("%s\r", llstr(info->state->records,llbuff));
3391
 
      fflush(stdout);
 
3489
      VOID(fflush(stdout));
3392
3490
    }
3393
3491
  }
3394
3492
  return(0);
3400
3498
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
3401
3499
                        const void *b)
3402
3500
{
3403
 
  uint32_t not_used[2];
3404
 
  return (ha_key_cmp(sort_param->seg, *((unsigned char* const *) a), *((unsigned char* const *) b),
 
3501
  uint not_used[2];
 
3502
  return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b),
3405
3503
                     USE_WHOLE_KEY, SEARCH_SAME, not_used));
3406
3504
} /* sort_key_cmp */
3407
3505
 
3408
3506
 
3409
3507
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
3410
3508
{
3411
 
  uint32_t diff_pos[2];
 
3509
  uint diff_pos[2];
3412
3510
  char llbuff[22],llbuff2[22];
3413
3511
  SORT_INFO *sort_info=sort_param->sort_info;
3414
3512
  MI_CHECK *param= sort_info->param;
3417
3515
  if (sort_info->key_block->inited)
3418
3516
  {
3419
3517
    cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3420
 
                   (unsigned char*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
 
3518
                   (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3421
3519
                   diff_pos);
3422
3520
    if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3423
3521
      ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3424
 
                 (unsigned char*) a, USE_WHOLE_KEY, 
 
3522
                 (uchar*) a, USE_WHOLE_KEY, 
3425
3523
                 SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3426
3524
    else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3427
3525
    {
3428
3526
      diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
3429
3527
                                                 sort_param->notnull,
3430
3528
                                                 sort_info->key_block->lastkey,
3431
 
                                                 (unsigned char*)a);
 
3529
                                                 (uchar*)a);
3432
3530
    }
3433
3531
    sort_param->unique[diff_pos[0]-1]++;
3434
3532
  }
3437
3535
    cmp= -1;
3438
3536
    if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3439
3537
      mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull,
3440
 
                                     (unsigned char*)a);
 
3538
                                     (uchar*)a);
3441
3539
  }
3442
3540
  if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
3443
3541
  {
3444
3542
    sort_info->dupp++;
3445
3543
    sort_info->info->lastpos=get_record_for_key(sort_info->info,
3446
3544
                                                sort_param->keyinfo,
3447
 
                                                (unsigned char*) a);
 
3545
                                                (uchar*) a);
3448
3546
    mi_check_print_warning(param,
3449
3547
                           "Duplicate key for record at %10s against record at %10s",
3450
3548
                           llstr(sort_info->info->lastpos,llbuff),
3457
3555
    return (sort_delete_record(sort_param));
3458
3556
  }
3459
3557
  return (sort_insert_key(sort_param,sort_info->key_block,
3460
 
                          (unsigned char*) a, HA_OFFSET_ERROR));
 
3558
                          (uchar*) a, HA_OFFSET_ERROR));
3461
3559
} /* sort_key_write */
3462
3560
 
3463
3561
 
3464
3562
        /* get pointer to record from a key */
3465
3563
 
3466
3564
static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
3467
 
                                   unsigned char *key)
 
3565
                                   uchar *key)
3468
3566
{
3469
3567
  return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key));
3470
3568
} /* get_record_for_key */
3473
3571
        /* Insert a key in sort-key-blocks */
3474
3572
 
3475
3573
static int sort_insert_key(MI_SORT_PARAM *sort_param,
3476
 
                           register SORT_KEY_BLOCKS *key_block, unsigned char *key,
 
3574
                           register SORT_KEY_BLOCKS *key_block, uchar *key,
3477
3575
                           my_off_t prev_block)
3478
3576
{
3479
 
  uint32_t a_length,t_length,nod_flag;
 
3577
  uint a_length,t_length,nod_flag;
3480
3578
  my_off_t filepos,key_file_length;
3481
 
  unsigned char *anc_buff,*lastkey;
 
3579
  uchar *anc_buff,*lastkey;
3482
3580
  MI_KEY_PARAM s_temp;
3483
3581
  MI_INFO *info;
3484
3582
  MI_KEYDEF *keyinfo=sort_param->keyinfo;
3511
3609
    _mi_kpointer(info,key_block->end_pos,prev_block);
3512
3610
 
3513
3611
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
3514
 
                                (unsigned char*) 0,lastkey,lastkey,key,
 
3612
                                (uchar*) 0,lastkey,lastkey,key,
3515
3613
                                 &s_temp);
3516
3614
  (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
3517
3615
  a_length+=t_length;
3519
3617
  key_block->end_pos+=t_length;
3520
3618
  if (a_length <= keyinfo->block_length)
3521
3619
  {
3522
 
    _mi_move_key(keyinfo,key_block->lastkey,key);
 
3620
    VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
3523
3621
    key_block->last_length=a_length-t_length;
3524
3622
    return(0);
3525
3623
  }
3538
3636
    if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
3539
3637
      return(1);
3540
3638
  }
3541
 
  else if (my_pwrite(info->s->kfile,(unsigned char*) anc_buff,
 
3639
  else if (my_pwrite(info->s->kfile,(uchar*) anc_buff,
3542
3640
                     (uint) keyinfo->block_length,filepos, param->myf_rw))
3543
3641
    return(1);
3544
3642
 
3556
3654
 
3557
3655
static int sort_delete_record(MI_SORT_PARAM *sort_param)
3558
3656
{
3559
 
  uint32_t i;
 
3657
  uint i;
3560
3658
  int old_file,error;
3561
 
  unsigned char *key;
 
3659
  uchar *key;
3562
3660
  SORT_INFO *sort_info=sort_param->sort_info;
3563
3661
  MI_CHECK *param=sort_info->param;
3564
3662
  MI_INFO *info=sort_info->info;
3591
3689
 
3592
3690
    for (i=0 ; i < sort_info->current_key ; i++)
3593
3691
    {
3594
 
      uint32_t key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
 
3692
      uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
3595
3693
      if (_mi_ck_delete(info,i,key,key_length))
3596
3694
      {
3597
3695
        mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
3612
3710
 
3613
3711
int flush_pending_blocks(MI_SORT_PARAM *sort_param)
3614
3712
{
3615
 
  uint32_t nod_flag,length;
 
3713
  uint nod_flag,length;
3616
3714
  my_off_t filepos,key_file_length;
3617
3715
  SORT_KEY_BLOCKS *key_block;
3618
3716
  SORT_INFO *sort_info= sort_param->sort_info;
3640
3738
                            DFLT_INIT_HITS, key_block->buff))
3641
3739
        return(1);
3642
3740
    }
3643
 
    else if (my_pwrite(info->s->kfile,(unsigned char*) key_block->buff,
 
3741
    else if (my_pwrite(info->s->kfile,(uchar*) key_block->buff,
3644
3742
                       (uint) keyinfo->block_length,filepos, myf_rw))
3645
3743
      return(1);
3646
3744
    nod_flag=1;
3651
3749
 
3652
3750
        /* alloc space and pointers for key_blocks */
3653
3751
 
3654
 
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
3655
 
                                         uint32_t buffer_length)
 
3752
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
 
3753
                                         uint buffer_length)
3656
3754
{
3657
 
  register uint32_t i;
 
3755
  register uint i;
3658
3756
  SORT_KEY_BLOCKS *block;
3659
3757
 
3660
3758
  if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
3667
3765
  for (i=0 ; i < blocks ; i++)
3668
3766
  {
3669
3767
    block[i].inited=0;
3670
 
    block[i].buff=(unsigned char*) (block+blocks)+(buffer_length+IO_SIZE)*i;
 
3768
    block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i;
3671
3769
  }
3672
3770
  return(block);
3673
3771
} /* alloc_key_blocks */
3697
3795
  MI_COLUMNDEF *recdef,*rec,*end;
3698
3796
  MI_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
3699
3797
  MI_STATUS_INFO status_info;
3700
 
  uint32_t unpack,key_parts;
 
3798
  uint unpack,key_parts;
3701
3799
  ha_rows max_records;
3702
3800
  uint64_t file_length,tmp_length;
3703
3801
  MI_CREATE_INFO create_info;
3717
3815
  if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
3718
3816
                                       (key_parts+share.base.keys))))
3719
3817
  {
3720
 
    my_afree((unsigned char*) keyinfo);
 
3818
    my_afree((uchar*) keyinfo);
3721
3819
    return(1);
3722
3820
  }
3723
3821
  if (!(recdef=(MI_COLUMNDEF*)
3724
3822
        my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3725
3823
  {
3726
 
    my_afree((unsigned char*) keyinfo);
3727
 
    my_afree((unsigned char*) keysegs);
 
3824
    my_afree((uchar*) keyinfo);
 
3825
    my_afree((uchar*) keysegs);
3728
3826
    return(1);
3729
3827
  }
3730
3828
  if (!(uniquedef=(MI_UNIQUEDEF*)
3731
3829
        my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
3732
3830
  {
3733
 
    my_afree((unsigned char*) recdef);
3734
 
    my_afree((unsigned char*) keyinfo);
3735
 
    my_afree((unsigned char*) keysegs);
 
3831
    my_afree((uchar*) recdef);
 
3832
    my_afree((uchar*) keyinfo);
 
3833
    my_afree((uchar*) keysegs);
3736
3834
    return(1);
3737
3835
  }
3738
3836
 
3790
3888
  set_if_bigger(file_length,tmp_length);
3791
3889
  set_if_bigger(file_length,(uint64_t) share.base.max_data_file_length);
3792
3890
 
3793
 
  mi_close(*org_info);
 
3891
  VOID(mi_close(*org_info));
3794
3892
  memset(&create_info, 0, sizeof(create_info));
3795
 
  create_info.max_rows=cmax(max_records,share.base.records);
 
3893
  create_info.max_rows=max(max_records,share.base.records);
3796
3894
  create_info.reloc_rows=share.base.reloc;
3797
3895
  create_info.old_options=(share.options |
3798
3896
                           (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
3831
3929
  }
3832
3930
  /* We are modifing */
3833
3931
  (*org_info)->s->options&= ~HA_OPTION_READ_ONLY_DATA;
3834
 
  _mi_readinfo(*org_info,F_WRLCK,0);
 
3932
  VOID(_mi_readinfo(*org_info,F_WRLCK,0));
3835
3933
  (*org_info)->state->records=info.state->records;
3836
3934
  if (share.state.create_time)
3837
3935
    (*org_info)->s->state.create_time=share.state.create_time;
3847
3945
    goto end;
3848
3946
  error=0;
3849
3947
end:
3850
 
  my_afree((unsigned char*) uniquedef);
3851
 
  my_afree((unsigned char*) keyinfo);
3852
 
  my_afree((unsigned char*) recdef);
3853
 
  my_afree((unsigned char*) keysegs);
 
3948
  my_afree((uchar*) uniquedef);
 
3949
  my_afree((uchar*) keyinfo);
 
3950
  my_afree((uchar*) recdef);
 
3951
  my_afree((uchar*) keysegs);
3854
3952
  return(error);
3855
3953
}
3856
3954
 
3857
3955
 
3858
3956
        /* write suffix to data file if neaded */
3859
3957
 
3860
 
int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile)
 
3958
int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
3861
3959
{
3862
3960
  MI_INFO *info=sort_info->info;
3863
3961
 
3864
3962
  if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
3865
3963
  {
3866
 
    unsigned char buff[MEMMAP_EXTRA_MARGIN];
 
3964
    uchar buff[MEMMAP_EXTRA_MARGIN];
3867
3965
    memset(buff, 0, sizeof(buff));
3868
3966
    if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
3869
3967
    {
3878
3976
 
3879
3977
        /* Update state and myisamchk_time of indexfile */
3880
3978
 
3881
 
int update_state_info(MI_CHECK *param, MI_INFO *info,uint32_t update)
 
3979
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
3882
3980
{
3883
3981
  MYISAM_SHARE *share=info->s;
3884
3982
 
3889
3987
  }
3890
3988
  if (update & UPDATE_STAT)
3891
3989
  {
3892
 
    uint32_t i, key_parts= mi_uint2korr(share->state.header.key_parts);
 
3990
    uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
3893
3991
    share->state.rec_per_key_rows=info->state->records;
3894
3992
    share->state.changed&= ~STATE_NOT_ANALYZED;
3895
3993
    if (info->state->records)
3923
4021
  }
3924
4022
  {                                             /* Force update of status */
3925
4023
    int error;
3926
 
    uint32_t r_locks=share->r_locks,w_locks=share->w_locks;
 
4024
    uint r_locks=share->r_locks,w_locks=share->w_locks;
3927
4025
    share->r_locks= share->w_locks= share->tot_locks= 0;
3928
4026
    error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK);
3929
4027
    share->r_locks=r_locks;
3951
4049
        */
3952
4050
 
3953
4051
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
3954
 
                               bool repair_only)
 
4052
                               my_bool repair_only)
3955
4053
{
3956
 
  unsigned char *record= 0;
 
4054
  uchar *record= 0;
3957
4055
 
3958
4056
  if (!info->s->base.auto_key ||
3959
4057
      ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1))
3983
4081
    if (my_errno != HA_ERR_END_OF_FILE)
3984
4082
    {
3985
4083
      mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3986
 
      free(mi_get_rec_buff_ptr(info, record));
 
4084
      my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3987
4085
      mi_check_print_error(param,"%d when reading last record",my_errno);
3988
4086
      return;
3989
4087
    }
3998
4096
      set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
3999
4097
  }
4000
4098
  mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
4001
 
  free(mi_get_rec_buff_ptr(info, record));
 
4099
  my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
4002
4100
  update_state_info(param, info, UPDATE_AUTO_INC);
4003
4101
  return;
4004
4102
}
4061
4159
{
4062
4160
  uint64_t count=0,tmp, unique_tuples;
4063
4161
  uint64_t tuples= records;
4064
 
  uint32_t parts;
 
4162
  uint parts;
4065
4163
  for (parts=0 ; parts < keyinfo->keysegs  ; parts++)
4066
4164
  {
4067
4165
    count+=unique[parts];
4098
4196
}
4099
4197
 
4100
4198
 
4101
 
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length)
 
4199
static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
4102
4200
{
4103
4201
  ha_checksum crc;
4104
 
  const unsigned char *end=buf+length;
 
4202
  const uchar *end=buf+length;
4105
4203
  for (crc=0; buf != end; buf++)
4106
 
    crc=((crc << 1) + *((unsigned char*) buf)) +
 
4204
    crc=((crc << 1) + *((uchar*) buf)) +
4107
4205
      test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1)));
4108
4206
  return crc;
4109
4207
}
4110
4208
 
4111
 
static bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
 
4209
static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
4112
4210
{
4113
 
  uint32_t key_maxlength=key->maxlength;
 
4211
  uint key_maxlength=key->maxlength;
4114
4212
  return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY) &&
4115
4213
          ((uint64_t) rows * key_maxlength >
4116
4214
           (uint64_t) myisam_max_temp_length));
4129
4227
{
4130
4228
  MYISAM_SHARE *share=info->s;
4131
4229
  MI_KEYDEF    *key=share->keyinfo;
4132
 
  uint32_t          i;
 
4230
  uint          i;
4133
4231
 
4134
4232
  assert(info->state->records == 0 &&
4135
4233
              (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES));
4151
4249
  even if the temporary file would be quite big!
4152
4250
*/
4153
4251
 
4154
 
bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
4155
 
                            uint64_t key_map, bool force)
 
4252
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
 
4253
                            uint64_t key_map, my_bool force)
4156
4254
{
4157
4255
  MYISAM_SHARE *share=info->s;
4158
4256
  MI_KEYDEF *key=share->keyinfo;
4159
 
  uint32_t i;
 
4257
  uint i;
4160
4258
 
4161
4259
  /*
4162
4260
    mi_repair_by_sort only works if we have at least one key. If we don't