30
30
#include <algorithm>
31
31
#include <iostream>
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"
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>
49
#include <drizzled/sort_field.h>
50
#include <drizzled/item/subselect.h>
51
#include <drizzled/statistics_variables.h>
52
#include <drizzled/system_variables.h>
51
54
using namespace std;
56
58
/* Defines used by filesort and uniques */
57
59
#define MERGEBUFF 7
119
120
int write_keys(unsigned char * *sort_keys,
121
internal::IO_CACHE *buffer_file,
122
internal::IO_CACHE *tempfile);
122
internal::io_cache_st *buffer_file,
123
internal::io_cache_st *tempfile);
124
125
void make_sortkey(unsigned char *to,
125
126
unsigned char *ref_pos);
126
127
void register_used_fields();
127
bool save_index(unsigned char **sort_keys,
128
void save_index(unsigned char **sort_keys,
129
130
filesort_info *table_sort);
133
134
/* functions defined in this file */
135
static char **make_char_array(char **old_pos, register uint32_t fields,
136
static char **make_char_array(char **old_pos, uint32_t fields,
136
137
uint32_t length);
138
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
139
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffer_file,
140
141
unsigned char *buf);
194
195
buffpek *buffpek_inst= 0;
195
196
ha_rows records= HA_POS_ERROR;
196
197
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;
198
internal::io_cache_st tempfile;
199
internal::io_cache_st buffpek_pointers;
200
internal::io_cache_st *selected_records_file;
201
internal::io_cache_st *outfile;
202
203
bool multi_byte_charset;
291
289
selected_records_file= 0;
294
if (multi_byte_charset && !(param.tmp_buffer= (char*) malloc(param.sort_length)))
292
if (multi_byte_charset)
293
param.tmp_buffer= (char*) malloc(param.sort_length);
299
295
memavl= getSession().variables.sortbuff_size;
300
296
min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
346
342
if (maxbuffer == 0) // The whole set is in memory
348
if (param.save_index(sort_keys,(uint32_t) records, &table_sort))
344
param.save_index(sort_keys,(uint32_t) records, &table_sort);
355
348
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
357
if (table_sort.buffpek)
358
free(table_sort.buffpek);
350
free(table_sort.buffpek);
359
351
table_sort.buffpek = 0;
361
353
if (!(table_sort.buffpek=
455
447
/** Make a array of string pointers. */
457
static char **make_char_array(char **old_pos, register uint32_t fields,
449
static char **make_char_array(char **old_pos, uint32_t fields,
464
(old_pos= (char**) malloc((uint32_t) fields*(length+sizeof(char*)))))
466
pos=old_pos; char_pos=((char*) (pos+fields)) -length;
467
while (fields--) *(pos++) = (char_pos+= length);
453
old_pos= (char**) malloc((uint32_t) fields * (length + sizeof(char*)));
455
char* char_pos= ((char*) (pos+fields)) - length;
457
*(pos++) = (char_pos+= length);
471
460
} /* make_char_array */
474
463
/** Read 'count' number of buffer pointers into memory. */
476
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffpek_pointers, uint32_t count,
465
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffpek_pointers, uint32_t count,
477
466
unsigned char *buf)
479
468
uint32_t length= sizeof(buffpek)*count;
482
471
return 0; /* sizeof(buffpek)*count will overflow */
484
473
tmp= (unsigned char *)malloc(length);
487
475
if (buffpek_pointers->reinit_io_cache(internal::READ_CACHE,0L,0,0) ||
488
476
my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
535
523
ha_rows FileSort::find_all_keys(SortParam *param,
536
524
optimizer::SqlSelect *select,
537
525
unsigned char **sort_keys,
538
internal::IO_CACHE *buffpek_pointers,
539
internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
526
internal::io_cache_st *buffpek_pointers,
527
internal::io_cache_st *tempfile, internal::io_cache_st *indexfile)
541
529
int error,flag,quick_select;
542
530
uint32_t idx,indexpos,ref_length;
724
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
725
internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
712
int SortParam::write_keys(unsigned char **sort_keys, uint32_t count,
713
internal::io_cache_st *buffpek_pointers, internal::io_cache_st *tempfile)
823
811
switch (sort_field->result_type) {
824
812
case STRING_RESULT:
826
const CHARSET_INFO * const cs=item->collation.collation;
814
const charset_info_st * const cs=item->collation.collation;
827
815
char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
829
817
uint32_t sort_field_length;
1062
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1050
void SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1067
1052
internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1068
offset= rec_length - res_length;
1053
uint32_t offset= rec_length - res_length;
1070
1055
if ((ha_rows) count > max_rows)
1071
1056
count=(uint32_t) max_rows;
1073
if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1058
unsigned char* to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count);
1076
1060
for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1078
1062
memcpy(to, *sort_keys+offset, res_length);
1079
1063
to+= res_length;
1086
1068
/** Merge buffers to make < MERGEBUFF2 buffers. */
1088
1070
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1089
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1071
buffpek *buffpek_inst, uint32_t *maxbuffer, internal::io_cache_st *t_file)
1091
internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
1073
internal::io_cache_st t_file2,*from_file,*to_file,*temp;
1092
1074
buffpek *lastbuff;
1094
1076
if (*maxbuffer < MERGEBUFF2)
1102
1084
from_file= t_file ; to_file= &t_file2;
1103
1085
while (*maxbuffer >= MERGEBUFF2)
1105
register uint32_t i;
1107
1089
if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1160
1142
(uint32_t)-1 if something goes wrong
1163
uint32_t FileSort::read_to_buffer(internal::IO_CACHE *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1145
uint32_t FileSort::read_to_buffer(internal::io_cache_st *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1165
register uint32_t count;
1166
1148
uint32_t length;
1168
1150
if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1220
int FileSort::merge_buffers(SortParam *param, internal::IO_CACHE *from_file,
1221
internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1202
int FileSort::merge_buffers(SortParam *param, internal::io_cache_st *from_file,
1203
internal::io_cache_st *to_file, unsigned char *sort_buffer,
1222
1204
buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1433
1415
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1434
1416
buffpek *buffpek_inst, uint32_t maxbuffer,
1435
internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1417
internal::io_cache_st *tempfile, internal::io_cache_st *outfile)
1437
1419
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1438
1420
buffpek_inst+maxbuffer,1))
1611
1593
length+= (null_fields+7)/8;
1613
if (length+sortlength_arg > getSession().variables.max_length_for_sort_data ||
1614
!(addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field)*
1595
if (length+sortlength_arg > getSession().variables.max_length_for_sort_data)
1597
addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field) * (fields+1));
1618
1599
*plength= length;
1619
1600
length= (null_fields+7)/8;