Commit c098d196 authored by unknown's avatar unknown

merging MyISAM changes into Maria (not done in 5.1->maria merge of

Jul 7th). "maria.test" and "ps_maria.test" still fail;
"ma_test_all" starts failing (MyISAM has the same issue see BUG#30094).


include/maria.h:
  merging MyISAM changes into Maria
mysys/mf_keycache.c:
  mi_test_all showed "floating point exception", this was already
  fixed in the latest 5.1, importing fix.
sql/item_xmlfunc.cc:
  compiler warning (already fixed in latest 5.1)
storage/maria/ha_maria.cc:
  merging MyISAM changes into Maria. See #ifdef ASK_MONTY.
storage/maria/ha_maria.h:
  merging MyISAM changes into Maria
storage/maria/ma_cache.c:
  merging MyISAM changes into Maria
storage/maria/ma_check.c:
  merging MyISAM changes into Maria
storage/maria/ma_create.c:
  merging MyISAM changes into Maria
storage/maria/ma_dynrec.c:
  merging MyISAM changes into Maria
storage/maria/ma_extra.c:
  merging MyISAM changes into Maria
storage/maria/ma_ft_boolean_search.c:
  merging MyISAM changes into Maria
storage/maria/ma_ft_nlq_search.c:
  merging MyISAM changes into Maria
storage/maria/ma_info.c:
  merging MyISAM changes into Maria
storage/maria/ma_key.c:
  merging MyISAM changes into Maria
storage/maria/ma_loghandler.c:
  compiler warning (part->length is size_t)
storage/maria/ma_open.c:
  merging MyISAM changes into Maria
storage/maria/ma_preload.c:
  merging MyISAM changes into Maria
storage/maria/ma_range.c:
  merging MyISAM changes into Maria
storage/maria/ma_rkey.c:
  merging MyISAM changes into Maria
storage/maria/ma_rt_index.c:
  merging MyISAM changes into Maria
storage/maria/ma_rt_key.c:
  merging MyISAM changes into Maria
storage/maria/ma_rt_split.c:
  merging MyISAM changes into Maria
storage/maria/ma_search.c:
  merging MyISAM changes into Maria
storage/maria/ma_sort.c:
  merging MyISAM changes into Maria
storage/maria/maria_def.h:
  merging MyISAM changes into Maria
parent 0ed84b06
...@@ -265,8 +265,8 @@ extern struct st_maria_info *maria_clone(struct st_maria_share *share, int mode) ...@@ -265,8 +265,8 @@ extern struct st_maria_info *maria_clone(struct st_maria_share *share, int mode)
extern int maria_panic(enum ha_panic_function function); extern int maria_panic(enum ha_panic_function function);
extern int maria_rfirst(struct st_maria_info *file, uchar *buf, int inx); extern int maria_rfirst(struct st_maria_info *file, uchar *buf, int inx);
extern int maria_rkey(struct st_maria_info *file, uchar *buf, int inx, extern int maria_rkey(struct st_maria_info *file, uchar *buf, int inx,
const uchar *key, const uchar *key, key_part_map keypart_map,
uint key_len, enum ha_rkey_function search_flag); enum ha_rkey_function search_flag);
extern int maria_rlast(struct st_maria_info *file, uchar *buf, int inx); extern int maria_rlast(struct st_maria_info *file, uchar *buf, int inx);
extern int maria_rnext(struct st_maria_info *file, uchar *buf, int inx); extern int maria_rnext(struct st_maria_info *file, uchar *buf, int inx);
extern int maria_rnext_same(struct st_maria_info *info, uchar *buf); extern int maria_rnext_same(struct st_maria_info *info, uchar *buf);
......
...@@ -2522,10 +2522,8 @@ uchar *key_cache_read(KEY_CACHE *keycache, ...@@ -2522,10 +2522,8 @@ uchar *key_cache_read(KEY_CACHE *keycache,
int error=0; int error=0;
uchar *start= buff; uchar *start= buff;
DBUG_ENTER("key_cache_read"); DBUG_ENTER("key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu page: %lu length: %u", DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, (uint) file, (ulong) filepos, length));
(ulong) (filepos / keycache->key_cache_block_size),
length));
if (keycache->key_cache_inited) if (keycache->key_cache_inited)
{ {
...@@ -2979,10 +2977,10 @@ int key_cache_write(KEY_CACHE *keycache, ...@@ -2979,10 +2977,10 @@ int key_cache_write(KEY_CACHE *keycache,
int error=0; int error=0;
DBUG_ENTER("key_cache_write"); DBUG_ENTER("key_cache_write");
DBUG_PRINT("enter", DBUG_PRINT("enter",
("fd: %u pos: %lu page: %lu length: %u block_length: %u", ("fd: %u pos: %lu length: %u block_length: %u key_block_length:
(uint) file, (ulong) filepos, %u",
(ulong) (filepos / keycache->key_cache_block_size), (uint) file, (ulong) filepos, length, block_length,
length, block_length)); keycache ? keycache->key_cache_block_size : 0));
if (!dont_write) if (!dont_write)
{ {
......
...@@ -2767,7 +2767,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf) ...@@ -2767,7 +2767,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
if ((rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length())) != MY_XML_OK) if ((rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length())) != MY_XML_OK)
{ {
char buf[128]; char buf[128];
my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %u: %s", my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %lu: %s",
my_xml_error_lineno(&p) + 1, my_xml_error_lineno(&p) + 1,
my_xml_error_pos(&p) + 1, my_xml_error_pos(&p) + 1,
my_xml_error_string(&p)); my_xml_error_string(&p));
......
This diff is collapsed.
...@@ -68,18 +68,21 @@ class ha_maria :public handler ...@@ -68,18 +68,21 @@ class ha_maria :public handler
virtual bool check_if_locking_is_allowed(uint sql_command, virtual bool check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE * table, ulong type, TABLE * table,
uint count, uint count, uint current,
uint *system_count,
bool called_by_logger_thread); bool called_by_logger_thread);
int open(const char *name, int mode, uint test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(uchar * buf); int write_row(uchar * buf);
int update_row(const uchar * old_data, uchar * new_data); int update_row(const uchar * old_data, uchar * new_data);
int delete_row(const uchar * buf); int delete_row(const uchar * buf);
int index_read(uchar * buf, const uchar * key, int index_read(uchar * buf, const uchar * key, key_part_map keypart_map,
uint key_len, enum ha_rkey_function find_flag); enum ha_rkey_function find_flag);
int index_read_idx(uchar * buf, uint idx, const uchar * key, int index_read_idx(uchar * buf, uint idx, const uchar * key,
uint key_len, enum ha_rkey_function find_flag); key_part_map keypart_map,
int index_read_last(uchar * buf, const uchar * key, uint key_len); enum ha_rkey_function find_flag);
int index_read_last(uchar * buf, const uchar * key,
key_part_map keypart_map);
int index_next(uchar * buf); int index_next(uchar * buf);
int index_prev(uchar * buf); int index_prev(uchar * buf);
int index_first(uchar * buf); int index_first(uchar * buf);
......
...@@ -40,7 +40,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, ...@@ -40,7 +40,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
{ {
uint read_length,in_buff_length; uint read_length,in_buff_length;
my_off_t offset; my_off_t offset;
char *in_buff_pos; uchar *in_buff_pos;
DBUG_ENTER("_ma_read_cache"); DBUG_ENTER("_ma_read_cache");
if (pos < info->pos_in_file) if (pos < info->pos_in_file)
...@@ -61,7 +61,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, ...@@ -61,7 +61,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
(my_off_t) (info->read_end - info->request_pos)) (my_off_t) (info->read_end - info->request_pos))
{ {
in_buff_pos=info->request_pos+(uint) offset; in_buff_pos=info->request_pos+(uint) offset;
in_buff_length= min(length,(uint) ((char*)(info->read_end)-in_buff_pos)); in_buff_length= min(length,(size_t) (info->read_end-in_buff_pos));
memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length); memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length)) if (!(length-=in_buff_length))
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -344,7 +344,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) ...@@ -344,7 +344,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
flush_pagecache_blocks(info->s->pagecache, flush_pagecache_blocks(info->s->pagecache,
&info->s->kfile, FLUSH_FORCE_WRITE); &info->s->kfile, FLUSH_FORCE_WRITE);
size= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0)); size= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size) if ((skr=(my_off_t) info->state->key_file_length) != size)
{ {
/* Don't give error if file generated by mariapack */ /* Don't give error if file generated by mariapack */
...@@ -539,7 +539,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info) ...@@ -539,7 +539,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
maria_extra(info,HA_EXTRA_KEYREAD,0); maria_extra(info,HA_EXTRA_KEYREAD,0);
bzero(info->lastkey,keyinfo->seg->length); bzero(info->lastkey,keyinfo->seg->length);
if (!maria_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey, if (!maria_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey,
keyinfo->seg->length, HA_READ_KEY_EXACT)) (key_part_map)1, HA_READ_KEY_EXACT))
{ {
/* Don't count this as a real warning, as maria_chk can't correct it */ /* Don't count this as a real warning, as maria_chk can't correct it */
uint save=param->warning_printed; uint save=param->warning_printed;
...@@ -603,7 +603,8 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, ...@@ -603,7 +603,8 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
{ {
/* purecov: begin tested */ /* purecov: begin tested */
/* Give it a chance to fit in the real file size. */ /* Give it a chance to fit in the real file size. */
my_off_t max_length= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0)); my_off_t max_length= my_seek(info->s->kfile.file, 0L, MY_SEEK_END,
MYF(MY_THREADSAFE));
_ma_check_print_error(param, "Invalid key block position: %s " _ma_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s", "key block size: %u file_length: %s",
llstr(page, llbuff), keyinfo->block_length, llstr(page, llbuff), keyinfo->block_length,
...@@ -4772,10 +4773,11 @@ int maria_test_if_almost_full(MARIA_HA *info) ...@@ -4772,10 +4773,11 @@ int maria_test_if_almost_full(MARIA_HA *info)
{ {
if (info->s->options & HA_OPTION_COMPRESS_RECORD) if (info->s->options & HA_OPTION_COMPRESS_RECORD)
return 0; return 0;
return (my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0))/10*9 > return my_seek(info->s->kfile.file, 0L, MY_SEEK_END,
(my_off_t) (info->s->base.max_key_file_length) || MYF(MY_THREADSAFE))/10*9 >
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 > (my_off_t) info->s->base.max_key_file_length ||
(my_off_t) info->s->base.max_data_file_length); my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
(my_off_t) info->s->base.max_data_file_length;
} }
/* Recreate table with bigger more alloced record-data */ /* Recreate table with bigger more alloced record-data */
......
...@@ -239,6 +239,10 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -239,6 +239,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
column--; column--;
if (column->type == (int) FIELD_SKIP_ZERO && column->length == 1) if (column->type == (int) FIELD_SKIP_ZERO && column->length == 1)
{ {
/*
NOTE1: here we change a field type FIELD_SKIP_ZERO ->
FIELD_NORMAL
*/
column->type=(int) FIELD_NORMAL; column->type=(int) FIELD_NORMAL;
column->empty_pos= 0; column->empty_pos= 0;
column->empty_bit= 0; column->empty_bit= 0;
...@@ -701,6 +705,10 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -701,6 +705,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
pthread_mutex_lock(&THR_LOCK_maria); pthread_mutex_lock(&THR_LOCK_maria);
/*
NOTE: For test_if_reopen() we need a real path name. Hence we need
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
*/
if (ci->index_file_name) if (ci->index_file_name)
{ {
char *iext= strrchr(ci->index_file_name, '.'); char *iext= strrchr(ci->index_file_name, '.');
...@@ -712,13 +720,14 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -712,13 +720,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR))) if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
*path= '\0'; *path= '\0';
fn_format(filename, name, ci->index_file_name, MARIA_NAME_IEXT, fn_format(filename, name, ci->index_file_name, MARIA_NAME_IEXT,
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT); MY_REPLACE_DIR | MY_UNPACK_FILENAME |
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
} }
else else
{ {
fn_format(filename, ci->index_file_name, "", MARIA_NAME_IEXT, fn_format(filename, ci->index_file_name, "", MARIA_NAME_IEXT,
MY_UNPACK_FILENAME | (have_iext ? MY_REPLACE_EXT : MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
MY_APPEND_EXT)); (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
} }
fn_format(linkname, name, "", MARIA_NAME_IEXT, fn_format(linkname, name, "", MARIA_NAME_IEXT,
MY_UNPACK_FILENAME|MY_APPEND_EXT); MY_UNPACK_FILENAME|MY_APPEND_EXT);
...@@ -734,10 +743,11 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -734,10 +743,11 @@ int maria_create(const char *name, enum data_file_type datafile_type,
} }
else else
{ {
char *iext= strrchr(name, '.');
int have_iext= iext && !strcmp(iext, MARIA_NAME_IEXT);
fn_format(filename, name, "", MARIA_NAME_IEXT, fn_format(filename, name, "", MARIA_NAME_IEXT,
(MY_UNPACK_FILENAME | MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
(flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
MY_APPEND_EXT);
linkname_ptr= NullS; linkname_ptr= NullS;
/* /*
Replace the current file. Replace the current file.
...@@ -752,6 +762,10 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -752,6 +762,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
A TRUNCATE command checks for the table in the cache only and could A TRUNCATE command checks for the table in the cache only and could
be fooled to believe, the table is not open. be fooled to believe, the table is not open.
Pull the emergency brake in this situation. (Bug #8306) Pull the emergency brake in this situation. (Bug #8306)
NOTE: The filename is compared against unique_file_name of every
open table. Hence we need a real path here.
*/ */
if (_ma_test_if_reopen(filename)) if (_ma_test_if_reopen(filename))
{ {
......
...@@ -887,7 +887,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to, ...@@ -887,7 +887,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
register const uchar *from) register const uchar *from)
{ {
uint length,new_length,flag,bit,i; uint length,new_length,flag,bit,i;
char *pos,*end,*startpos,*packpos; uchar *pos,*end,*startpos,*packpos;
enum en_fieldtype type; enum en_fieldtype type;
reg3 MARIA_COLUMNDEF *column; reg3 MARIA_COLUMNDEF *column;
MARIA_BLOB *blob; MARIA_BLOB *blob;
...@@ -941,7 +941,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to, ...@@ -941,7 +941,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
pos= (uchar*) from; end= (uchar*) from + length; pos= (uchar*) from; end= (uchar*) from + length;
if (type == FIELD_SKIP_ENDSPACE) if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */ { /* Pack trailing spaces */
while (end > (char*) from && *(end-1) == ' ') while (end > from && *(end-1) == ' ')
end--; end--;
} }
else else
...@@ -1007,8 +1007,8 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to, ...@@ -1007,8 +1007,8 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
*packpos= (char) (uchar) flag; *packpos= (char) (uchar) flag;
if (info->s->calc_checksum) if (info->s->calc_checksum)
*to++= (uchar) info->cur_row.checksum; *to++= (uchar) info->cur_row.checksum;
DBUG_PRINT("exit",("packed length: %d",(int) ((char*)to-startpos))); DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
DBUG_RETURN((uint) ((char*)to-startpos)); DBUG_RETURN((uint) (to-startpos));
} /* _ma_rec_pack */ } /* _ma_rec_pack */
...@@ -1018,12 +1018,12 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to, ...@@ -1018,12 +1018,12 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
Returns 0 if record is ok. Returns 0 if record is ok.
*/ */
my_bool _ma_rec_check(MARIA_HA *info,const char *record, uchar *rec_buff, my_bool _ma_rec_check(MARIA_HA *info,const uchar *record, uchar *rec_buff,
ulong packed_length, my_bool with_checksum, ulong packed_length, my_bool with_checksum,
ha_checksum checksum) ha_checksum checksum)
{ {
uint length,new_length,flag,bit,i; uint length,new_length,flag,bit,i;
char *pos,*end,*packpos,*to; uchar *pos,*end,*packpos,*to;
enum en_fieldtype type; enum en_fieldtype type;
reg3 MARIA_COLUMNDEF *column; reg3 MARIA_COLUMNDEF *column;
DBUG_ENTER("_ma_rec_check"); DBUG_ENTER("_ma_rec_check");
...@@ -1123,7 +1123,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, uchar *rec_buff, ...@@ -1123,7 +1123,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, uchar *rec_buff,
else else
to+= length; to+= length;
} }
if (packed_length != (uint) (to - (char*) rec_buff) + if (packed_length != (uint) (to - rec_buff) +
test(info->s->calc_checksum) || (bit != 1 && (flag & ~(bit - 1)))) test(info->s->calc_checksum) || (bit != 1 && (flag & ~(bit - 1))))
goto err; goto err;
if (with_checksum && ((uchar) checksum != (uchar) *to)) if (with_checksum && ((uchar) checksum != (uchar) *to))
......
...@@ -379,11 +379,13 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, ...@@ -379,11 +379,13 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
break; /* Not supported */ break; /* Not supported */
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
/* /*
Memory map the data file if it is not already mapped and if there Memory map the data file if it is not already mapped. It is safe
are no other threads using this table. intern_lock prevents other to memory map a file while other threads are using file I/O on it.
threads from starting to use the table while we are mapping it. Assigning a new address to a function pointer is an atomic
operation. intern_lock prevents that two or more mappings are done
at the same time.
*/ */
if (!share->file_map && (share->tot_locks == 1)) if (!share->file_map)
{ {
if (_ma_dynmap_file(info, share->state.state.data_file_length)) if (_ma_dynmap_file(info, share->state.state.data_file_length))
{ {
......
...@@ -286,8 +286,8 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param, ...@@ -286,8 +286,8 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
} }
static void _ftb_parse_query(FTB *ftb, uchar *query, uint len, static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
struct st_mysql_ftparser *parser) struct st_mysql_ftparser *parser)
{ {
MYSQL_FTPARSER_PARAM *param; MYSQL_FTPARSER_PARAM *param;
MY_FTB_PARAM ftb_param; MY_FTB_PARAM ftb_param;
...@@ -295,9 +295,9 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len, ...@@ -295,9 +295,9 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len,
DBUG_ASSERT(parser); DBUG_ASSERT(parser);
if (ftb->state != UNINITIALIZED) if (ftb->state != UNINITIALIZED)
DBUG_VOID_RETURN; DBUG_RETURN(0);
if (! (param= maria_ftparser_call_initializer(ftb->info, ftb->keynr, 0))) if (! (param= maria_ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
DBUG_VOID_RETURN; DBUG_RETURN(1);
ftb_param.ftb= ftb; ftb_param.ftb= ftb;
ftb_param.depth= 0; ftb_param.depth= 0;
...@@ -312,8 +312,7 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len, ...@@ -312,8 +312,7 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len,
param->length= len; param->length= len;
param->flags= 0; param->flags= 0;
param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO; param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO;
parser->parse(param); DBUG_RETURN(parser->parse(param));
DBUG_VOID_RETURN;
} }
...@@ -537,9 +536,10 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, uchar *query, ...@@ -537,9 +536,10 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, uchar *query,
ftbe->phrase= NULL; ftbe->phrase= NULL;
ftbe->document= 0; ftbe->document= 0;
ftb->root=ftbe; ftb->root=ftbe;
_ftb_parse_query(ftb, query, query_len, keynr == NO_SUCH_KEY ? if (unlikely(_ftb_parse_query(ftb, query, query_len,
&ft_default_parser : keynr == NO_SUCH_KEY ? &ft_default_parser :
info->s->keyinfo[keynr].parser); info->s->keyinfo[keynr].parser)))
goto err;
/* /*
Hack: instead of init_queue, we'll use reinit queue to be able Hack: instead of init_queue, we'll use reinit queue to be able
to alloc queue with alloc_root() to alloc queue with alloc_root()
...@@ -621,7 +621,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param, ...@@ -621,7 +621,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
{ {
param->mysql_add_word(param, word.pos, word.len, 0); param->mysql_add_word(param, word.pos, word.len, 0);
if (phrase_param->match) if (phrase_param->match)
return 1; break;
} }
return 0; return 0;
} }
...@@ -639,6 +639,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param, ...@@ -639,6 +639,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
RETURN VALUE RETURN VALUE
1 is returned if phrase found, 0 else. 1 is returned if phrase found, 0 else.
-1 is returned if error occurs.
*/ */
static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len, static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
...@@ -666,12 +667,13 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len, ...@@ -666,12 +667,13 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
param->length= len; param->length= len;
param->flags= 0; param->flags= 0;
param->mode= MYSQL_FTPARSER_WITH_STOPWORDS; param->mode= MYSQL_FTPARSER_WITH_STOPWORDS;
parser->parse(param); if (unlikely(parser->parse(param)))
return -1;
DBUG_RETURN(ftb_param.match ? 1 : 0); DBUG_RETURN(ftb_param.match ? 1 : 0);
} }
static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) static int _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
{ {
FT_SEG_ITERATOR ftsi; FT_SEG_ITERATOR ftsi;
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
...@@ -703,17 +705,19 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_ ...@@ -703,17 +705,19 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_
weight=ftbe->cur_weight*ftbe->weight; weight=ftbe->cur_weight*ftbe->weight;
if (mode && ftbe->phrase) if (mode && ftbe->phrase)
{ {
int not_found=1; int found= 0;
memcpy(&ftsi, ftsi_orig, sizeof(ftsi)); memcpy(&ftsi, ftsi_orig, sizeof(ftsi));
while (_ma_ft_segiterator(&ftsi) && not_found) while (_ma_ft_segiterator(&ftsi) && !found)
{ {
if (!ftsi.pos) if (!ftsi.pos)
continue; continue;
not_found = ! _ftb_check_phrase(ftb, ftsi.pos, ftsi.len, found= _ftb_check_phrase(ftb, ftsi.pos, ftsi.len, ftbe, parser);
ftbe, parser); if (unlikely(found < 0))
return 1;
} }
if (not_found) break; if (!found)
break;
} /* ftbe->quot */ } /* ftbe->quot */
} }
else else
...@@ -745,6 +749,7 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_ ...@@ -745,6 +749,7 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_
weight*= ftbe->weight; weight*= ftbe->weight;
} }
} }
return 0;
} }
...@@ -777,7 +782,11 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record) ...@@ -777,7 +782,11 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record)
{ {
while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
{ {
_ftb_climb_the_tree(ftb, ftbw, 0); if (unlikely(_ftb_climb_the_tree(ftb, ftbw, 0)))
{
my_errno= HA_ERR_OUT_OF_MEM;
goto err;
}
/* update queue */ /* update queue */
_ft2_search(ftb, ftbw, 0); _ft2_search(ftb, ftbw, 0);
...@@ -853,7 +862,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, ...@@ -853,7 +862,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
if (ftbw->docid[1] == ftb->info->cur_row.lastpos) if (ftbw->docid[1] == ftb->info->cur_row.lastpos)
continue; continue;
ftbw->docid[1]= ftb->info->cur_row.lastpos; ftbw->docid[1]= ftb->info->cur_row.lastpos;
_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi); if (unlikely(_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi)))
return 1;
} }
return(0); return(0);
} }
...@@ -926,7 +936,8 @@ float maria_ft_boolean_find_relevance(FT_INFO *ftb, uchar *record, uint length) ...@@ -926,7 +936,8 @@ float maria_ft_boolean_find_relevance(FT_INFO *ftb, uchar *record, uint length)
continue; continue;
param->doc= (uchar *)ftsi.pos; param->doc= (uchar *)ftsi.pos;
param->length= ftsi.len; param->length= ftsi.len;
parser->parse(param); if (unlikely(parser->parse(param)))
return 0;
} }
ftbe=ftb->root; ftbe=ftb->root;
if (ftbe->docid[1]==docid && ftbe->cur_weight>0 && if (ftbe->docid[1]==docid && ftbe->cur_weight>0 &&
......
...@@ -258,8 +258,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query, ...@@ -258,8 +258,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
{ {
info->update|= HA_STATE_AKTIV; info->update|= HA_STATE_AKTIV;
ftparser_param->flags= MYSQL_FTFLAGS_NEED_COPY; ftparser_param->flags= MYSQL_FTFLAGS_NEED_COPY;
_ma_ft_parse(&wtree, info, keynr, record, ftparser_param, if (unlikely(_ma_ft_parse(&wtree, info, keynr, record, ftparser_param,
&wtree.mem_root); &wtree.mem_root)))
{
delete_queue(&best);
goto err;
}
} }
} }
delete_queue(&best); delete_queue(&best);
......
...@@ -57,9 +57,9 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag) ...@@ -57,9 +57,9 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
x->keys = share->state.header.keys; x->keys = share->state.header.keys;
x->check_time = share->state.check_time; x->check_time = share->state.check_time;
x->mean_reclength = info->state->records ? x->mean_reclength = x->records ?
(ulong) ((info->state->data_file_length-info->state->empty)/ (ulong) ((x->data_file_length - x->delete_length) /x ->records) :
info->state->records) : (ulong) share->min_pack_length; (ulong) share->min_pack_length;
} }
if (flag & HA_STATUS_ERRKEY) if (flag & HA_STATUS_ERRKEY)
{ {
......
...@@ -206,7 +206,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -206,7 +206,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
uint keynr key number uint keynr key number
key Store packed key here key Store packed key here
old Not packed key old Not packed key
k_length Length of 'old' to use keypart_map bitmap of used keyparts
last_used_keyseg out parameter. May be NULL last_used_keyseg out parameter. May be NULL
RETURN RETURN
...@@ -216,34 +216,37 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -216,34 +216,37 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
*/ */
uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
const uchar *old, uint k_length, HA_KEYSEG **last_used_keyseg) const uchar *old, key_part_map keypart_map,
HA_KEYSEG **last_used_keyseg)
{ {
uchar *start_key=key; uchar *start_key=key;
HA_KEYSEG *keyseg; HA_KEYSEG *keyseg;
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
DBUG_ENTER("_ma_pack_key"); DBUG_ENTER("_ma_pack_key");
for (keyseg=info->s->keyinfo[keynr].seg ; /* "one part" rtree key is 2*SPDIMS part key in Maria */
keyseg->type && (int) k_length > 0; if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
old+=keyseg->length, keyseg++) keypart_map= (((key_part_map)1) << (2*SPDIMS)) - 1;
/* only key prefixes are supported */
DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
old+= keyseg->length, keyseg++)
{ {
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
uint length=min((uint) keyseg->length,(uint) k_length); uint length= keyseg->length;
uint char_length; uint char_length;
const uchar *pos; const uchar *pos;
CHARSET_INFO *cs=keyseg->charset; CHARSET_INFO *cs=keyseg->charset;
keypart_map>>= 1;
if (keyseg->null_bit) if (keyseg->null_bit)
{ {
k_length--;
if (!(*key++= (char) 1-*old++)) /* Copy null marker */ if (!(*key++= (char) 1-*old++)) /* Copy null marker */
{ {
k_length-=length;
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
{
k_length-=2; /* Skip length */
old+= 2; old+= 2;
}
continue; /* Found NULL */ continue; /* Found NULL */
} }
} }
...@@ -253,17 +256,16 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -253,17 +256,16 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
if (keyseg->flag & HA_SPACE_PACK) if (keyseg->flag & HA_SPACE_PACK)
{ {
const uchar *end= pos + length; const uchar *end= pos + length;
if (type != HA_KEYTYPE_NUM) if (type == HA_KEYTYPE_NUM)
{
while (end > pos && end[-1] == ' ')
end--;
}
else
{ {
while (pos < end && pos[0] == ' ') while (pos < end && pos[0] == ' ')
pos++; pos++;
} }
k_length-=length; else if (type != HA_KEYTYPE_BINARY)
{
while (end > pos && end[-1] == ' ')
end--;
}
length=(uint) (end-pos); length=(uint) (end-pos);
FIX_LENGTH(cs, pos, length, char_length); FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length); store_key_length_inc(key,char_length);
...@@ -275,7 +277,6 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -275,7 +277,6 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
{ {
/* Length of key-part used with maria_rkey() always 2 */ /* Length of key-part used with maria_rkey() always 2 */
uint tmp_length=uint2korr(pos); uint tmp_length=uint2korr(pos);
k_length-= 2+length;
pos+=2; pos+=2;
set_if_smaller(length,tmp_length); /* Safety */ set_if_smaller(length,tmp_length); /* Safety */
FIX_LENGTH(cs, pos, length, char_length); FIX_LENGTH(cs, pos, length, char_length);
...@@ -288,11 +289,8 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -288,11 +289,8 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
else if (keyseg->flag & HA_SWAP_KEY) else if (keyseg->flag & HA_SWAP_KEY)
{ /* Numerical column */ { /* Numerical column */
pos+=length; pos+=length;
k_length-=length;
while (length--) while (length--)
{
*key++ = *--pos; *key++ = *--pos;
}
continue; continue;
} }
FIX_LENGTH(cs, pos, length, char_length); FIX_LENGTH(cs, pos, length, char_length);
...@@ -300,30 +298,10 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, ...@@ -300,30 +298,10 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
if (length > char_length) if (length > char_length)
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
key+= length; key+= length;
k_length-=length;
} }
if (last_used_keyseg) if (last_used_keyseg)
*last_used_keyseg= keyseg; *last_used_keyseg= keyseg;
#ifdef NOT_USED
if (keyseg->type)
{
/* Part-key ; fill with ASCII 0 for easier searching */
length= (uint) -k_length; /* unused part of last key */
do
{
if (keyseg->flag & HA_NULL_PART)
length++;
if (keyseg->flag & HA_SPACE_PACK)
length+=2;
else
length+= keyseg->length;
keyseg++;
} while (keyseg->type);
bzero(key,length);
key+=length;
}
#endif
DBUG_PRINT("exit", ("length: %u", (uint) (key-start_key))); DBUG_PRINT("exit", ("length: %u", (uint) (key-start_key)));
DBUG_RETURN((uint) (key-start_key)); DBUG_RETURN((uint) (key-start_key));
} /* _ma_pack_key */ } /* _ma_pack_key */
......
...@@ -3553,8 +3553,8 @@ static my_bool translog_relative_LSN_encode(struct st_translog_parts *parts, ...@@ -3553,8 +3553,8 @@ static my_bool translog_relative_LSN_encode(struct st_translog_parts *parts,
COMPRESSED_LSN_MAX_STORE_SIZE)) - COMPRESSED_LSN_MAX_STORE_SIZE)) -
dst_ptr); dst_ptr);
parts->record_length-= (economy= lsns_len - part->length); parts->record_length-= (economy= lsns_len - part->length);
DBUG_PRINT("info", ("new length of LSNs: %u economy: %d", DBUG_PRINT("info", ("new length of LSNs: %lu economy: %d",
part->length, economy)); (ulong)part->length, economy));
parts->total_record_length-= economy; parts->total_record_length-= economy;
part->str= (char*)dst_ptr; part->str= (char*)dst_ptr;
} }
......
...@@ -392,7 +392,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -392,7 +392,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
key_parts+=fulltext_keys*FT_SEGS; key_parts+=fulltext_keys*FT_SEGS;
if (share->base.max_key_length > maria_max_key_length() || if (share->base.max_key_length > maria_max_key_length() ||
keys > MARIA_MAX_KEY || key_parts >= MARIA_MAX_KEY * HA_MAX_KEY_SEG) keys > MARIA_MAX_KEY || key_parts > MARIA_MAX_KEY * HA_MAX_KEY_SEG)
{ {
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts)); DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
my_errno=HA_ERR_UNSUPPORTED; my_errno=HA_ERR_UNSUPPORTED;
...@@ -667,22 +667,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -667,22 +667,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
_ma_setup_functions(share); _ma_setup_functions(share);
if ((*share->once_init)(share, info.dfile.file)) if ((*share->once_init)(share, info.dfile.file))
goto err; goto err;
if (open_flags & HA_OPEN_MMAP)
{
info.s= share;
if (_ma_dynmap_file(&info, share->state.state.data_file_length))
{
/* purecov: begin inspected */
/* Ignore if mmap fails. Use file I/O instead. */
DBUG_PRINT("warning", ("mmap failed: errno: %d", errno));
/* purecov: end */
}
else
{
share->file_read= _ma_mmap_pread;
share->file_write= _ma_mmap_pwrite;
}
}
share->is_log_table= FALSE; share->is_log_table= FALSE;
if (open_flags & HA_OPEN_TMP_TABLE) if (open_flags & HA_OPEN_TMP_TABLE)
share->options|= HA_OPTION_TMP_TABLE; share->options|= HA_OPTION_TMP_TABLE;
...@@ -721,6 +705,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -721,6 +705,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
} }
} }
#endif #endif
/*
Memory mapping can only be requested after initializing intern_lock.
*/
if (open_flags & HA_OPEN_MMAP)
{
info.s= share;
maria_extra(&info, HA_EXTRA_MMAP, 0);
}
} }
else else
{ {
...@@ -1022,10 +1014,10 @@ uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite) ...@@ -1022,10 +1014,10 @@ uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite)
} }
if (pWrite & 1) if (pWrite & 1)
DBUG_RETURN(my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L, DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
MYF(MY_NABP | MY_THREADSAFE))); MYF(MY_NABP | MY_THREADSAFE)) != 0);
DBUG_RETURN(my_write(file, (char*) buff, (uint) (ptr-buff), DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
MYF(MY_NABP))); MYF(MY_NABP)) != 0);
} }
...@@ -1089,10 +1081,10 @@ uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, my_bool pRead) ...@@ -1089,10 +1081,10 @@ uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, my_bool pRead)
if (pRead) if (pRead)
{ {
if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP))) if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
return (MY_FILE_ERROR); return 1;
} }
else if (my_read(file, buff, state->state_length,MYF(MY_NABP))) else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
return (MY_FILE_ERROR); return 1;
_ma_state_info_read(buff, state); _ma_state_info_read(buff, state);
} }
return 0; return 0;
...@@ -1143,7 +1135,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base) ...@@ -1143,7 +1135,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
*ptr++= base->extra_alloc_procent; *ptr++= base->extra_alloc_procent;
bzero(ptr,16); ptr+= 16; /* extra */ bzero(ptr,16); ptr+= 16; /* extra */
DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE); DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE);
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
} }
...@@ -1204,7 +1196,7 @@ uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef) ...@@ -1204,7 +1196,7 @@ uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
mi_int2store(ptr,keydef->keylength); ptr+= 2; mi_int2store(ptr,keydef->keylength); ptr+= 2;
mi_int2store(ptr,keydef->minlength); ptr+= 2; mi_int2store(ptr,keydef->minlength); ptr+= 2;
mi_int2store(ptr,keydef->maxlength); ptr+= 2; mi_int2store(ptr,keydef->maxlength); ptr+= 2;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
} }
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef) char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef)
...@@ -1247,7 +1239,7 @@ int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg) ...@@ -1247,7 +1239,7 @@ int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
mi_int4store(ptr, pos); mi_int4store(ptr, pos);
ptr+=4; ptr+=4;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
} }
...@@ -1287,7 +1279,7 @@ uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def) ...@@ -1287,7 +1279,7 @@ uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def)
*ptr++= (uchar) def->key; *ptr++= (uchar) def->key;
*ptr++ = (uchar) def->null_are_equal; *ptr++ = (uchar) def->null_are_equal;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
} }
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *def) char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *def)
...@@ -1315,7 +1307,7 @@ uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef) ...@@ -1315,7 +1307,7 @@ uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
mi_int2store(ptr,columndef->empty_pos); ptr+= 2; mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
(*ptr++)= columndef->null_bit; (*ptr++)= columndef->null_bit;
(*ptr++)= columndef->empty_bit; (*ptr++)= columndef->empty_bit;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
} }
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef) char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
......
...@@ -55,12 +55,17 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves) ...@@ -55,12 +55,17 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
block_length= keyinfo[0].block_length; block_length= keyinfo[0].block_length;
/* Check whether all indexes use the same block size */ if (ignore_leaves)
for (i= 1 ; i < keys ; i++)
{ {
if (keyinfo[i].block_length != block_length) /* Check whether all indexes use the same block size */
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); for (i= 1 ; i < keys ; i++)
{
if (keyinfo[i].block_length != block_length)
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
}
} }
else
block_length= share->pagecache->block_size;
length= info->preload_buff_size/block_length * block_length; length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length); set_if_bigger(length, block_length);
......
...@@ -21,12 +21,11 @@ ...@@ -21,12 +21,11 @@
#include "maria_def.h" #include "maria_def.h"
#include "ma_rt_index.h" #include "ma_rt_index.h"
static ha_rows _ma_record_pos(MARIA_HA *info,const uchar *key,uint key_len, static ha_rows _ma_record_pos(MARIA_HA *,const uchar *, key_part_map,
enum ha_rkey_function search_flag); enum ha_rkey_function);
static double _ma_search_pos(MARIA_HA *info,MARIA_KEYDEF *keyinfo, uchar *key, static double _ma_search_pos(MARIA_HA *, MARIA_KEYDEF *, uchar *,
uint key_len,uint nextflag, my_off_t pos); uint, uint, my_off_t);
static uint _ma_keynr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page, static uint _ma_keynr(MARIA_HA *, MARIA_KEYDEF *, uchar *, uchar *, uint *);
uchar *keypos, uint *ret_max_key);
/** /**
...@@ -84,7 +83,7 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key, ...@@ -84,7 +83,7 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
} }
key_buff= info->lastkey+info->s->base.max_key_length; key_buff= info->lastkey+info->s->base.max_key_length;
start_key_len= _ma_pack_key(info,inx, key_buff, start_key_len= _ma_pack_key(info,inx, key_buff,
min_key->key, min_key->length, min_key->key, min_key->keypart_map,
(HA_KEYSEG**) 0); (HA_KEYSEG**) 0);
res= maria_rtree_estimate(info, inx, key_buff, start_key_len, res= maria_rtree_estimate(info, inx, key_buff, start_key_len,
maria_read_vec[min_key->flag]); maria_read_vec[min_key->flag]);
...@@ -95,13 +94,13 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key, ...@@ -95,13 +94,13 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
case HA_KEY_ALG_BTREE: case HA_KEY_ALG_BTREE:
default: default:
start_pos= (min_key ? start_pos= (min_key ?
_ma_record_pos(info, min_key->key, min_key->length, _ma_record_pos(info, min_key->key, min_key->keypart_map,
min_key->flag) : min_key->flag) :
(ha_rows) 0); (ha_rows) 0);
end_pos= (max_key ? end_pos= (max_key ?
_ma_record_pos(info, max_key->key, max_key->length, _ma_record_pos(info, max_key->key, max_key->keypart_map,
max_key->flag) : max_key->flag) :
info->state->records+ (ha_rows) 1); info->state->records + (ha_rows) 1);
res= (end_pos < start_pos ? (ha_rows) 0 : res= (end_pos < start_pos ? (ha_rows) 0 :
(end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos)); (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
...@@ -126,20 +125,22 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key, ...@@ -126,20 +125,22 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
/* Find relative position (in records) for key in index-tree */ /* Find relative position (in records) for key in index-tree */
static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key, uint key_len, static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function search_flag) enum ha_rkey_function search_flag)
{ {
uint inx=(uint) info->lastinx, nextflag; uint inx=(uint) info->lastinx, nextflag, key_len;
MARIA_KEYDEF *keyinfo=info->s->keyinfo+inx; MARIA_KEYDEF *keyinfo=info->s->keyinfo+inx;
uchar *key_buff; uchar *key_buff;
double pos; double pos;
DBUG_ENTER("_ma_record_pos"); DBUG_ENTER("_ma_record_pos");
DBUG_PRINT("enter",("search_flag: %d",search_flag)); DBUG_PRINT("enter",("search_flag: %d",search_flag));
DBUG_ASSERT(keypart_map);
if (key_len == 0) if (key_len == 0)
key_len= USE_WHOLE_KEY; key_len= USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length; key_buff=info->lastkey+info->s->base.max_key_length;
key_len= _ma_pack_key(info, inx, key_buff, key, key_len, key_len= _ma_pack_key(info, inx, key_buff, key, keypart_map,
(HA_KEYSEG**) 0); (HA_KEYSEG**) 0);
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg, DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg,
key_buff, key_len);); key_buff, key_len););
...@@ -147,8 +148,42 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key, uint key_len, ...@@ -147,8 +148,42 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key, uint key_len,
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
key_len=USE_WHOLE_KEY; key_len=USE_WHOLE_KEY;
/*
my_handler.c:mi_compare_text() has a flag 'skip_end_space'.
This is set in my_handler.c:ha_key_cmp() in dependence on the
compare flags 'nextflag' and the column type.
TEXT columns are of type HA_KEYTYPE_VARTEXT. In this case the
condition is skip_end_space= ((nextflag & (SEARCH_FIND |
SEARCH_UPDATE)) == SEARCH_FIND).
SEARCH_FIND is used for an exact key search. The combination
SEARCH_FIND | SEARCH_UPDATE is used in write/update/delete
operations with a comment like "Not real duplicates", whatever this
means. From the condition above we can see that 'skip_end_space' is
always false for these operations. The result is that trailing space
counts in key comparison and hence, emtpy strings ('', string length
zero, but not NULL) compare less that strings starting with control
characters and these in turn compare less than strings starting with
blanks.
When estimating the number of records in a key range, we request an
exact search for the minimum key. This translates into a plain
SEARCH_FIND flag. Using this alone would lead to a 'skip_end_space'
compare. Empty strings would be expected above control characters.
Their keys would not be found because they are located below control
characters.
This is the reason that we add the SEARCH_UPDATE flag here. It makes
the key estimation compare in the same way like key write operations
do. Olny so we will find the keys where they have been inserted.
Adding the flag unconditionally does not hurt as it is used in the
above mentioned condition only. So it can safely be used together
with other flags.
*/
pos= _ma_search_pos(info,keyinfo, key_buff, key_len, pos= _ma_search_pos(info,keyinfo, key_buff, key_len,
nextflag | SEARCH_SAVE_BUFF, nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE,
info->s->state.key_root[inx]); info->s->state.key_root[inx]);
if (pos >= 0.0) if (pos >= 0.0)
{ {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
/* Ordinary search_flag is 0 ; Give error if no record with key */ /* Ordinary search_flag is 0 ; Give error if no record with key */
int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key, int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key,
uint key_len, enum ha_rkey_function search_flag) key_part_map keypart_map, enum ha_rkey_function search_flag)
{ {
uchar *key_buff; uchar *key_buff;
MARIA_SHARE *share=info->s; MARIA_SHARE *share=info->s;
...@@ -47,20 +47,21 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key, ...@@ -47,20 +47,21 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key,
key is already packed!; This happens when we are using a MERGE TABLE key is already packed!; This happens when we are using a MERGE TABLE
*/ */
key_buff= info->lastkey+info->s->base.max_key_length; key_buff= info->lastkey+info->s->base.max_key_length;
pack_key_length= key_len; pack_key_length= keypart_map;
bmove(key_buff,key,key_len); bmove(key_buff, key, pack_key_length);
last_used_keyseg= 0; last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
} }
else else
{ {
if (key_len == 0) DBUG_ASSERT(keypart_map);
key_len=USE_WHOLE_KEY;
/* Save the packed key for later use in the second buffer of lastkey. */ /* Save the packed key for later use in the second buffer of lastkey. */
key_buff=info->lastkey+info->s->base.max_key_length; key_buff=info->lastkey+info->s->base.max_key_length;
pack_key_length= _ma_pack_key(info,(uint) inx, key_buff, key, pack_key_length= _ma_pack_key(info,(uint) inx, key_buff, key,
key_len, &last_used_keyseg); keypart_map, &last_used_keyseg);
/* Save packed_key_length for use by the MERGE engine. */ /* Save packed_key_length for use by the MERGE engine. */
info->pack_key_length= pack_key_length; info->pack_key_length= pack_key_length;
info->last_used_keyseg= (uint16) (last_used_keyseg -
info->s->keyinfo[inx].seg);
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg, DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg,
key_buff, pack_key_length);); key_buff, pack_key_length););
} }
......
This diff is collapsed.
...@@ -34,6 +34,7 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key, ...@@ -34,6 +34,7 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
{ {
uint page_size = maria_data_on_page(page_buf); uint page_size = maria_data_on_page(page_buf);
uint nod_flag = _ma_test_if_nod(page_buf); uint nod_flag = _ma_test_if_nod(page_buf);
DBUG_ENTER("maria_rtree_add_key");
if (page_size + key_length + info->s->base.rec_reflength <= if (page_size + key_length + info->s->base.rec_reflength <=
keyinfo->block_length) keyinfo->block_length)
...@@ -42,22 +43,27 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key, ...@@ -42,22 +43,27 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
if (nod_flag) if (nod_flag)
{ {
/* save key */ /* save key */
DBUG_ASSERT(_ma_kpos(nod_flag, key) < info->state->key_file_length);
memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag); memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag);
page_size += key_length + nod_flag; page_size += key_length + nod_flag;
} }
else else
{ {
/* save key */ /* save key */
DBUG_ASSERT(_ma_dpos(info, nod_flag, key + key_length +
info->s->base.rec_reflength) <
info->state->data_file_length +
info->s->base.pack_reclength);
memcpy(rt_PAGE_END(page_buf), key, key_length + memcpy(rt_PAGE_END(page_buf), key, key_length +
info->s->base.rec_reflength); info->s->base.rec_reflength);
page_size += key_length + info->s->base.rec_reflength; page_size += key_length + info->s->base.rec_reflength;
} }
maria_putint(page_buf, page_size, nod_flag); maria_putint(page_buf, page_size, nod_flag);
return 0; DBUG_RETURN(0);
} }
return (maria_rtree_split_page(info, keyinfo, page_buf, key, key_length, DBUG_RETURN(maria_rtree_split_page(info, keyinfo, page_buf, key, key_length,
new_page) ? -1 : 1); new_page) ? -1 : 1);
} }
...@@ -91,11 +97,13 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key, ...@@ -91,11 +97,13 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key, int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
uint key_length, my_off_t child_page) uint key_length, my_off_t child_page)
{ {
DBUG_ENTER("maria_rtree_set_key_mbr");
if (!_ma_fetch_keypage(info, keyinfo, child_page, if (!_ma_fetch_keypage(info, keyinfo, child_page,
DFLT_INIT_HITS, info->buff, 0)) DFLT_INIT_HITS, info->buff, 0))
return -1; DBUG_RETURN(-1);
return maria_rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); DBUG_RETURN(maria_rtree_page_mbr(info, keyinfo->seg,
info->buff, key, key_length));
} }
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
...@@ -266,13 +266,15 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -266,13 +266,15 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uint full_length= key_length + (nod_flag ? nod_flag : uint full_length= key_length + (nod_flag ? nod_flag :
info->s->base.rec_reflength); info->s->base.rec_reflength);
int max_keys= (maria_data_on_page(page)-2) / (full_length); int max_keys= (maria_data_on_page(page)-2) / (full_length);
DBUG_ENTER("maria_rtree_split_page");
DBUG_PRINT("rtree", ("splitting block"));
n_dim = keyinfo->keysegs / 2; n_dim = keyinfo->keysegs / 2;
if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) * if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) *
(max_keys + 1 + 4) + (max_keys + 1 + 4) +
sizeof(SplitStruct) * (max_keys + 1)))) sizeof(SplitStruct) * (max_keys + 1))))
return -1; DBUG_RETURN(-1); /* purecov: inspected */
task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4)); task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));
...@@ -343,12 +345,18 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -343,12 +345,18 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
else else
err_code= _ma_write_keypage(info, keyinfo, *new_page_offs, err_code= _ma_write_keypage(info, keyinfo, *new_page_offs,
DFLT_INIT_HITS, new_page); DFLT_INIT_HITS, new_page);
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
my_afree((uchar*)new_page); my_afree((uchar*)new_page);
split_err: split_err:
/**
@todo the cast below is useless (coord_buf is uchar*); at the moment we
changed all "byte" to "uchar", some casts became useless and should be
removed.
*/
my_afree((uchar*) coord_buf); my_afree((uchar*) coord_buf);
return err_code; DBUG_RETURN(err_code);
} }
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
...@@ -927,11 +927,16 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag, ...@@ -927,11 +927,16 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
/* /*
Keys are compressed the following way: Keys are compressed the following way:
prefix length Packed length of prefix for the prev key. (1 or 3 bytes) prefix length Packed length of prefix common with prev key. (1 or 3 bytes)
for each key segment: for each key segment:
[is null] Null indicator if can be null (1 byte, zero means null) [is null] Null indicator if can be null (1 byte, zero means null)
[length] Packed length if varlength (1 or 3 bytes) [length] Packed length if varlength (1 or 3 bytes)
key segment 'length' bytes of key segment value
pointer Reference to the data file (last_keyseg->length). pointer Reference to the data file (last_keyseg->length).
get_key_length() is a macro. It gets the prefix length from 'page'
and puts it into 'length'. It increments 'page' by 1 or 3, depending
on the packed length of the prefix length.
*/ */
get_key_length(length,page); get_key_length(length,page);
if (length) if (length)
...@@ -946,34 +951,44 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag, ...@@ -946,34 +951,44 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
my_errno=HA_ERR_CRASHED; my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0); /* Wrong key */ DBUG_RETURN(0); /* Wrong key */
} }
from=key; from_end=key+length; /* Key is packed against prev key, take prefix from prev key. */
from= key;
from_end= key + length;
} }
else else
{ {
from=page; from_end=page_end; /* Not packed key */ /* Key is not packed against prev key, take all from page buffer. */
from= page;
from_end= page_end;
} }
/* /*
The trouble is that key is split in two parts: The trouble is that key can be split in two parts:
The first part is in from ...from_end-1. The first part (prefix) is in from .. from_end - 1.
The second part starts at page The second part starts at page.
The split can be at every byte position. So we need to check for
the end of the first part before using every byte.
*/ */
for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++) for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
{ {
if (keyseg->flag & HA_NULL_PART) if (keyseg->flag & HA_NULL_PART)
{ {
/* If prefix is used up, switch to rest. */
if (from == from_end) { from=page; from_end=page_end; } if (from == from_end) { from=page; from_end=page_end; }
if (!(*key++ = *from++)) if (!(*key++ = *from++))
continue; /* Null part */ continue; /* Null part */
} }
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK)) if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
{ {
/* Get length of dynamic length key part */ /* If prefix is used up, switch to rest. */
if (from == from_end) { from=page; from_end=page_end; } if (from == from_end) { from=page; from_end=page_end; }
/* Get length of dynamic length key part */
if ((length= (uint) (uchar) (*key++ = *from++)) == 255) if ((length= (uint) (uchar) (*key++ = *from++)) == 255)
{ {
/* If prefix is used up, switch to rest. */
if (from == from_end) { from=page; from_end=page_end; } if (from == from_end) { from=page; from_end=page_end; }
length= ((uint) (uchar) ((*key++ = *from++))) << 8; length= ((uint) (uchar) ((*key++ = *from++))) << 8;
/* If prefix is used up, switch to rest. */
if (from == from_end) { from=page; from_end=page_end; } if (from == from_end) { from=page; from_end=page_end; }
length+= (uint) (uchar) ((*key++ = *from++)); length+= (uint) (uchar) ((*key++ = *from++));
} }
...@@ -994,14 +1009,26 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag, ...@@ -994,14 +1009,26 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
key+=length; key+=length;
from+=length; from+=length;
} }
/*
Last segment (type == 0) contains length of data pointer.
If we have mixed key blocks with data pointer and key block pointer,
we have to copy both.
*/
length=keyseg->length+nod_flag; length=keyseg->length+nod_flag;
if ((tmp=(uint) (from_end-from)) <= length) if ((tmp=(uint) (from_end-from)) <= length)
{ {
/* Remaining length is less or equal max possible length. */
memcpy(key+tmp,page,length-tmp); /* Get last part of key */ memcpy(key+tmp,page,length-tmp); /* Get last part of key */
*page_pos= page+length-tmp; *page_pos= page+length-tmp;
} }
else else
{ {
/*
Remaining length is greater than max possible length.
This can happen only if we switched to the new key bytes already.
'page_end' is calculated with MI_MAX_KEY_BUFF. So it can be far
behind the real end of the key.
*/
if (from_end != page_end) if (from_end != page_end)
{ {
DBUG_PRINT("error",("Error when unpacking key")); DBUG_PRINT("error",("Error when unpacking key"));
...@@ -1009,6 +1036,7 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag, ...@@ -1009,6 +1036,7 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
my_errno=HA_ERR_CRASHED; my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0); /* Error */ DBUG_RETURN(0); /* Error */
} }
/* Copy data pointer and, if appropriate, key block pointer. */
memcpy((uchar*) key,(uchar*) from,(size_t) length); memcpy((uchar*) key,(uchar*) from,(size_t) length);
*page_pos= from+length; *page_pos= from+length;
} }
......
...@@ -138,8 +138,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, ...@@ -138,8 +138,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
while (memavl >= MIN_SORT_MEMORY) while (memavl >= MIN_SORT_MEMORY)
{ {
if ((my_off_t) (records+1)*(sort_length+sizeof(char*)) <= if ((records < UINT_MAX32) &&
(my_off_t) memavl) ((my_off_t) (records + 1) *
(sort_length + sizeof(char*)) <= (my_off_t) memavl))
keys= records+1; keys= records+1;
else else
do do
...@@ -151,7 +152,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, ...@@ -151,7 +152,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
keys < (uint) maxbuffer) keys < (uint) maxbuffer)
{ {
_ma_check_print_error(info->sort_info->param, _ma_check_print_error(info->sort_info->param,
"sort_buffer_size is to small"); "maria_sort_buffer_size is too small");
goto err; goto err;
} }
} }
...@@ -175,7 +176,8 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, ...@@ -175,7 +176,8 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
} }
if (memavl < MIN_SORT_MEMORY) if (memavl < MIN_SORT_MEMORY)
{ {
_ma_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */ _ma_check_print_error(info->sort_info->param, "Maria sort buffer"
" too small"); /* purecov: tested */
goto err; /* purecov: tested */ goto err; /* purecov: tested */
} }
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */ (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
...@@ -369,7 +371,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) ...@@ -369,7 +371,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
keys < (uint) maxbuffer) keys < (uint) maxbuffer)
{ {
_ma_check_print_error(sort_param->sort_info->param, _ma_check_print_error(sort_param->sort_info->param,
"sort_buffer_size is to small"); "maria_sort_buffer_size is too small");
goto err; goto err;
} }
} }
...@@ -397,7 +399,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) ...@@ -397,7 +399,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
if (memavl < MIN_SORT_MEMORY) if (memavl < MIN_SORT_MEMORY)
{ {
_ma_check_print_error(sort_param->sort_info->param, _ma_check_print_error(sort_param->sort_info->param,
"Sort buffer too small"); "Maria sort buffer too small");
goto err; /* purecov: tested */ goto err; /* purecov: tested */
} }
...@@ -775,7 +777,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys, ...@@ -775,7 +777,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
{ {
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1)) buffpek+i,buffpek+i+MERGEBUFF-1))
break; /* purecov: inspected */ goto cleanup;
} }
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+ *maxbuffer)) buffpek+i,buffpek+ *maxbuffer))
...@@ -785,6 +787,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys, ...@@ -785,6 +787,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
temp=from_file; from_file=to_file; to_file=temp; temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1; *maxbuffer= (int) (lastbuff-buffpek)-1;
} }
cleanup:
close_cached_file(to_file); /* This holds old result */ close_cached_file(to_file); /* This holds old result */
if (to_file == t_file) if (to_file == t_file)
*t_file=t_file2; /* Copy result file */ *t_file=t_file2; /* Copy result file */
......
...@@ -442,6 +442,7 @@ struct st_maria_info ...@@ -442,6 +442,7 @@ struct st_maria_info
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */ enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length; uint save_lastkey_length;
uint pack_key_length; /* For MARIAMRG */ uint pack_key_length; /* For MARIAMRG */
uint16 last_used_keyseg; /* For MARIAMRG */
int errkey; /* Got last error on this key */ int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */ int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */ int tmp_lock_type; /* When locked by readinfo */
...@@ -749,7 +750,7 @@ extern my_off_t _ma_new(MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level); ...@@ -749,7 +750,7 @@ extern my_off_t _ma_new(MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level);
extern uint _ma_make_key(MARIA_HA *info, uint keynr, uchar *key, extern uint _ma_make_key(MARIA_HA *info, uint keynr, uchar *key,
const uchar *record, MARIA_RECORD_POS filepos); const uchar *record, MARIA_RECORD_POS filepos);
extern uint _ma_pack_key(MARIA_HA *info, uint keynr, uchar *key, extern uint _ma_pack_key(MARIA_HA *info, uint keynr, uchar *key,
const uchar *old, uint key_length, const uchar *old, key_part_map keypart_map,
HA_KEYSEG ** last_used_keyseg); HA_KEYSEG ** last_used_keyseg);
extern int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS); extern int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS);
extern int _ma_read_cache(IO_CACHE *info, uchar *buff, MARIA_RECORD_POS pos, extern int _ma_read_cache(IO_CACHE *info, uchar *buff, MARIA_RECORD_POS pos,
...@@ -760,7 +761,7 @@ extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size, ...@@ -760,7 +761,7 @@ extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size,
size_t new_size); size_t new_size);
extern ulong _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from, extern ulong _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from,
ulong reclength); ulong reclength);
extern my_bool _ma_rec_check(MARIA_HA *info, const char *record, extern my_bool _ma_rec_check(MARIA_HA *info, const uchar *record,
uchar *packpos, ulong packed_length, uchar *packpos, ulong packed_length,
my_bool with_checkum, ha_checksum checksum); my_bool with_checkum, ha_checksum checksum);
extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos, extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment