Merge lp:~akopytov/percona-server/bug878404-5.5 into lp:percona-server/5.5

Proposed by Alexey Kopytov
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 193
Proposed branch: lp:~akopytov/percona-server/bug878404-5.5
Merge into: lp:percona-server/5.5
Diff against target: 741 lines (+729/-0)
2 files modified
patches/bug45702.patch (+728/-0)
patches/series (+1/-0)
To merge this branch: bzr merge lp:~akopytov/percona-server/bug878404-5.5
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+80496@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

LGTM.

(This is a kind of bug that should not have happened in the first place, all those (uint) casts in the original code look just terrible.)

review: Approve
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

(Found this while reviewing 5.1)

What is the largest supported size of DYNAMIC_ARRAY? The elements and max_element fields are ulong instead of uint. But get_index_dynamic returns signed int (now long), so if size_of_element == 1, get_index_dynamic will not work correctly for element indexes > LONG_MAX. size_t is able to hold the value of ret, but int/long not necessarily so.

review: Needs Information
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Yes, the return value of get_index_dynamic() must be signed because it returns -1 for a non-existing element. So the effective limit for dynamic array is LONG_MAX elements *if* get_index_dynamic() is used. I didn't want to change the interface to make the patch less intrusive. And it is enough for our purposes because:

