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;
722
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
723
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;
727
671
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
728
672
if (!my_b_inited(tempfile) &&
729
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,
733
676
/* check we won't have more buffpeks than we can possibly keep in memory */
734
677
if (my_b_tell(buffpek_pointers) + sizeof(buffpek) > (uint64_t)UINT_MAX)
739
679
buffpek.file_pos= my_b_tell(tempfile);
740
if ((ha_rows) count > max_rows)
741
count=(uint32_t) max_rows;
680
if ((ha_rows) count > param->max_rows)
681
count=(uint32_t) param->max_rows;
743
682
buffpek.count=(ha_rows) count;
745
for (unsigned char **ptr= sort_keys + count ; sort_keys != ptr ; sort_keys++)
683
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
747
684
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
753
686
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
759
692
} /* write_keys */
818
752
Item *item=sort_field->item;
819
753
maybe_null= item->maybe_null;
821
754
switch (sort_field->result_type) {
822
755
case STRING_RESULT:
824
const CHARSET_INFO * const cs=item->collation.collation;
825
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
827
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);
831
/* All item->str() to use some extra byte for end null.. */
832
String tmp((char*) to,sort_field->length+4,cs);
833
String *res= item->str_result(&tmp);
837
memset(to-1, 0, sort_field->length+1);
841
This should only happen during extreme conditions if we run out
842
of memory or have an item marked not null when it can be null.
843
This code is here mainly to avoid a hard crash in this case.
846
memset(to, 0, sort_field->length); // Avoid crash
850
length= res->length();
851
sort_field_length= sort_field->length - sort_field->suffix_length;
852
diff=(int) (sort_field_length - length);
856
length= sort_field_length;
858
if (sort_field->suffix_length)
860
/* Store length last in result_string */
861
store_length(to + sort_field_length, length,
862
sort_field->suffix_length);
864
if (sort_field->need_strxnfrm)
866
char *from=(char*) res->ptr();
868
if ((unsigned char*) from == to)
870
set_if_smaller(length,sort_field->length);
871
memcpy(tmp_buffer,from,length);
874
tmp_length= my_strnxfrm(cs,to,sort_field->length,
875
(unsigned char*) from, length);
876
assert(tmp_length == sort_field->length);
770
memset(to-1, 0, sort_field->length+1);
880
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
881
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);
887
820
int64_t value= item->val_int_result();
891
824
if (item->null_value)
902
to[7]= (unsigned char) value;
903
to[6]= (unsigned char) (value >> 8);
904
to[5]= (unsigned char) (value >> 16);
905
to[4]= (unsigned char) (value >> 24);
906
to[3]= (unsigned char) (value >> 32);
907
to[2]= (unsigned char) (value >> 40);
908
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);
909
842
if (item->unsigned_flag) /* Fix sign */
910
843
to[0]= (unsigned char) (value >> 56);
912
845
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
915
848
case DECIMAL_RESULT:
917
850
my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
1060
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;
1063
995
unsigned char *to;
1065
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1066
offset= rec_length - res_length;
1068
if ((ha_rows) count > max_rows)
1069
count=(uint32_t) max_rows;
1071
if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1074
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++)
1076
1007
memcpy(to, *sort_keys+offset, res_length);
1077
1008
to+= res_length;
1084
1014
/** Merge buffers to make < MERGEBUFF2 buffers. */
1086
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1087
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;
1089
1020
internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
1090
1021
buffpek *lastbuff;
1092
1023
if (*maxbuffer < MERGEBUFF2)
1094
1025
if (flush_io_cache(t_file) ||
1095
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,
1100
1030
from_file= t_file ; to_file= &t_file2;
1101
1031
while (*maxbuffer >= MERGEBUFF2)
1103
register uint32_t i;
1105
if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1110
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))
1115
1037
lastbuff=buffpek_inst;
1116
1038
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
1118
1040
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
1119
1041
buffpek_inst+i,buffpek_inst+i+MERGEBUFF-1,0))
1125
1044
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
1126
1045
buffpek_inst+i,buffpek_inst+ *maxbuffer,0))
1131
1047
if (flush_io_cache(to_file))
1136
1049
temp=from_file; from_file=to_file; to_file=temp;
1137
from_file->setup_io_cache();
1138
to_file->setup_io_cache();
1050
setup_io_cache(from_file);
1051
setup_io_cache(to_file);
1139
1052
*maxbuffer= (uint32_t) (lastbuff-buffpek_inst)-1;
1143
to_file->close_cached_file(); // This holds old result
1055
close_cached_file(to_file); // This holds old result
1144
1056
if (to_file == t_file)
1146
1058
*t_file=t_file2; // Copy result file
1147
t_file->setup_io_cache();
1059
setup_io_cache(t_file);
1150
1062
return(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
1218
int FileSort::merge_buffers(SortParam *param, internal::IO_CACHE *from_file,
1219
internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1220
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,
1224
1133
uint32_t rec_length,res_length,offset;
1410
1314
if (my_b_write(to_file, (unsigned char *) strpos, res_length))
1418
1321
while ((error=(int) read_to_buffer(from_file,buffpek_inst, rec_length))
1419
1322
!= -1 && error != 0);
1422
1325
lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1423
1326
lastbuff->file_pos= to_start_filepos;
1426
1329
} /* merge_buffers */
1429
1332
/* Do a merge to output-file (save only positions) */
1431
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1432
buffpek *buffpek_inst, uint32_t maxbuffer,
1433
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)
1435
1338
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1436
1339
buffpek_inst+maxbuffer,1))
1440
1342
} /* merge_index */
1500
1405
sortorder->result_type= sortorder->item->result_type();
1501
1406
if (sortorder->item->result_as_int64_t())
1502
1407
sortorder->result_type= INT_RESULT;
1504
1408
switch (sortorder->result_type) {
1505
1409
case STRING_RESULT:
1506
sortorder->length=sortorder->item->max_length;
1410
sortorder->length=sortorder->item->max_length;
1507
1411
set_if_smaller(sortorder->length,
1508
getSession().variables.max_sort_length);
1509
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1412
session->variables.max_sort_length);
1413
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1511
1415
sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1512
sortorder->need_strxnfrm= 1;
1513
*multi_byte_charset= 1;
1416
sortorder->need_strxnfrm= 1;
1417
*multi_byte_charset= 1;
1515
1419
else if (cs == &my_charset_bin)
1517
1421
/* Store length last to be able to sort blob/varbinary */
1518
1422
sortorder->suffix_length= suffix_length(sortorder->length);
1519
1423
sortorder->length+= sortorder->suffix_length;
1522
1426
case INT_RESULT:
1523
sortorder->length=8; // Size of intern int64_t
1427
sortorder->length=8; // Size of intern int64_t
1525
1429
case DECIMAL_RESULT:
1526
1430
sortorder->length=
1527
1431
my_decimal_get_binary_size(sortorder->item->max_length -
1529
1433
sortorder->item->decimals);
1531
1435
case REAL_RESULT:
1532
sortorder->length=sizeof(double);
1436
sortorder->length=sizeof(double);
1534
1438
case ROW_RESULT:
1535
// This case should never be choosen
1440
// This case should never be choosen
1539
1444
if (sortorder->item->maybe_null)
1540
length++; // Place for NULL marker
1445
length++; // Place for NULL marker
1542
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);
1543
1449
length+=sortorder->length;
1545
1451
sortorder->field= (Field*) 0; // end marker