~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_check.c

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
*/
42
42
 
43
43
#include "myisamdef.h"
44
 
#include <mystrings/m_string.h>
45
44
#include <stdarg.h>
46
45
#include <mysys/my_getopt.h>
47
46
#ifdef HAVE_SYS_VADVISE_H
53
52
#ifdef HAVE_SYS_MMAN_H
54
53
#include <sys/mman.h>
55
54
#endif
56
 
#include <drizzled/util/test.h>
57
 
 
58
 
 
59
 
/* Functions defined in this file */
 
55
 
 
56
#ifndef USE_RAID
 
57
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
 
58
#define my_raid_delete(A,B,C) my_delete(A,B)
 
59
#endif
 
60
 
 
61
        /* Functions defined in this file */
60
62
 
61
63
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint32_t nr);
62
64
static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
120
122
    /* Don't count this as a real warning, as check can correct this ! */
121
123
    uint32_t save=param->warning_printed;
122
124
    mi_check_print_warning(param,
123
 
                           share->state.open_count==1 ?
124
 
                           "%d client is using or hasn't closed the table properly" :
 
125
                           share->state.open_count==1 ? 
 
126
                           "%d client is using or hasn't closed the table properly" : 
125
127
                           "%d clients are using or haven't closed the table properly",
126
128
                           share->state.open_count);
127
129
    /* If this will be fixed by the check, forget the warning */
328
330
  flush_key_blocks(info->s->key_cache,
329
331
                   info->s->kfile, FLUSH_FORCE_WRITE);
330
332
 
331
 
  size= lseek(info->s->kfile, 0, SEEK_END);
 
333
  size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
332
334
  if ((skr=(my_off_t) info->state->key_file_length) != size)
333
335
  {
334
336
    /* Don't give error if file generated by myisampack */
352
354
                           llstr(info->state->key_file_length,buff),
353
355
                           llstr(info->s->base.max_key_file_length-1,buff));
354
356
 
355
 
  size=lseek(info->dfile,0L,SEEK_END);
 
357
  size=my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
356
358
  skr=(my_off_t) info->state->data_file_length;
357
359
  if (info->s->options & HA_OPTION_COMPRESS_RECORD)
358
360
    skr+= MEMMAP_EXTRA_MARGIN;
441
443
    found_keys++;
442
444
 
443
445
    param->record_checksum=init_checksum;
444
 
 
 
446
    
445
447
    memset(&param->unique_count, 0, sizeof(param->unique_count));
446
448
    memset(&param->notnull_count, 0, sizeof(param->notnull_count));
447
449
 
547
549
    if (param->testflag & T_STATISTICS)
548
550
      update_key_parts(keyinfo, rec_per_key_part, param->unique_count,
549
551
                       param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
550
 
                       param->notnull_count: NULL,
 
552
                       param->notnull_count: NULL, 
551
553
                       (uint64_t)info->state->records);
552
554
  }
553
555
  if (param->testflag & T_INFO)
584
586
  {
585
587
    /* purecov: begin tested */
586
588
    /* Give it a chance to fit in the real file size. */
587
 
    my_off_t max_length= lseek(info->s->kfile, 0, SEEK_END);
 
589
    my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END,
 
590
                                 MYF(MY_THREADSAFE));
588
591
    mi_check_print_error(param, "Invalid key block position: %s  "
589
592
                         "key block size: %u  file_length: %s",
590
593
                         llstr(page, llbuff), keyinfo->block_length,
673
676
    1. Find out which prefix tuples of last_key don't contain NULLs, and
674
677
       update the array of notnull counters accordingly.
675
678
    2. Find the first keypart number where the prev_key and last_key tuples
676
 
       are different(A), or last_key has NULL value(B), and return it, so the
677
 
       caller can count number of unique tuples for each key prefix. We don't
678
 
       need (B) to be counted, and that is compensated back in
 
679
       are different(A), or last_key has NULL value(B), and return it, so the 
 
680
       caller can count number of unique tuples for each key prefix. We don't 
 
681
       need (B) to be counted, and that is compensated back in 
679
682
       update_key_parts().
680
683
 
681
684
  RETURN
690
693
  uint32_t first_null_seg, kp;
691
694
  HA_KEYSEG *seg;
692
695
 
693
 
  /*
 
696
  /* 
694
697
     Find the first keypart where values are different or either of them is
695
698
     NULL. We get results in diffs array:
696
699
     diffs[0]= 1 + number of first different keypart
698
701
                      last_key that is NULL or different from corresponding
699
702
                      value in prev_key.
700
703
  */
701
 
  ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY,
 
704
  ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, 
702
705
             SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs);
