24
#include <drizzled/server_includes.h>
24
#include "mysql_priv.h"
26
#include <stddef.h> /* for macro offsetof */
25
29
#include "sql_sort.h"
26
#include <drizzled/drizzled_error_messages.h>
31
/// How to write record_ref.
32
#define WRITE_REF(file,from) \
33
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
28
36
/* functions defined in this file */
30
static char **make_char_array(char **old_pos, register uint32_t fields,
31
uint32_t length, myf my_flag);
32
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
38
static char **make_char_array(char **old_pos, register uint fields,
39
uint length, myf my_flag);
40
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
34
42
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
35
unsigned char * *sort_keys, IO_CACHE *buffer_file,
43
uchar * *sort_keys, IO_CACHE *buffer_file,
36
44
IO_CACHE *tempfile,IO_CACHE *indexfile);
37
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
38
uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
39
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
45
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
46
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
47
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
40
48
static void register_used_fields(SORTPARAM *param);
41
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
49
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
43
uint32_t maxbuffer,IO_CACHE *tempfile,
51
uint maxbuffer,IO_CACHE *tempfile,
44
52
IO_CACHE *outfile);
45
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count,
46
filesort_info_st *table_sort);
47
static uint32_t suffix_length(uint32_t string_length);
48
static uint32_t sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
53
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count,
54
FILESORT_INFO *table_sort);
55
static uint suffix_length(ulong string_length);
56
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
49
57
bool *multi_byte_charset);
50
58
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
51
uint32_t sortlength, uint32_t *plength);
59
uint sortlength, uint *plength);
52
60
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
56
64
Creates a set of pointers that can be used to read the rows
87
95
examined_rows will be set to number of examined rows
90
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
98
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
91
99
SQL_SELECT *select, ha_rows max_rows,
92
100
bool sort_positions, ha_rows *examined_rows)
95
uint32_t memavl, min_sort_memory;
103
ulong memavl, min_sort_memory;
98
106
ha_rows records= HA_POS_ERROR;
99
unsigned char **sort_keys= 0;
107
uchar **sort_keys= 0;
100
108
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
102
110
bool multi_byte_charset;
104
filesort_info_st table_sort;
105
TableList *tab= table->pos_in_table_list;
111
DBUG_ENTER("filesort");
112
DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length););
113
#ifdef SKIP_DBUG_IN_FILESORT
114
DBUG_PUSH(""); /* No DBUG here */
116
FILESORT_INFO table_sort;
117
TABLE_LIST *tab= table->pos_in_table_list;
106
118
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
108
DRIZZLE_FILESORT_START();
120
MYSQL_FILESORT_START();
111
123
Release InnoDB's adaptive hash index latch (if holding) before
126
138
my_b_clear(&buffpek_pointers);
129
memset(¶m, 0, sizeof(param));
141
bzero((char*) ¶m,sizeof(param));
130
142
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
131
143
param.ref_length= table->file->ref_length;
132
144
param.addon_field= 0;
133
145
param.addon_length= 0;
134
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !sort_positions)
146
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
147
!table->fulltext_searched && !sort_positions)
137
150
Get the descriptors of all fields whose values are appended
200
213
memavl= thd->variables.sortbuff_size;
201
min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
214
min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
202
215
while (memavl >= min_sort_memory)
205
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
206
param.keys=(uint32_t) cmin(records+1, keys);
218
ulong keys= memavl/(param.rec_length+sizeof(char*));
219
param.keys=(uint) min(records+1, keys);
207
220
if ((table_sort.sort_keys=
208
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
221
(uchar **) make_char_array((char **) table_sort.sort_keys,
209
222
param.keys, param.rec_length, MYF(0))))
211
224
old_memavl=memavl;
229
242
&tempfile, selected_records_file)) ==
232
maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
245
maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
234
247
if (maxbuffer == 0) // The whole set is in memory
236
if (save_index(¶m,sort_keys,(uint32_t) records, &table_sort))
249
if (save_index(¶m,sort_keys,(uint) records, &table_sort))
241
254
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
243
if (table_sort.buffpek)
244
free(table_sort.buffpek);
256
x_free(table_sort.buffpek);
245
257
table_sort.buffpek= 0;
247
259
if (!(table_sort.buffpek=
248
(unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
260
(uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
249
261
table_sort.buffpek)))
251
263
buffpek= (BUFFPEK *) table_sort.buffpek;
266
278
param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
267
279
param.rec_length-1);
268
280
maxbuffer--; // Offset from 0
269
if (merge_many_buff(¶m,(unsigned char*) sort_keys,buffpek,&maxbuffer,
281
if (merge_many_buff(¶m,(uchar*) sort_keys,buffpek,&maxbuffer,
272
284
if (flush_io_cache(&tempfile) ||
273
285
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
275
if (merge_index(¶m,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
287
if (merge_index(¶m,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
313
322
MYF(ME_ERROR+ME_WAITTANG));
315
324
statistic_add(thd->status_var.filesort_rows,
316
(uint32_t) records, &LOCK_status);
325
(ulong) records, &LOCK_status);
317
326
*examined_rows= param.examined_rows;
318
memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
319
DRIZZLE_FILESORT_END();
320
return(error ? HA_POS_ERROR : records);
327
#ifdef SKIP_DBUG_IN_FILESORT
328
DBUG_POP(); /* Ok to DBUG */
330
memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
331
DBUG_PRINT("exit",("records: %ld", (long) records));
332
MYSQL_FILESORT_END();
333
DBUG_RETURN(error ? HA_POS_ERROR : records);
324
void filesort_free_buffers(Table *table, bool full)
337
void filesort_free_buffers(TABLE *table, bool full)
326
339
if (table->sort.record_pointers)
328
free((unsigned char*) table->sort.record_pointers);
341
my_free((uchar*) table->sort.record_pointers,MYF(0));
329
342
table->sort.record_pointers=0;
333
346
if (table->sort.sort_keys )
335
if ((unsigned char*) table->sort.sort_keys)
336
free((unsigned char*) table->sort.sort_keys);
348
x_free((uchar*) table->sort.sort_keys);
337
349
table->sort.sort_keys= 0;
339
351
if (table->sort.buffpek)
341
if ((unsigned char*) table->sort.buffpek)
342
free((unsigned char*) table->sort.buffpek);
353
x_free((uchar*) table->sort.buffpek);
343
354
table->sort.buffpek= 0;
344
355
table->sort.buffpek_len= 0;
347
358
if (table->sort.addon_buf)
349
free((char *) table->sort.addon_buf);
350
free((char *) table->sort.addon_field);
360
my_free((char *) table->sort.addon_buf, MYF(0));
361
my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
351
362
table->sort.addon_buf=0;
352
363
table->sort.addon_field=0;
356
367
/** Make a array of string pointers. */
358
static char **make_char_array(char **old_pos, register uint32_t fields,
359
uint32_t length, myf my_flag)
369
static char **make_char_array(char **old_pos, register uint fields,
370
uint length, myf my_flag)
361
372
register char **pos;
374
DBUG_ENTER("make_char_array");
365
(old_pos= (char**) my_malloc((uint32_t) fields*(length+sizeof(char*)),
377
(old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
368
380
pos=old_pos; char_pos=((char*) (pos+fields)) -length;
369
381
while (fields--) *(pos++) = (char_pos+= length);
384
DBUG_RETURN(old_pos);
373
385
} /* make_char_array */
376
388
/** Read 'count' number of buffer pointers into memory. */
378
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
390
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
381
uint32_t length= sizeof(BUFFPEK)*count;
382
unsigned char *tmp= buf;
393
ulong length= sizeof(BUFFPEK)*count;
395
DBUG_ENTER("read_buffpek_from_file");
383
396
if (count > UINT_MAX/sizeof(BUFFPEK))
384
397
return 0; /* sizeof(BUFFPEK)*count will overflow */
386
tmp= (unsigned char *)my_malloc(length, MYF(MY_WME));
399
tmp= (uchar *)my_malloc(length, MYF(MY_WME));
389
402
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
390
my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
403
my_b_read(buffpek_pointers, (uchar*) tmp, length))
405
my_free((char*) tmp, MYF(0));
437
450
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
438
unsigned char **sort_keys,
439
452
IO_CACHE *buffpek_pointers,
440
453
IO_CACHE *tempfile, IO_CACHE *indexfile)
442
455
int error,flag,quick_select;
443
uint32_t idx,indexpos,ref_length;
444
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
456
uint idx,indexpos,ref_length;
457
uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
447
460
THD *thd= current_thd;
448
461
volatile THD::killed_state *killed= &thd->killed;
450
463
MY_BITMAP *save_read_set, *save_write_set;
464
DBUG_ENTER("find_all_keys");
465
DBUG_PRINT("info",("using: %s",
466
(select ? select->quick ? "ranges" : "where":
453
470
error=quick_select=0;
578
593
if (thd->is_error())
579
return(HA_POS_ERROR);
594
DBUG_RETURN(HA_POS_ERROR);
581
596
/* Signal we should use orignal column read and write maps */
582
597
sort_form->column_bitmaps_set(save_read_set, save_write_set);
599
DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos));
584
600
if (error != HA_ERR_END_OF_FILE)
586
602
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
587
return(HA_POS_ERROR); /* purecov: inspected */
603
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
589
605
if (indexpos && idx &&
590
606
write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
591
return(HA_POS_ERROR); /* purecov: inspected */
592
return(my_b_inited(tempfile) ?
607
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
608
DBUG_RETURN(my_b_inited(tempfile) ?
593
609
(ha_rows) (my_b_tell(tempfile)/param->rec_length) :
595
611
} /* find_all_keys */
621
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
637
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
622
638
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
624
640
size_t sort_length, rec_length;
643
DBUG_ENTER("write_keys");
628
645
sort_length= param->sort_length;
629
646
rec_length= param->rec_length;
630
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
648
quicksort(sort_keys,count,sort_length);
650
my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
631
652
if (!my_b_inited(tempfile) &&
632
653
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
634
655
goto err; /* purecov: inspected */
635
656
/* check we won't have more buffpeks than we can possibly keep in memory */
636
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
657
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (ulonglong)UINT_MAX)
638
659
buffpek.file_pos= my_b_tell(tempfile);
639
660
if ((ha_rows) count > param->max_rows)
640
count=(uint32_t) param->max_rows; /* purecov: inspected */
661
count=(uint) param->max_rows; /* purecov: inspected */
641
662
buffpek.count=(ha_rows) count;
642
663
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
643
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
664
if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
645
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
666
if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
651
672
} /* write_keys */
758
781
if (sort_field->need_strxnfrm)
760
783
char *from=(char*) res->ptr();
762
if ((unsigned char*) from == to)
785
if ((uchar*) from == to)
764
787
set_if_smaller(length,sort_field->length);
765
788
memcpy(param->tmp_buffer,from,length);
766
789
from=param->tmp_buffer;
768
791
tmp_length= my_strnxfrm(cs,to,sort_field->length,
769
(unsigned char*) from, length);
770
assert(tmp_length == sort_field->length);
792
(uchar*) from, length);
793
DBUG_ASSERT(tmp_length == sort_field->length);
774
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
797
my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
775
798
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
781
int64_t value= item->val_int_result();
804
longlong value= item->val_int_result();
784
807
*to++=1; /* purecov: inspected */
785
808
if (item->null_value)
788
memset(to-1, 0, sort_field->length+1);
811
bzero((char*) to-1,sort_field->length+1);
791
memset(to, 0, sort_field->length);
814
DBUG_PRINT("warning",
815
("Got null on something that shouldn't be null"));
816
bzero((char*) to,sort_field->length);
796
to[7]= (unsigned char) value;
797
to[6]= (unsigned char) (value >> 8);
798
to[5]= (unsigned char) (value >> 16);
799
to[4]= (unsigned char) (value >> 24);
800
to[3]= (unsigned char) (value >> 32);
801
to[2]= (unsigned char) (value >> 40);
802
to[1]= (unsigned char) (value >> 48);
803
if (item->unsigned_flag) /* Fix sign */
804
to[0]= (unsigned char) (value >> 56);
806
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
821
#if SIZEOF_LONG_LONG > 4
822
to[7]= (uchar) value;
823
to[6]= (uchar) (value >> 8);
824
to[5]= (uchar) (value >> 16);
825
to[4]= (uchar) (value >> 24);
826
to[3]= (uchar) (value >> 32);
827
to[2]= (uchar) (value >> 40);
828
to[1]= (uchar) (value >> 48);
829
if (item->unsigned_flag) /* Fix sign */
830
to[0]= (uchar) (value >> 56);
832
to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
834
to[3]= (uchar) value;
835
to[2]= (uchar) (value >> 8);
836
to[1]= (uchar) (value >> 16);
837
if (item->unsigned_flag) /* Fix sign */
838
to[0]= (uchar) (value >> 24);
840
to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
809
844
case DECIMAL_RESULT:
882
917
nulls[addonf->null_offset]|= addonf->null_bit;
883
918
#ifdef HAVE_purify
884
memset(to, 0, addonf->length);
919
bzero(to, addonf->length);
889
924
#ifdef HAVE_purify
890
unsigned char *end= field->pack(to, field->ptr);
891
uint32_t length= (uint32_t) ((to + addonf->length) - end);
892
assert((int) length >= 0);
925
uchar *end= field->pack(to, field->ptr);
926
uint length= (uint) ((to + addonf->length) - end);
927
DBUG_ASSERT((int) length >= 0);
894
memset(end, 0, length);
896
931
(void) field->pack(to, field->ptr);
953
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
954
filesort_info_st *table_sort)
988
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
989
FILESORT_INFO *table_sort)
956
uint32_t offset,res_length;
991
uint offset,res_length;
993
DBUG_ENTER("save_index");
959
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
995
my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
960
996
res_length= param->res_length;
961
997
offset= param->rec_length-res_length;
962
998
if ((ha_rows) count > param->max_rows)
963
count=(uint32_t) param->max_rows;
999
count=(uint) param->max_rows;
964
1000
if (!(to= table_sort->record_pointers=
965
(unsigned char*) my_malloc(res_length*count, MYF(MY_WME))))
966
return(1); /* purecov: inspected */
967
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
1001
(uchar*) my_malloc(res_length*count, MYF(MY_WME))))
1002
DBUG_RETURN(1); /* purecov: inspected */
1003
for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
969
1005
memcpy(to, *sort_keys+offset, res_length);
970
1006
to+= res_length;
976
1012
/** Merge buffers to make < MERGEBUFF2 buffers. */
978
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
979
BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
1014
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
1015
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
982
1018
IO_CACHE t_file2,*from_file,*to_file,*temp;
983
1019
BUFFPEK *lastbuff;
1020
DBUG_ENTER("merge_many_buff");
985
1022
if (*maxbuffer < MERGEBUFF2)
986
return(0); /* purecov: inspected */
1023
DBUG_RETURN(0); /* purecov: inspected */
987
1024
if (flush_io_cache(t_file) ||
988
1025
open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
990
return(1); /* purecov: inspected */
1027
DBUG_RETURN(1); /* purecov: inspected */
992
1029
from_file= t_file ; to_file= &t_file2;
993
1030
while (*maxbuffer >= MERGEBUFF2)
1029
1066
Read data to buffer.
1032
(uint32_t)-1 if something goes wrong
1069
(uint)-1 if something goes wrong
1035
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1036
uint32_t rec_length)
1072
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1038
register uint32_t count;
1075
register uint count;
1041
if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
1078
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1043
if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1044
return((uint32_t) -1); /* purecov: inspected */
1080
if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1081
return((uint) -1); /* purecov: inspected */
1045
1082
buffpek->key=buffpek->base;
1046
1083
buffpek->file_pos+= length; /* New filepos */
1047
1084
buffpek->count-= count;
1062
1099
@param[in] key_length key length
1065
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint32_t key_length)
1102
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1067
unsigned char *reuse_end= reuse->base + reuse->max_keys * key_length;
1068
for (uint32_t i= 0; i < queue->elements; ++i)
1104
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
1105
for (uint i= 0; i < queue->elements; ++i)
1070
1107
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1071
1108
if (bp->base + bp->max_keys * key_length == reuse->base)
1105
1142
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1106
IO_CACHE *to_file, unsigned char *sort_buffer,
1143
IO_CACHE *to_file, uchar *sort_buffer,
1107
1144
BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1111
uint32_t rec_length,res_length,offset;
1148
uint rec_length,res_length,offset;
1112
1149
size_t sort_length;
1114
1151
ha_rows max_rows,org_max_rows;
1115
1152
my_off_t to_start_filepos;
1116
unsigned char *strpos;
1117
1154
BUFFPEK *buffpek;
1119
1156
qsort2_cmp cmp;
1120
1157
void *first_cmp_arg;
1121
1158
volatile THD::killed_state *killed= ¤t_thd->killed;
1122
1159
THD::killed_state not_killable;
1160
DBUG_ENTER("merge_buffers");
1124
1162
status_var_increment(current_thd->status_var.filesort_merge_passes);
1125
1163
if (param->not_killable)
1133
1171
res_length= param->res_length;
1134
1172
sort_length= param->sort_length;
1135
1173
offset= rec_length-res_length;
1136
maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
1174
maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
1137
1175
to_start_filepos= my_b_tell(to_file);
1138
strpos= (unsigned char*) sort_buffer;
1176
strpos= (uchar*) sort_buffer;
1139
1177
org_max_rows=max_rows= param->max_rows;
1141
1179
/* The following will fire if there is not enough space in sort_buffer */
1142
assert(maxcount!=0);
1180
DBUG_ASSERT(maxcount!=0);
1144
1182
if (param->unique_buff)
1151
1189
cmp= get_ptr_compare(sort_length);
1152
1190
first_cmp_arg= (void*) &sort_length;
1154
if (init_queue(&queue, (uint32_t) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1192
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1155
1193
(queue_compare) cmp, first_cmp_arg))
1156
return(1); /* purecov: inspected */
1194
DBUG_RETURN(1); /* purecov: inspected */
1157
1195
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1159
1197
buffpek->base= strpos;
1160
1198
buffpek->max_keys= maxcount;
1161
strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
1199
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1163
1201
if (error == -1)
1164
1202
goto err; /* purecov: inspected */
1165
1203
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
1166
queue_insert(&queue, (unsigned char*) buffpek);
1204
queue_insert(&queue, (uchar*) buffpek);
1169
1207
if (param->unique_buff)
1206
1244
if (cmp) // Remove duplicates
1208
1246
if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1209
(unsigned char**) &buffpek->key))
1247
(uchar**) &buffpek->key))
1210
1248
goto skip_duplicate;
1211
memcpy(param->unique_buff, buffpek->key, rec_length);
1249
memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
1215
if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
1253
if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1217
1255
error=1; goto err; /* purecov: inspected */
1222
if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
1260
if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1224
1262
error=1; goto err; /* purecov: inspected */
1269
1307
if ((ha_rows) buffpek->mem_count > max_rows)
1270
1308
{ /* Don't write too many records */
1271
buffpek->mem_count= (uint32_t) max_rows;
1309
buffpek->mem_count= (uint) max_rows;
1272
1310
buffpek->count= 0; /* Don't read more */
1274
1312
max_rows-= buffpek->mem_count;
1277
if (my_b_write(to_file,(unsigned char*) buffpek->key,
1315
if (my_b_write(to_file,(uchar*) buffpek->key,
1278
1316
(rec_length*buffpek->mem_count)))
1280
1318
error= 1; goto err; /* purecov: inspected */
1299
1337
!= -1 && error != 0);
1302
lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
1340
lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1303
1341
lastbuff->file_pos= to_start_filepos;
1305
1343
delete_queue(&queue);
1307
1345
} /* merge_buffers */
1310
1348
/* Do a merge to output-file (save only positions) */
1312
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1313
BUFFPEK *buffpek, uint32_t maxbuffer,
1350
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
1351
BUFFPEK *buffpek, uint maxbuffer,
1314
1352
IO_CACHE *tempfile, IO_CACHE *outfile)
1354
DBUG_ENTER("merge_index");
1316
1355
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1317
1356
buffpek+maxbuffer,1))
1318
return(1); /* purecov: inspected */
1357
DBUG_RETURN(1); /* purecov: inspected */
1320
1359
} /* merge_index */
1323
static uint32_t suffix_length(uint32_t string_length)
1362
static uint suffix_length(ulong string_length)
1325
1364
if (string_length < 256)
1569
1614
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1571
void change_double_for_sort(double nr,unsigned char *to)
1616
void change_double_for_sort(double nr,uchar *to)
1573
unsigned char *tmp=(unsigned char*) to;
1618
uchar *tmp=(uchar*) to;
1575
1620
{ /* Change to zero string */
1576
tmp[0]=(unsigned char) 128;
1577
memset(tmp+1, 0, sizeof(nr)-1);
1622
bzero((char*) tmp+1,sizeof(nr)-1);
1581
1626
#ifdef WORDS_BIGENDIAN
1582
memcpy(tmp,&nr,sizeof(nr));
1627
memcpy_fixed(tmp,&nr,sizeof(nr));
1585
unsigned char *ptr= (unsigned char*) &nr;
1630
uchar *ptr= (uchar*) &nr;
1586
1631
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1587
1632
tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1588
1633
tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1595
1640
if (tmp[0] & 128) /* Negative */
1596
1641
{ /* make complement */
1598
1643
for (i=0 ; i < sizeof(nr); i++)
1599
tmp[i]=tmp[i] ^ (unsigned char) 255;
1644
tmp[i]=tmp[i] ^ (uchar) 255;
1602
1647
{ /* Set high and move exponent one up */
1603
uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1605
exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1606
tmp[0]= (unsigned char) (exp_part >> 8);
1607
tmp[1]= (unsigned char) exp_part;
1648
ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
1650
exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
1651
tmp[0]= (uchar) (exp_part >> 8);
1652
tmp[1]= (uchar) exp_part;