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
3125
SORT_INFO *sort_info=sort_param->sort_info;
2872
3126
MI_INFO *info=sort_info->info;
3127
DBUG_ENTER("sort_key_read");
2874
3129
if ((error=sort_get_next_record(sort_param)))
2876
3131
if (info->state->records == sort_info->max_records)
2878
3133
mi_check_print_error(sort_info->param,
2879
3134
"Key %d - Found too many records; Can't continue",
2880
3135
sort_param->key+1);
2883
3138
sort_param->real_key_length=
2884
3139
(info->s->rec_reflength+
2885
_mi_make_key(info, sort_param->key, (unsigned char*) key,
3140
_mi_make_key(info, sort_param->key, (uchar*) key,
2886
3141
sort_param->record, sort_param->filepos));
2887
3142
#ifdef HAVE_purify
2888
memset(key+sort_param->real_key_length, 0,
2889
(sort_param->key_length-sort_param->real_key_length));
3143
bzero(key+sort_param->real_key_length,
3144
(sort_param->key_length-sort_param->real_key_length));
2891
return(sort_write_record(sort_param));
3146
DBUG_RETURN(sort_write_record(sort_param));
2892
3147
} /* sort_key_read */
3149
static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
3152
SORT_INFO *sort_info=sort_param->sort_info;
3153
MI_INFO *info=sort_info->info;
3155
DBUG_ENTER("sort_ft_key_read");
3157
if (!sort_param->wordlist)
3161
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3162
if ((error=sort_get_next_record(sort_param)))
3164
if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record,
3165
&sort_param->wordroot)))
3169
error=sort_write_record(sort_param);
3171
sort_param->wordptr=sort_param->wordlist=wptr;
3176
wptr=(FT_WORD*)(sort_param->wordptr);
3179
sort_param->real_key_length=(info->s->rec_reflength+
3180
_ft_make_key(info, sort_param->key,
3181
key, wptr++, sort_param->filepos));
3183
if (sort_param->key_length > sort_param->real_key_length)
3184
bzero(key+sort_param->real_key_length,
3185
(sort_param->key_length-sort_param->real_key_length));
3189
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3190
sort_param->wordlist=0;
3191
error=sort_write_record(sort_param);
3194
sort_param->wordptr=(void*)wptr;
3197
} /* sort_ft_key_read */
2896
3201
Read next record from file using parameters in sort_info.
3269
3575
case COMPRESSED_RECORD:
3576
for (searching=0 ;; searching=1, sort_param->pos++)
3578
if (_mi_read_cache(&sort_param->read_cache,(uchar*) block_info.header,
3580
share->pack.ref_length,READING_NEXT))
3582
if (searching && ! sort_param->fix_datafile)
3584
param->error_printed=1;
3585
param->retry_repair=1;
3586
param->testflag|=T_RETRY_WITHOUT_QUICK;
3587
DBUG_RETURN(1); /* Something wrong with data */
3589
sort_param->start_recpos=sort_param->pos;
3590
if (_mi_pack_get_block_info(info, &sort_param->bit_buff, &block_info,
3591
&sort_param->rec_buff, -1, sort_param->pos))
3593
if (!block_info.rec_len &&
3594
sort_param->pos + MEMMAP_EXTRA_MARGIN ==
3595
sort_param->read_cache.end_of_file)
3597
if (block_info.rec_len < (uint) share->min_pack_length ||
3598
block_info.rec_len > (uint) share->max_pack_length)
3601
mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
3603
llstr(sort_param->pos,llbuff));
3606
if (_mi_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
3607
block_info.filepos, block_info.rec_len,
3611
mi_check_print_info(param,"Couldn't read whole record from %s",
3612
llstr(sort_param->pos,llbuff));
3615
if (_mi_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
3616
sort_param->rec_buff, block_info.rec_len))
3619
mi_check_print_info(param,"Found wrong record at %s",
3620
llstr(sort_param->pos,llbuff));
3623
if (!sort_param->fix_datafile)
3625
sort_param->filepos=sort_param->pos;
3626
if (sort_param->master)
3627
share->state.split++;
3629
sort_param->max_pos=(sort_param->pos=block_info.filepos+
3630
block_info.rec_len);
3631
info->packed_length=block_info.rec_len;
3632
if (sort_param->calc_checksum)
3633
param->glob_crc+= (info->checksum=
3634
mi_checksum(info, sort_param->record));
3270
3637
case BLOCK_RECORD:
3271
3638
assert(0); /* Impossible */
3273
return(1); /* Impossible */
3640
DBUG_RETURN(1); /* Impossible */
3402
3788
if (sort_info->key_block->inited)
3404
3790
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3405
(unsigned char*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3791
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
3407
3793
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
3408
3794
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
3409
(unsigned char*) a, USE_WHOLE_KEY,
3795
(uchar*) a, USE_WHOLE_KEY,
3410
3796
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
3411
3797
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
3413
3799
diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
3414
3800
sort_param->notnull,
3415
3801
sort_info->key_block->lastkey,
3418
3804
sort_param->unique[diff_pos[0]-1]++;
3441
3827
param->testflag|=T_RETRY_WITHOUT_QUICK;
3828
if (sort_info->param->testflag & T_VERBOSE)
3829
_mi_print_key(stdout,sort_param->seg,(uchar*) a, USE_WHOLE_KEY);
3442
3830
return (sort_delete_record(sort_param));
3835
mi_check_print_error(param,
3836
"Internal error: Keys are not in order from sort");
3444
3840
return (sort_insert_key(sort_param,sort_info->key_block,
3445
(unsigned char*) a, HA_OFFSET_ERROR));
3841
(uchar*) a, HA_OFFSET_ERROR));
3446
3842
} /* sort_key_write */
3844
int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
3846
SORT_INFO *sort_info=sort_param->sort_info;
3847
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3848
MYISAM_SHARE *share=sort_info->info->s;
3849
uint val_off, val_len;
3851
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3854
val_len=share->ft2_keyinfo.keylength;
3855
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3856
to=ft_buf->lastkey+val_off;
3860
/* flushing first-level tree */
3861
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3863
for (from=to+val_len;
3864
!error && from < ft_buf->buf;
3867
memcpy(to, from, val_len);
3868
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3873
/* flushing second-level tree keyblocks */
3874
error=flush_pending_blocks(sort_param);
3875
/* updating lastkey with second-level tree info */
3876
ft_intXstore(ft_buf->lastkey+val_off, -ft_buf->count);
3877
_mi_dpointer(sort_info->info, ft_buf->lastkey+val_off+HA_FT_WLEN,
3878
share->state.key_root[sort_param->key]);
3879
/* restoring first level tree data in sort_info/sort_param */
3880
sort_info->key_block=sort_info->key_block_end- sort_info->param->sort_key_blocks;
3881
sort_param->keyinfo=share->keyinfo+sort_param->key;
3882
share->state.key_root[sort_param->key]=HA_OFFSET_ERROR;
3883
/* writing lastkey in first-level tree */
3884
return error ? error :
3885
sort_insert_key(sort_param,sort_info->key_block,
3886
ft_buf->lastkey,HA_OFFSET_ERROR);
3889
static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
3891
uint a_len, val_off, val_len, error;
3893
SORT_INFO *sort_info=sort_param->sort_info;
3894
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3895
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3897
val_len=HA_FT_WLEN+sort_info->info->s->base.rec_reflength;
3898
get_key_full_length_rdonly(a_len, (uchar *)a);
3903
use two-level tree only if key_reflength fits in rec_reflength place
3904
and row format is NOT static - for _mi_dpointer not to garble offsets
3906
if ((sort_info->info->s->base.key_reflength <=
3907
sort_info->info->s->base.rec_reflength) &&
3908
(sort_info->info->s->options &
3909
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
3910
ft_buf=(SORT_FT_BUF *)my_malloc(sort_param->keyinfo->block_length +
3911
sizeof(SORT_FT_BUF), MYF(MY_WME));
3915
sort_param->key_write=sort_key_write;
3916
return sort_key_write(sort_param, a);
3918
sort_info->ft_buf=ft_buf;
3919
goto word_init_ft_buf; /* no need to duplicate the code */
3921
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3923
if (ha_compare_text(sort_param->seg->charset,
3924
((uchar *)a)+1,a_len-1,
3925
ft_buf->lastkey+1,val_off-1, 0, 0)==0)
3927
if (!ft_buf->buf) /* store in second-level tree */
3930
return sort_insert_key(sort_param,key_block,
3931
((uchar *)a)+a_len, HA_OFFSET_ERROR);
3934
/* storing the key in the buffer. */
3935
memcpy (ft_buf->buf, (char *)a+a_len, val_len);
3936
ft_buf->buf+=val_len;
3937
if (ft_buf->buf < ft_buf->end)
3940
/* converting to two-level tree */
3941
p=ft_buf->lastkey+val_off;
3943
while (key_block->inited)
3945
sort_info->key_block=key_block;
3946
sort_param->keyinfo=& sort_info->info->s->ft2_keyinfo;
3947
ft_buf->count=(ft_buf->buf - p)/val_len;
3949
/* flushing buffer to second-level tree */
3950
for (error=0; !error && p < ft_buf->buf; p+= val_len)
3951
error=sort_insert_key(sort_param,key_block,p,HA_OFFSET_ERROR);
3956
/* flushing buffer */
3957
if ((error=sort_ft_buf_flush(sort_param)))
3962
memcpy(ft_buf->lastkey, a, a_len);
3963
ft_buf->buf=ft_buf->lastkey+a_len;
3965
32 is just a safety margin here
3966
(at least max(val_len, sizeof(nod_flag)) should be there).
3967
May be better performance could be achieved if we'd put
3968
(sort_info->keyinfo->block_length-32)/XXX
3970
TODO: benchmark the best value for XXX.
3972
ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32);
3974
} /* sort_ft_key_write */
3449
3977
/* get pointer to record from a key */
3451
3979
static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
3454
3982
return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key));
3455
3983
} /* get_record_for_key */
3458
3986
/* Insert a key in sort-key-blocks */
3460
3988
static int sort_insert_key(MI_SORT_PARAM *sort_param,
3461
register SORT_KEY_BLOCKS *key_block, unsigned char *key,
3989
register SORT_KEY_BLOCKS *key_block, uchar *key,
3462
3990
my_off_t prev_block)
3464
uint32_t a_length,t_length,nod_flag;
3992
uint a_length,t_length,nod_flag;
3465
3993
my_off_t filepos,key_file_length;
3466
unsigned char *anc_buff,*lastkey;
3994
uchar *anc_buff,*lastkey;
3467
3995
MI_KEY_PARAM s_temp;
3469
3997
MI_KEYDEF *keyinfo=sort_param->keyinfo;
3470
3998
SORT_INFO *sort_info= sort_param->sort_info;
3471
3999
MI_CHECK *param=sort_info->param;
4000
DBUG_ENTER("sort_insert_key");
3473
4002
anc_buff=key_block->buff;
3474
4003
info=sort_info->info;
3504
4033
key_block->end_pos+=t_length;
3505
4034
if (a_length <= keyinfo->block_length)
3507
_mi_move_key(keyinfo,key_block->lastkey,key);
4036
VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
3508
4037
key_block->last_length=a_length-t_length;
3512
4041
/* Fill block with end-zero and write filled block */
3513
4042
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);
4043
bzero((uchar*) anc_buff+key_block->last_length,
4044
keyinfo->block_length- key_block->last_length);
3516
4045
key_file_length=info->state->key_file_length;
3517
4046
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3520
4049
/* If we read the page from the key cache, we have to write it back to it */
3521
4050
if (key_file_length == info->state->key_file_length)
3523
4052
if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
3526
else if (my_pwrite(info->s->kfile,(unsigned char*) anc_buff,
4055
else if (my_pwrite(info->s->kfile,(uchar*) anc_buff,
3527
4056
(uint) keyinfo->block_length,filepos, param->myf_rw))
4058
DBUG_DUMP("buff",(uchar*) anc_buff,mi_getint(anc_buff));
3530
4060
/* Write separator-key to block in next level */
3531
4061
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
3534
4064
/* clear old block and write new key in it */
3535
4065
key_block->inited=0;
3536
return(sort_insert_key(sort_param, key_block,key,prev_block));
4066
DBUG_RETURN(sort_insert_key(sort_param, key_block,key,prev_block));
3537
4067
} /* sort_insert_key */
3615
4147
_mi_kpointer(info,key_block->end_pos,filepos);
3616
4148
key_file_length=info->state->key_file_length;
3617
memset(key_block->buff+length, 0, keyinfo->block_length-length);
4149
bzero((uchar*) key_block->buff+length, keyinfo->block_length-length);
3618
4150
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
3621
4153
/* If we read the page from the key cache, we have to write it back */
3622
4154
if (key_file_length == info->state->key_file_length)
3624
4156
if (_mi_write_keypage(info, keyinfo, filepos,
3625
4157
DFLT_INIT_HITS, key_block->buff))
3628
else if (my_pwrite(info->s->kfile,(unsigned char*) key_block->buff,
4160
else if (my_pwrite(info->s->kfile,(uchar*) key_block->buff,
3629
4161
(uint) keyinfo->block_length,filepos, myf_rw))
4163
DBUG_DUMP("buff",(uchar*) key_block->buff,length);
3633
4166
info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */
3635
4168
} /* flush_pending_blocks */
3637
4170
/* 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)
4172
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
3642
register uint32_t i;
3643
4176
SORT_KEY_BLOCKS *block;
4177
DBUG_ENTER("alloc_key_blocks");
3645
4179
if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
3646
4180
buffer_length+IO_SIZE)*blocks,
3695
4230
unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
3696
4231
(param->testflag & T_UNPACK);
3697
4232
if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
3699
memcpy(keyinfo,share.keyinfo,sizeof(MI_KEYDEF)*share.base.keys);
4234
memcpy((uchar*) keyinfo,(uchar*) share.keyinfo,
4235
(size_t) (sizeof(MI_KEYDEF)*share.base.keys));
3701
4237
key_parts= share.base.all_key_parts;
3702
4238
if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
3703
4239
(key_parts+share.base.keys))))
3705
my_afree((unsigned char*) keyinfo);
4241
my_afree((uchar*) keyinfo);
3708
4244
if (!(recdef=(MI_COLUMNDEF*)
3709
4245
my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
3711
my_afree((unsigned char*) keyinfo);
3712
my_afree((unsigned char*) keysegs);
4247
my_afree((uchar*) keyinfo);
4248
my_afree((uchar*) keysegs);
3715
4251
if (!(uniquedef=(MI_UNIQUEDEF*)
3716
4252
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);
4254
my_afree((uchar*) recdef);
4255
my_afree((uchar*) keyinfo);
4256
my_afree((uchar*) keysegs);
3724
4260
/* Copy the column definitions */
3725
memcpy(recdef, share.rec, sizeof(MI_COLUMNDEF)*(share.base.fields+1));
4261
memcpy((uchar*) recdef,(uchar*) share.rec,
4262
(size_t) (sizeof(MI_COLUMNDEF)*(share.base.fields+1)));
3726
4263
for (rec=recdef,end=recdef+share.base.fields; rec != end ; rec++)
3728
4265
if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
3769
4306
(param->testflag & T_UNPACK);
3770
4307
share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
3772
file_length=(uint64_t) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
4309
file_length=(ulonglong) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0));
3773
4310
tmp_length= file_length+file_length/10;
3774
4311
set_if_bigger(file_length,param->max_data_file_length);
3775
4312
set_if_bigger(file_length,tmp_length);
3776
set_if_bigger(file_length,(uint64_t) share.base.max_data_file_length);
4313
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);
4315
VOID(mi_close(*org_info));
4316
bzero((char*) &create_info,sizeof(create_info));
4317
create_info.max_rows=max(max_records,share.base.records);
3781
4318
create_info.reloc_rows=share.base.reloc;
3782
4319
create_info.old_options=(share.options |
3783
4320
(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);
4372
my_afree((uchar*) uniquedef);
4373
my_afree((uchar*) keyinfo);
4374
my_afree((uchar*) recdef);
4375
my_afree((uchar*) keysegs);
3843
4380
/* write suffix to data file if neaded */
3845
int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile)
4382
int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
3847
4384
MI_INFO *info=sort_info->info;
3849
4386
if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
3851
unsigned char buff[MEMMAP_EXTRA_MARGIN];
3852
memset(buff, 0, sizeof(buff));
4388
uchar buff[MEMMAP_EXTRA_MARGIN];
4389
bzero(buff,sizeof(buff));
3853
4390
if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
3855
4392
mi_check_print_error(sort_info->param,
3968
4506
if (my_errno != HA_ERR_END_OF_FILE)
3970
4508
mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3971
free(mi_get_rec_buff_ptr(info, record));
4509
my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3972
4510
mi_check_print_error(param,"%d when reading last record",my_errno);
3975
4513
if (!repair_only)
3976
4514
info->s->state.auto_increment=param->auto_increment_value;
3980
uint64_t auto_increment= retrieve_auto_increment(info, record);
4518
ulonglong auto_increment= retrieve_auto_increment(info, record);
3981
4519
set_if_bigger(info->s->state.auto_increment,auto_increment);
3982
4520
if (!repair_only)
3983
4521
set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
3985
4523
mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
3986
free(mi_get_rec_buff_ptr(info, record));
4524
my_free(mi_get_rec_buff_ptr(info, record), MYF(0));
3987
4525
update_state_info(param, info, UPDATE_AUTO_INC);
4086
static ha_checksum mi_byte_checksum(const unsigned char *buf, uint32_t length)
4624
static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
4088
4626
ha_checksum crc;
4089
const unsigned char *end=buf+length;
4627
const uchar *end=buf+length;
4090
4628
for (crc=0; buf != end; buf++)
4091
crc=((crc << 1) + *((unsigned char*) buf)) +
4629
crc=((crc << 1) + *((uchar*) buf)) +
4092
4630
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)
4634
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));
4636
uint key_maxlength=key->maxlength;
4637
if (key->flag & HA_FULLTEXT)
4639
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
4640
key->seg->charset->mbmaxlen;
4641
key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
4643
return (key->flag & HA_SPATIAL) ||
4644
(key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
4645
((ulonglong) rows * key_maxlength >
4646
(ulonglong) myisam_max_temp_length));
4134
Return true if we can use repair by sorting
4679
Return TRUE if we can use repair by sorting
4135
4680
One can set the force argument to force to use sorting
4136
4681
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)
4684
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
4685
ulonglong key_map, my_bool force)
4142
4687
MYISAM_SHARE *share=info->s;
4143
4688
MI_KEYDEF *key=share->keyinfo;
4147
4692
mi_repair_by_sort only works if we have at least one key. If we don't
4148
4693
have any keys, we should use the normal repair.
4150
4695
if (! mi_is_any_key_active(key_map))
4151
return false; /* Can't use sort */
4696
return FALSE; /* Can't use sort */
4152
4697
for (i=0 ; i < share->base.keys ; i++,key++)
4154
4699
if (!force && mi_too_big_key_for_sort(key,rows))