Commit 3b091bba authored by Sergey Vojtovich's avatar Sergey Vojtovich

Merge fixes for BUG51877, BUG51866, BUG47598 to mysql-5.1-bugteam.

parents f3b8b07a 5eff6aed
......@@ -631,4 +631,17 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
1
DROP TABLE t1;
#
# BUG#51866 - crash with repair by sort and fulltext keys
#
CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
INSERT INTO t1 VALUES('aaaa');
SET myisam_sort_buffer_size=4;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
End of 5.1 tests
......@@ -1540,5 +1540,12 @@ a
HANDLER t1 READ a LAST;
a
HANDLER t1 CLOSE;
HANDLER t1 OPEN;
HANDLER t1 READ a FIRST;
a
INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
# should not crash
HANDLER t1 READ a NEXT;
HANDLER t1 CLOSE;
DROP TABLE t1;
End of 5.0 tests.
......@@ -756,4 +756,17 @@ TRUNCATE t1;
HANDLER t1 READ FIRST;
ERROR 42S02: Unknown table 't1' in HANDLER
DROP TABLE t1;
#
# BUG#51877 - HANDLER interface causes invalid memory read
#
CREATE TABLE t1(a INT, KEY(a));
HANDLER t1 OPEN;
HANDLER t1 READ a FIRST;
a
INSERT INTO t1 VALUES(1);
HANDLER t1 READ a NEXT;
a
1
HANDLER t1 CLOSE;
DROP TABLE t1;
End of 5.1 tests
......@@ -2313,6 +2313,8 @@ INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
......@@ -2363,6 +2365,8 @@ CREATE TABLE t1(a CHAR(255), KEY(a));
SELECT * FROM t1, t1 AS a1;
a a
SET myisam_sort_buffer_size=4;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
INSERT INTO t1 VALUES
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
......
......@@ -523,6 +523,8 @@ select @@max_user_connections;
100
set global max_write_lock_count=100;
set myisam_sort_buffer_size=100;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
set global net_buffer_length=100;
Warnings:
Warning 1292 Truncated incorrect net_buffer_length value: '100'
......
......@@ -8,11 +8,15 @@ SELECT @start_session_value;
8388608
'#--------------------FN_DYNVARS_005_01-------------------------#'
SET @@global.myisam_sort_buffer_size = 100;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SET @@global.myisam_sort_buffer_size = DEFAULT;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
8388608
SET @@session.myisam_sort_buffer_size = 200;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '200'
SET @@session.myisam_sort_buffer_size = DEFAULT;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
......@@ -28,9 +32,11 @@ SELECT @@session.myisam_sort_buffer_size = 8388608;
1
'#--------------------FN_DYNVARS_005_03-------------------------#'
SET @@global.myisam_sort_buffer_size = 4;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
4
4096
SET @@global.myisam_sort_buffer_size = 4294967295;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
......@@ -41,9 +47,11 @@ SELECT @@global.myisam_sort_buffer_size ;
655354
'#--------------------FN_DYNVARS_005_04-------------------------#'
SET @@session.myisam_sort_buffer_size = 4;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
SET @@session.myisam_sort_buffer_size = 4294967295;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
......@@ -58,13 +66,13 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
4
4096
SET @@global.myisam_sort_buffer_size = -1024;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-1024'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
4
4096
SET @@global.myisam_sort_buffer_size = 429496729533;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '429496729533'
......@@ -101,28 +109,28 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
SET @@session.myisam_sort_buffer_size = -2;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-2'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
SET @@session.myisam_sort_buffer_size = 65530.34.;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
SET @@session.myisam_sort_buffer_size = test;
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
SET @@session.myisam_sort_buffer_size = "test";
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
4
4096
'#------------------FN_DYNVARS_005_06-----------------------#'
SELECT @@global.myisam_sort_buffer_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -141,20 +149,24 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
4
4096
SET @@global.myisam_sort_buffer_size = FALSE;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
4
4096
'#---------------------FN_DYNVARS_001_09----------------------#'
SET @@global.myisam_sort_buffer_size = 10;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '10'
SELECT @@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size
0
1
'#---------------------FN_DYNVARS_001_10----------------------#'
SET @@myisam_sort_buffer_size = 100;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SELECT @@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size
1
......@@ -167,7 +179,7 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@myisam_sort_buffer_size ;
@@myisam_sort_buffer_size
4
4096
SELECT local.myisam_sort_buffer_size ;
ERROR 42S02: Unknown table 'local' in field list
SELECT session.myisam_sort_buffer_size ;
......
......@@ -575,5 +575,14 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
DROP TABLE t1;
--echo #
--echo # BUG#51866 - crash with repair by sort and fulltext keys
--echo #
CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
INSERT INTO t1 VALUES('aaaa');
SET myisam_sort_buffer_size=4;
REPAIR TABLE t1;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
--echo End of 5.1 tests
......@@ -914,14 +914,15 @@ HANDLER t1 READ a PREV;
HANDLER t1 READ a LAST;
HANDLER t1 CLOSE;
#TODO: re-enable this test please when bug #51877 is solved
# second crash fixed when the tree has changed since the last search.
#HANDLER t1 OPEN;
#HANDLER t1 READ a FIRST;
#INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
#HANDLER t1 READ a NEXT;
#HANDLER t1 CLOSE;
#TODO: end of the 51877 dependent section
HANDLER t1 OPEN;
HANDLER t1 READ a FIRST;
INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
--echo # should not crash
--disable_result_log
HANDLER t1 READ a NEXT;
--enable_result_log
HANDLER t1 CLOSE;
DROP TABLE t1;
......
......@@ -37,4 +37,15 @@ TRUNCATE t1;
HANDLER t1 READ FIRST;
DROP TABLE t1;
--echo #
--echo # BUG#51877 - HANDLER interface causes invalid memory read
--echo #
CREATE TABLE t1(a INT, KEY(a));
HANDLER t1 OPEN;
HANDLER t1 READ a FIRST;
INSERT INTO t1 VALUES(1);
HANDLER t1 READ a NEXT;
HANDLER t1 CLOSE;
DROP TABLE t1;
--echo End of 5.1 tests
......@@ -6858,7 +6858,7 @@ The minimum value for this variable is 4096.",
"The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
(uchar**) &global_system_variables.myisam_sort_buff_size,
(uchar**) &max_system_variables.myisam_sort_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0},
{"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
"Use memory mapping for reading and writing MyISAM tables.",
(uchar**) &opt_myisam_use_mmap,
......
......@@ -2396,10 +2396,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
/*
fulltext indexes may have much more entries than the
number of rows in the table. We estimate the number here.
Note, built-in parser is always nr. 0 - see ftparser_call_initializer()
*/
if (sort_param.keyinfo->ftkey_nr == 0)
if (sort_param.keyinfo->parser == &ft_default_parser)
{
/*
for built-in parser the number of generated index entries
......@@ -2416,8 +2414,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
so, we'll use all the sort memory and start from ~10 buffpeks.
(see _create_index_by_sort)
*/
sort_info.max_records=
10*param->sort_buffer_length/sort_param.key_length;
sort_info.max_records= 10 *
max(param->sort_buffer_length, MIN_SORT_BUFFER) /
sort_param.key_length;
}
sort_param.key_read=sort_ft_key_read;
......
......@@ -652,6 +652,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
pthread_mutex_unlock(&THR_LOCK_myisam);
bzero(info.buff, share->base.max_key_block_length * 2);
if (myisam_log_file >= 0)
{
intern_filename(name_buff,share->index_file_name);
......
......@@ -86,13 +86,6 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if ((length=keyinfo->block_length) > IO_SIZE*2 &&
info->state->key_file_length != page+length)
length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
#ifdef HAVE_purify
{
length=mi_getint(buff);
bzero((uchar*) buff+length,keyinfo->block_length-length);
length=keyinfo->block_length;
}
#endif
DBUG_RETURN((key_cache_write(info->s->key_cache,
info->s->kfile,page, level, (uchar*) buff,length,
(uint) keyinfo->block_length,
......
......@@ -28,6 +28,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
{
int error,changed;
uint flag;
uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("mi_rnext");
if ((inx = _mi_check_index(info,inx)) < 0)
......@@ -55,6 +56,20 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
info->s->state.key_root[inx]);
break;
}
/*
"search first" failed. This means we have no pivot for
"search next", or in other words MI_INFO::lastkey is
likely uninitialized.
Normally SQL layer would never request "search next" if
"search first" failed. But HANDLER may do anything.
As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
equals to mi_rfirst(), we must restore original state
as if failing mi_rfirst() was not called.
*/
if (error)
update_mask|= HA_STATE_PREV_FOUND;
}
else
{
......@@ -100,7 +115,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
}
/* Don't clear if database-changed */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= HA_STATE_NEXT_FOUND;
info->update|= update_mask;
if (error)
{
......
......@@ -825,7 +825,7 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
(size_t) (length=new_left_length - left_length - k_length));
pos=buff+2+length;
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
bmove((uchar*) buff + 2, (uchar*) pos + k_length, new_right_length - 2);
}
else
{ /* Move keys -> buff */
......
......@@ -641,18 +641,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
}
case 1: /* root was split, grow a new root */
{
uchar *new_root_buf;
uchar *new_root_buf= info->buff + info->s->base.max_key_block_length;
my_off_t new_root;
uchar *new_key;
uint nod_flag = info->s->base.key_reflength;
DBUG_PRINT("rtree", ("root was split, grow a new root"));
if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length +
MI_MAX_KEY_BUFF)))
{
my_errno = HA_ERR_OUT_OF_MEM;
DBUG_RETURN(-1); /* purecov: inspected */
}
mi_putint(new_root_buf, 2, nod_flag);
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
......@@ -680,10 +674,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
(ulong) new_root, 0, mi_test_if_nod(new_root_buf)));
my_afree((uchar*)new_root_buf);
break;
err1:
my_afree((uchar*)new_root_buf);
DBUG_RETURN(-1); /* purecov: inspected */
}
default:
......
......@@ -258,7 +258,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
double *old_coord;
int n_dim;
uchar *source_cur, *cur1, *cur2;
uchar *new_page;
uchar *new_page= info->buff;
int err_code= 0;
uint nod_flag= mi_test_if_nod(page);
uint full_length= key_length + (nod_flag ? nod_flag :
......@@ -304,12 +304,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
goto split_err;
}
if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length)))
{
err_code= -1;
goto split_err;
}
info->buff_used= 1;
stop = task + (max_keys + 1);
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
......@@ -345,8 +340,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
DFLT_INIT_HITS, new_page);
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
my_afree((uchar*)new_page);
split_err:
my_afree((uchar*) coord_buf);
DBUG_RETURN(err_code);
......
......@@ -28,13 +28,11 @@
/* static variables */
#undef MIN_SORT_MEMORY
#undef MYF_RW
#undef DISK_BUFFER_SIZE
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
#define DISK_BUFFER_SIZE (IO_SIZE*16)
......@@ -131,12 +129,12 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
memavl=max(sortbuff_size,MIN_SORT_MEMORY);
memavl= max(sortbuff_size, MIN_SORT_BUFFER);
records= info->sort_info->max_records;
sort_length= info->key_length;
LINT_INIT(keys);
while (memavl >= MIN_SORT_MEMORY)
while (memavl >= MIN_SORT_BUFFER)
{
if ((records < UINT_MAX32) &&
((my_off_t) (records + 1) *
......@@ -171,10 +169,10 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
break;
}
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
memavl=MIN_SORT_MEMORY;
if ((memavl= memavl/4*3) < MIN_SORT_BUFFER && old_memavl > MIN_SORT_BUFFER)
memavl= MIN_SORT_BUFFER;
}
if (memavl < MIN_SORT_MEMORY)
if (memavl < MIN_SORT_BUFFER)
{
mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
goto err; /* purecov: tested */
......@@ -348,12 +346,12 @@ pthread_handler_t thr_find_all_keys(void *arg)
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sort_keys= (uchar **) NULL;
memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
idx= (uint)sort_param->sort_info->max_records;
sort_length= sort_param->key_length;
maxbuffer= 1;
while (memavl >= MIN_SORT_MEMORY)
while (memavl >= MIN_SORT_BUFFER)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
(my_off_t) memavl)
......@@ -391,11 +389,11 @@ pthread_handler_t thr_find_all_keys(void *arg)
break;
}
old_memavl= memavl;
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
old_memavl > MIN_SORT_MEMORY)
memavl= MIN_SORT_MEMORY;
if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
old_memavl > MIN_SORT_BUFFER)
memavl= MIN_SORT_BUFFER;
}
if (memavl < MIN_SORT_MEMORY)
if (memavl < MIN_SORT_BUFFER)
{
mi_check_print_error(sort_param->sort_info->param,
"MyISAM sort buffer too small");
......@@ -564,7 +562,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (!mergebuf)
{
length=param->sort_buffer_length;
while (length >= MIN_SORT_MEMORY)
while (length >= MIN_SORT_BUFFER)
{
if ((mergebuf= my_malloc(length, MYF(0))))
break;
......
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