- the value used to initialize it in sort.c is signed anyway
- get_index_dynamic() is not used in sort.c

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Setting to approved as the patch is identical to the already approved and merged 5.1 version: https://code.launchpad.net/~akopytov/percona-server/bug878404-5.1/+merge/80495

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'patches/bug45702.patch'
2--- patches/bug45702.patch 1970-01-01 00:00:00 +0000
3+++ patches/bug45702.patch 2011-10-27 07:36:24 +0000
4@@ -0,0 +1,728 @@
5+--- a/include/my_sys.h
6++++ b/include/my_sys.h
7+@@ -320,8 +320,8 @@
8+ typedef struct st_dynamic_array
9+ {
10+ uchar *buffer;
11+- uint elements,max_element;
12+- uint alloc_increment;
13++ ulong elements, max_element;
14++ ulong alloc_increment;
15+ uint size_of_element;
16+ } DYNAMIC_ARRAY;
17+
18+@@ -758,21 +758,21 @@
19+ #define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E)
20+ #define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E)
21+ extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
22+- void *init_buffer, uint init_alloc,
23+- uint alloc_increment);
24++ void *init_buffer, ulong init_alloc,
25++ ulong alloc_increment);
26+ /* init_dynamic_array() function is deprecated */
27+ extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
28+- uint init_alloc, uint alloc_increment);
29++ ulong init_alloc, ulong alloc_increment);
30+ extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,uchar * element);
31+ extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array);
32+ extern uchar *pop_dynamic(DYNAMIC_ARRAY*);
33+-extern my_bool set_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index);
34+-extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements);
35+-extern void get_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index);
36++extern my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index);
37++extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements);
38++extern void get_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index);
39+ extern void delete_dynamic(DYNAMIC_ARRAY *array);
40+-extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
41++extern void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong array_index);
42+ extern void freeze_size(DYNAMIC_ARRAY *array);
43+-extern int get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element);
44++extern long get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element);
45+ #define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element)
46+ #define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
47+ #define push_dynamic(A,B) insert_dynamic((A),(B))
48+--- a/mysys/array.c
49++++ b/mysys/array.c
50+@@ -41,8 +41,8 @@
51+ */
52+
53+ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
54+- void *init_buffer, uint init_alloc,
55+- uint alloc_increment)
56++ void *init_buffer, ulong init_alloc,
57++ ulong alloc_increment)
58+ {
59+ DBUG_ENTER("init_dynamic_array");
60+ if (!alloc_increment)
61+@@ -73,7 +73,7 @@
62+ }
63+
64+ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
65+- uint init_alloc, uint alloc_increment)
66++ ulong init_alloc, ulong alloc_increment)
67+ {
68+ /* placeholder to preserve ABI */
69+ return my_init_dynamic_array_ci(array, element_size, init_alloc,
70+@@ -196,7 +196,7 @@
71+ FALSE Ok
72+ */
73+
74+-my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
75++my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx)
76+ {
77+ if (idx >= array->elements)
78+ {
79+@@ -228,11 +228,11 @@
80+ TRUE Allocation of new memory failed
81+ */
82+
83+-my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
84++my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements)
85+ {
86+ if (max_elements >= array->max_element)
87+ {
88+- uint size;
89++ ulong size;
90+ uchar *new_ptr;
91+ size= (max_elements + array->alloc_increment)/array->alloc_increment;
92+ size*= array->alloc_increment;
93+@@ -273,11 +273,11 @@
94+ idx Index of element wanted.
95+ */
96+
97+-void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
98++void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx)
99+ {
100+ if (idx >= array->elements)
101+ {
102+- DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
103++ DBUG_PRINT("warning",("To big array idx: %lu, array size is %lu",
104+ idx,array->elements));
105+ bzero(element,array->size_of_element);
106+ return;
107+@@ -320,7 +320,7 @@
108+ idx Index of element to be deleted
109+ */
110+
111+-void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
112++void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong idx)
113+ {
114+ char *ptr= (char*) array->buffer+array->size_of_element*idx;
115+ array->elements--;
116+@@ -340,7 +340,7 @@
117+
118+ void freeze_size(DYNAMIC_ARRAY *array)
119+ {
120+- uint elements=max(array->elements,1);
121++ ulong elements= max(array->elements, 1);
122+
123+ /*
124+ Do nothing if we are using a static buffer
125+@@ -368,7 +368,7 @@
126+
127+ */
128+
129+-int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element)
130++long get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element)
131+ {
132+ size_t ret;
133+ if (array->buffer > element)
134+--- a/storage/myisam/mi_check.c
135++++ b/storage/myisam/mi_check.c
136+@@ -2429,7 +2429,7 @@
137+
138+ if (_create_index_by_sort(&sort_param,
139+ (my_bool) (!(param->testflag & T_VERBOSE)),
140+- (uint) param->sort_buffer_length))
141++ param->sort_buffer_length))
142+ {
143+ param->retry_repair=1;
144+ goto err;
145+--- a/storage/myisam/sort.c
146++++ b/storage/myisam/sort.c
147+@@ -45,42 +45,42 @@
148+
149+ /* Functions defined in this file */
150+
151+-static ha_rows find_all_keys(MI_SORT_PARAM *info,uint keys,
152++static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys,
153+ uchar **sort_keys,
154+- DYNAMIC_ARRAY *buffpek,int *maxbuffer,
155++ DYNAMIC_ARRAY *buffpek, long *maxbuffer,
156+ IO_CACHE *tempfile,
157+ IO_CACHE *tempfile_for_exceptions);
158+ static int write_keys(MI_SORT_PARAM *info,uchar **sort_keys,
159+- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
160++ ulong count, BUFFPEK *buffpek,IO_CACHE *tempfile);
161+ static int write_key(MI_SORT_PARAM *info, uchar *key,
162+ IO_CACHE *tempfile);
163+ static int write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
164+- uint count);
165+-static int merge_many_buff(MI_SORT_PARAM *info,uint keys,
166++ ulong count);
167++static int merge_many_buff(MI_SORT_PARAM *info, ulong keys,
168+ uchar * *sort_keys,
169+- BUFFPEK *buffpek,int *maxbuffer,
170++ BUFFPEK *buffpek, long *maxbuffer,
171+ IO_CACHE *t_file);
172+-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
173++static ulong read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
174+ uint sort_length);
175+-static int merge_buffers(MI_SORT_PARAM *info,uint keys,
176++static int merge_buffers(MI_SORT_PARAM *info, ulong keys,
177+ IO_CACHE *from_file, IO_CACHE *to_file,
178+ uchar * *sort_keys, BUFFPEK *lastbuff,
179+ BUFFPEK *Fb, BUFFPEK *Tb);
180+-static int merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
181++static int merge_index(MI_SORT_PARAM *, ulong, uchar **, BUFFPEK *, long,
182+ IO_CACHE *);
183+ static int flush_ft_buf(MI_SORT_PARAM *info);
184+
185+ static int write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys,
186+- uint count, BUFFPEK *buffpek,
187++ ulong count, BUFFPEK *buffpek,
188+ IO_CACHE *tempfile);
189+-static uint read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
190+- uint sort_length);
191++static ulong read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
192++ uint sort_length);
193+ static int write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file,
194+- uchar *key, uint sort_length, uint count);
195++ uchar *key, uint sort_length, ulong count);
196+ static int write_merge_key_varlen(MI_SORT_PARAM *info,
197+ IO_CACHE *to_file,
198+ uchar* key, uint sort_length,
199+- uint count);
200++ ulong count);
201+ static inline int
202+ my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
203+
204+@@ -101,8 +101,9 @@
205+ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
206+ ulong sortbuff_size)
207+ {
208+- int error,maxbuffer,skr;
209+- uint memavl,old_memavl,keys,sort_length;
210++ int error;
211++ long maxbuffer, skr;
212++ ulong memavl, old_memavl, keys, sort_length;
213+ DYNAMIC_ARRAY buffpek;
214+ ha_rows records;
215+ uchar **sort_keys;
216+@@ -136,25 +137,25 @@
217+
218+ while (memavl >= MIN_SORT_BUFFER)
219+ {
220+- if ((records < UINT_MAX32) &&
221++ if ((records < ULONG_MAX) &&
222+ ((my_off_t) (records + 1) *
223+ (sort_length + sizeof(char*)) <= (my_off_t) memavl))
224+- keys= (uint)records+1;
225++ keys= (ulong) records + 1;
226+ else
227+ do
228+ {
229+ skr=maxbuffer;
230+- if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer ||
231+- (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/
232++ if (memavl < sizeof(BUFFPEK) * (ulong) maxbuffer ||
233++ (keys = (memavl - sizeof(BUFFPEK) * (ulong) maxbuffer) /
234+ (sort_length+sizeof(char*))) <= 1 ||
235+- keys < (uint) maxbuffer)
236++ keys < (ulong) maxbuffer)
237+ {
238+ mi_check_print_error(info->sort_info->param,
239+ "myisam_sort_buffer_size is too small");
240+ goto err;
241+ }
242+ }
243+- while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
244++ while ((maxbuffer= (long) (records / (keys - 1) + 1)) != skr);
245+
246+ if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
247+ HA_FT_MAXBYTELEN, MYF(0))))
248+@@ -180,7 +181,7 @@
249+ (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
250+
251+ if (!no_messages)
252+- printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
253++ printf(" - Searching for keys, allocating buffer for %lu keys\n", keys);
254+
255+ if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
256+ &tempfile,&tempfile_for_exceptions))
257+@@ -190,7 +191,7 @@
258+ {
259+ if (!no_messages)
260+ printf(" - Dumping %lu keys\n", (ulong) records);
261+- if (write_index(info,sort_keys, (uint) records))
262++ if (write_index(info,sort_keys, (ulong) records))
263+ goto err; /* purecov: inspected */
264+ }
265+ else
266+@@ -253,13 +254,13 @@
267+
268+ /* Search after all keys and place them in a temp. file */
269+
270+-static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys,
271++static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys,
272+ uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
273+- int *maxbuffer, IO_CACHE *tempfile,
274++ long *maxbuffer, IO_CACHE *tempfile,
275+ IO_CACHE *tempfile_for_exceptions)
276+ {
277+ int error;
278+- uint idx;
279++ ulong idx;
280+ DBUG_ENTER("find_all_keys");
281+
282+ idx=error=0;
283+@@ -308,8 +309,8 @@
284+ {
285+ MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
286+ int error;
287+- uint memavl,old_memavl,keys,sort_length;
288+- uint idx, maxbuffer;
289++ ulong memavl,old_memavl,keys,sort_length;
290++ ulong idx, maxbuffer;
291+ uchar **sort_keys=0;
292+
293+ LINT_INIT(keys);
294+@@ -345,7 +346,7 @@
295+ sort_keys= (uchar **) NULL;
296+
297+ memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
298+- idx= (uint)sort_param->sort_info->max_records;
299++ idx= (ulong) sort_param->sort_info->max_records;
300+ sort_length= sort_param->key_length;
301+ maxbuffer= 1;
302+
303+@@ -356,21 +357,21 @@
304+ keys= idx+1;
305+ else
306+ {
307+- uint skr;
308++ ulong skr;
309+ do
310+ {
311+ skr= maxbuffer;
312+ if (memavl < sizeof(BUFFPEK)*maxbuffer ||
313+ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
314+ (sort_length+sizeof(char*))) <= 1 ||
315+- keys < (uint) maxbuffer)
316++ keys < maxbuffer)
317+ {
318+ mi_check_print_error(sort_param->sort_info->param,
319+ "myisam_sort_buffer_size is too small");
320+ goto err;
321+ }
322+ }
323+- while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
324++ while ((maxbuffer= (idx/(keys-1)+1)) != skr);
325+ }
326+ if ((sort_keys= (uchar**)
327+ my_malloc(keys*(sort_length+sizeof(char*))+
328+@@ -399,7 +400,7 @@
329+ }
330+
331+ if (sort_param->sort_info->param->testflag & T_VERBOSE)
332+- printf("Key %d - Allocating buffer for %d keys\n",
333++ printf("Key %d - Allocating buffer for %lu keys\n",
334+ sort_param->key + 1, keys);
335+ sort_param->sort_keys= sort_keys;
336+
337+@@ -553,7 +554,7 @@
338+ }
339+ if (sinfo->buffpek.elements)
340+ {
341+- uint maxbuffer=sinfo->buffpek.elements-1;
342++ ulong maxbuffer=sinfo->buffpek.elements-1;
343+ if (!mergebuf)
344+ {
345+ length=param->sort_buffer_length;
346+@@ -576,7 +577,7 @@
347+ printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
348+ if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
349+ dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
350+- (int*) &maxbuffer, &sinfo->tempfile))
351++ (long *) &maxbuffer, &sinfo->tempfile))
352+ {
353+ got_error=1;
354+ continue;
355+@@ -640,7 +641,7 @@
356+ /* Write all keys in memory to file for later merge */
357+
358+ static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
359+- uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
360++ ulong count, BUFFPEK *buffpek, IO_CACHE *tempfile)
361+ {
362+ uchar **end;
363+ uint sort_length=info->key_length;
364+@@ -682,7 +683,7 @@
365+
366+ static int write_keys_varlen(MI_SORT_PARAM *info,
367+ register uchar **sort_keys,
368+- uint count, BUFFPEK *buffpek,
369++ ulong count, BUFFPEK *buffpek,
370+ IO_CACHE *tempfile)
371+ {
372+ uchar **end;
373+@@ -727,7 +728,7 @@
374+ /* Write index */
375+
376+ static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
377+- register uint count)
378++ register ulong count)
379+ {
380+ DBUG_ENTER("write_index");
381+
382+@@ -744,11 +745,11 @@
383+
384+ /* Merge buffers to make < MERGEBUFF2 buffers */
385+
386+-static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
387++static int merge_many_buff(MI_SORT_PARAM *info, ulong keys,
388+ uchar **sort_keys, BUFFPEK *buffpek,
389+- int *maxbuffer, IO_CACHE *t_file)
390++ long *maxbuffer, IO_CACHE *t_file)
391+ {
392+- register int i;
393++ register long i;
394+ IO_CACHE t_file2, *from_file, *to_file, *temp;
395+ BUFFPEK *lastbuff;
396+ DBUG_ENTER("merge_many_buff");
397+@@ -778,7 +779,7 @@
398+ if (flush_io_cache(to_file))
399+ break; /* purecov: inspected */
400+ temp=from_file; from_file=to_file; to_file=temp;
401+- *maxbuffer= (int) (lastbuff-buffpek)-1;
402++ *maxbuffer= (long) (lastbuff-buffpek)-1;
403+ }
404+ cleanup:
405+ close_cached_file(to_file); /* This holds old result */
406+@@ -807,18 +808,18 @@
407+ -1 Error
408+ */
409+
410+-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
411+- uint sort_length)
412++static ulong read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
413++ uint sort_length)
414+ {
415+- register uint count;
416+- uint length;
417++ register ulong count;
418++ ulong length;
419+
420+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
421++ if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count)))
422+ {
423+ if (mysql_file_pread(fromfile->file, (uchar*) buffpek->base,
424+ (length= sort_length*count),
425+ buffpek->file_pos, MYF_RW))
426+- return((uint) -1); /* purecov: inspected */
427++ return((ulong) -1); /* purecov: inspected */
428+ buffpek->key=buffpek->base;
429+ buffpek->file_pos+= length; /* New filepos */
430+ buffpek->count-= count;
431+@@ -827,15 +828,15 @@
432+ return (count*sort_length);
433+ } /* read_to_buffer */
434+
435+-static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
436++static ulong read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
437+ uint sort_length)
438+ {
439+- register uint count;
440++ register ulong count;
441+ uint16 length_of_key = 0;
442+- uint idx;
443++ ulong idx;
444+ uchar *buffp;
445+
446+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
447++ if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count)))
448+ {
449+ buffp = buffpek->base;
450+
451+@@ -843,11 +844,11 @@
452+ {
453+ if (mysql_file_pread(fromfile->file, (uchar*)&length_of_key,
454+ sizeof(length_of_key), buffpek->file_pos, MYF_RW))
455+- return((uint) -1);
456++ return((ulong) -1);
457+ buffpek->file_pos+=sizeof(length_of_key);
458+ if (mysql_file_pread(fromfile->file, (uchar*) buffp,
459+ length_of_key, buffpek->file_pos, MYF_RW))
460+- return((uint) -1);
461++ return((ulong) -1);
462+ buffpek->file_pos+=length_of_key;
463+ buffp = buffp + sort_length;
464+ }
465+@@ -861,9 +862,9 @@
466+
467+ static int write_merge_key_varlen(MI_SORT_PARAM *info,
468+ IO_CACHE *to_file, uchar* key,
469+- uint sort_length, uint count)
470++ uint sort_length, ulong count)
471+ {
472+- uint idx;
473++ ulong idx;
474+ uchar *bufs = key;
475+
476+ for (idx=1;idx<=count;idx++)
477+@@ -879,7 +880,7 @@
478+
479+ static int write_merge_key(MI_SORT_PARAM *info __attribute__((unused)),
480+ IO_CACHE *to_file, uchar *key,
481+- uint sort_length, uint count)
482++ uint sort_length, ulong count)
483+ {
484+ return my_b_write(to_file, key, (size_t) sort_length*count);
485+ }
486+@@ -890,12 +891,13 @@
487+ */
488+
489+ static int
490+-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
491++merge_buffers(MI_SORT_PARAM *info, ulong keys, IO_CACHE *from_file,
492+ IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
493+ BUFFPEK *Fb, BUFFPEK *Tb)
494+ {
495+- int error;
496+- uint sort_length,maxcount;
497++ ulong error;
498++ uint sort_length;
499++ ulong maxcount;
500+ ha_rows count;
501+ my_off_t UNINIT_VAR(to_start_filepos);
502+ uchar *strpos;
503+@@ -905,7 +907,7 @@
504+ DBUG_ENTER("merge_buffers");
505+
506+ count=error=0;
507+- maxcount=keys/((uint) (Tb-Fb) +1);
508++ maxcount= keys / ((ulong) (Tb-Fb) + 1);
509+ DBUG_ASSERT(maxcount > 0);
510+ LINT_INIT(to_start_filepos);
511+ if (to_file)
512+@@ -913,7 +915,7 @@
513+ strpos=(uchar*) sort_keys;
514+ sort_length=info->key_length;
515+
516+- if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
517++ if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
518+ (int (*)(void*, uchar *,uchar*)) info->key_cmp,
519+ (void*) info))
520+ DBUG_RETURN(1); /* purecov: inspected */
521+@@ -923,9 +925,8 @@
522+ count+= buffpek->count;
523+ buffpek->base= strpos;
524+ buffpek->max_keys=maxcount;
525+- strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek,
526+- sort_length));
527+- if (error == -1)
528++ strpos+= (error= info->read_to_buffer(from_file,buffpek, sort_length));
529++ if (error == (ulong) -1)
530+ goto err; /* purecov: inspected */
531+ queue_insert(&queue,(uchar*) buffpek);
532+ }
533+@@ -957,10 +958,10 @@
534+ buffpek->key+=sort_length;
535+ if (! --buffpek->mem_count)
536+ {
537+- if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
538++ if (!(error= info->read_to_buffer(from_file,buffpek,sort_length)))
539+ {
540+ uchar *base=buffpek->base;
541+- uint max_keys=buffpek->max_keys;
542++ ulong max_keys=buffpek->max_keys;
543+
544+ (void) queue_remove(&queue,0);
545+
546+@@ -985,7 +986,7 @@
547+ break; /* One buffer have been removed */
548+ }
549+ }
550+- else if (error == -1)
551++ else if (error == (ulong) -1)
552+ goto err; /* purecov: inspected */
553+ queue_replaced(&queue); /* Top element has been replaced */
554+ }
555+@@ -1018,23 +1019,23 @@
556+ }
557+ }
558+ }
559+- while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
560+- error != 0);
561++ while ((error= info->read_to_buffer(from_file,buffpek,sort_length))
562++ != (ulong) -1 && error != 0);
563+
564+ lastbuff->count=count;
565+ if (to_file)
566+ lastbuff->file_pos=to_start_filepos;
567+ err:
568+ delete_queue(&queue);
569+- DBUG_RETURN(error);
570++ DBUG_RETURN(error != 0);
571+ } /* merge_buffers */
572+
573+
574+ /* Do a merge to output-file (save only positions) */
575+
576+ static int
577+-merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
578+- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
579++merge_index(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys,
580++ BUFFPEK *buffpek, long maxbuffer, IO_CACHE *tempfile)
581+ {
582+ DBUG_ENTER("merge_index");
583+ if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
584+--- /dev/null
585++++ b/mysql-test/r/percona_bug45702.result
586+@@ -0,0 +1,21 @@
587++CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;
588++INSERT INTO t1 VALUES (), (), (), (), (), (), (), ();
589++INSERT INTO t1 SELECT NULL FROM t1;
590++INSERT INTO t1 SELECT NULL FROM t1;
591++INSERT INTO t1 SELECT NULL FROM t1;
592++INSERT INTO t1 SELECT NULL FROM t1;
593++INSERT INTO t1 SELECT NULL FROM t1;
594++INSERT INTO t1 SELECT NULL FROM t1;
595++INSERT INTO t1 SELECT NULL FROM t1;
596++INSERT INTO t1 SELECT NULL FROM t1;
597++INSERT INTO t1 SELECT NULL FROM t1;
598++SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size;
599++SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024;
600++REPAIR TABLE t1;
601++Table Op Msg_type Msg_text
602++test.t1 repair status OK
603++- recovering (with sort) MyISAM-table 'MYSQLD_DATADIR/test/t1'
604++Data records: 4096
605++- Fixing index 1
606++SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size;
607++DROP TABLE t1;
608+--- /dev/null
609++++ b/mysql-test/t/percona_bug45702.test
610+@@ -0,0 +1,34 @@
611++###############################################################################
612++# Bug #45702: Impossible to specify myisam_sort_buffer > 4GB on 64 bit machines
613++###############################################################################
614++
615++--source include/have_64bit.inc
616++
617++# Check that having data larger than MIN_SORT_BUFFER bytes can be handled by
618++# _create_index_by_sort() with myisam_sort_buffer_size = 4 GB without errors.
619++# The full test with large data volumes can not be a part of the test suite.
620++
621++CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;
622++INSERT INTO t1 VALUES (), (), (), (), (), (), (), ();
623++INSERT INTO t1 SELECT NULL FROM t1;
624++INSERT INTO t1 SELECT NULL FROM t1;
625++INSERT INTO t1 SELECT NULL FROM t1;
626++INSERT INTO t1 SELECT NULL FROM t1;
627++INSERT INTO t1 SELECT NULL FROM t1;
628++INSERT INTO t1 SELECT NULL FROM t1;
629++INSERT INTO t1 SELECT NULL FROM t1;
630++INSERT INTO t1 SELECT NULL FROM t1;
631++INSERT INTO t1 SELECT NULL FROM t1;
632++
633++SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size;
634++SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024;
635++
636++REPAIR TABLE t1;
637++
638++--let $MYSQLD_DATADIR= `select @@datadir`
639++--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
640++--exec $MYISAMCHK -r --sort_buffer_size=4G $MYSQLD_DATADIR/test/t1
641++
642++SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size;
643++
644++DROP TABLE t1;
645+--- a/sql/opt_range.cc
646++++ b/sql/opt_range.cc
647+@@ -11716,7 +11716,7 @@
648+ }
649+ if (min_max_ranges.elements > 0)
650+ {
651+- fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
652++ fprintf(DBUG_FILE, "%*susing %lu quick_ranges for MIN/MAX:\n",
653+ indent, "", min_max_ranges.elements);
654+ }
655+ }
656+--- a/mysys/my_pread.c
657++++ b/mysys/my_pread.c
658+@@ -49,6 +49,7 @@
659+ myf MyFlags)
660+ {
661+ size_t readbytes;
662++ size_t total_readbytes= 0;
663+ int error= 0;
664+ #if !defined (HAVE_PREAD) && !defined (_WIN32)
665+ int save_errno;
666+@@ -76,8 +77,30 @@
667+ #endif
668+ error= (readbytes != Count);
669+ #endif
670++ if (readbytes > 0)
671++ total_readbytes+= readbytes;
672++
673+ if(error)
674+ {
675++ if (readbytes > 0 && readbytes < Count && errno == 0)
676++ {
677++ /*
678++ pread() may return less bytes than requested even if enough bytes are
679++ available according to the Linux man page.
680++ This makes determining the end-of-file condition a bit harder.
681++ We just do another pread() call to see if more bytes can be read,
682++ since all my_pread() users expect it to always return all available
683++ bytes. For end-of-file 0 bytes is returned. This can never be the case
684++ for a partial read, since according to the man page, -1 is returned
685++ with errno set to EINTR if no data has been read.
686++ */
687++ Buffer+= readbytes;
688++ offset+= readbytes;
689++ Count-= readbytes;
690++
691++ continue;
692++ }
693++
694+ my_errno= errno ? errno : -1;
695+ if (errno == 0 || (readbytes != (size_t) -1 &&
696+ (MyFlags & (MY_NABP | MY_FNABP))))
697+@@ -107,7 +130,7 @@
698+ }
699+ if (MyFlags & (MY_NABP | MY_FNABP))
700+ DBUG_RETURN(0); /* Read went ok; Return 0 */
701+- DBUG_RETURN(readbytes); /* purecov: inspected */
702++ DBUG_RETURN(total_readbytes); /* purecov: inspected */
703+ }
704+ } /* my_pread */
705+
706+--- a/storage/myisam/myisamdef.h
707++++ b/storage/myisam/myisamdef.h
708+@@ -340,10 +340,10 @@
709+ int (*key_write)(struct st_mi_sort_param *, const void *);
710+ void (*lock_in_memory)(MI_CHECK *);
711+ int (*write_keys)(struct st_mi_sort_param *, register uchar **,
712+- uint , struct st_buffpek *, IO_CACHE *);
713+- uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
714++ ulong , struct st_buffpek *, IO_CACHE *);
715++ ulong (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
716+ int (*write_key)(struct st_mi_sort_param *, IO_CACHE *,uchar *,
717+- uint, uint);
718++ uint, ulong);
719+ } MI_SORT_PARAM;
720+
721+ /* Some defines used by isam-funktions */
722+--- a/sql/rpl_mi.cc
723++++ b/sql/rpl_mi.cc
724+@@ -491,7 +491,7 @@
725+ (1 + mi->ignore_server_ids.elements), MYF(MY_WME));
726+ if (!ignore_server_ids_buf)
727+ DBUG_RETURN(1);
728+- ulong cur_len= sprintf(ignore_server_ids_buf, "%u",
729++ ulong cur_len= sprintf(ignore_server_ids_buf, "%lu",
730+ mi->ignore_server_ids.elements);
731+ for (ulong i= 0; i < mi->ignore_server_ids.elements; i++)
732+ {
733
734=== modified file 'patches/series'
735--- patches/series 2011-10-13 09:13:42 +0000
736+++ patches/series 2011-10-27 07:36:24 +0000
737@@ -59,3 +59,4 @@
738 xtradb_bug317074.patch
739 subunit.patch
740 bug860910.patch
741+bug45702.patch

Subscribers

People subscribed via source and target branches