24
#include <drizzled/server_includes.h>
25
#include <drizzled/sql_sort.h>
26
#include <drizzled/error.h>
27
#include <drizzled/probes.h>
28
#include <drizzled/session.h>
29
#include <drizzled/table.h>
30
#include <drizzled/table_list.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"
45
35
using namespace std;
50
37
/* functions defined in this file */
52
39
static char **make_char_array(char **old_pos, register uint32_t fields,
55
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
59
static ha_rows find_all_keys(SORTPARAM *param,
60
optimizer::SqlSelect *select,
61
unsigned char * *sort_keys,
62
internal::IO_CACHE *buffer_file,
63
internal::IO_CACHE *tempfile,
64
internal::IO_CACHE *indexfile);
66
static int write_keys(SORTPARAM *param,
67
unsigned char * *sort_keys,
69
internal::IO_CACHE *buffer_file,
70
internal::IO_CACHE *tempfile);
72
static void make_sortkey(SORTPARAM *param,
74
unsigned char *ref_pos);
41
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
43
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
44
unsigned char * *sort_keys, IO_CACHE *buffer_file,
45
IO_CACHE *tempfile,IO_CACHE *indexfile);
46
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
47
uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
48
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
75
49
static void register_used_fields(SORTPARAM *param);
76
static int merge_index(SORTPARAM *param,
77
unsigned char *sort_buffer,
50
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
80
internal::IO_CACHE *tempfile,
81
internal::IO_CACHE *outfile);
82
static bool save_index(SORTPARAM *param,
83
unsigned char **sort_keys,
52
uint32_t maxbuffer,IO_CACHE *tempfile,
54
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count,
85
55
filesort_info_st *table_sort);
86
56
static uint32_t suffix_length(uint32_t string_length);
87
static uint32_t sortlength(Session *session,
88
SORT_FIELD *sortorder,
90
bool *multi_byte_charset);
91
static SORT_ADDON_FIELD *get_addon_fields(Session *session,
57
static uint32_t sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
58
bool *multi_byte_charset);
59
static SORT_ADDON_FIELD *get_addon_fields(Session *session, Field **ptabfield,
60
uint32_t sortlength, uint32_t *plength);
95
61
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
96
62
unsigned char *buff);
148
114
TableList *tab= table->pos_in_table_list;
149
115
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
151
DRIZZLE_FILESORT_START(table->s->getSchemaName(), table->s->getTableName());
117
DRIZZLE_FILESORT_START();
154
120
Release InnoDB's adaptive hash index latch (if holding) before
157
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
123
ha_release_temporary_latches(session);
160
126
Don't use table->sort in filesort as it is also used by
161
QuickIndexMergeSelect. Work with a copy and put it back at the end
127
QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
162
128
when index_merge select has finished with it.
164
130
memcpy(&table_sort, &table->sort, sizeof(filesort_info_st));
242
208
memavl= session->variables.sortbuff_size;
243
min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
209
min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
244
210
while (memavl >= min_sort_memory)
246
212
uint32_t old_memavl;
247
213
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
248
param.keys= (uint32_t) min(records+1, (ha_rows)keys);
214
param.keys=(uint32_t) cmin(records+1, keys);
249
215
if ((table_sort.sort_keys=
250
216
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
251
217
param.keys, param.rec_length)))
254
if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
220
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
255
221
memavl= min_sort_memory;
257
223
sort_keys= table_sort.sort_keys;
358
324
(uint32_t) records, &LOCK_status);
359
325
*examined_rows= param.examined_rows;
360
326
memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
361
DRIZZLE_FILESORT_DONE(error, records);
362
return (error ? HA_POS_ERROR : records);
327
DRIZZLE_FILESORT_END();
328
return(error ? HA_POS_ERROR : records);
366
void Table::filesort_free_buffers(bool full)
332
void filesort_free_buffers(Table *table, bool full)
368
if (sort.record_pointers)
334
if (table->sort.record_pointers)
370
free((unsigned char*) sort.record_pointers);
371
sort.record_pointers=0;
336
free((unsigned char*) table->sort.record_pointers);
337
table->sort.record_pointers=0;
341
if (table->sort.sort_keys )
377
if ((unsigned char*) sort.sort_keys)
378
free((unsigned char*) sort.sort_keys);
343
if ((unsigned char*) table->sort.sort_keys)
344
free((unsigned char*) table->sort.sort_keys);
345
table->sort.sort_keys= 0;
347
if (table->sort.buffpek)
383
if ((unsigned char*) sort.buffpek)
384
free((unsigned char*) sort.buffpek);
349
if ((unsigned char*) table->sort.buffpek)
350
free((unsigned char*) table->sort.buffpek);
351
table->sort.buffpek= 0;
352
table->sort.buffpek_len= 0;
355
if (table->sort.addon_buf)
391
free((char *) sort.addon_buf);
392
free((char *) sort.addon_field);
357
free((char *) table->sort.addon_buf);
358
free((char *) table->sort.addon_field);
359
table->sort.addon_buf=0;
360
table->sort.addon_field=0;
475
441
HA_POS_ERROR on error.
478
static ha_rows find_all_keys(SORTPARAM *param,
479
optimizer::SqlSelect *select,
444
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
480
445
unsigned char **sort_keys,
481
internal::IO_CACHE *buffpek_pointers,
482
internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
446
IO_CACHE *buffpek_pointers,
447
IO_CACHE *tempfile, IO_CACHE *indexfile)
484
449
int error,flag,quick_select;
485
450
uint32_t idx,indexpos,ref_length;
486
451
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
487
internal::my_off_t record;
488
453
Table *sort_form;
489
454
Session *session= current_session;
490
455
volatile Session::killed_state *killed= &session->killed;
492
MyBitmap *save_read_set, *save_write_set;
457
bitset<MAX_FIELDS> *save_read_set, *save_write_set;
495
460
error=quick_select=0;
496
461
sort_form=param->sort_form;
497
file= sort_form->cursor;
462
file=sort_form->file;
498
463
ref_length=param->ref_length;
499
464
ref_pos= ref_buff;
500
465
quick_select=select && select->quick;
502
flag= ((!indexfile && ! file->isOrdered())
467
flag= ((!indexfile && file->ha_table_flags() & HA_REC_NOT_IN_SEQ)
503
468
|| quick_select);
504
469
if (indexfile || flag)
505
470
ref_pos= &file->ref[0];
668
635
sort_length= param->sort_length;
669
636
rec_length= param->rec_length;
670
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
637
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
671
638
if (!my_b_inited(tempfile) &&
672
639
open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
641
goto err; /* purecov: inspected */
675
642
/* check we won't have more buffpeks than we can possibly keep in memory */
676
643
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
678
645
buffpek.file_pos= my_b_tell(tempfile);
679
646
if ((ha_rows) count > param->max_rows)
680
count=(uint32_t) param->max_rows;
647
count=(uint32_t) param->max_rows; /* purecov: inspected */
681
648
buffpek.count=(ha_rows) count;
682
649
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
683
650
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
993
963
uint32_t offset,res_length;
994
964
unsigned char *to;
996
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
966
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
997
967
res_length= param->res_length;
998
968
offset= param->rec_length-res_length;
999
969
if ((ha_rows) count > param->max_rows)
1000
970
count=(uint32_t) param->max_rows;
1001
971
if (!(to= table_sort->record_pointers=
1002
972
(unsigned char*) malloc(res_length*count)))
973
return(1); /* purecov: inspected */
1004
974
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
1006
976
memcpy(to, *sort_keys+offset, res_length);
1013
983
/** Merge buffers to make < MERGEBUFF2 buffers. */
1015
985
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
1016
BUFFPEK *buffpek, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
986
BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
1018
988
register uint32_t i;
1019
internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
989
IO_CACHE t_file2,*from_file,*to_file,*temp;
1020
990
BUFFPEK *lastbuff;
1022
992
if (*maxbuffer < MERGEBUFF2)
993
return(0); /* purecov: inspected */
1024
994
if (flush_io_cache(t_file) ||
1025
995
open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
997
return(1); /* purecov: inspected */
1029
999
from_file= t_file ; to_file= &t_file2;
1030
1000
while (*maxbuffer >= MERGEBUFF2)
1032
if (reinit_io_cache(from_file,internal::READ_CACHE,0L,0,0))
1002
if (reinit_io_cache(from_file,READ_CACHE,0L,0,0))
1034
if (reinit_io_cache(to_file,internal::WRITE_CACHE,0L,0,0))
1004
if (reinit_io_cache(to_file,WRITE_CACHE,0L,0,0))
1036
1006
lastbuff=buffpek;
1037
1007
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
1069
1039
(uint32_t)-1 if something goes wrong
1072
uint32_t read_to_buffer(internal::IO_CACHE *fromfile, BUFFPEK *buffpek,
1073
uint32_t rec_length)
1042
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1043
uint32_t rec_length)
1075
1045
register uint32_t count;
1076
1046
uint32_t length;
1078
if ((count= (uint32_t) min((ha_rows) buffpek->max_keys,buffpek->count)))
1048
if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
1080
1050
if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1081
return((uint32_t) -1);
1083
buffpek->key= buffpek->base;
1051
return((uint32_t) -1); /* purecov: inspected */
1052
buffpek->key=buffpek->base;
1084
1053
buffpek->file_pos+= length; /* New filepos */
1085
buffpek->count-= count;
1054
buffpek->count-= count;
1086
1055
buffpek->mem_count= count;
1088
1057
return (count*rec_length);