summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
Diffstat (limited to 'myisam')
-rw-r--r--myisam/ft_boolean_search.c6
-rw-r--r--myisam/mi_check.c10
-rw-r--r--myisam/mi_create.c10
-rw-r--r--myisam/mi_packrec.c66
-rw-r--r--myisam/mi_test3.c4
-rw-r--r--myisam/mi_write.c23
-rw-r--r--myisam/rt_index.c3
-rw-r--r--myisam/sort.c7
-rw-r--r--myisam/sp_key.c5
9 files changed, 83 insertions, 51 deletions
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
index 9a51eff88e1..ffc7e1bf104 100644
--- a/myisam/ft_boolean_search.c
+++ b/myisam/ft_boolean_search.c
@@ -155,7 +155,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
sizeof(FTB_WORD) +
(param.trunc ? MI_MAX_KEY_BUFF :
- w.len+extra));
+ w.len*ftb->charset->mbmaxlen+extra));
ftbw->len=w.len+1;
ftbw->flags=0;
ftbw->off=0;
@@ -348,7 +348,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
FTB_EXPR *top_ftbe=ftbe->up->up;
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);
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 2999482549c..f7e7ffd42f6 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -26,6 +26,7 @@
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
+#include "rt_index.h"
#ifndef USE_RAID
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
@@ -1465,6 +1466,12 @@ static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
if (_mi_ft_add(info,i,(char*) key,buff,filepos))
goto err;
}
+ else if (info->s->keyinfo[i].flag & HA_SPATIAL)
+ {
+ uint key_length=_mi_make_key(info,i,key,buff,filepos);
+ if (rtree_insert(info, i, key, key_length))
+ goto err;
+ }
else
{
uint key_length=_mi_make_key(info,i,key,buff,filepos);
@@ -3987,7 +3994,8 @@ static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
key->seg->charset->mbmaxlen;
key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
}
- return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
+ return (key->flag & HA_SPATIAL) ||
+ (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
((ulonglong) rows * key_maxlength >
(ulonglong) myisam_max_temp_length));
}
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 7fc7cc4edf1..f99a2c655d2 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)
{
@@ -297,6 +297,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
{
@@ -397,7 +398,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 e059bbb569f..7d053ddfd22 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -124,8 +124,8 @@ int mi_write(MI_INFO *info, byte *record)
{
if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
- DBUG_PRINT("error",("Got error: %d on write",my_errno));
- goto err;
+ DBUG_PRINT("error",("Got error: %d on write",my_errno));
+ goto err;
}
}
if (local_lock_tree)
@@ -159,18 +159,14 @@ int mi_write(MI_INFO *info, byte *record)
err:
save_errno=my_errno;
- if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
+ if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
+ my_errno == HA_ERR_NULL_IN_SPATIAL)
{
if (info->bulk_insert)
{
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 +325,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 +345,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,7 +366,7 @@ 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;
@@ -389,6 +385,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);
diff --git a/myisam/rt_index.c b/myisam/rt_index.c
index cfb2ca877f4..bdf5ee9c60f 100644
--- a/myisam/rt_index.c
+++ b/myisam/rt_index.c
@@ -710,7 +710,8 @@ err1:
int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length)
{
- return (rtree_insert_level(info, keynr, key, key_length, -1) == -1) ? -1 : 0;
+ return (!key_length ||
+ (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0;
}
diff --git a/myisam/sort.c b/myisam/sort.c
index 3dc066e877c..39bde41e4c9 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -84,7 +84,9 @@ static int NEAR_F write_merge_key_varlen(MI_SORT_PARAM *info,
IO_CACHE *to_file,
char* key, uint sort_length,
uint count);
-inline int my_var_write(MI_SORT_PARAM *info,IO_CACHE *to_file, byte *bufs);
+static inline int
+my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs);
+
/*
Creates a index of sorted keys
@@ -625,7 +627,8 @@ static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
} /* write_keys */
-inline int my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs)
+static inline int
+my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs)
{
int err;
uint16 len = _mi_keylength(info->keyinfo, (uchar*) bufs);
diff --git a/myisam/sp_key.c b/myisam/sp_key.c
index 0e424a9e193..b61e8094cde 100644
--- a/myisam/sp_key.c
+++ b/myisam/sp_key.c
@@ -50,6 +50,11 @@ uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key,
dlen = _mi_calc_blob_length(keyseg->bit_start, pos);
memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*));
+ if (!dptr)
+ {
+ my_errno= HA_ERR_NULL_IN_SPATIAL;
+ return 0;
+ }
sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr); /* SRID */
for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++)