27
27
#include <limits.h>
30
30
#include <algorithm>
33
#include <drizzled/drizzled.h>
34
#include <drizzled/sql_sort.h>
35
#include <drizzled/filesort.h>
36
#include <drizzled/error.h>
37
#include <drizzled/probes.h>
38
#include <drizzled/session.h>
39
#include <drizzled/table.h>
40
#include <drizzled/table_list.h>
41
#include <drizzled/optimizer/range.h>
42
#include <drizzled/records.h>
43
#include <drizzled/internal/iocache.h>
44
#include <drizzled/internal/my_sys.h>
45
#include <plugin/myisam/myisam.h>
46
#include <drizzled/plugin/transactional_storage_engine.h>
47
#include <drizzled/atomics.h>
48
#include <drizzled/global_buffer.h>
50
#include <drizzled/sort_field.h>
32
#include "drizzled/sql_sort.h"
33
#include "drizzled/error.h"
34
#include "drizzled/probes.h"
35
#include "drizzled/session.h"
36
#include "drizzled/table.h"
37
#include "drizzled/table_list.h"
38
#include "drizzled/optimizer/range.h"
39
#include "drizzled/records.h"
40
#include "drizzled/internal/iocache.h"
41
#include "drizzled/internal/my_sys.h"
42
#include "plugin/myisam/myisam.h"
43
#include "drizzled/plugin/transactional_storage_engine.h"
53
45
using namespace std;
58
/* Defines used by filesort and uniques */
62
class BufferCompareContext
65
qsort_cmp2 key_compare;
66
void *key_compare_arg;
68
BufferCompareContext() :
77
uint32_t rec_length; /* Length of sorted records */
78
uint32_t sort_length; /* Length of sorted columns */
79
uint32_t ref_length; /* Length of record ref. */
80
uint32_t addon_length; /* Length of added packed fields */
81
uint32_t res_length; /* Length of records in final sorted file/buffer */
82
uint32_t keys; /* Max keys / buffer */
83
ha_rows max_rows,examined_rows;
84
Table *sort_form; /* For quicker make_sortkey */
85
SortField *local_sortorder;
87
sort_addon_field *addon_field; /* Descriptors for companion fields */
88
unsigned char *unique_buff;
91
/* The fields below are used only by Unique class */
93
BufferCompareContext cmp_context;
121
int write_keys(unsigned char * *sort_keys,
123
internal::IO_CACHE *buffer_file,
124
internal::IO_CACHE *tempfile);
126
void make_sortkey(unsigned char *to,
127
unsigned char *ref_pos);
128
void register_used_fields();
129
bool save_index(unsigned char **sort_keys,
131
filesort_info *table_sort);
135
50
/* functions defined in this file */
137
static char **make_char_array(char **old_pos, uint32_t fields,
52
static char **make_char_array(char **old_pos, register uint32_t fields,
140
55
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
142
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);
144
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,
145
96
static void unpack_addon_fields(sort_addon_field *addon_field,
146
97
unsigned char *buff);
148
FileSort::FileSort(Session &arg) :
155
100
Creates a set of pointers that can be used to read the rows
185
131
examined_rows will be set to number of examined rows
188
ha_rows FileSort::run(Table *table, SortField *sortorder, uint32_t s_length,
189
optimizer::SqlSelect *select, ha_rows max_rows,
190
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)
193
uint32_t memavl= 0, min_sort_memory;
139
uint32_t memavl, min_sort_memory;
194
140
uint32_t maxbuffer;
195
size_t allocated_sort_memory= 0;
196
buffpek *buffpek_inst= 0;
141
buffpek *buffpek_inst;
197
142
ha_rows records= HA_POS_ERROR;
198
143
unsigned char **sort_keys= 0;
199
internal::IO_CACHE tempfile;
200
internal::IO_CACHE buffpek_pointers;
201
internal::IO_CACHE *selected_records_file;
202
internal::IO_CACHE *outfile;
144
internal::IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
204
146
bool multi_byte_charset;
207
Don't use table->sort in filesort as it is also used by
208
QuickIndexMergeSelect. Work with a copy and put it back at the end
209
when index_merge select has finished with it.
211
filesort_info table_sort(table->sort);
212
table->sort.io_cache= NULL;
148
filesort_info table_sort;
214
149
TableList *tab= table->pos_in_table_list;
215
150
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
220
155
Release InnoDB's adaptive hash index latch (if holding) before
223
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;
226
168
outfile= table_sort.io_cache;
227
assert(tempfile.buffer == 0);
228
assert(buffpek_pointers.buffer == 0);
230
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);
231
175
param.ref_length= table->cursor->ref_length;
176
param.addon_field= 0;
177
param.addon_length= 0;
233
178
if (!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) && !sort_positions)
236
181
Get the descriptors of all fields whose values are appended
237
182
to sorted fields and get its total length in param.spack_length.
239
param.addon_field= get_addon_fields(table->getFields(),
184
param.addon_field= get_addon_fields(session, table->getFields(),
240
185
param.sort_length,
241
186
¶m.addon_length);
293
236
selected_records_file= 0;
296
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)))
301
memavl= getSession().variables.sortbuff_size;
243
memavl= session->variables.sortbuff_size;
302
244
min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
303
245
while (memavl >= min_sort_memory)
305
247
uint32_t old_memavl;
306
248
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
307
249
param.keys= (uint32_t) min(records+1, (ha_rows)keys);
309
allocated_sort_memory= param.keys * param.rec_length;
310
if (not global_sort_buffer.add(allocated_sort_memory))
312
my_error(ER_OUT_OF_GLOBAL_SORTMEMORY, MYF(ME_ERROR+ME_WAITTANG));
316
250
if ((table_sort.sort_keys=
317
251
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
318
252
param.keys, param.rec_length)))
321
global_sort_buffer.sub(allocated_sort_memory);
322
254
old_memavl= memavl;
323
255
if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
324
256
memavl= min_sort_memory;
329
261
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
333
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)))
338
268
param.keys--; /* TODO: check why we do this */
339
269
param.sort_form= table;
340
270
param.end=(param.local_sortorder=sortorder)+s_length;
341
if ((records= find_all_keys(¶m,select,sort_keys, &buffpek_pointers,
342
&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)) ==
346
275
maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek_inst));
348
277
if (maxbuffer == 0) // The whole set is in memory
350
if (param.save_index(sort_keys,(uint32_t) records, &table_sort))
279
if (save_index(¶m,sort_keys,(uint32_t) records, &table_sort))
361
288
table_sort.buffpek = 0;
363
290
if (!(table_sort.buffpek=
364
(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)))
368
294
buffpek_inst= (buffpek *) table_sort.buffpek;
369
295
table_sort.buffpek_len= maxbuffer;
370
buffpek_pointers.close_cached_file();
296
close_cached_file(&buffpek_pointers);
371
297
/* Open cached file if it isn't open */
372
if (! my_b_inited(outfile) && outfile->open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,READ_RECORD_BUFFER, MYF(MY_WME)))
377
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))
383
306
Use also the space previously used by string pointers in sort_buffer
384
307
for temporary key storage.
386
param.keys=((param.keys*(param.rec_length+sizeof(char*))) / param.rec_length-1);
309
param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
388
311
maxbuffer--; // Offset from 0
389
312
if (merge_many_buff(¶m,(unsigned char*) sort_keys,buffpek_inst,&maxbuffer, &tempfile))
394
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))
399
317
if (merge_index(¶m,(unsigned char*) sort_keys,buffpek_inst,maxbuffer,&tempfile, outfile))
405
320
if (records > param.max_rows)
407
records= param.max_rows;
321
records=param.max_rows;
412
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())
415
331
table_sort.sort_keys= 0;
417
333
table_sort.buffpek= 0;
418
334
table_sort.buffpek_len= 0;
421
tempfile.close_cached_file();
422
buffpek_pointers.close_cached_file();
336
close_cached_file(&tempfile);
337
close_cached_file(&buffpek_pointers);
424
338
if (my_b_inited(outfile))
426
340
if (flush_io_cache(outfile))
431
internal::my_off_t save_pos= outfile->pos_in_file;
343
internal::my_off_t save_pos=outfile->pos_in_file;
432
344
/* For following reads */
433
if (outfile->reinit_io_cache(internal::READ_CACHE,0L,0,0))
345
if (reinit_io_cache(outfile,internal::READ_CACHE,0L,0,0))
437
347
outfile->end_of_file=save_pos;
443
352
my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
448
getSession().status_var.filesort_rows+= (uint32_t) records;
357
session->status_var.filesort_rows+= (uint32_t) records;
450
examined_rows= param.examined_rows;
451
global_sort_buffer.sub(allocated_sort_memory);
452
table->sort= table_sort;
359
*examined_rows= param.examined_rows;
360
memcpy(&table->sort, &table_sort, sizeof(filesort_info));
453
361
DRIZZLE_FILESORT_DONE(error, records);
454
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);
457
398
/** Make a array of string pointers. */
459
static char **make_char_array(char **old_pos, uint32_t fields,
400
static char **make_char_array(char **old_pos, register uint32_t fields,
534
475
HA_POS_ERROR on error.
537
ha_rows FileSort::find_all_keys(SortParam *param,
538
optimizer::SqlSelect *select,
539
unsigned char **sort_keys,
540
internal::IO_CACHE *buffpek_pointers,
541
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)
543
485
int error,flag,quick_select;
544
486
uint32_t idx,indexpos,ref_length;
545
487
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
546
488
internal::my_off_t record;
547
489
Table *sort_form;
548
volatile Session::killed_state_t *killed= getSession().getKilledPtr();
490
volatile Session::killed_state *killed= &session->killed;
550
492
boost::dynamic_bitset<> *save_read_set= NULL;
551
493
boost::dynamic_bitset<> *save_write_set= NULL;
726
int SortParam::write_keys(unsigned char **sort_keys, uint32_t count,
727
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;
731
671
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
732
672
if (!my_b_inited(tempfile) &&
733
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,
822
762
Item *item=sort_field->item;
823
763
maybe_null= item->maybe_null;
825
764
switch (sort_field->result_type) {
826
765
case STRING_RESULT:
828
const CHARSET_INFO * const cs=item->collation.collation;
829
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
831
uint32_t sort_field_length;
767
const CHARSET_INFO * const cs=item->collation.collation;
768
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
770
uint32_t sort_field_length;
774
/* All item->str() to use some extra byte for end null.. */
775
String tmp((char*) to,sort_field->length+4,cs);
776
String *res= item->str_result(&tmp);
835
/* All item->str() to use some extra byte for end null.. */
836
String tmp((char*) to,sort_field->length+4,cs);
837
String *res= item->str_result(&tmp);
841
memset(to-1, 0, sort_field->length+1);
845
This should only happen during extreme conditions if we run out
846
of memory or have an item marked not null when it can be null.
847
This code is here mainly to avoid a hard crash in this case.
850
memset(to, 0, sort_field->length); // Avoid crash
854
length= res->length();
855
sort_field_length= sort_field->length - sort_field->suffix_length;
856
diff=(int) (sort_field_length - length);
860
length= sort_field_length;
862
if (sort_field->suffix_length)
864
/* Store length last in result_string */
865
store_length(to + sort_field_length, length,
866
sort_field->suffix_length);
868
if (sort_field->need_strxnfrm)
870
char *from=(char*) res->ptr();
872
if ((unsigned char*) from == to)
874
set_if_smaller(length,sort_field->length);
875
memcpy(tmp_buffer,from,length);
878
tmp_length= my_strnxfrm(cs,to,sort_field->length,
879
(unsigned char*) from, length);
880
assert(tmp_length == sort_field->length);
780
memset(to-1, 0, sort_field->length+1);
884
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
885
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
784
This should only happen during extreme conditions if we run out
785
of memory or have an item marked not null when it can be null.
786
This code is here mainly to avoid a hard crash in this case.
789
memset(to, 0, sort_field->length); // Avoid crash
793
length= res->length();
794
sort_field_length= sort_field->length - sort_field->suffix_length;
795
diff=(int) (sort_field_length - length);
799
length= sort_field_length;
801
if (sort_field->suffix_length)
803
/* Store length last in result_string */
804
store_length(to + sort_field_length, length,
805
sort_field->suffix_length);
807
if (sort_field->need_strxnfrm)
809
char *from=(char*) res->ptr();
811
if ((unsigned char*) from == to)
813
set_if_smaller(length,sort_field->length);
814
memcpy(param->tmp_buffer,from,length);
815
from=param->tmp_buffer;
817
tmp_length= my_strnxfrm(cs,to,sort_field->length,
818
(unsigned char*) from, length);
819
assert(tmp_length == sort_field->length);
823
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
824
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
891
830
int64_t value= item->val_int_result();
895
834
if (item->null_value)
906
to[7]= (unsigned char) value;
907
to[6]= (unsigned char) (value >> 8);
908
to[5]= (unsigned char) (value >> 16);
909
to[4]= (unsigned char) (value >> 24);
910
to[3]= (unsigned char) (value >> 32);
911
to[2]= (unsigned char) (value >> 40);
912
to[1]= (unsigned char) (value >> 48);
845
to[7]= (unsigned char) value;
846
to[6]= (unsigned char) (value >> 8);
847
to[5]= (unsigned char) (value >> 16);
848
to[4]= (unsigned char) (value >> 24);
849
to[3]= (unsigned char) (value >> 32);
850
to[2]= (unsigned char) (value >> 40);
851
to[1]= (unsigned char) (value >> 48);
913
852
if (item->unsigned_flag) /* Fix sign */
914
853
to[0]= (unsigned char) (value >> 56);
916
855
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
919
858
case DECIMAL_RESULT:
921
type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
860
my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
924
863
if (item->null_value)
1017
953
/* Save filepos last */
1018
memcpy(to, ref_pos, (size_t) ref_length);
954
memcpy(to, ref_pos, (size_t) param->ref_length);
1024
fields used by sorting in the sorted table's read set
961
Register fields used by sorting in the sorted table's read set
1027
void SortParam::register_used_fields()
964
static void register_used_fields(SORTPARAM *param)
1029
966
SortField *sort_field;
1030
Table *table= sort_form;
967
Table *table=param->sort_form;
1032
for (sort_field= local_sortorder ;
969
for (sort_field= param->local_sortorder ;
970
sort_field != param->end ;
1037
974
if ((field= sort_field->field))
1039
976
if (field->getTable() == table)
1040
table->setReadSet(field->position());
977
table->setReadSet(field->field_index);
1064
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1001
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
1002
filesort_info *table_sort)
1004
uint32_t offset,res_length;
1067
1005
unsigned char *to;
1069
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1070
offset= rec_length - res_length;
1072
if ((ha_rows) count > max_rows)
1073
count=(uint32_t) max_rows;
1075
if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1078
for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1007
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
1008
res_length= param->res_length;
1009
offset= param->rec_length-res_length;
1010
if ((ha_rows) count > param->max_rows)
1011
count=(uint32_t) param->max_rows;
1012
if (!(to= table_sort->record_pointers=
1013
(unsigned char*) malloc(res_length*count)))
1015
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
1080
1017
memcpy(to, *sort_keys+offset, res_length);
1081
1018
to+= res_length;
1088
1024
/** Merge buffers to make < MERGEBUFF2 buffers. */
1090
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1091
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1026
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
1027
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1093
1029
internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
1094
1030
buffpek *lastbuff;
1433
1366
/* Do a merge to output-file (save only positions) */
1435
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1436
buffpek *buffpek_inst, uint32_t maxbuffer,
1437
internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1368
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1369
buffpek *buffpek_inst, uint32_t maxbuffer,
1370
internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1439
1372
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1440
1373
buffpek_inst+maxbuffer,1))
1444
1376
} /* merge_index */
1504
1439
sortorder->result_type= sortorder->item->result_type();
1505
1440
if (sortorder->item->result_as_int64_t())
1506
1441
sortorder->result_type= INT_RESULT;
1508
1442
switch (sortorder->result_type) {
1509
1443
case STRING_RESULT:
1510
sortorder->length=sortorder->item->max_length;
1444
sortorder->length=sortorder->item->max_length;
1511
1445
set_if_smaller(sortorder->length,
1512
getSession().variables.max_sort_length);
1513
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1446
session->variables.max_sort_length);
1447
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1515
1449
sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1516
sortorder->need_strxnfrm= 1;
1517
*multi_byte_charset= 1;
1450
sortorder->need_strxnfrm= 1;
1451
*multi_byte_charset= 1;
1519
1453
else if (cs == &my_charset_bin)
1521
1455
/* Store length last to be able to sort blob/varbinary */
1522
1456
sortorder->suffix_length= suffix_length(sortorder->length);
1523
1457
sortorder->length+= sortorder->suffix_length;
1526
1460
case INT_RESULT:
1527
sortorder->length=8; // Size of intern int64_t
1461
sortorder->length=8; // Size of intern int64_t
1529
1463
case DECIMAL_RESULT:
1530
1464
sortorder->length=
1531
class_decimal_get_binary_size(sortorder->item->max_length -
1465
my_decimal_get_binary_size(sortorder->item->max_length -
1532
1466
(sortorder->item->decimals ? 1 : 0),
1533
1467
sortorder->item->decimals);
1535
1469
case REAL_RESULT:
1536
sortorder->length=sizeof(double);
1470
sortorder->length=sizeof(double);
1538
1472
case ROW_RESULT:
1539
// This case should never be choosen
1474
// This case should never be choosen
1543
1478
if (sortorder->item->maybe_null)
1544
length++; // Place for NULL marker
1479
length++; // Place for NULL marker
1546
set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1481
set_if_smaller(sortorder->length,
1482
(size_t)session->variables.max_sort_length);
1547
1483
length+=sortorder->length;
1549
1485
sortorder->field= (Field*) 0; // end marker