703
706
  seg= keyseg + diffs[0] - 1;
704
707
 
707
710
  for (kp= 0; kp < first_null_seg; kp++)
708
711
    notnull[kp]++;
709
712
 
710
 
  /*
 
713
  /* 
711
714
    Return 1+ number of first key part where values differ. Don't care if
712
715
    these were NULLs and not .... We compensate for that in
713
716
    update_key_parts.
729
732
  char llbuff[22];
730
733
  uint32_t diff_pos[2];
731
734
 
732
 
  if (!(temp_buff=(unsigned char*) malloc(keyinfo->block_length)))
 
735
  if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
733
736
  {
734
737
    mi_check_print_error(param,"Not enough memory for keyblock");
735
738
    return(-1);
798
801
                     diff_pos);
799
802
        else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
800
803
        {
801
 
          diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg,
 
804
          diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg, 
802
805
                                                  param->notnull_count,
803
806
                                                  info->lastkey, key);
804
807
        }
805
808
        param->unique_count[diff_pos[0]-1]++;
806
809
      }
807
810
      else
808
 
      {
 
811
      {  
809
812
        if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
810
813
          mi_collect_stats_nonulls_first(keyinfo->seg, param->notnull_count,
811
814
                                         key);
827
830
                llstr(page,llbuff), used_length, (keypos - buff));
828
831
    goto err;
829
832
  }
830
 
  free(temp_buff);
 
833
  my_afree((unsigned char*) temp_buff);
831
834
  return(0);
832
835
 err:
833
 
  free(temp_buff);
 
836
  my_afree((unsigned char*) temp_buff);
834
837
  return(1);
835
838
} /* chk_index */
836
839
 
1461
1464
  if (!rep_quick)
1462
1465
  {
1463
1466
    /* 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)
 
1467
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
1468
                                           share->data_file_name, "",
 
1469
                                           DATA_TMP_EXT, 2+4),
 
1470
                                 0,param->tmpfile_createflag,
 
1471
                                 share->base.raid_type,
 
1472
                                 share->base.raid_chunks,
 
1473
                                 share->base.raid_chunksize,
 
1474
                                 MYF(0))) < 0)
1469
1475
    {
1470
1476
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
1471
 
                           param->temp_filename);
 
1477
                           param->temp_filename);
1472
1478
      goto err;
1473
1479
    }
1474
1480
    if (new_header_length &&
1475
1481
        filecopy(param,new_file,info->dfile,0L,new_header_length,
1476
 
                 "datafile-header"))
 
1482
                 "datafile-header"))
1477
1483
      goto err;
1478
1484
    info->s->state.dellink= HA_OFFSET_ERROR;
1479
1485
    info->rec_cache.file=new_file;
1489
1495
  sort_param.pos=sort_param.max_pos=share->pack.header_length;
1490
1496
  sort_param.filepos=new_header_length;
1491
1497
  param->read_cache.end_of_file=sort_info.filelength=
1492
 
    lseek(info->dfile,0L,SEEK_END);
 
1498
    my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
1493
1499
  sort_info.dupp=0;
1494
1500
  sort_param.fix_datafile= (bool) (! rep_quick);
1495
1501
  sort_param.master=1;
1629
1635
    if (new_file >= 0)
1630
1636
    {
1631
1637
      my_close(new_file,MYF(0));
1632
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
1638
      my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
 
1639
                     MYF(MY_WME));
1633
1640
      info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
1634
1641
    }
1635
1642
    mi_mark_crashed_on_repair(info);
1755
1762
 
1756
1763
        /* Tell system that we want all memory for our cache */
1757
1764
 
1758
 
void lock_memory(MI_CHECK *param)
 
1765
void lock_memory(MI_CHECK *param __attribute__((unused)))
1759
1766
{
1760
1767
#ifdef SUN_OS                           /* Key-cacheing thrases on sun 4.1 */
1761
1768
  if (param->opt_lock_memory)
1765
1772
      mi_check_print_warning(param,
1766
1773
                             "Failed to lock memory. errno %d",my_errno);
1767
1774
  }
1768
 
#else
1769
 
  (void)param;
1770
1775
#endif
1771
1776
} /* lock_memory */
1772
1777
 
