--- a/include/my_sys.h +++ b/include/my_sys.h @@ -320,8 +320,8 @@ typedef struct st_dynamic_array { uchar *buffer; - uint elements,max_element; - uint alloc_increment; + ulong elements, max_element; + ulong alloc_increment; uint size_of_element; } DYNAMIC_ARRAY; @@ -758,21 +758,21 @@ #define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) #define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, - void *init_buffer, uint init_alloc, - uint alloc_increment); + void *init_buffer, ulong init_alloc, + ulong alloc_increment); /* init_dynamic_array() function is deprecated */ extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, uint alloc_increment); + ulong init_alloc, ulong alloc_increment); extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,uchar * element); extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array); extern uchar *pop_dynamic(DYNAMIC_ARRAY*); -extern my_bool set_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); -extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements); -extern void get_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); +extern my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index); +extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements); +extern void get_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index); extern void delete_dynamic(DYNAMIC_ARRAY *array); -extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); +extern void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong array_index); extern void freeze_size(DYNAMIC_ARRAY *array); -extern int get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element); +extern long get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element); #define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element) #define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index)) #define push_dynamic(A,B) insert_dynamic((A),(B)) --- a/mysys/array.c +++ b/mysys/array.c @@ -41,8 +41,8 @@ */ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, - void *init_buffer, uint init_alloc, - uint alloc_increment) + void *init_buffer, ulong init_alloc, + ulong alloc_increment) { DBUG_ENTER("init_dynamic_array"); if (!alloc_increment) @@ -73,7 +73,7 @@ } my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, uint alloc_increment) + ulong init_alloc, ulong alloc_increment) { /* placeholder to preserve ABI */ return my_init_dynamic_array_ci(array, element_size, init_alloc, @@ -196,7 +196,7 @@ FALSE Ok */ -my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) +my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx) { if (idx >= array->elements) { @@ -228,11 +228,11 @@ TRUE Allocation of new memory failed */ -my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) +my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements) { if (max_elements >= array->max_element) { - uint size; + ulong size; uchar *new_ptr; size= (max_elements + array->alloc_increment)/array->alloc_increment; size*= array->alloc_increment; @@ -273,11 +273,11 @@ idx Index of element wanted. */ -void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) +void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx) { if (idx >= array->elements) { - DBUG_PRINT("warning",("To big array idx: %d, array size is %d", + DBUG_PRINT("warning",("To big array idx: %lu, array size is %lu", idx,array->elements)); bzero(element,array->size_of_element); return; @@ -320,7 +320,7 @@ idx Index of element to be deleted */ -void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx) +void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong idx) { char *ptr= (char*) array->buffer+array->size_of_element*idx; array->elements--; @@ -340,7 +340,7 @@ void freeze_size(DYNAMIC_ARRAY *array) { - uint elements=max(array->elements,1); + ulong elements= max(array->elements, 1); /* Do nothing if we are using a static buffer @@ -368,7 +368,7 @@ */ -int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element) +long get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element) { size_t ret; if (array->buffer > element) --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2429,7 +2429,7 @@ if (_create_index_by_sort(&sort_param, (my_bool) (!(param->testflag & T_VERBOSE)), - (uint) param->sort_buffer_length)) + param->sort_buffer_length)) { param->retry_repair=1; goto err; --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -45,42 +45,42 @@ /* Functions defined in this file */ -static ha_rows find_all_keys(MI_SORT_PARAM *info,uint keys, +static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys, - DYNAMIC_ARRAY *buffpek,int *maxbuffer, + DYNAMIC_ARRAY *buffpek, long *maxbuffer, IO_CACHE *tempfile, IO_CACHE *tempfile_for_exceptions); static int write_keys(MI_SORT_PARAM *info,uchar **sort_keys, - uint count, BUFFPEK *buffpek,IO_CACHE *tempfile); + ulong count, BUFFPEK *buffpek,IO_CACHE *tempfile); static int write_key(MI_SORT_PARAM *info, uchar *key, IO_CACHE *tempfile); static int write_index(MI_SORT_PARAM *info,uchar * *sort_keys, - uint count); -static int merge_many_buff(MI_SORT_PARAM *info,uint keys, + ulong count); +static int merge_many_buff(MI_SORT_PARAM *info, ulong keys, uchar * *sort_keys, - BUFFPEK *buffpek,int *maxbuffer, + BUFFPEK *buffpek, long *maxbuffer, IO_CACHE *t_file); -static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, +static ulong read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, uint sort_length); -static int merge_buffers(MI_SORT_PARAM *info,uint keys, +static int merge_buffers(MI_SORT_PARAM *info, ulong keys, IO_CACHE *from_file, IO_CACHE *to_file, uchar * *sort_keys, BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb); -static int merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int, +static int merge_index(MI_SORT_PARAM *, ulong, uchar **, BUFFPEK *, long, IO_CACHE *); static int flush_ft_buf(MI_SORT_PARAM *info); static int write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys, - uint count, BUFFPEK *buffpek, + ulong count, BUFFPEK *buffpek, IO_CACHE *tempfile); -static uint read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek, - uint sort_length); +static ulong read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek, + uint sort_length); static int write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file, - uchar *key, uint sort_length, uint count); + uchar *key, uint sort_length, ulong count); static int write_merge_key_varlen(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar* key, uint sort_length, - uint count); + ulong count); static inline int my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs); @@ -101,8 +101,9 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong sortbuff_size) { - int error,maxbuffer,skr; - uint memavl,old_memavl,keys,sort_length; + int error; + long maxbuffer, skr; + ulong memavl, old_memavl, keys, sort_length; DYNAMIC_ARRAY buffpek; ha_rows records; uchar **sort_keys; @@ -136,25 +137,25 @@ while (memavl >= MIN_SORT_BUFFER) { - if ((records < UINT_MAX32) && + if ((records < ULONG_MAX) && ((my_off_t) (records + 1) * (sort_length + sizeof(char*)) <= (my_off_t) memavl)) - keys= (uint)records+1; + keys= (ulong) records + 1; else do { skr=maxbuffer; - if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/ + if (memavl < sizeof(BUFFPEK) * (ulong) maxbuffer || + (keys = (memavl - sizeof(BUFFPEK) * (ulong) maxbuffer) / (sort_length+sizeof(char*))) <= 1 || - keys < (uint) maxbuffer) + keys < (ulong) maxbuffer) { mi_check_print_error(info->sort_info->param, "myisam_sort_buffer_size is too small"); goto err; } } - while ((maxbuffer= (int) (records/(keys-1)+1)) != skr); + while ((maxbuffer= (long) (records / (keys - 1) + 1)) != skr); if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ HA_FT_MAXBYTELEN, MYF(0)))) @@ -180,7 +181,7 @@ (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */ if (!no_messages) - printf(" - Searching for keys, allocating buffer for %d keys\n",keys); + printf(" - Searching for keys, allocating buffer for %lu keys\n", keys); if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer, &tempfile,&tempfile_for_exceptions)) @@ -190,7 +191,7 @@ { if (!no_messages) printf(" - Dumping %lu keys\n", (ulong) records); - if (write_index(info,sort_keys, (uint) records)) + if (write_index(info,sort_keys, (ulong) records)) goto err; /* purecov: inspected */ } else @@ -253,13 +254,13 @@ /* Search after all keys and place them in a temp. file */ -static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, +static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys, DYNAMIC_ARRAY *buffpek, - int *maxbuffer, IO_CACHE *tempfile, + long *maxbuffer, IO_CACHE *tempfile, IO_CACHE *tempfile_for_exceptions) { int error; - uint idx; + ulong idx; DBUG_ENTER("find_all_keys"); idx=error=0; @@ -308,8 +309,8 @@ { MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; int error; - uint memavl,old_memavl,keys,sort_length; - uint idx, maxbuffer; + ulong memavl,old_memavl,keys,sort_length; + ulong idx, maxbuffer; uchar **sort_keys=0; LINT_INIT(keys); @@ -345,7 +346,7 @@ sort_keys= (uchar **) NULL; memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); - idx= (uint)sort_param->sort_info->max_records; + idx= (ulong) sort_param->sort_info->max_records; sort_length= sort_param->key_length; maxbuffer= 1; @@ -356,21 +357,21 @@ keys= idx+1; else { - uint skr; + ulong skr; do { skr= maxbuffer; if (memavl < sizeof(BUFFPEK)*maxbuffer || (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ (sort_length+sizeof(char*))) <= 1 || - keys < (uint) maxbuffer) + keys < maxbuffer) { mi_check_print_error(sort_param->sort_info->param, "myisam_sort_buffer_size is too small"); goto err; } } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); + while ((maxbuffer= (idx/(keys-1)+1)) != skr); } if ((sort_keys= (uchar**) my_malloc(keys*(sort_length+sizeof(char*))+ @@ -399,7 +400,7 @@ } if (sort_param->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %d keys\n", + printf("Key %d - Allocating buffer for %lu keys\n", sort_param->key + 1, keys); sort_param->sort_keys= sort_keys; @@ -553,7 +554,7 @@ } if (sinfo->buffpek.elements) { - uint maxbuffer=sinfo->buffpek.elements-1; + ulong maxbuffer=sinfo->buffpek.elements-1; if (!mergebuf) { length=param->sort_buffer_length; @@ -576,7 +577,7 @@ printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys); if (merge_many_buff(sinfo, keys, (uchar **)mergebuf, dynamic_element(&sinfo->buffpek, 0, BUFFPEK *), - (int*) &maxbuffer, &sinfo->tempfile)) + (long *) &maxbuffer, &sinfo->tempfile)) { got_error=1; continue; @@ -640,7 +641,7 @@ /* Write all keys in memory to file for later merge */ static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, - uint count, BUFFPEK *buffpek, IO_CACHE *tempfile) + ulong count, BUFFPEK *buffpek, IO_CACHE *tempfile) { uchar **end; uint sort_length=info->key_length; @@ -682,7 +683,7 @@ static int write_keys_varlen(MI_SORT_PARAM *info, register uchar **sort_keys, - uint count, BUFFPEK *buffpek, + ulong count, BUFFPEK *buffpek, IO_CACHE *tempfile) { uchar **end; @@ -727,7 +728,7 @@ /* Write index */ static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys, - register uint count) + register ulong count) { DBUG_ENTER("write_index"); @@ -744,11 +745,11 @@ /* Merge buffers to make < MERGEBUFF2 buffers */ -static int merge_many_buff(MI_SORT_PARAM *info, uint keys, +static int merge_many_buff(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys, BUFFPEK *buffpek, - int *maxbuffer, IO_CACHE *t_file) + long *maxbuffer, IO_CACHE *t_file) { - register int i; + register long i; IO_CACHE t_file2, *from_file, *to_file, *temp; BUFFPEK *lastbuff; DBUG_ENTER("merge_many_buff"); @@ -778,7 +779,7 @@ if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; - *maxbuffer= (int) (lastbuff-buffpek)-1; + *maxbuffer= (long) (lastbuff-buffpek)-1; } cleanup: close_cached_file(to_file); /* This holds old result */ @@ -807,18 +808,18 @@ -1 Error */ -static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, - uint sort_length) +static ulong read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, + uint sort_length) { - register uint count; - uint length; + register ulong count; + ulong length; - if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) + if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count))) { if (mysql_file_pread(fromfile->file, (uchar*) buffpek->base, (length= sort_length*count), buffpek->file_pos, MYF_RW)) - return((uint) -1); /* purecov: inspected */ + return((ulong) -1); /* purecov: inspected */ buffpek->key=buffpek->base; buffpek->file_pos+= length; /* New filepos */ buffpek->count-= count; @@ -827,15 +828,15 @@ return (count*sort_length); } /* read_to_buffer */ -static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek, +static ulong read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek, uint sort_length) { - register uint count; + register ulong count; uint16 length_of_key = 0; - uint idx; + ulong idx; uchar *buffp; - if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) + if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count))) { buffp = buffpek->base; @@ -843,11 +844,11 @@ { if (mysql_file_pread(fromfile->file, (uchar*)&length_of_key, sizeof(length_of_key), buffpek->file_pos, MYF_RW)) - return((uint) -1); + return((ulong) -1); buffpek->file_pos+=sizeof(length_of_key); if (mysql_file_pread(fromfile->file, (uchar*) buffp, length_of_key, buffpek->file_pos, MYF_RW)) - return((uint) -1); + return((ulong) -1); buffpek->file_pos+=length_of_key; buffp = buffp + sort_length; } @@ -861,9 +862,9 @@ static int write_merge_key_varlen(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar* key, - uint sort_length, uint count) + uint sort_length, ulong count) { - uint idx; + ulong idx; uchar *bufs = key; for (idx=1;idx<=count;idx++) @@ -879,7 +880,7 @@ static int write_merge_key(MI_SORT_PARAM *info __attribute__((unused)), IO_CACHE *to_file, uchar *key, - uint sort_length, uint count) + uint sort_length, ulong count) { return my_b_write(to_file, key, (size_t) sort_length*count); } @@ -890,12 +891,13 @@ */ static int -merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, +merge_buffers(MI_SORT_PARAM *info, ulong keys, IO_CACHE *from_file, IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb) { - int error; - uint sort_length,maxcount; + ulong error; + uint sort_length; + ulong maxcount; ha_rows count; my_off_t UNINIT_VAR(to_start_filepos); uchar *strpos; @@ -905,7 +907,7 @@ DBUG_ENTER("merge_buffers"); count=error=0; - maxcount=keys/((uint) (Tb-Fb) +1); + maxcount= keys / ((ulong) (Tb-Fb) + 1); DBUG_ASSERT(maxcount > 0); LINT_INIT(to_start_filepos); if (to_file) @@ -913,7 +915,7 @@ strpos=(uchar*) sort_keys; sort_length=info->key_length; - if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0, + if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0, (int (*)(void*, uchar *,uchar*)) info->key_cmp, (void*) info)) DBUG_RETURN(1); /* purecov: inspected */ @@ -923,9 +925,8 @@ count+= buffpek->count; buffpek->base= strpos; buffpek->max_keys=maxcount; - strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek, - sort_length)); - if (error == -1) + strpos+= (error= info->read_to_buffer(from_file,buffpek, sort_length)); + if (error == (ulong) -1) goto err; /* purecov: inspected */ queue_insert(&queue,(uchar*) buffpek); } @@ -957,10 +958,10 @@ buffpek->key+=sort_length; if (! --buffpek->mem_count) { - if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length))) + if (!(error= info->read_to_buffer(from_file,buffpek,sort_length))) { uchar *base=buffpek->base; - uint max_keys=buffpek->max_keys; + ulong max_keys=buffpek->max_keys; (void) queue_remove(&queue,0); @@ -985,7 +986,7 @@ break; /* One buffer have been removed */ } } - else if (error == -1) + else if (error == (ulong) -1) goto err; /* purecov: inspected */ queue_replaced(&queue); /* Top element has been replaced */ } @@ -1018,23 +1019,23 @@ } } } - while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 && - error != 0); + while ((error= info->read_to_buffer(from_file,buffpek,sort_length)) + != (ulong) -1 && error != 0); lastbuff->count=count; if (to_file) lastbuff->file_pos=to_start_filepos; err: delete_queue(&queue); - DBUG_RETURN(error); + DBUG_RETURN(error != 0); } /* merge_buffers */ /* Do a merge to output-file (save only positions) */ static int -merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, - BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile) +merge_index(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys, + BUFFPEK *buffpek, long maxbuffer, IO_CACHE *tempfile) { DBUG_ENTER("merge_index"); if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek, --- /dev/null +++ b/mysql-test/r/percona_bug45702.result @@ -0,0 +1,21 @@ +CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM; +INSERT INTO t1 VALUES (), (), (), (), (), (), (), (); +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size; +SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024; +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +- recovering (with sort) MyISAM-table 'MYSQLD_DATADIR/test/t1' +Data records: 4096 +- Fixing index 1 +SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size; +DROP TABLE t1; --- /dev/null +++ b/mysql-test/t/percona_bug45702.test @@ -0,0 +1,34 @@ +############################################################################### +# Bug #45702: Impossible to specify myisam_sort_buffer > 4GB on 64 bit machines +############################################################################### + +--source include/have_64bit.inc + +# Check that having data larger than MIN_SORT_BUFFER bytes can be handled by +# _create_index_by_sort() with myisam_sort_buffer_size = 4 GB without errors. +# The full test with large data volumes can not be a part of the test suite. + +CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM; +INSERT INTO t1 VALUES (), (), (), (), (), (), (), (); +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; +INSERT INTO t1 SELECT NULL FROM t1; + +SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size; +SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024; + +REPAIR TABLE t1; + +--let $MYSQLD_DATADIR= `select @@datadir` +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--exec $MYISAMCHK -r --sort_buffer_size=4G $MYSQLD_DATADIR/test/t1 + +SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size; + +DROP TABLE t1; --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11728,7 +11728,7 @@ } if (min_max_ranges.elements > 0) { - fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n", + fprintf(DBUG_FILE, "%*susing %lu quick_ranges for MIN/MAX:\n", indent, "", min_max_ranges.elements); } } --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -49,6 +49,7 @@ myf MyFlags) { size_t readbytes; + size_t total_readbytes= 0; int error= 0; #if !defined (HAVE_PREAD) && !defined (_WIN32) int save_errno; @@ -76,8 +77,30 @@ #endif error= (readbytes != Count); #endif + if (readbytes > 0) + total_readbytes+= readbytes; + if(error) { + if (readbytes > 0 && readbytes < Count && errno == 0) + { + /* + pread() may return less bytes than requested even if enough bytes are + available according to the Linux man page. + This makes determining the end-of-file condition a bit harder. + We just do another pread() call to see if more bytes can be read, + since all my_pread() users expect it to always return all available + bytes. For end-of-file 0 bytes is returned. This can never be the case + for a partial read, since according to the man page, -1 is returned + with errno set to EINTR if no data has been read. + */ + Buffer+= readbytes; + offset+= readbytes; + Count-= readbytes; + + continue; + } + my_errno= errno ? errno : -1; if (errno == 0 || (readbytes != (size_t) -1 && (MyFlags & (MY_NABP | MY_FNABP)))) @@ -107,7 +130,7 @@ } if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Read went ok; Return 0 */ - DBUG_RETURN(readbytes); /* purecov: inspected */ + DBUG_RETURN(total_readbytes); /* purecov: inspected */ } } /* my_pread */ --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -340,10 +340,10 @@ int (*key_write)(struct st_mi_sort_param *, const void *); void (*lock_in_memory)(MI_CHECK *); int (*write_keys)(struct st_mi_sort_param *, register uchar **, - uint , struct st_buffpek *, IO_CACHE *); - uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); + ulong , struct st_buffpek *, IO_CACHE *); + ulong (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); int (*write_key)(struct st_mi_sort_param *, IO_CACHE *,uchar *, - uint, uint); + uint, ulong); } MI_SORT_PARAM; /* Some defines used by isam-funktions */ --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -491,7 +491,7 @@ (1 + mi->ignore_server_ids.elements), MYF(MY_WME)); if (!ignore_server_ids_buf) DBUG_RETURN(1); - ulong cur_len= sprintf(ignore_server_ids_buf, "%u", + ulong cur_len= sprintf(ignore_server_ids_buf, "%lu", mi->ignore_server_ids.elements); for (ulong i= 0; i < mi->ignore_server_ids.elements; i++) {