44
41
#include "drizzled/internal/my_sys.h"
45
42
#include "plugin/myisam/myisam.h"
46
43
#include "drizzled/plugin/transactional_storage_engine.h"
47
#include "drizzled/atomics.h"
48
#include "drizzled/global_buffer.h"
51
45
using namespace std;
56
/* Defines used by filesort and uniques */
60
class BufferCompareContext
63
qsort_cmp2 key_compare;
64
void *key_compare_arg;
66
BufferCompareContext() :
75
uint32_t rec_length; /* Length of sorted records */
76
uint32_t sort_length; /* Length of sorted columns */
77
uint32_t ref_length; /* Length of record ref. */
78
uint32_t addon_length; /* Length of added packed fields */
79
uint32_t res_length; /* Length of records in final sorted file/buffer */
80
uint32_t keys; /* Max keys / buffer */
81
ha_rows max_rows,examined_rows;
82
Table *sort_form; /* For quicker make_sortkey */
83
SortField *local_sortorder;
85
sort_addon_field *addon_field; /* Descriptors for companion fields */
86
unsigned char *unique_buff;
89
/* The fields below are used only by Unique class */
91
BufferCompareContext cmp_context;
119
int write_keys(unsigned char * *sort_keys,
121
internal::IO_CACHE *buffer_file,
122
internal::IO_CACHE *tempfile);
124
void make_sortkey(unsigned char *to,
125
unsigned char *ref_pos);
126
void register_used_fields();
127
bool save_index(unsigned char **sort_keys,
129
filesort_info *table_sort);
133
50
/* functions defined in this file */
135
52
static char **make_char_array(char **old_pos, register uint32_t fields,
140
57
unsigned char *buf);
59
static ha_rows find_all_keys(Session *session,
61
optimizer::SqlSelect *select,
62
unsigned char * *sort_keys,
63
internal::IO_CACHE *buffer_file,
64
internal::IO_CACHE *tempfile,
65
internal::IO_CACHE *indexfile);
67
static int write_keys(SORTPARAM *param,
68
unsigned char * *sort_keys,
70
internal::IO_CACHE *buffer_file,
71
internal::IO_CACHE *tempfile);
73
static void make_sortkey(SORTPARAM *param,
75
unsigned char *ref_pos);
76
static void register_used_fields(SORTPARAM *param);
77
static int merge_index(SORTPARAM *param,
78
unsigned char *sort_buffer,
81
internal::IO_CACHE *tempfile,
82
internal::IO_CACHE *outfile);
83
static bool save_index(SORTPARAM *param,
84
unsigned char **sort_keys,
86
filesort_info *table_sort);
142
87
static uint32_t suffix_length(uint32_t string_length);
88
static uint32_t sortlength(Session *session,
91
bool *multi_byte_charset);
92
static sort_addon_field *get_addon_fields(Session *session,
143
96
static void unpack_addon_fields(sort_addon_field *addon_field,
144
97
unsigned char *buff);
146
FileSort::FileSort(Session &arg) :
153
100
Creates a set of pointers that can be used to read the rows
183
131
examined_rows will be set to number of examined rows
186
ha_rows FileSort::run(Table *table, SortField *sortorder, uint32_t s_length,
187
optimizer::SqlSelect *select, ha_rows max_rows,
188
bool sort_positions, ha_rows &examined_rows)
134
ha_rows filesort(Session *session, Table *table, SortField *sortorder, uint32_t s_length,
135
optimizer::SqlSelect *select, ha_rows max_rows,
136
bool sort_positions, ha_rows *examined_rows)
191
uint32_t memavl= 0, min_sort_memory;
139
uint32_t memavl, min_sort_memory;
192
140
uint32_t maxbuffer;
193
size_t allocated_sort_memory= 0;
194
buffpek *buffpek_inst= 0;
141
buffpek *buffpek_inst;
195
142
ha_rows records= HA_POS_ERROR;
196
143
unsigned char **sort_keys= 0;
197
internal::IO_CACHE tempfile;
198
internal::IO_CACHE buffpek_pointers;
199
internal::IO_CACHE *selected_records_file;
200
internal::IO_CACHE *outfile;
144
internal::IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
202
146
bool multi_byte_charset;
205
Don't use table->sort in filesort as it is also used by
206
QuickIndexMergeSelect. Work with a copy and put it back at the end
207
when index_merge select has finished with it.
209
filesort_info table_sort(table->sort);
210
table->sort.io_cache= NULL;
148
filesort_info table_sort;
212
149
TableList *tab= table->pos_in_table_list;
213
150
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
218
155
Release InnoDB's adaptive hash index latch (if holding) before
221
plugin::TransactionalStorageEngine::releaseTemporaryLatches(&getSession());
158
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
161
Don't use table->sort in filesort as it is also used by
162
QuickIndexMergeSelect. Work with a copy and put it back at the end
163
when index_merge select has finished with it.
165
memcpy(&table_sort, &table->sort, sizeof(filesort_info));
166
table->sort.io_cache= NULL;
224
168
outfile= table_sort.io_cache;
225
assert(tempfile.buffer == 0);
226
assert(buffpek_pointers.buffer == 0);
228
param.sort_length= sortlength(sortorder, s_length, &multi_byte_charset);
169
my_b_clear(&tempfile);
170
my_b_clear(&buffpek_pointers);
173
memset(¶m, 0, sizeof(param));
174
param.sort_length= sortlength(session, sortorder, s_length, &multi_byte_charset);
229
175
param.ref_length= table->cursor->ref_length;
176
param.addon_field= 0;
177
param.addon_length= 0;
231
178
if (!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) && !sort_positions)
234
181
Get the descriptors of all fields whose values are appended
235
182
to sorted fields and get its total length in param.spack_length.
237
param.addon_field= get_addon_fields(table->getFields(),
184
param.addon_field= get_addon_fields(session, table->getFields(),
238
185
param.sort_length,
239
186
¶m.addon_length);
291
236
selected_records_file= 0;
294
if (multi_byte_charset && !(param.tmp_buffer= (char*) malloc(param.sort_length)))
239
if (multi_byte_charset &&
240
!(param.tmp_buffer= (char*) malloc(param.sort_length)))
299
memavl= getSession().variables.sortbuff_size;
243
memavl= session->variables.sortbuff_size;
300
244
min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
301
245
while (memavl >= min_sort_memory)
303
247
uint32_t old_memavl;
304
248
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
305
249
param.keys= (uint32_t) min(records+1, (ha_rows)keys);
307
allocated_sort_memory= param.keys * param.rec_length;
308
if (not global_sort_buffer.add(allocated_sort_memory))
310
my_error(ER_OUT_OF_GLOBAL_SORTMEMORY, MYF(ME_ERROR+ME_WAITTANG));
314
250
if ((table_sort.sort_keys=
315
251
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
316
252
param.keys, param.rec_length)))
319
global_sort_buffer.sub(allocated_sort_memory);
320
254
old_memavl= memavl;
321
255
if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
322
256
memavl= min_sort_memory;
327
261
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
331
if (buffpek_pointers.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
264
if (open_cached_file(&buffpek_pointers,drizzle_tmpdir.c_str(),TEMP_PREFIX,
265
DISK_BUFFER_SIZE, MYF(MY_WME)))
336
268
param.keys--; /* TODO: check why we do this */
337
269
param.sort_form= table;
338
270
param.end=(param.local_sortorder=sortorder)+s_length;
339
if ((records= find_all_keys(¶m,select,sort_keys, &buffpek_pointers,
340
&tempfile, selected_records_file)) == HA_POS_ERROR)
271
if ((records=find_all_keys(session, ¶m,select,sort_keys, &buffpek_pointers,
272
&tempfile, selected_records_file)) ==
344
275
maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek_inst));
346
277
if (maxbuffer == 0) // The whole set is in memory
348
if (param.save_index(sort_keys,(uint32_t) records, &table_sort))
279
if (save_index(¶m,sort_keys,(uint32_t) records, &table_sort))
359
288
table_sort.buffpek = 0;
361
290
if (!(table_sort.buffpek=
362
(unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer, table_sort.buffpek)))
291
(unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
292
table_sort.buffpek)))
366
294
buffpek_inst= (buffpek *) table_sort.buffpek;
367
295
table_sort.buffpek_len= maxbuffer;
368
buffpek_pointers.close_cached_file();
296
close_cached_file(&buffpek_pointers);
369
297
/* Open cached file if it isn't open */
370
if (! my_b_inited(outfile) && outfile->open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,READ_RECORD_BUFFER, MYF(MY_WME)))
375
if (outfile->reinit_io_cache(internal::WRITE_CACHE,0L,0,0))
298
if (! my_b_inited(outfile) &&
299
open_cached_file(outfile,drizzle_tmpdir.c_str(),TEMP_PREFIX,READ_RECORD_BUFFER,
302
if (reinit_io_cache(outfile,internal::WRITE_CACHE,0L,0,0))
381
306
Use also the space previously used by string pointers in sort_buffer
382
307
for temporary key storage.
384
param.keys=((param.keys*(param.rec_length+sizeof(char*))) / param.rec_length-1);
309
param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
386
311
maxbuffer--; // Offset from 0
387
312
if (merge_many_buff(¶m,(unsigned char*) sort_keys,buffpek_inst,&maxbuffer, &tempfile))
392
if (flush_io_cache(&tempfile) || tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
314
if (flush_io_cache(&tempfile) ||
315
reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
397
317
if (merge_index(¶m,(unsigned char*) sort_keys,buffpek_inst,maxbuffer,&tempfile, outfile))
403
320
if (records > param.max_rows)
405
records= param.max_rows;
321
records=param.max_rows;
410
if (not subselect || not subselect->is_uncacheable())
325
if (param.tmp_buffer)
326
if (param.tmp_buffer)
327
free(param.tmp_buffer);
328
if (!subselect || !subselect->is_uncacheable())
413
331
table_sort.sort_keys= 0;
415
333
table_sort.buffpek= 0;
416
334
table_sort.buffpek_len= 0;
419
tempfile.close_cached_file();
420
buffpek_pointers.close_cached_file();
336
close_cached_file(&tempfile);
337
close_cached_file(&buffpek_pointers);
422
338
if (my_b_inited(outfile))
424
340
if (flush_io_cache(outfile))
429
internal::my_off_t save_pos= outfile->pos_in_file;
343
internal::my_off_t save_pos=outfile->pos_in_file;
430
344
/* For following reads */
431
if (outfile->reinit_io_cache(internal::READ_CACHE,0L,0,0))
345
if (reinit_io_cache(outfile,internal::READ_CACHE,0L,0,0))
435
347
outfile->end_of_file=save_pos;
441
352
my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
446
getSession().status_var.filesort_rows+= (uint32_t) records;
357
session->status_var.filesort_rows+= (uint32_t) records;
448
examined_rows= param.examined_rows;
449
global_sort_buffer.sub(allocated_sort_memory);
450
table->sort= table_sort;
359
*examined_rows= param.examined_rows;
360
memcpy(&table->sort, &table_sort, sizeof(filesort_info));
451
361
DRIZZLE_FILESORT_DONE(error, records);
452
362
return (error ? HA_POS_ERROR : records);
366
void Table::filesort_free_buffers(bool full)
368
if (sort.record_pointers)
370
free((unsigned char*) sort.record_pointers);
371
sort.record_pointers=0;
377
if ((unsigned char*) sort.sort_keys)
378
free((unsigned char*) sort.sort_keys);
383
if ((unsigned char*) sort.buffpek)
384
free((unsigned char*) sort.buffpek);
391
free((char *) sort.addon_buf);
392
free((char *) sort.addon_field);
455
398
/** Make a array of string pointers. */
457
400
static char **make_char_array(char **old_pos, register uint32_t fields,
532
475
HA_POS_ERROR on error.
535
ha_rows FileSort::find_all_keys(SortParam *param,
536
optimizer::SqlSelect *select,
537
unsigned char **sort_keys,
538
internal::IO_CACHE *buffpek_pointers,
539
internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
478
static ha_rows find_all_keys(Session *session,
480
optimizer::SqlSelect *select,
481
unsigned char **sort_keys,
482
internal::IO_CACHE *buffpek_pointers,
483
internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
541
485
int error,flag,quick_select;
542
486
uint32_t idx,indexpos,ref_length;
543
487
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
544
488
internal::my_off_t record;
545
489
Table *sort_form;
546
volatile Session::killed_state_t *killed= getSession().getKilledPtr();
490
volatile Session::killed_state *killed= &session->killed;
548
492
boost::dynamic_bitset<> *save_read_set= NULL;
549
493
boost::dynamic_bitset<> *save_write_set= NULL;
724
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
725
internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
662
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
663
internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
665
size_t sort_length, rec_length;
669
sort_length= param->sort_length;
670
rec_length= param->rec_length;
729
671
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
730
672
if (!my_b_inited(tempfile) &&
731
tempfile->open_cached_file(drizzle_tmpdir.c_str(), TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
673
open_cached_file(tempfile, drizzle_tmpdir.c_str(), TEMP_PREFIX, DISK_BUFFER_SIZE,
735
676
/* check we won't have more buffpeks than we can possibly keep in memory */
736
677
if (my_b_tell(buffpek_pointers) + sizeof(buffpek) > (uint64_t)UINT_MAX)
741
679
buffpek.file_pos= my_b_tell(tempfile);
742
if ((ha_rows) count > max_rows)
743
count=(uint32_t) max_rows;
680
if ((ha_rows) count > param->max_rows)
681
count=(uint32_t) param->max_rows;
745
682
buffpek.count=(ha_rows) count;
747
for (unsigned char **ptr= sort_keys + count ; sort_keys != ptr ; sort_keys++)
683
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
749
684
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
755
686
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
761
692
} /* write_keys */
820
752
Item *item=sort_field->item;
821
753
maybe_null= item->maybe_null;
823
754
switch (sort_field->result_type) {
824
755
case STRING_RESULT:
826
const CHARSET_INFO * const cs=item->collation.collation;
827
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
829
uint32_t sort_field_length;
757
const CHARSET_INFO * const cs=item->collation.collation;
758
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
760
uint32_t sort_field_length;
764
/* All item->str() to use some extra byte for end null.. */
765
String tmp((char*) to,sort_field->length+4,cs);
766
String *res= item->str_result(&tmp);
833
/* All item->str() to use some extra byte for end null.. */
834
String tmp((char*) to,sort_field->length+4,cs);
835
String *res= item->str_result(&tmp);
839
memset(to-1, 0, sort_field->length+1);
843
This should only happen during extreme conditions if we run out
844
of memory or have an item marked not null when it can be null.
845
This code is here mainly to avoid a hard crash in this case.
848
memset(to, 0, sort_field->length); // Avoid crash
852
length= res->length();
853
sort_field_length= sort_field->length - sort_field->suffix_length;
854
diff=(int) (sort_field_length - length);
858
length= sort_field_length;
860
if (sort_field->suffix_length)
862
/* Store length last in result_string */
863
store_length(to + sort_field_length, length,
864
sort_field->suffix_length);
866
if (sort_field->need_strxnfrm)
868
char *from=(char*) res->ptr();
870
if ((unsigned char*) from == to)
872
set_if_smaller(length,sort_field->length);
873
memcpy(tmp_buffer,from,length);
876
tmp_length= my_strnxfrm(cs,to,sort_field->length,
877
(unsigned char*) from, length);
878
assert(tmp_length == sort_field->length);
770
memset(to-1, 0, sort_field->length+1);
882
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
883
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
774
This should only happen during extreme conditions if we run out
775
of memory or have an item marked not null when it can be null.
776
This code is here mainly to avoid a hard crash in this case.
779
memset(to, 0, sort_field->length); // Avoid crash
783
length= res->length();
784
sort_field_length= sort_field->length - sort_field->suffix_length;
785
diff=(int) (sort_field_length - length);
789
length= sort_field_length;
791
if (sort_field->suffix_length)
793
/* Store length last in result_string */
794
store_length(to + sort_field_length, length,
795
sort_field->suffix_length);
797
if (sort_field->need_strxnfrm)
799
char *from=(char*) res->ptr();
801
if ((unsigned char*) from == to)
803
set_if_smaller(length,sort_field->length);
804
memcpy(param->tmp_buffer,from,length);
805
from=param->tmp_buffer;
807
tmp_length= my_strnxfrm(cs,to,sort_field->length,
808
(unsigned char*) from, length);
809
assert(tmp_length == sort_field->length);
813
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
814
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
889
820
int64_t value= item->val_int_result();
893
824
if (item->null_value)
904
to[7]= (unsigned char) value;
905
to[6]= (unsigned char) (value >> 8);
906
to[5]= (unsigned char) (value >> 16);
907
to[4]= (unsigned char) (value >> 24);
908
to[3]= (unsigned char) (value >> 32);
909
to[2]= (unsigned char) (value >> 40);
910
to[1]= (unsigned char) (value >> 48);
835
to[7]= (unsigned char) value;
836
to[6]= (unsigned char) (value >> 8);
837
to[5]= (unsigned char) (value >> 16);
838
to[4]= (unsigned char) (value >> 24);
839
to[3]= (unsigned char) (value >> 32);
840
to[2]= (unsigned char) (value >> 40);
841
to[1]= (unsigned char) (value >> 48);
911
842
if (item->unsigned_flag) /* Fix sign */
912
843
to[0]= (unsigned char) (value >> 56);
914
845
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
917
848
case DECIMAL_RESULT:
919
type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
850
my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
922
853
if (item->null_value)
991
919
if (addonf->null_bit && field->is_null())
993
921
nulls[addonf->null_offset]|= addonf->null_bit;
995
923
memset(to, 0, addonf->length);
1000
#ifdef HAVE_VALGRIND
1001
929
unsigned char *end= field->pack(to, field->ptr);
1002
uint32_t local_length= (uint32_t) ((to + addonf->length) - end);
1003
assert((int) local_length >= 0);
1005
memset(end, 0, local_length);
930
uint32_t length= (uint32_t) ((to + addonf->length) - end);
931
assert((int) length >= 0);
933
memset(end, 0, length);
1007
935
(void) field->pack(to, field->ptr);
1062
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
991
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
992
filesort_info *table_sort)
994
uint32_t offset,res_length;
1065
995
unsigned char *to;
1067
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1068
offset= rec_length - res_length;
1070
if ((ha_rows) count > max_rows)
1071
count=(uint32_t) max_rows;
1073
if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1076
for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
997
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
998
res_length= param->res_length;
999
offset= param->rec_length-res_length;
1000
if ((ha_rows) count > param->max_rows)
1001
count=(uint32_t) param->max_rows;
1002
if (!(to= table_sort->record_pointers=
1003
(unsigned char*) malloc(res_length*count)))
1005
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
1078
1007
memcpy(to, *sort_keys+offset, res_length);
1079
1008
to+= res_length;
1086
1014
/** Merge buffers to make < MERGEBUFF2 buffers. */
1088
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1089
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1016
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
1017
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1019
register uint32_t i;
1091
1020
internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
1092
1021
buffpek *lastbuff;
1094
1023
if (*maxbuffer < MERGEBUFF2)
1096
1025
if (flush_io_cache(t_file) ||
1097
t_file2.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,DISK_BUFFER_SIZE, MYF(MY_WME)))
1026
open_cached_file(&t_file2,drizzle_tmpdir.c_str(),TEMP_PREFIX,DISK_BUFFER_SIZE,
1102
1030
from_file= t_file ; to_file= &t_file2;
1103
1031
while (*maxbuffer >= MERGEBUFF2)
1105
register uint32_t i;
1107
if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1112
if (to_file->reinit_io_cache(internal::WRITE_CACHE,0L,0,0))
1033
if (reinit_io_cache(from_file,internal::READ_CACHE,0L,0,0))
1035
if (reinit_io_cache(to_file,internal::WRITE_CACHE,0L,0,0))
1117
1037
lastbuff=buffpek_inst;
1118
1038
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
1120
1040
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
1121
1041
buffpek_inst+i,buffpek_inst+i+MERGEBUFF-1,0))
1127
1044
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
1128
1045
buffpek_inst+i,buffpek_inst+ *maxbuffer,0))
1133
1047
if (flush_io_cache(to_file))
1138
1049
temp=from_file; from_file=to_file; to_file=temp;
1139
from_file->setup_io_cache();
1140
to_file->setup_io_cache();
1050
setup_io_cache(from_file);
1051
setup_io_cache(to_file);
1141
1052
*maxbuffer= (uint32_t) (lastbuff-buffpek_inst)-1;
1145
to_file->close_cached_file(); // This holds old result
1055
close_cached_file(to_file); // This holds old result
1146
1056
if (to_file == t_file)
1148
1058
*t_file=t_file2; // Copy result file
1149
t_file->setup_io_cache();
1059
setup_io_cache(t_file);
1152
1062
return(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
1220
int FileSort::merge_buffers(SortParam *param, internal::IO_CACHE *from_file,
1221
internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1222
buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1127
int merge_buffers(SORTPARAM *param, internal::IO_CACHE *from_file,
1128
internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1129
buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1226
1133
uint32_t rec_length,res_length,offset;
1412
1314
if (my_b_write(to_file, (unsigned char *) strpos, res_length))
1420
1321
while ((error=(int) read_to_buffer(from_file,buffpek_inst, rec_length))
1421
1322
!= -1 && error != 0);
1424
1325
lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1425
1326
lastbuff->file_pos= to_start_filepos;
1428
1329
} /* merge_buffers */
1431
1332
/* Do a merge to output-file (save only positions) */
1433
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1434
buffpek *buffpek_inst, uint32_t maxbuffer,
1435
internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1334
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1335
buffpek *buffpek_inst, uint32_t maxbuffer,
1336
internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1437
1338
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1438
1339
buffpek_inst+maxbuffer,1))
1442
1342
} /* merge_index */
1502
1405
sortorder->result_type= sortorder->item->result_type();
1503
1406
if (sortorder->item->result_as_int64_t())
1504
1407
sortorder->result_type= INT_RESULT;
1506
1408
switch (sortorder->result_type) {
1507
1409
case STRING_RESULT:
1508
sortorder->length=sortorder->item->max_length;
1410
sortorder->length=sortorder->item->max_length;
1509
1411
set_if_smaller(sortorder->length,
1510
getSession().variables.max_sort_length);
1511
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1412
session->variables.max_sort_length);
1413
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1513
1415
sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1514
sortorder->need_strxnfrm= 1;
1515
*multi_byte_charset= 1;
1416
sortorder->need_strxnfrm= 1;
1417
*multi_byte_charset= 1;
1517
1419
else if (cs == &my_charset_bin)
1519
1421
/* Store length last to be able to sort blob/varbinary */
1520
1422
sortorder->suffix_length= suffix_length(sortorder->length);
1521
1423
sortorder->length+= sortorder->suffix_length;
1524
1426
case INT_RESULT:
1525
sortorder->length=8; // Size of intern int64_t
1427
sortorder->length=8; // Size of intern int64_t
1527
1429
case DECIMAL_RESULT:
1528
1430
sortorder->length=
1529
class_decimal_get_binary_size(sortorder->item->max_length -
1431
my_decimal_get_binary_size(sortorder->item->max_length -
1530
1432
(sortorder->item->decimals ? 1 : 0),
1531
1433
sortorder->item->decimals);
1533
1435
case REAL_RESULT:
1534
sortorder->length=sizeof(double);
1436
sortorder->length=sizeof(double);
1536
1438
case ROW_RESULT:
1537
// This case should never be choosen
1440
// This case should never be choosen
1541
1444
if (sortorder->item->maybe_null)
1542
length++; // Place for NULL marker
1445
length++; // Place for NULL marker
1544
set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1447
set_if_smaller(sortorder->length,
1448
(size_t)session->variables.max_sort_length);
1545
1449
length+=sortorder->length;
1547
1451
sortorder->field= (Field*) 0; // end marker