1897
1902
  new_page_pos=param->new_file_pos;
1898
1903
  param->new_file_pos+=keyinfo->block_length;
1899
1904
 
1900
 
  if (!(buff=(unsigned char*) malloc(keyinfo->block_length)))
 
1905
  if (!(buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
1901
1906
  {
1902
1907
    mi_check_print_error(param,"Not enough memory for key block");
1903
1908
    return(-1);
1940
1945
    mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
1941
1946
    goto err;
1942
1947
  }
1943
 
  free(buff);
 
1948
  my_afree((unsigned char*) buff);
1944
1949
  return(0);
1945
1950
err:
1946
 
  free(buff);
 
1951
  my_afree((unsigned char*) buff);
1947
1952
  return(1);
1948
1953
} /* sort_one_index */
1949
1954
 
1959
1964
 
1960
1965
int change_to_newfile(const char * filename, const char * old_ext,
1961
1966
                      const char * new_ext,
1962
 
                      uint32_t raid_chunks,
 
1967
                      uint32_t raid_chunks __attribute__((unused)),
1963
1968
                      myf MyFlags)
1964
1969
{
1965
 
  (void)raid_chunks;
1966
1970
  char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
1967
1971
  /* Get real path to filename */
1968
1972
  (void) fn_format(old_filename,filename,"",old_ext,2+4+32);
1982
1986
  ulong buff_length;
1983
1987
 
1984
1988
  buff_length=(ulong) cmin(param->write_buffer_length,length);
1985
 
  if (!(buff=malloc(buff_length)))
 
1989
  if (!(buff=my_malloc(buff_length,MYF(0))))
1986
1990
  {
1987
1991
    buff=tmp_buff; buff_length=IO_SIZE;
1988
1992
  }
1989
1993
 
1990
 
  lseek(from,start,SEEK_SET);
 
1994
  my_seek(from,start,MY_SEEK_SET,MYF(0));
1991
1995
  while (length > buff_length)
1992
1996
  {
1993
1997
    if (my_read(from,(unsigned char*) buff,buff_length,MYF(MY_NABP)) ||
2085
2089
  if (!rep_quick)
2086
2090
  {
2087
2091
    /* Get real path for data file */
2088
 
    if ((new_file=my_create(fn_format(param->temp_filename,
2089
 
                                      share->data_file_name, "",
2090
 
                                      DATA_TMP_EXT, 2+4),
2091
 
                            0,param->tmpfile_createflag,
2092
 
                            MYF(0))) < 0)
 
2092
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2093
                                           share->data_file_name, "",
 
2094
                                           DATA_TMP_EXT, 2+4),
 
2095
                                 0,param->tmpfile_createflag,
 
2096
                                 share->base.raid_type,
 
2097
                                 share->base.raid_chunks,
 
2098
                                 share->base.raid_chunksize,
 
2099
                                 MYF(0))) < 0)
2093
2100
    {
2094
2101
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2095
 
                           param->temp_filename);
 
2102
                           param->temp_filename);
2096
2103
      goto err;
