diff options
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/ft_boolean_search.c | 26 | ||||
-rw-r--r-- | myisam/mi_check.c | 9 | ||||
-rw-r--r-- | myisam/mi_create.c | 10 | ||||
-rw-r--r-- | myisam/mi_packrec.c | 66 | ||||
-rw-r--r-- | myisam/mi_test3.c | 4 | ||||
-rw-r--r-- | myisam/mi_write.c | 17 |
6 files changed, 78 insertions, 54 deletions
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 196cb5c21fb..c432ac5a16c 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -164,9 +164,9 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end, if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC; ftbw->weight=weight; ftbw->up=up; - ftbw->docid[0]=ftbw->docid[1]=HA_POS_ERROR; + ftbw->docid[0]=ftbw->docid[1]=HA_OFFSET_ERROR; ftbw->ndepth= (param.yesno<0) + depth; - ftbw->key_root=HA_POS_ERROR; + ftbw->key_root=HA_OFFSET_ERROR; memcpy(ftbw->word+1, w.pos, w.len); ftbw->word[0]=w.len; if (param.yesno > 0) up->ythresh++; @@ -181,7 +181,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end, ftbe->weight=weight; ftbe->up=up; ftbe->ythresh=ftbe->yweaks=0; - ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR; + ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR; if ((ftbe->quot=param.quot)) ftb->with_scan|=2; if (param.yesno > 0) up->ythresh++; _ftb_parse_query(ftb, start, end, ftbe, depth+1); @@ -259,7 +259,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) { if (!ftbw->off || !(ftbw->flags & FTB_FLAG_TRUNC)) { - ftbw->docid[0]=HA_POS_ERROR; + ftbw->docid[0]=HA_OFFSET_ERROR; if ((ftbw->flags & FTB_FLAG_YES) && ftbw->up->up==0) { /* @@ -346,9 +346,9 @@ static void _ftb_init_index_search(FT_INFO *ftb) ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */ { FTB_EXPR *top_ftbe=ftbe->up->up; - ftbw->docid[0]=HA_POS_ERROR; + ftbw->docid[0]=HA_OFFSET_ERROR; for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up) - if (ftbe->flags & FTB_FLAG_YES) + if (!(ftbe->flags & FTB_FLAG_NO)) ftbe->yweaks++; ftbe=0; break; @@ -356,7 +356,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) } if (!ftbe) continue; - /* 3 */ + /* 4 */ if (!is_tree_inited(& ftb->no_dupes)) init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), _ftb_no_dupes_cmp,0,0,0); @@ -387,7 +387,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ftb->charset= ((keynr==NO_SUCH_KEY) ? default_charset_info : info->s->keyinfo[keynr].seg->charset); ftb->with_scan=0; - ftb->lastpos=HA_POS_ERROR; + ftb->lastpos=HA_OFFSET_ERROR; bzero(& ftb->no_dupes, sizeof(TREE)); init_alloc_root(&ftb->mem_root, 1024, 1024); @@ -410,7 +410,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ftbe->quot=0; ftbe->up=0; ftbe->ythresh=ftbe->yweaks=0; - ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR; + ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR; ftb->root=ftbe; _ftb_parse_query(ftb, &query, query+query_len, ftbe, 0); ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root, @@ -561,7 +561,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) while (ftb->state == INDEX_SEARCH && (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) != - HA_POS_ERROR) + HA_OFFSET_ERROR) { while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) { @@ -615,7 +615,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) const byte *end; my_off_t docid=ftb->info->lastpos; - if (docid == HA_POS_ERROR) + if (docid == HA_OFFSET_ERROR) return -2.0; if (!ftb->queue.elements) return 0; @@ -627,9 +627,9 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) for (i=0; i < ftb->queue.elements; i++) { - ftb->list[i]->docid[1]=HA_POS_ERROR; + ftb->list[i]->docid[1]=HA_OFFSET_ERROR; for (x=ftb->list[i]->up; x; x=x->up) - x->docid[1]=HA_POS_ERROR; + x->docid[1]=HA_OFFSET_ERROR; } } diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 9afe5ee2dac..112a371c9fe 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -656,6 +656,15 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (chk_index_down(param,info,&info->s->ft2_keyinfo,record, temp_buff,&tmp_keys,key_checksum,1)) goto err; + if (tmp_keys + subkeys) + { + mi_check_print_error(param, + "Number of words in the 2nd level tree " + "does not match the number in the header. " + "Parent word in on the page %s, offset %u", + llstr(page,llbuff), (uint) (old_keypos-buff)); + goto err; + } (*keys)+=tmp_keys-1; continue; } diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 6b9683dff45..e139997e0c7 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -16,7 +16,7 @@ /* Create a MyISAM table */ -#include "fulltext.h" +#include "ftdefs.h" #include "sp_defs.h" #if defined(MSDOS) || defined(__WIN__) @@ -41,7 +41,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, File dfile,file; int errpos,save_errno; myf create_flag; - uint fields,length,max_key_length,packed,pointer, + uint fields,length,max_key_length,packed,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length_skip, base_pos,varchar_count,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; @@ -238,7 +238,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { share.state.key_root[i]= HA_OFFSET_ERROR; - min_key_length_skip=length=0; + min_key_length_skip=length=real_length_diff=0; key_length=pointer; if (keydef->flag & HA_SPATIAL) { @@ -296,6 +296,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; length++; /* At least one length byte */ min_key_length_skip+=HA_FT_MAXBYTELEN; + real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT; } else { @@ -402,7 +403,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_segs) share.state.rec_per_key_part[key_segs-1]=1L; length+=key_length; - keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE); + keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff, + pointer,MI_MAX_KEYPTR_SIZE); if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || length >= MI_MAX_KEY_BUFF) { diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 94eb2de17e2..a277c2ca9d1 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -42,8 +42,9 @@ { bits-=(bit+1); break; } \ pos+= *pos +#define OFFSET_TABLE_SIZE 512 -static void read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree, +static uint read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree, uint16 **decode_table,byte **intervall_buff, uint16 *tmp_buff); static void make_quick_table(uint16 *to_table,uint16 *decode_table, @@ -53,7 +54,7 @@ static void fill_quick_table(uint16 *table,uint bits, uint max_bits, uint value); static uint copy_decode_table(uint16 *to_pos,uint offset, uint16 *decode_table); -static uint find_longest_bitstream(uint16 *table); +static uint find_longest_bitstream(uint16 *table, uint16 *end); static void (*get_unpack_function(MI_COLUMNDEF *rec))(MI_COLUMNDEF *field, MI_BIT_BUFF *buff, uchar *to, @@ -146,12 +147,12 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) { if (!my_errno) my_errno=HA_ERR_END_OF_FILE; - DBUG_RETURN(1); + goto err0; } if (memcmp((byte*) header,(byte*) myisam_pack_file_magic,4)) { my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(1); + goto err0; } share->pack.header_length= uint4korr(header+4); share->min_pack_length=(uint) uint4korr(header+8); @@ -173,20 +174,20 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) my_malloc((uint) (trees*sizeof(MI_DECODE_TREE)+ intervall_length*sizeof(byte)), MYF(MY_WME)))) - DBUG_RETURN(1); + goto err0; intervall_buff=(byte*) (share->decode_trees+trees); length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits)); if (!(share->decode_tables=(uint16*) - my_malloc((length+512)*sizeof(uint16)+ + my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+ (uint) (share->pack.header_length+7), MYF(MY_WME | MY_ZEROFILL)))) { my_free((gptr) share->decode_trees,MYF(0)); - DBUG_RETURN(1); + goto err1; } tmp_buff=share->decode_tables+length; - disk_cache=(byte*) (tmp_buff+512); + disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE); if (my_read(file,disk_cache, (uint) (share->pack.header_length-sizeof(header)), @@ -194,7 +195,7 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) { my_free((gptr) share->decode_trees,MYF(0)); my_free((gptr) share->decode_tables,MYF(0)); - DBUG_RETURN(1); + goto err2; } huff_tree_bits=max_bit(trees ? trees-1 : 0); @@ -213,8 +214,9 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) skip_to_next_byte(&bit_buff); decode_table=share->decode_tables; for (i=0 ; i < trees ; i++) - read_huff_table(&bit_buff,share->decode_trees+i,&decode_table, - &intervall_buff,tmp_buff); + if (read_huff_table(&bit_buff,share->decode_trees+i,&decode_table, + &intervall_buff,tmp_buff)) + goto err3; decode_table=(uint16*) my_realloc((gptr) share->decode_tables, (uint) ((byte*) decode_table - (byte*) share->decode_tables), @@ -224,8 +226,7 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) share->decode_tables=decode_table; for (i=0 ; i < trees ; i++) share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table, - diff, - uint16*); + diff, uint16*); } /* Fix record-ref-length for keys */ @@ -242,19 +243,24 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) } if (bit_buff.error || bit_buff.pos < bit_buff.end) - { /* info_length was wrong */ - my_errno=HA_ERR_WRONG_IN_RECORD; - my_free((gptr) share->decode_trees,MYF(0)); - my_free((gptr) share->decode_tables,MYF(0)); - DBUG_RETURN(1); - } + goto err3; + DBUG_RETURN(0); + +err3: + my_errno=HA_ERR_WRONG_IN_RECORD; +err2: + my_free((gptr) share->decode_tables,MYF(0)); +err1: + my_free((gptr) share->decode_trees,MYF(0)); +err0: + DBUG_RETURN(1); } /* Read on huff-code-table from datafile */ -static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, +static uint read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, uint16 **decode_table, byte **intervall_buff, uint16 *tmp_buff) { @@ -297,7 +303,9 @@ static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, decode_tree->intervalls= *intervall_buff; if (! intervall_length) { - table_bits=find_longest_bitstream(tmp_buff); + table_bits=find_longest_bitstream(tmp_buff, tmp_buff+OFFSET_TABLE_SIZE); + if (table_bits == (uint) ~0) + return 1; if (table_bits > myisam_quick_table_bits) table_bits=myisam_quick_table_bits; next_free_offset= (1 << table_bits); @@ -315,7 +323,7 @@ static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, bit_buff->pos+=intervall_length; bit_buff->bits=0; } - return; + return 0; } @@ -390,15 +398,23 @@ static uint copy_decode_table(uint16 *to_pos, uint offset, } -static uint find_longest_bitstream(uint16 *table) +static uint find_longest_bitstream(uint16 *table, uint16 *end) { uint length=1,length2; if (!(*table & IS_CHAR)) - length=find_longest_bitstream(table+ *table)+1; + { + uint16 *next= table + *table; + if (next > end || next == table) + return ~0; + length=find_longest_bitstream(next, end)+1; + } table++; if (!(*table & IS_CHAR)) { - length2=find_longest_bitstream(table+ *table)+1; + uint16 *next= table + *table; + if (next > end || next == table) + return ~0; + length2=find_longest_bitstream(table+ *table, end)+1; length=max(length,length2); } return length; diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c index dca04a9a64b..27d23317b5c 100644 --- a/myisam/mi_test3.c +++ b/myisam/mi_test3.c @@ -40,7 +40,7 @@ #endif -const char *filename= "test3.MSI"; +const char *filename= "test3"; uint tests=10,forks=10,key_cacheing=0,use_log=0; static void get_options(int argc, char *argv[]); @@ -363,7 +363,7 @@ int test_write(MI_INFO *file,int id,int lock_type) } sprintf(record.id,"%7d",getpid()); - strmov(record.text,"Testing..."); + strnmov(record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; for (i=count=0 ; i < tries ; i++) diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 579ba3c18bd..c2f24ae1ae3 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -165,12 +165,7 @@ err: { uint j; for (j=0 ; j < share->base.keys ; j++) - { - if (is_tree_inited(&info->bulk_insert[j])) - { - reset_tree(&info->bulk_insert[j]); - } - } + mi_flush_bulk_insert(info, j); } info->errkey= (int) i; while ( i-- > 0) @@ -329,7 +324,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *temp_buff,*keypos; uchar keybuff[MI_MAX_KEY_BUFF]; my_bool was_last_key; - my_off_t next_page; + my_off_t next_page, dupp_key_pos; DBUG_ENTER("w_search"); DBUG_PRINT("enter",("page: %ld",page)); @@ -349,9 +344,9 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, /* get position to record with duplicated key */ tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff); if (tmp_key_length) - info->dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length); + dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length); else - info->dupp_key_pos= HA_OFFSET_ERROR; + dupp_key_pos= HA_OFFSET_ERROR; if (keyinfo->flag & HA_FULLTEXT) { uint off; @@ -370,8 +365,9 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, else { /* popular word. two-level tree. going down */ - my_off_t root=info->dupp_key_pos; + my_off_t root=dupp_key_pos; keyinfo=&info->s->ft2_keyinfo; + get_key_full_length_rdonly(off, key); key+=off; keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */ error=_mi_ck_real_write_btree(info, keyinfo, key, 0, @@ -388,6 +384,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, } else /* not HA_FULLTEXT, normal HA_NOSAME key */ { + info->dupp_key_pos= dupp_key_pos; my_afree((byte*) temp_buff); my_errno=HA_ERR_FOUND_DUPP_KEY; DBUG_RETURN(-1); |