40
40
only. And it is sufficient to calculate the checksum once only.
43
#include "myisamdef.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>
50
#include <sys/types.h>
52
50
#ifdef HAVE_SYS_MMAN_H
53
51
#include <sys/mman.h>
55
#include <drizzled/util/test.h>
58
/* Functions defined in this file */
60
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint32_t nr);
56
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
57
#define my_raid_delete(A,B,C) my_delete(A,B)
60
/* Functions defined in this file */
62
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr);
61
63
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);
64
my_off_t page, uchar *buff, ha_rows *keys,
65
ha_checksum *key_checksum, uint level);
66
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
65
67
static ha_checksum calc_checksum(ha_rows count);
66
68
static int writekeys(MI_SORT_PARAM *sort_param);
67
69
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
68
70
my_off_t pagepos, File new_file);
69
71
static int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
72
static int sort_ft_key_read(MI_SORT_PARAM *sort_param,void *key);
70
73
static int sort_get_next_record(MI_SORT_PARAM *sort_param);
71
74
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
75
static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a);
72
76
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
73
77
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
75
79
static int sort_insert_key(MI_SORT_PARAM *sort_param,
76
80
register SORT_KEY_BLOCKS *key_block,
77
unsigned char *key, my_off_t prev_block);
81
uchar *key, my_off_t prev_block);
78
82
static int sort_delete_record(MI_SORT_PARAM *sort_param);
79
83
/*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);
84
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
86
static ha_checksum mi_byte_checksum(const uchar *buf, uint length);
83
87
static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
85
89
void myisamchk_init(MI_CHECK *param)
87
memset(param, 0, sizeof(*param));
91
bzero((uchar*) param,sizeof(*param));
88
92
param->opt_follow_links=1;
89
param->keys_in_use= ~(uint64_t) 0;
93
param->keys_in_use= ~(ulonglong) 0;
90
94
param->search_after_block=HA_OFFSET_ERROR;
91
95
param->auto_increment_value= 0;
92
96
param->use_buffers=USE_BUFFER_INIT;
442
450
param->record_checksum=init_checksum;
444
memset(¶m->unique_count, 0, sizeof(param->unique_count));
445
memset(¶m->notnull_count, 0, sizeof(param->notnull_count));
452
bzero((char*) ¶m->unique_count,sizeof(param->unique_count));
453
bzero((char*) ¶m->notnull_count,sizeof(param->notnull_count));
447
455
if ((!(param->testflag & T_SILENT)))
448
456
printf ("- check data record references index: %d\n",key+1);
449
if (share->state.key_root[key] == HA_OFFSET_ERROR && (info->state->records == 0))
457
if (keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL))
459
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
460
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
451
462
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],
452
463
DFLT_INIT_HITS,info->buff,0))
520
531
/* Check that there isn't a row with auto_increment = 0 in the table */
521
532
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,
533
bzero(info->lastkey,keyinfo->seg->length);
534
if (!mi_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey,
524
535
(key_part_map)1, HA_READ_KEY_EXACT))
526
537
/* Don't count this as a real warning, as myisamchk can't correct it */
527
uint32_t save=param->warning_printed;
538
uint save=param->warning_printed;
528
539
mi_check_print_warning(param, "Found row where the auto_increment "
529
540
"column has the value 0");
530
541
param->warning_printed=save;
564
575
if (param->key_file_blocks != info->state->key_file_length &&
565
param->keys_in_use != ~(uint64_t) 0)
576
param->keys_in_use != ~(ulonglong) 0)
566
577
mi_check_print_warning(param, "Some data are unreferenced in keyfile");
567
578
if (found_keys != full_text_keys)
568
579
param->record_checksum=old_record_checksum-init_checksum; /* Remove delete links */
570
581
param->record_checksum=0;
575
586
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)
587
my_off_t page, uchar *buff, ha_rows *keys,
588
ha_checksum *key_checksum, uint level)
579
590
char llbuff[22],llbuff2[22];
591
DBUG_ENTER("chk_index_down");
581
593
/* Key blocks must lay within the key file length entirely. */
582
594
if (page + keyinfo->block_length > info->state->key_file_length)
719
731
/* Check if index is ok */
721
733
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)
734
my_off_t page, uchar *buff, ha_rows *keys,
735
ha_checksum *key_checksum, uint level)
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;
738
uint used_length,comp_flag,nod_flag,key_length=0;
739
uchar key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
728
740
my_off_t next_page,record;
730
uint32_t diff_pos[2];
732
if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
743
DBUG_ENTER("chk_index");
744
DBUG_DUMP("buff",(uchar*) buff,mi_getint(buff));
746
/* TODO: implement appropriate check for RTree keys */
747
if (keyinfo->flag & HA_SPATIAL)
750
if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
734
752
mi_check_print_error(param,"Not enough memory for keyblock");
738
756
if (keyinfo->flag & HA_NOSAME)
814
(*key_checksum)+= mi_byte_checksum((unsigned char*) key,
836
(*key_checksum)+= mi_byte_checksum((uchar*) key,
815
837
key_length- info->s->rec_reflength);
816
838
record= _mi_dpos(info,0,key+key_length);
839
if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */
843
get_key_full_length_rdonly(off, key);
844
subkeys=ft_sintXkorr(key+off);
848
if (chk_index_down(param,info,&info->s->ft2_keyinfo,record,
849
temp_buff,&tmp_keys,key_checksum,1))
851
if (tmp_keys + subkeys)
853
mi_check_print_error(param,
854
"Number of words in the 2nd level tree "
855
"does not match the number in the header. "
856
"Parent word in on the page %s, offset %u",
857
llstr(page,llbuff), (uint) (old_keypos-buff));
817
865
if (record >= info->state->data_file_length)
868
char llbuff2[22], llbuff3[22];
819
870
mi_check_print_error(param,"Found key at page %s that points to record outside datafile",llstr(page,llbuff));
871
DBUG_PRINT("test",("page: %s record: %s filelength: %s",
872
llstr(page,llbuff),llstr(record,llbuff2),
873
llstr(info->state->data_file_length,llbuff3)));
874
DBUG_DUMP("key",(uchar*) key,key_length);
875
DBUG_DUMP("new_in_page",(uchar*) old_keypos,(uint) (keypos-old_keypos));
822
878
param->record_checksum+=(ha_checksum) record;
1116
1177
pos=block_info.filepos+block_info.block_len;
1118
1179
case COMPRESSED_RECORD:
1180
if (_mi_read_cache(¶m->read_cache,(uchar*) block_info.header, pos,
1181
info->s->pack.ref_length, READING_NEXT))
1185
VOID(_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
1186
&info->rec_buff, -1, start_recpos));
1187
pos=block_info.filepos+block_info.rec_len;
1188
if (block_info.rec_len < (uint) info->s->min_pack_length ||
1189
block_info.rec_len > (uint) info->s->max_pack_length)
1191
mi_check_print_error(param,
1192
"Found block with wrong recordlength: %d at %s",
1193
block_info.rec_len, llstr(start_recpos,llbuff));
1197
if (_mi_read_cache(¶m->read_cache,(uchar*) info->rec_buff,
1198
block_info.filepos, block_info.rec_len, READING_NEXT))
1200
if (_mi_pack_rec_unpack(info, &info->bit_buff, record,
1201
info->rec_buff, block_info.rec_len))
1203
mi_check_print_error(param,"Found wrong record at %s",
1204
llstr(start_recpos,llbuff));
1207
if (static_row_size)
1208
param->glob_crc+= mi_static_checksum(info,record);
1210
param->glob_crc+= mi_checksum(info,record);
1211
link_used+= (block_info.filepos - start_recpos);
1212
used+= (pos-start_recpos);
1119
1213
case BLOCK_RECORD:
1120
1214
assert(0); /* Impossible */
1249
1350
printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n",
1250
1351
llstr(records,llbuff), (long)((used-link_used)/records),
1251
1352
(info->s->base.blobs ? 0.0 :
1252
(uint64_t2double((uint64_t) info->s->base.reclength*records)-
1353
(ulonglong2double((ulonglong) info->s->base.reclength*records)-
1253
1354
my_off_t2double(used))/
1254
uint64_t2double((uint64_t) info->s->base.reclength*records)*100.0));
1355
ulonglong2double((ulonglong) info->s->base.reclength*records)*100.0));
1255
1356
printf("Recordspace used:%9.0f%% Empty space:%12d%% Blocks/Record: %6.2f\n",
1256
(uint64_t2double(used-link_used)/uint64_t2double(used-link_used+empty)*100.0),
1257
(!records ? 100 : (int) (uint64_t2double(del_length+empty)/
1357
(ulonglong2double(used-link_used)/ulonglong2double(used-link_used+empty)*100.0),
1358
(!records ? 100 : (int) (ulonglong2double(del_length+empty)/
1258
1359
my_off_t2double(used)*100.0)),
1259
uint64_t2double(splits - del_blocks) / records);
1360
ulonglong2double(splits - del_blocks) / records);
1261
1362
printf("Record blocks:%12s Delete blocks:%10s\n",
1262
1363
llstr(splits-del_blocks,llbuff),llstr(del_blocks,llbuff2));
1461
1572
if (!rep_quick)
1463
1574
/* Get real path for data file */
1464
if ((new_file=my_create(fn_format(param->temp_filename,
1465
share->data_file_name, "",
1467
0,param->tmpfile_createflag,
1575
if ((new_file=my_raid_create(fn_format(param->temp_filename,
1576
share->data_file_name, "",
1578
0,param->tmpfile_createflag,
1579
share->base.raid_type,
1580
share->base.raid_chunks,
1581
share->base.raid_chunksize,
1470
1584
mi_check_print_error(param,"Can't create new tempfile: '%s'",
1471
param->temp_filename);
1585
param->temp_filename);
1474
1588
if (new_header_length &&
1475
1589
filecopy(param,new_file,info->dfile,0L,new_header_length,
1478
1592
info->s->state.dellink= HA_OFFSET_ERROR;
1479
1593
info->rec_cache.file=new_file;
1628
1745
llstr(sort_param.start_recpos,llbuff));
1629
1746
if (new_file >= 0)
1631
my_close(new_file,MYF(0));
1632
my_delete(param->temp_filename, MYF(MY_WME));
1748
VOID(my_close(new_file,MYF(0)));
1749
VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
1633
1751
info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
1635
1753
mi_mark_crashed_on_repair(info);
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)
1642
rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1643
if (rec_buff_ptr != NULL)
1647
free(sort_info.buff);
1648
end_io_cache(¶m->read_cache);
1755
my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
1756
MYF(MY_ALLOW_ZERO_PTR));
1757
my_free(mi_get_rec_buff_ptr(info, sort_param.record),
1758
MYF(MY_ALLOW_ZERO_PTR));
1759
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
1760
VOID(end_io_cache(¶m->read_cache));
1649
1761
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1650
end_io_cache(&info->rec_cache);
1762
VOID(end_io_cache(&info->rec_cache));
1651
1763
got_error|=flush_blocks(param, share->key_cache, share->kfile);
1652
1764
if (!got_error && param->testflag & T_UNPACK)
1654
share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
1766
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
1655
1767
share->pack.header_length=0;
1656
1768
share->data_file_type=sort_info.new_data_file_type;
1658
1770
share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES |
1659
1771
STATE_NOT_ANALYZED);
1772
DBUG_RETURN(got_error);
1666
1778
static int writekeys(MI_SORT_PARAM *sort_param)
1668
register uint32_t i;
1670
1782
MI_INFO *info= sort_param->sort_info->info;
1671
unsigned char *buff= sort_param->record;
1783
uchar *buff= sort_param->record;
1672
1784
my_off_t filepos= sort_param->filepos;
1785
DBUG_ENTER("writekeys");
1674
1787
key=info->lastkey+info->s->base.max_key_length;
1675
1788
for (i=0 ; i < info->s->base.keys ; i++)
1677
1790
if (mi_is_key_active(info->s->state.key_map, i))
1680
uint32_t key_length=_mi_make_key(info,i,key,buff,filepos);
1792
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
1794
if (_mi_ft_add(info, i, key, buff, filepos))
1798
else if (info->s->keyinfo[i].flag & HA_SPATIAL)
1800
uint key_length=_mi_make_key(info,i,key,buff,filepos);
1801
if (rtree_insert(info, i, key, key_length))
1804
#endif /*HAVE_SPATIAL*/
1807
uint key_length=_mi_make_key(info,i,key,buff,filepos);
1681
1808
if (_mi_ck_write(info,i,key,key_length))
1689
1816
if (my_errno == HA_ERR_FOUND_DUPP_KEY)
1725
1860
key_length=_mi_make_key(info,i,key,record,oldpos);
1726
1861
if (info->s->keyinfo[i].flag & HA_NOSAME)
1727
1862
{ /* Change pointer direct */
1729
1864
MI_KEYDEF *keyinfo;
1730
1865
keyinfo=info->s->keyinfo+i;
1731
1866
if (_mi_search(info,keyinfo,key,USE_WHOLE_KEY,
1732
1867
(uint) (SEARCH_SAME | SEARCH_SAVE_BUFF),
1733
1868
info->s->state.key_root[i]))
1735
1870
nod_flag=mi_test_if_nod(info->buff);
1736
1871
_mi_dpointer(info,info->int_keypos-nod_flag-
1737
1872
info->s->rec_reflength,newpos);
1738
1873
if (_mi_write_keypage(info,keyinfo,info->last_keypage,
1739
1874
DFLT_INIT_HITS,info->buff))
1743
1878
{ /* Change old key to new */
1744
1879
if (_mi_ck_delete(info,i,key,key_length))
1746
1881
key_length=_mi_make_key(info,i,key,record,newpos);
1747
1882
if (_mi_ck_write(info,i,key,key_length))
1753
1888
} /* movepoint */
1886
2024
static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
1887
2025
my_off_t pagepos, File new_file)
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];
2027
uint length,nod_flag,used_length, key_length;
2028
uchar *buff,*keypos,*endpos;
2029
uchar key[HA_MAX_POSSIBLE_KEY_BUFF];
1892
2030
my_off_t new_page_pos,next_page;
1893
2031
char llbuff[22];
2032
DBUG_ENTER("sort_one_index");
2034
/* cannot walk over R-tree indices */
2035
DBUG_ASSERT(keyinfo->key_alg != HA_KEY_ALG_RTREE);
1895
2036
new_page_pos=param->new_file_pos;
1896
2037
param->new_file_pos+=keyinfo->block_length;
1898
if (!(buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
2039
if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
1900
2041
mi_check_print_error(param,"Not enough memory for key block");
1903
2044
if (!_mi_fetch_keypage(info,keyinfo,pagepos,DFLT_INIT_HITS,buff,0))
1919
2060
_mi_kpointer(info,keypos-nod_flag,param->new_file_pos); /* Save new pos */
1920
2061
if (sort_one_index(param,info,keyinfo,next_page,new_file))
2064
("From page: %ld, keyoffset: %lu used_length: %d",
2065
(ulong) pagepos, (ulong) (keypos - buff),
2066
(int) used_length));
2067
DBUG_DUMP("buff",(uchar*) buff,used_length);
1925
2071
if (keypos >= endpos ||
1926
2072
(key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,key)) == 0)
1928
assert(keypos <= endpos);
2074
DBUG_ASSERT(keypos <= endpos);
2075
if (keyinfo->flag & HA_FULLTEXT)
2079
get_key_full_length_rdonly(off, key);
2080
subkeys=ft_sintXkorr(key+off);
2083
next_page= _mi_dpos(info,0,key+key_length);
2084
_mi_dpointer(info,keypos-nod_flag-info->s->rec_reflength,
2085
param->new_file_pos); /* Save new pos */
2086
if (sort_one_index(param,info,&info->s->ft2_keyinfo,
2087
next_page,new_file))
1932
2094
/* Fill block with zero and write it to the new index file */
1933
2095
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,
2096
bzero((uchar*) buff+length,keyinfo->block_length-length);
2097
if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
1936
2098
new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
1938
2100
mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
1941
my_afree((unsigned char*) buff);
2103
my_afree((uchar*) buff);
1944
my_afree((unsigned char*) buff);
2106
my_afree((uchar*) buff);
1946
2108
} /* sort_one_index */
1958
2120
int change_to_newfile(const char * filename, const char * old_ext,
1959
2121
const char * new_ext,
1960
uint32_t raid_chunks __attribute__((unused)),
2122
uint raid_chunks __attribute__((unused)),
1963
2125
char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
2128
return my_raid_redel(fn_format(old_filename,filename,"",old_ext,2+4),
2129
fn_format(new_filename,filename,"",new_ext,2+4),
2131
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
1964
2133
/* Get real path to filename */
1965
2134
(void) fn_format(old_filename,filename,"",old_ext,2+4+32);
1966
2135
return my_redel(old_filename,
1978
2164
char tmp_buff[IO_SIZE],*buff;
1979
2165
ulong buff_length;
2166
DBUG_ENTER("filecopy");
1981
buff_length=(ulong) cmin(param->write_buffer_length,length);
2168
buff_length=(ulong) min(param->write_buffer_length,length);
1982
2169
if (!(buff=my_malloc(buff_length,MYF(0))))
1984
2171
buff=tmp_buff; buff_length=IO_SIZE;
1987
my_seek(from,start,MY_SEEK_SET,MYF(0));
2174
VOID(my_seek(from,start,MY_SEEK_SET,MYF(0)));
1988
2175
while (length > buff_length)
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))
2177
if (my_read(from,(uchar*) buff,buff_length,MYF(MY_NABP)) ||
2178
my_write(to,(uchar*) buff,buff_length,param->myf_rw))
1993
2180
length-= buff_length;
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))
2182
if (my_read(from,(uchar*) buff,(uint) length,MYF(MY_NABP)) ||
2183
my_write(to,(uchar*) buff,(uint) length,param->myf_rw))
1998
2185
if (buff != tmp_buff)
2186
my_free(buff,MYF(0));
2002
2189
if (buff != tmp_buff)
2190
my_free(buff,MYF(0));
2004
2191
mi_check_print_error(param,"Can't copy %s to tempfile, error %d",
2005
2192
type,my_errno);
2190
2383
info->state->records=info->state->del=share->state.split=0;
2191
2384
info->state->empty=0;
2386
if (sort_param.keyinfo->flag & HA_FULLTEXT)
2388
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
2389
sort_param.keyinfo->seg->charset->mbmaxlen;
2390
sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
2392
fulltext indexes may have much more entries than the
2393
number of rows in the table. We estimate the number here.
2395
Note, built-in parser is always nr. 0 - see ftparser_call_initializer()
2397
if (sort_param.keyinfo->ftparser_nr == 0)
2400
for built-in parser the number of generated index entries
2401
cannot be larger than the size of the data file divided
2402
by the minimal word's length
2404
sort_info.max_records=
2405
(ha_rows) (sort_info.filelength/ft_min_word_len+1);
2410
for external plugin parser we cannot tell anything at all :(
2411
so, we'll use all the sort memory and start from ~10 buffpeks.
2412
(see _create_index_by_sort)
2414
sort_info.max_records=
2415
10*param->sort_buffer_length/sort_param.key_length;
2418
sort_param.key_read=sort_ft_key_read;
2419
sort_param.key_write=sort_ft_key_write;
2194
2423
sort_param.key_read=sort_key_read;
2195
2424
sort_param.key_write=sort_key_write;
2198
2427
if (_create_index_by_sort(&sort_param,
2199
(bool) (!(param->testflag & T_VERBOSE)),
2428
(my_bool) (!(param->testflag & T_VERBOSE)),
2200
2429
(uint) param->sort_buffer_length))
2202
2431
param->retry_repair=1;
2337
2568
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
2338
2569
share->state.changed|=STATE_NOT_SORTED_PAGES;
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)
2344
rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
2345
if (rec_buff_ptr != NULL)
2349
free((unsigned char*) sort_info.key_block);
2350
free(sort_info.buff);
2351
end_io_cache(¶m->read_cache);
2571
my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
2572
MYF(MY_ALLOW_ZERO_PTR));
2573
my_free(mi_get_rec_buff_ptr(info, sort_param.record),
2574
MYF(MY_ALLOW_ZERO_PTR));
2575
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
2576
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
2577
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
2578
VOID(end_io_cache(¶m->read_cache));
2352
2579
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
2353
2580
if (!got_error && (param->testflag & T_UNPACK))
2355
share->state.header.options[0]&= (unsigned char) ~HA_OPTION_COMPRESS_RECORD;
2582
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
2356
2583
share->pack.header_length=0;
2585
DBUG_RETURN(got_error);
2871
3121
SORT_INFO *sort_info=sort_param->sort_info;
2872
3122
MI_INFO *info=sort_info->info;
3123
DBUG_ENTER("sort_key_read");
2874
3125
if ((error=sort_get_next_record(sort_param)))
2876
3127
if (info->state->records == sort_info->max_records)
2878
3129
mi_check_print_error(sort_info->param,
2879
3130
"Key %d - Found too many records; Can't continue",
2880
3131
sort_param->key+1);
2883
3134
sort_param->real_key_length=
2884
3135
(info->s->rec_reflength+
2885
_mi_make_key(info, sort_param->key, (unsigned char*) key,
3136
_mi_make_key(info, sort_param->key, (uchar*) key,
2886
3137
sort_param->record, sort_param->filepos));
2887
3138
#ifdef HAVE_purify
2888
memset(key+sort_param->real_key_length, 0,
2889
(sort_param->key_length-sort_param->real_key_length));
3139
bzero(key+sort_param->real_key_length,
3140
(sort_param->key_length-sort_param->real_key_length));
2891
return(sort_write_record(sort_param));
3142
DBUG_RETURN(sort_write_record(sort_param));
2892
3143
} /* sort_key_read */
3145
static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
3148
SORT_INFO *sort_info=sort_param->sort_info;
3149
MI_INFO *info=sort_info->info;
3151
DBUG_ENTER("sort_ft_key_read");
3153
if (!sort_param->wordlist)
3157
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3158
if ((error=sort_get_next_record(sort_param)))
3160
if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record,
3161
&sort_param->wordroot)))
3165
error=sort_write_record(sort_param);
3167
sort_param->wordptr=sort_param->wordlist=wptr;
3172
wptr=(FT_WORD*)(sort_param->wordptr);
3175
sort_param->real_key_length=(info->s->rec_reflength+
3176
_ft_make_key(info, sort_param->key,
3177
key, wptr++, sort_param->filepos));
3179
if (sort_param->key_length > sort_param->real_key_length)
3180
bzero(key+sort_param->real_key_length,
3181
(sort_param->key_length-sort_param->real_key_length));
3185
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3186
sort_param->wordlist=0;
3187
error=sort_write_record(sort_param);
3190
sort_param->wordptr=(void*)wptr;
3193
} /* sort_ft_key_read */
2896
3197
Read next record from file using parameters in sort_info.
3269
3571
case COMPRESSED_RECORD:
3572
for (searching=0 ;; searching=1, sort_param->pos++)
3574
if (_mi_read_cache(&sort_param->read_cache,(uchar*) block_info.header,
3576
share->pack.ref_length,READING_NEXT))
3578
if (searching && ! sort_param->fix_datafile)
3580
param->error_printed=1;
3581
param->retry_repair=1;
3582
param->testflag|=T_RETRY_WITHOUT_QUICK;
3583
DBUG_RETURN(1); /* Something wrong with data */
3585
sort_param->start_recpos=sort_param->pos;
3586
if (_mi_pack_get_block_info(info, &sort_param->bit_buff, &block_info,
3587
&sort_param->rec_buff, -1, sort_param->pos))
3589
if (!block_info.rec_len &&
3590
sort_param->pos + MEMMAP_EXTRA_MARGIN ==
3591
sort_param->read_cache.end_of_file)
3593
if (block_info.rec_len < (uint) share->min_pack_length ||
3594
block_info.rec_len > (uint) share->max_pack_length)
3597
mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
3599
llstr(sort_param->pos,llbuff));
3602
if (_mi_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
3603
block_info.filepos, block_info.rec_len,
3607
mi_check_print_info(param,"Couldn't read whole record from %s",
3608
llstr(sort_param->pos,llbuff));
3611
if (_mi_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
3612
sort_param->rec_buff, block_info.rec_len))
3615
mi_check_print_info(param,"Found wrong record at %s",
3616
llstr(sort_param->pos,llbuff));
3619
if (!sort_param->fix_datafile)
3621
sort_param->filepos=sort_param->pos;
3622
if (sort_param->master)
3623
share->state.split++;
3625
sort_param->max_pos=(sort_param->pos=block_info.filepos+
3626
block_info.rec_len);
3627
info->packed_length=block_info.rec_len;
3628
if (sort_param->calc_checksum)
3629
param->glob_crc+= (info->checksum=
3630
mi_checksum(info, sort_param->record));
3270
3633
case BLOCK_RECORD:
3271
3634
assert(0); /* Impossible */
3273
return(1); /* Impossible */
3636
DBUG_RETURN(1); /* Impossible */
3402
3784
if (sort_info->key_block->inited)
3404
3786
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3405
(unsigned char*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3787
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3407
3789
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3408
3790
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3409
(unsigned char*) a, USE_WHOLE_KEY,
3791
(uchar*) a, USE_WHOLE_KEY,
3410
3792
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3411
3793
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3413
3795
diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
3414
3796
sort_param->notnull,
3415
3797
sort_info->key_block->lastkey,
3418
3800
sort_param->unique[diff_pos[0]-1]++;
3441
3823
param->testflag|=T_RETRY_WITHOUT_QUICK;
3824
if (sort_info->param->testflag & T_VERBOSE)
3825
_mi_print_key(stdout,sort_param->seg,(uchar*) a, USE_WHOLE_KEY);
3442
3826
return (sort_delete_record(sort_param));
3831
mi_check_print_error(param,
3832
"Internal error: Keys are not in order from sort");
3444
3836
return (sort_insert_key(sort_param,sort_info->key_block,
3445
(unsigned char*) a, HA_OFFSET_ERROR));
3837
(uchar*) a, HA_OFFSET_ERROR));
3446
3838
} /* sort_key_write */
3840
int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
3842
SORT_INFO *sort_info=sort_param->sort_info;
3843
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3844
MYISAM_SHARE *share=sort_info->info->s;
3845
uint val_off, val_len;
3847
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3850
val_len=share->ft2_keyinfo.keylength;
3851
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3852
to=ft_buf->lastkey+val_off;
3856
/* flushing first-level tree */
3857
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3859
for (from=to+val_len;
3860
!error && from < ft_buf->buf;
3863
memcpy(to, from, val_len);
3864
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3869
/* flushing second-level tree keyblocks */
3870
error=flush_pending_blocks(sort_param);
3871
/* updating lastkey with second-level tree info */
3872
ft_intXstore(ft_buf->lastkey+val_off, -ft_buf->count);
3873
_mi_dpointer(sort_info->info, ft_buf->lastkey+val_off+HA_FT_WLEN,
3874
share->state.key_root[sort_param->key]);
3875
/* restoring first level tree data in sort_info/sort_param */
3876
sort_info->key_block=sort_info->key_block_end- sort_info->param->sort_key_blocks;
3877
sort_param->keyinfo=share->keyinfo+sort_param->key;
3878
share->state.key_root[sort_param->key]=HA_OFFSET_ERROR;
3879
/* writing lastkey in first-level tree */
3880
return error ? error :
3881
sort_insert_key(sort_param,sort_info->key_block,
3882
ft_buf->lastkey,HA_OFFSET_ERROR);
3885
static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
3887
uint a_len, val_off, val_len, error;
3889
SORT_INFO *sort_info=sort_param->sort_info;
3890
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3891
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3893
val_len=HA_FT_WLEN+sort_info->info->s->base.rec_reflength;
3894
get_key_full_length_rdonly(a_len, (uchar *)a);
3899
use two-level tree only if key_reflength fits in rec_reflength place
3900
and row format is NOT static - for _mi_dpointer not to garble offsets
3902
if ((sort_info->info->s->base.key_reflength <=
3903
sort_info->info->s->base.rec_reflength) &&
3904
(sort_info->info->s->options &
3905
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
3906
ft_buf=(SORT_FT_BUF *)my_malloc(sort_param->keyinfo->block_length +
3907
sizeof(SORT_FT_BUF), MYF(MY_WME));
3911
sort_param->key_write=sort_key_write;
3912
return sort_key_write(sort_param, a);
3914
sort_info->ft_buf=ft_buf;
3915
goto word_init_ft_buf; /* no need to duplicate the code */
3917
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3919
if (ha_compare_text(sort_param->seg->charset,
3920
((uchar *)a)+1,a_len-1,
3921
ft_buf->lastkey+1,val_off-1, 0, 0)==0)
3923
if (!ft_buf->buf) /* store in second-level tree */
3926
return sort_insert_key(sort_param,key_block,
3927
((uchar *)a)+a_len, HA_OFFSET_ERROR);
3930
/* storing the key in the buffer. */
3931
memcpy (ft_buf->buf, (char *)a+a_len, val_len);
3932
ft_buf->buf+=val_len;
3933
if (ft_buf->buf < ft_buf->end)
3936
/* converting to two-level tree */
3937
p=ft_buf->lastkey+val_off;
3939
while (key_block->inited)
3941
sort_info->key_block=key_block;
3942
sort_param->keyinfo=& sort_info->info->s->ft2_keyinfo;
3943
ft_buf->count=(ft_buf->buf - p)/val_len;
3945
/* flushing buffer to second-level tree */
3946
for (error=0; !error && p < ft_buf->buf; p+= val_len)
3947
error=sort_insert_key(sort_param,key_block,p,HA_OFFSET_ERROR);
3952
/* flushing buffer */
3953
if ((error=sort_ft_buf_flush(sort_param)))
3958
memcpy(ft_buf->lastkey, a, a_len);
3959
ft_buf->buf=ft_buf->lastkey+a_len;
3961
32 is just a safety margin here
3962
(at least max(val_len, sizeof(nod_flag)) should be there).
3963
May be better performance could be achieved if we'd put
3964
(sort_info->keyinfo->block_length-32)/XXX
3966
TODO: benchmark the best value for XXX.
3968
ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32);
3970
} /* sort_ft_key_write */
3449
3973
/* get pointer to record from a key */
3451
3975
static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
3454
3978
return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key));
3455
3979
} /* get_record_for_key */
3458
3982
/* Insert a key in sort-key-blocks */
3460
3984
static int sort_insert_key(MI_SORT_PARAM *sort_param,
3461
register SORT_KEY_BLOCKS *key_block, unsigned char *key,
3985
register SORT_KEY_BLOCKS *key_block, uchar *key,
3462
3986
my_off_t prev_block)
3464
uint32_t a_length,t_length,nod_flag;
3988
uint a_length,t_length,nod_flag;
3465
3989
my_off_t filepos,key_file_length;
3466
unsigned char *anc_buff,*lastkey;
3990
uchar *anc_buff,*lastkey;
3467
3991
MI_KEY_PARAM s_temp;
3469
3993
MI_KEYDEF *keyinfo=sort_param->keyinfo;
3470
3994
SORT_INFO *sort_info= sort_param->sort_info;
3471
3995
MI_CHECK *param=sort_info->param;
3996
DBUG_ENTER("sort_insert_key");
3473
3998
anc_buff=key_block->buff;
3474
3999
info=sort_info->info;
3504
4029
key_block->end_pos+=t_length;
3505
4030
if (a_length <= keyinfo->block_length)
3507
_mi_move_key(keyinfo,key_block->lastkey,key);
4032
VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
3508
4033
key_block->last_length=a_length-t_length;
3512
4037
/* Fill block with end-zero and write filled block */
3513
4038
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);
4039
bzero((uchar*) anc_buff+key_block->last_length,
4040
keyinfo->block_length- key_block->last_length);
3516
4041
key_file_length=info->state->key_file_length;
3517
4042
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3520
4045
/* If we read the page from the key cache, we have to write it back to it */
3521
4046
if (key_file_length == info->state->key_file_length)
3523
4048
if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
3526
else if (my_pwrite(info->s->kfile,(unsigned char*) anc_buff,
4051
else if (my_pwrite(info->s->kfile,(uchar*) anc_buff,
3527
4052
(uint) keyinfo->block_length,filepos, param->myf_rw))
4054
DBUG_DUMP("buff",(uchar*) anc_buff,mi_getint(anc_buff));
3530
4056
/* Write separator-key to block in next level */
3531
4057
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
3534
4060
/* clear old block and write new key in it */
3535
4061
key_block->inited=0;
3536
return(sort_insert_key(sort_param, key_block,key,prev_block));
4062
DBUG_RETURN(sort_insert_key(sort_param, key_block,key,prev_block));
3537
4063
} /* sort_insert_key */
3615
4143
_mi_kpointer(info,key_block->end_pos,filepos);
3616
4144
key_file_length=info->state->key_file_length;
3617
memset(key_block->buff+length, 0, keyinfo->block_length-length);
4145
bzero((uchar*) key_block->buff+length, keyinfo->block_length-length);
3618
4146
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3621
4149
/* If we read the page from the key cache, we have to write it back */
3622
4150
if (key_file_length == info->state->key_file_length)
3624
4152
if (_mi_write_keypage(info, keyinfo, filepos,
3625
4153
DFLT_INIT_HITS, key_block->buff))
3628
else if (my_pwrite(info->s->kfile,(unsigned char*) key_block->buff,
4156
else if (my_pwrite(info->s->kfile,(uchar*) key_block->buff,
3629
4157
(uint) keyinfo->block_length,filepos, myf_rw))
4159
DBUG_DUMP("buff",(uchar*) key_block->buff,length);
3633
4162
info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */
3635
4164
} /* flush_pending_blocks */
3637
4166
/* alloc space and pointers for key_blocks */
3639
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint32_t blocks,
3640
uint32_t buffer_length)
4168
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
3642
register uint32_t i;
3643
4172
SORT_KEY_BLOCKS *block;
4173
DBUG_ENTER("alloc_key_blocks");
3645
4175
if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
3646
4176
buffer_length+IO_SIZE)*blocks,
3695
4226
unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
3696
4227
(param->testflag & T_UNPACK);
3697
4228
if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
3699
memcpy(keyinfo,share.keyinfo,sizeof(MI_KEYDEF)*share.base.keys);
4230
memcpy((uchar*) keyinfo,(uchar*) share.keyinfo,
4231
(size_t) (sizeof(MI_KEYDEF)*share.base.keys));
3701
4233
key_parts= share.base.all_key_parts;
3702
4234
if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
3703
4235
(key_parts+share.base.keys))))
3705
my_afree((unsigned char*) keyinfo);
4237
my_afree((uchar*) keyinfo);
3708
4240
if (!(recdef=(MI_COLUMNDEF*)
3709
4241
my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3711
my_afree((unsigned char*) keyinfo);
3712
my_afree((unsigned char*) keysegs);
4243
my_afree((uchar*) keyinfo);
4244
my_afree((uchar*) keysegs);
3715
4247
if (!(uniquedef=(MI_UNIQUEDEF*)
3716
4248
my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
3718
my_afree((unsigned char*) recdef);
3719
my_afree((unsigned char*) keyinfo);
3720
my_afree((unsigned char*) keysegs);
4250
my_afree((uchar*) recdef);
4251
my_afree((uchar*) keyinfo);
4252
my_afree((uchar*) keysegs);
3724
4256
/* Copy the column definitions */
3725
memcpy(recdef, share.rec, sizeof(MI_COLUMNDEF)*(share.base.fields+1));
4257
memcpy((uchar*) recdef,(uchar*) share.rec,
4258
(size_t) (sizeof(MI_COLUMNDEF)*(share.base.fields+1)));
3726
4259
for (rec=recdef,end=recdef+share.base.fields; rec != end ; rec++)
3728
4261
if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
3769
4302
(param->testflag & T_UNPACK);
3770
4303
share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
3772
file_length=(uint64_t) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
4305
file_length=(ulonglong) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
3773
4306
tmp_length= file_length+file_length/10;
3774
4307
set_if_bigger(file_length,param->max_data_file_length);
3775
4308
set_if_bigger(file_length,tmp_length);
3776
set_if_bigger(file_length,(uint64_t) share.base.max_data_file_length);
4309
set_if_bigger(file_length,(ulonglong) share.base.max_data_file_length);
3778
mi_close(*org_info);
3779
memset(&create_info, 0, sizeof(create_info));
3780
create_info.max_rows=cmax(max_records,share.base.records);
4311
VOID(mi_close(*org_info));
4312
bzero((char*) &create_info,sizeof(create_info));
4313
create_info.max_rows=max(max_records,share.base.records);
3781
4314
create_info.reloc_rows=share.base.reloc;
3782
4315
create_info.old_options=(share.options |
3783
4316
(unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
3835
my_afree((unsigned char*) uniquedef);
3836
my_afree((unsigned char*) keyinfo);
3837
my_afree((unsigned char*) recdef);
3838
my_afree((unsigned char*) keysegs);
4368
my_afree((uchar*) uniquedef);
4369
my_afree((uchar*) keyinfo);
4370
my_afree((uchar*) recdef);
4371
my_afree((uchar*) keysegs);
3843
4376
/* write suffix to data file if neaded */
3845
int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile)
4378
int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
3847
4380
MI_INFO *info=sort_info->info;
3849
4382
if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
3851
unsigned char buff[MEMMAP_EXTRA_MARGIN];
3852
memset(buff, 0, sizeof(buff));
4384
uchar buff[MEMMAP_EXTRA_MARGIN];
4385
bzero(buff,sizeof(buff));
3853
4386
if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
3855
4388
mi_check_print_error(sort_info->param,
3968
4502
if (my_errno != HA_ERR_END_OF_FILE)
3970
4504
mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3971
free(mi_get_rec_buff_ptr(info, record));
4505
my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3972
4506
mi_check_print_error(param,"%d when reading last record",my_errno);
3975
4509
if (!repair_only)
3976
4510
info->s->state.auto_increment=param->auto_increment_value;
3980
uint64_t auto_increment= retrieve_auto_increment(info, record);
4514
ulonglong auto_increment= retrieve_auto_increment(info, record);
3981
4515
set_if_bigger(info->s->state.auto_increment,auto_increment);
3982
4516
if (!repair_only)
3983
4517
set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
3985
4519
mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3986
free(mi_get_rec_buff_ptr(info, record));
4520
my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3987
4521
update_state_info(param, info, UPDATE_AUTO_INC);
4086
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length)
4620
static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
4088
4622
ha_checksum crc;
4089
const unsigned char *end=buf+length;
4623
const uchar *end=buf+length;
4090
4624
for (crc=0; buf != end; buf++)
4091
crc=((crc << 1) + *((unsigned char*) buf)) +
4625
crc=((crc << 1) + *((uchar*) buf)) +
4092
4626
test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1)));
4096
static bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
4630
static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
4098
uint32_t key_maxlength=key->maxlength;
4099
return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY) &&
4100
((uint64_t) rows * key_maxlength >
4101
(uint64_t) myisam_max_temp_length));
4632
uint key_maxlength=key->maxlength;
4633
if (key->flag & HA_FULLTEXT)
4635
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
4636
key->seg->charset->mbmaxlen;
4637
key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
4639
return (key->flag & HA_SPATIAL) ||
4640
(key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
4641
((ulonglong) rows * key_maxlength >
4642
(ulonglong) myisam_max_temp_length));
4134
Return true if we can use repair by sorting
4675
Return TRUE if we can use repair by sorting
4135
4676
One can set the force argument to force to use sorting
4136
4677
even if the temporary file would be quite big!
4139
bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
4140
uint64_t key_map, bool force)
4680
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
4681
ulonglong key_map, my_bool force)
4142
4683
MYISAM_SHARE *share=info->s;
4143
4684
MI_KEYDEF *key=share->keyinfo;
4147
4688
mi_repair_by_sort only works if we have at least one key. If we don't
4148
4689
have any keys, we should use the normal repair.
4150
4691
if (! mi_is_any_key_active(key_map))
4151
return false; /* Can't use sort */
4692
return FALSE; /* Can't use sort */
4152
4693
for (i=0 ; i < share->base.keys ; i++,key++)
4154
4695
if (!force && mi_too_big_key_for_sort(key,rows))