2097
2104
    }
2098
2105
    if (new_header_length &&
2127
2134
  sort_info.dupp=0;
2128
2135
  sort_info.buff=0;
2129
2136
  param->read_cache.end_of_file=sort_info.filelength=
2130
 
    lseek(param->read_cache.file,0L,SEEK_END);
 
2137
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2131
2138
 
2132
2139
  sort_param.wordlist=NULL;
2133
2140
 
2142
2149
     (ha_rows) (sort_info.filelength/length+1));
2143
2150
  sort_param.key_cmp=sort_key_cmp;
2144
2151
  sort_param.lock_in_memory=lock_memory;
 
2152
  sort_param.tmpdir=param->tmpdir;
2145
2153
  sort_param.sort_info=&sort_info;
2146
2154
  sort_param.fix_datafile= (bool) (! rep_quick);
2147
2155
  sort_param.master =1;
2148
 
 
 
2156
  
2149
2157
  del=info->state->del;
2150
2158
  param->glob_crc=0;
2151
2159
  if (param->testflag & T_CALC_CHECKSUM)
2329
2337
    if (new_file >= 0)
2330
2338
    {
2331
2339
      my_close(new_file,MYF(0));
2332
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2340
      my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2341
                     MYF(MY_WME));
2333
2342
      if (info->dfile == new_file)
2334
 
        info->dfile= -1;
 
2343
        info->dfile= -1;
2335
2344
    }
2336
2345
    mi_mark_crashed_on_repair(info);
2337
2346
  }
2494
2503
  if (!rep_quick)
2495
2504
  {
2496
2505
    /* Get real path for data file */
2497
 
    if ((new_file=my_create(fn_format(param->temp_filename,
2498
 
                                      share->data_file_name, "",
2499
 
                                      DATA_TMP_EXT,
2500
 
                                      2+4),
2501
 
                            0,param->tmpfile_createflag,
2502
 
                            MYF(0))) < 0)
 
2506
    if ((new_file=my_raid_create(fn_format(param->temp_filename,
 
2507
                                           share->data_file_name, "",
 
2508
                                           DATA_TMP_EXT,
 
2509
                                           2+4),
 
2510
                                 0,param->tmpfile_createflag,
 
2511
                                 share->base.raid_type,
 
2512
                                 share->base.raid_chunks,
 
2513
                                 share->base.raid_chunksize,
 
2514
                                 MYF(0))) < 0)
2503
2515
    {
2504
2516
      mi_check_print_error(param,"Can't create new tempfile: '%s'",
2505
2517
                           param->temp_filename);
2536
2548
  sort_info.dupp=0;
2537
2549
  sort_info.buff=0;
2538
2550
  param->read_cache.end_of_file=sort_info.filelength=
2539
 
    lseek(param->read_cache.file,0L,SEEK_END);
 
2551
    my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
2540
2552
 
2541
2553
  if (share->data_file_type == DYNAMIC_RECORD)
2542
2554
    rec_length=cmax(share->base.min_pack_length+1,share->base.min_block_length);
2567
2579
  if (share->options & HA_OPTION_COMPRESS_RECORD)
2568
2580
    set_if_bigger(max_pack_reclength, share->max_pack_length);
2569
2581
  if (!(sort_param=(MI_SORT_PARAM *)
2570
 
        malloc(share->base.keys *
2571
 
               (sizeof(MI_SORT_PARAM) + max_pack_reclength))))
 
2582
        my_malloc((uint) share->base.keys *
 
2583
                  (sizeof(MI_SORT_PARAM) + max_pack_reclength),
 
2584
                  MYF(MY_ZEROFILL))))
2572
2585
  {
2573
2586
    mi_check_print_error(param,"Not enough memory for key!");
2574
2587
    goto err;
2575
2588
  }
2576
 
  memset(sort_param, 0, share->base.keys *
2577
 
                        (sizeof(MI_SORT_PARAM) + max_pack_reclength));
2578
2589
  total_key_length=0;
2579
2590
  rec_per_key_part= param->rec_per_key_part;
2580
2591
  info->state->records=info->state->del=share->state.split=0;
2610
2621
    }
2611
2622
    sort_param[i].key_cmp=sort_key_cmp;
2612
2623
    sort_param[i].lock_in_memory=lock_memory;
 
2624
    sort_param[i].tmpdir=param->tmpdir;
2613
2625
    sort_param[i].sort_info=&sort_info;
2614
2626
    sort_param[i].master=0;
2615
2627
    sort_param[i].fix_datafile=0;
2839
2851
    if (new_file >= 0)
2840
2852
    {
2841
2853
      my_close(new_file,MYF(0));
2842
 
      my_delete(param->temp_filename, MYF(MY_WME));
 
2854
      my_raid_delete(param->temp_filename,share->base.raid_chunks,
 
2855
                     MYF(MY_WME));
2843
2856
      if (info->dfile == new_file)
2844
 
        info->dfile= -1;
 
2857
        info->dfile= -1;
2845
2858
    }
2846
2859
    mi_mark_crashed_on_repair(info);
2847
2860
  }
2887
2900
     _mi_make_key(info, sort_param->key, (unsigned char*) key,
2888
2901
                  sort_param->record, sort_param->filepos));
2889
2902
#ifdef HAVE_purify
2890
 
  memset((unsigned char *)key+sort_param->real_key_length, 0,
 
2903
  memset(key+sort_param->real_key_length, 0,
2891
2904
         (sort_param->key_length-sort_param->real_key_length));
2892
2905
#endif
2893
2906
  return(sort_write_record(sort_param));
3327
3340
          MI_DYN_DELETE_BLOCK_HEADER;
3328
3341
        if (sort_info->buff_length < reclength)
3329
3342
        {
3330
 
          void *tmpptr= NULL;
3331
 
          tmpptr= realloc(sort_info->buff, reclength);
3332
 
          if(tmpptr)
3333
 
          {
3334
 
            sort_info->buff_length=reclength;
3335
 
            sort_info->buff= tmpptr;
3336
 
          }
3337
 
          else
3338
 
          {
3339
 
            mi_check_print_error(param,"Could not realloc() sort_info->buff "
3340
 
                                 " to %ul bytes", reclength);
3341
 
            return(1);
3342
 
          }
 
3343
          if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength,
 
3344
                                           MYF(MY_FREE_ON_ERROR |
 
3345
                                               MY_ALLOW_ZERO_PTR))))
 
3346
            return(1);
 
3347
          sort_info->buff_length=reclength;
3343
3348
        }
3344
3349
        from= sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
3345
3350
      }
3416
3421
                   diff_pos);
3417
3422
    if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3418
3423
      ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3419
 
                 (unsigned char*) a, USE_WHOLE_KEY,
 
3424
                 (unsigned char*) a, USE_WHOLE_KEY, 
3420
3425
                 SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3421
3426
    else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3422
3427
    {
3652
3657
  register uint32_t i;
3653
3658
  SORT_KEY_BLOCKS *block;
3654
3659
 
3655
 
  if (!(block=(SORT_KEY_BLOCKS*) malloc((sizeof(SORT_KEY_BLOCKS)+
3656
 
                                        buffer_length+IO_SIZE)*blocks)))
 
3660
  if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
 
3661
                                            buffer_length+IO_SIZE)*blocks,
 
3662
                                           MYF(0))))
3657
3663
  {
3658
3664
    mi_check_print_error(param,"Not enough memory for sort-key-blocks");
3659
3665
    return(0);
3673
3679
{
3674
3680
  if (info->s->options & HA_OPTION_COMPRESS_RECORD)
3675
3681
    return 0;
3676
 
  return (my_off_t)(lseek(info->s->kfile, 0L, SEEK_END) / 10 * 9) >
 
3682
  return my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)) / 10 * 9 >
3677
3683
         (my_off_t) info->s->base.max_key_file_length ||
3678
 
         (my_off_t)(lseek(info->dfile, 0L, SEEK_END) / 10 * 9) >
 
3684
         my_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
3679
3685
         (my_off_t) info->s->base.max_data_file_length;
3680
3686
}
3681
3687
 
3703
3709
  share= *(*org_info)->s;
3704
3710
  unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
3705
3711
    (param->testflag & T_UNPACK);
3706
 
  if (!(keyinfo=(MI_KEYDEF*) malloc(sizeof(MI_KEYDEF)*share.base.keys)))
 
3712
  if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
3707
3713
    return(0);
3708
3714
  memcpy(keyinfo,share.keyinfo,sizeof(MI_KEYDEF)*share.base.keys);
3709
3715
 
3710
3716
  key_parts= share.base.all_key_parts;
3711
 
  if (!(keysegs=(HA_KEYSEG*) malloc(sizeof(HA_KEYSEG)*
3712
 
                                    (key_parts+share.base.keys))))
 
3717
  if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
 
3718
                                       (key_parts+share.base.keys))))
3713
3719
  {
3714
 
    free(keyinfo);
 
3720
    my_afree((unsigned char*) keyinfo);
3715
3721
    return(1);
3716
3722
  }
3717
3723
  if (!(recdef=(MI_COLUMNDEF*)
3718
 
        malloc(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
 
3724
        my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3719
3725
  {
3720
 
    free(keyinfo);
3721
 
    free(keysegs);
 
3726
    my_afree((unsigned char*) keyinfo);
 
3727
    my_afree((unsigned char*) keysegs);
3722
3728
    return(1);
3723
3729
  }
3724
3730
  if (!(uniquedef=(MI_UNIQUEDEF*)
3725
 
        malloc(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
 
3731
        my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
3726
3732
  {
3727
 
    free(recdef);
3728
 
    free(keyinfo);
3729
 
    free(keysegs);
 
3733
    my_afree((unsigned char*) recdef);
 
3734
    my_afree((unsigned char*) keyinfo);
 
3735
    my_afree((unsigned char*) keysegs);
3730
3736
    return(1);
3731
3737
  }
3732
3738
 
3770
3776
  if (share.options & HA_OPTION_COMPRESS_RECORD)
3771
3777
    share.base.records=max_records=info.state->records;
3772
3778
  else if (share.base.min_pack_length)
3773
 
    max_records=(ha_rows) (lseek(info.dfile,0L,SEEK_END) /
 
3779
    max_records=(ha_rows) (my_seek(info.dfile,0L,MY_SEEK_END,MYF(0)) /
3774
3780
                           (ulong) share.base.min_pack_length);
3775
3781
  else
3776
3782
    max_records=0;
3778
3784
    (param->testflag & T_UNPACK);
3779
3785
  share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
3780
3786
 
3781
 
  file_length=(uint64_t) lseek(info.dfile,0L,SEEK_END);
 
3787
  file_length=(uint64_t) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
3782
3788
  tmp_length= file_length+file_length/10;
3783
3789
  set_if_bigger(file_length,param->max_data_file_length);
3784
3790
  set_if_bigger(file_length,tmp_length);
3841
3847
    goto end;
3842
3848
  error=0;
3843
3849
end:
3844
 
  free(uniquedef);
3845
 
  free(keyinfo);
3846
 
  free(recdef);
3847
 
  free(keysegs);
 
3850
  my_afree((unsigned char*) uniquedef);
 
3851
  my_afree((unsigned char*) keyinfo);
 
3852
  my_afree((unsigned char*) recdef);
 
3853
  my_afree((unsigned char*) keysegs);
3848
3854
  return(error);
3849
3855
}
3850
3856
 
3962
3968
      !(param->testflag & T_REP))
3963
3969
    printf("Updating MyISAM file: %s\n", param->isam_file_name);
3964
3970
  /*
3965
 
    We have to use an allocated buffer instead of info->rec_buff as
 
3971
    We have to use an allocated buffer instead of info->rec_buff as 
3966
3972
    _mi_put_key_in_record() may use info->rec_buff
3967
3973
  */
3968
3974
  if (!mi_alloc_rec_buff(info, -1, &record))
4010
4016
      records               Number of records in the table
4011
4017
 
4012
4018
  DESCRIPTION
4013
 
    This function is called produce index statistics values from unique and
 
4019
    This function is called produce index statistics values from unique and 
4014
4020
    notnull_tuples arrays after these arrays were produced with sequential
4015
4021
    index scan (the scan is done in two places: chk_index() and
4016
4022
    sort_key_write()).
4024
4030
 
4025
4031
    For MI_STATS_METHOD_IGNORE_NULLS method, notnull_tuples is an array too:
4026
4032
      notnull_tuples[0]= (#of {keypart1} tuples such that keypart1 is not NULL)
4027
 
      notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all
 
4033
      notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all 
4028
4034
                          keypart{i} are not NULL)
4029
4035
      ...
4030
4036
    For all other statistics collection methods notnull_tuples==NULL.
4031
4037
 
4032
4038
    Output is an array:
4033
 
    rec_per_key_part[k] =
4034
 
     = E(#records in the table such that keypart_1=c_1 AND ... AND
4035
 
         keypart_k=c_k for arbitrary constants c_1 ... c_k)
4036
 
 
 
4039
    rec_per_key_part[k] = 
 
4040
     = E(#records in the table such that keypart_1=c_1 AND ... AND 
 
4041
         keypart_k=c_k for arbitrary constants c_1 ... c_k) 
 
4042
     
4037
4043
     = {assuming that values have uniform distribution and index contains all
4038
4044
        tuples from the domain (or that {c_1, ..., c_k} tuple is choosen from
4039
4045
        index tuples}
4040
 
 
 
4046
     
4041
4047
     = #tuples-in-the-index / #distinct-tuples-in-the-index.
4042
 
 
4043
 
    The #tuples-in-the-index and #distinct-tuples-in-the-index have different
 
4048
    
 
4049
    The #tuples-in-the-index and #distinct-tuples-in-the-index have different 
4044
4050
    meaning depending on which statistics collection method is used:
4045
 
 
 
4051
    
4046
4052
    MI_STATS_METHOD_*  how are nulls compared?  which tuples are counted?
4047
4053
     NULLS_EQUAL            NULL == NULL           all tuples in table
4048
4054
     NULLS_NOT_EQUAL        NULL != NULL           all tuples in table
4059
4065
  for (parts=0 ; parts < keyinfo->keysegs  ; parts++)
4060
4066
  {
4061
4067
    count+=unique[parts];
4062
 
    unique_tuples= count + 1;
 
4068
    unique_tuples= count + 1;    
4063
4069
    if (notnull)
4064
4070
    {
4065
4071
      tuples= notnull[parts];
4066
 
      /*
4067
 
        #(unique_tuples not counting tuples with NULLs) =
4068
 
          #(unique_tuples counting tuples with NULLs as different) -
 
4072
      /* 
 
4073
        #(unique_tuples not counting tuples with NULLs) = 
 
4074
          #(unique_tuples counting tuples with NULLs as different) - 
4069
4075
          #(tuples with NULLs)
4070
4076
      */
4071
4077
      unique_tuples -= (records - notnull[parts]);
4072
4078
    }
4073
 
 
 
4079
    
4074
4080
    if (unique_tuples == 0)
4075
4081
      tmp= 1;
4076
4082
    else if (count == 0)
4078
4084
    else
4079
4085
      tmp= (tuples + unique_tuples/2) / unique_tuples;
4080
4086
 
4081
 
    /*
4082
 
      for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
 
4087
    /* 
 
4088
      for some weird keys (e.g. FULLTEXT) tmp can be <1 here. 
4083
4089
      let's ensure it is not
4084
4090
    */
4085
4091
    set_if_bigger(tmp,1);