24
24
#include <drizzled/server_includes.h>
26
#include <drizzled/drizzled_error_messages.h>
28
/// How to write record_ref.
29
#define WRITE_REF(file,from) \
30
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
33
/* functions defined in this file */
35
static char **make_char_array(char **old_pos, register uint fields,
36
uint length, myf my_flag);
37
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
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>
37
/* functions defined in this file */
39
static char **make_char_array(char **old_pos, register uint32_t fields,
41
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
39
43
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
40
uchar * *sort_keys, IO_CACHE *buffer_file,
44
unsigned char * *sort_keys, IO_CACHE *buffer_file,
41
45
IO_CACHE *tempfile,IO_CACHE *indexfile);
42
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
43
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
44
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
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);
45
49
static void register_used_fields(SORTPARAM *param);
46
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
50
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
48
uint maxbuffer,IO_CACHE *tempfile,
52
uint32_t maxbuffer,IO_CACHE *tempfile,
49
53
IO_CACHE *outfile);
50
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count,
51
FILESORT_INFO *table_sort);
52
static uint suffix_length(uint32_t string_length);
53
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
54
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count,
55
filesort_info_st *table_sort);
56
static uint32_t suffix_length(uint32_t string_length);
57
static uint32_t sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
54
58
bool *multi_byte_charset);
55
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
56
uint sortlength, uint *plength);
59
static SORT_ADDON_FIELD *get_addon_fields(Session *session, Field **ptabfield,
60
uint32_t sortlength, uint32_t *plength);
57
61
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
61
65
Creates a set of pointers that can be used to read the rows
68
72
The result set is stored in table->io_cache or
69
73
table->record_pointers.
71
@param thd Current thread
75
@param session Current thread
72
76
@param table Table to sort
73
77
@param sortorder How to sort the table
74
78
@param s_length Number of elements in sortorder
75
79
@param select condition to apply to the rows
76
80
@param max_rows Return only this many rows
77
81
@param sort_positions Set to 1 if we want to force sorting by position
78
(Needed by UPDATE/INSERT or ALTER TABLE)
82
(Needed by UPDATE/INSERT or ALTER Table)
79
83
@param examined_rows Store number of examined rows here
92
96
examined_rows will be set to number of examined rows
95
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
99
ha_rows filesort(Session *session, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
96
100
SQL_SELECT *select, ha_rows max_rows,
97
101
bool sort_positions, ha_rows *examined_rows)
100
104
uint32_t memavl, min_sort_memory;
102
106
BUFFPEK *buffpek;
103
107
ha_rows records= HA_POS_ERROR;
104
uchar **sort_keys= 0;
105
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
108
unsigned char **sort_keys= 0;
109
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
107
111
bool multi_byte_charset;
109
FILESORT_INFO table_sort;
110
TABLE_LIST *tab= table->pos_in_table_list;
113
filesort_info_st table_sort;
114
TableList *tab= table->pos_in_table_list;
111
115
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
113
117
DRIZZLE_FILESORT_START();
116
120
Release InnoDB's adaptive hash index latch (if holding) before
119
ha_release_temporary_latches(thd);
123
ha_release_temporary_latches(session);
122
Don't use table->sort in filesort as it is also used by
123
QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
126
Don't use table->sort in filesort as it is also used by
127
QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
124
128
when index_merge select has finished with it.
126
memcpy(&table_sort, &table->sort, sizeof(FILESORT_INFO));
130
memcpy(&table_sort, &table->sort, sizeof(filesort_info_st));
127
131
table->sort.io_cache= NULL;
129
133
outfile= table_sort.io_cache;
130
134
my_b_clear(&tempfile);
131
135
my_b_clear(&buffpek_pointers);
134
138
memset(¶m, 0, sizeof(param));
135
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
139
param.sort_length= sortlength(session, sortorder, s_length, &multi_byte_charset);
136
140
param.ref_length= table->file->ref_length;
137
141
param.addon_field= 0;
138
142
param.addon_length= 0;
139
143
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !sort_positions)
142
Get the descriptors of all fields whose values are appended
146
Get the descriptors of all fields whose values are appended
143
147
to sorted fields and get its total length in param.spack_length.
145
param.addon_field= get_addon_fields(thd, table->field,
149
param.addon_field= get_addon_fields(session, table->field,
146
150
param.sort_length,
147
151
¶m.addon_length);
201
204
if (multi_byte_charset &&
202
!(param.tmp_buffer= (char*) my_malloc(param.sort_length,MYF(MY_WME))))
205
!(param.tmp_buffer= (char*) malloc(param.sort_length)))
205
memavl= thd->variables.sortbuff_size;
206
min_sort_memory= max((uint)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
208
memavl= session->variables.sortbuff_size;
209
min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
207
210
while (memavl >= min_sort_memory)
209
212
uint32_t old_memavl;
210
213
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
211
param.keys=(uint) min(records+1, keys);
214
param.keys= (uint32_t) min(records+1, (ha_rows)keys);
212
215
if ((table_sort.sort_keys=
213
(uchar **) make_char_array((char **) table_sort.sort_keys,
214
param.keys, param.rec_length, MYF(0))))
216
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
217
param.keys, param.rec_length)))
217
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)
218
221
memavl= min_sort_memory;
220
223
sort_keys= table_sort.sort_keys;
234
237
&tempfile, selected_records_file)) ==
237
maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
240
maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
239
242
if (maxbuffer == 0) // The whole set is in memory
241
if (save_index(¶m,sort_keys,(uint) records, &table_sort))
244
if (save_index(¶m,sort_keys,(uint32_t) records, &table_sort))
246
249
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
248
x_free(table_sort.buffpek);
251
if (table_sort.buffpek)
252
free(table_sort.buffpek);
249
253
table_sort.buffpek= 0;
251
255
if (!(table_sort.buffpek=
252
(uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
256
(unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
253
257
table_sort.buffpek)))
255
259
buffpek= (BUFFPEK *) table_sort.buffpek;
270
274
param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
271
275
param.rec_length-1);
272
276
maxbuffer--; // Offset from 0
273
if (merge_many_buff(¶m,(uchar*) sort_keys,buffpek,&maxbuffer,
277
if (merge_many_buff(¶m,(unsigned char*) sort_keys,buffpek,&maxbuffer,
276
280
if (flush_io_cache(&tempfile) ||
277
281
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
279
if (merge_index(¶m,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
283
if (merge_index(¶m,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
313
320
my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
314
321
MYF(ME_ERROR+ME_WAITTANG));
316
statistic_add(thd->status_var.filesort_rows,
323
statistic_add(session->status_var.filesort_rows,
317
324
(uint32_t) records, &LOCK_status);
318
325
*examined_rows= param.examined_rows;
319
memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
326
memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
320
327
DRIZZLE_FILESORT_END();
321
328
return(error ? HA_POS_ERROR : records);
325
void filesort_free_buffers(TABLE *table, bool full)
332
void filesort_free_buffers(Table *table, bool full)
327
334
if (table->sort.record_pointers)
329
my_free((uchar*) table->sort.record_pointers,MYF(0));
336
free((unsigned char*) table->sort.record_pointers);
330
337
table->sort.record_pointers=0;
334
341
if (table->sort.sort_keys )
336
x_free((uchar*) table->sort.sort_keys);
343
if ((unsigned char*) table->sort.sort_keys)
344
free((unsigned char*) table->sort.sort_keys);
337
345
table->sort.sort_keys= 0;
339
347
if (table->sort.buffpek)
341
x_free((uchar*) table->sort.buffpek);
349
if ((unsigned char*) table->sort.buffpek)
350
free((unsigned char*) table->sort.buffpek);
342
351
table->sort.buffpek= 0;
343
352
table->sort.buffpek_len= 0;
346
355
if (table->sort.addon_buf)
348
my_free((char *) table->sort.addon_buf, MYF(0));
349
my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
357
free((char *) table->sort.addon_buf);
358
free((char *) table->sort.addon_field);
350
359
table->sort.addon_buf=0;
351
360
table->sort.addon_field=0;
375
383
/** Read 'count' number of buffer pointers into memory. */
377
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
385
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
380
388
uint32_t length= sizeof(BUFFPEK)*count;
389
unsigned char *tmp= buf;
382
390
if (count > UINT_MAX/sizeof(BUFFPEK))
383
391
return 0; /* sizeof(BUFFPEK)*count will overflow */
385
tmp= (uchar *)my_malloc(length, MYF(MY_WME));
393
tmp= (unsigned char *)malloc(length);
388
396
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
389
my_b_read(buffpek_pointers, (uchar*) tmp, length))
397
my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
391
my_free((char*) tmp, MYF(0));
436
444
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
445
unsigned char **sort_keys,
438
446
IO_CACHE *buffpek_pointers,
439
447
IO_CACHE *tempfile, IO_CACHE *indexfile)
441
449
int error,flag,quick_select;
442
uint idx,indexpos,ref_length;
443
uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
450
uint32_t idx,indexpos,ref_length;
451
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
446
THD *thd= current_thd;
447
volatile THD::killed_state *killed= &thd->killed;
454
Session *session= current_session;
455
volatile Session::killed_state *killed= &session->killed;
449
457
MY_BITMAP *save_read_set, *save_write_set;
617
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
626
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
618
627
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
620
629
size_t sort_length, rec_length;
624
633
sort_length= param->sort_length;
625
634
rec_length= param->rec_length;
626
my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
635
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
627
636
if (!my_b_inited(tempfile) &&
628
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
637
open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
630
639
goto err; /* purecov: inspected */
631
640
/* check we won't have more buffpeks than we can possibly keep in memory */
634
643
buffpek.file_pos= my_b_tell(tempfile);
635
644
if ((ha_rows) count > param->max_rows)
636
count=(uint) param->max_rows; /* purecov: inspected */
645
count=(uint32_t) param->max_rows; /* purecov: inspected */
637
646
buffpek.count=(ha_rows) count;
638
647
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
639
if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
648
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
641
if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
650
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
754
763
if (sort_field->need_strxnfrm)
756
765
char *from=(char*) res->ptr();
758
if ((uchar*) from == to)
767
if ((unsigned char*) from == to)
760
769
set_if_smaller(length,sort_field->length);
761
770
memcpy(param->tmp_buffer,from,length);
762
771
from=param->tmp_buffer;
764
773
tmp_length= my_strnxfrm(cs,to,sort_field->length,
765
(uchar*) from, length);
774
(unsigned char*) from, length);
766
775
assert(tmp_length == sort_field->length);
770
my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
779
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
771
780
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
792
#if SIZEOF_LONG_LONG > 4
793
to[7]= (uchar) value;
794
to[6]= (uchar) (value >> 8);
795
to[5]= (uchar) (value >> 16);
796
to[4]= (uchar) (value >> 24);
797
to[3]= (uchar) (value >> 32);
798
to[2]= (uchar) (value >> 40);
799
to[1]= (uchar) (value >> 48);
800
if (item->unsigned_flag) /* Fix sign */
801
to[0]= (uchar) (value >> 56);
803
to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
805
to[3]= (uchar) value;
806
to[2]= (uchar) (value >> 8);
807
to[1]= (uchar) (value >> 16);
808
if (item->unsigned_flag) /* Fix sign */
809
to[0]= (uchar) (value >> 24);
811
to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
801
to[7]= (unsigned char) value;
802
to[6]= (unsigned char) (value >> 8);
803
to[5]= (unsigned char) (value >> 16);
804
to[4]= (unsigned char) (value >> 24);
805
to[3]= (unsigned char) (value >> 32);
806
to[2]= (unsigned char) (value >> 40);
807
to[1]= (unsigned char) (value >> 48);
808
if (item->unsigned_flag) /* Fix sign */
809
to[0]= (unsigned char) (value >> 56);
811
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
815
814
case DECIMAL_RESULT:
959
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
960
FILESORT_INFO *table_sort)
957
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
958
filesort_info_st *table_sort)
962
uint offset,res_length;
960
uint32_t offset,res_length;
965
my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
963
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
966
964
res_length= param->res_length;
967
965
offset= param->rec_length-res_length;
968
966
if ((ha_rows) count > param->max_rows)
969
count=(uint) param->max_rows;
970
if (!(to= table_sort->record_pointers=
971
(uchar*) my_malloc(res_length*count, MYF(MY_WME))))
967
count=(uint32_t) param->max_rows;
968
if (!(to= table_sort->record_pointers=
969
(unsigned char*) malloc(res_length*count)))
972
970
return(1); /* purecov: inspected */
973
for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
971
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
975
973
memcpy(to, *sort_keys+offset, res_length);
982
980
/** Merge buffers to make < MERGEBUFF2 buffers. */
984
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
985
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
982
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
983
BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
988
986
IO_CACHE t_file2,*from_file,*to_file,*temp;
989
987
BUFFPEK *lastbuff;
991
989
if (*maxbuffer < MERGEBUFF2)
992
990
return(0); /* purecov: inspected */
993
991
if (flush_io_cache(t_file) ||
994
open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
992
open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
996
994
return(1); /* purecov: inspected */
1035
1033
Read data to buffer.
1038
(uint)-1 if something goes wrong
1036
(uint32_t)-1 if something goes wrong
1041
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1039
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1040
uint32_t rec_length)
1044
register uint count;
1042
register uint32_t count;
1047
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1045
if ((count= (uint32_t) min((ha_rows) buffpek->max_keys,buffpek->count)))
1049
if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1050
return((uint) -1); /* purecov: inspected */
1051
buffpek->key=buffpek->base;
1047
if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1048
return((uint32_t) -1); /* purecov: inspected */
1050
buffpek->key= buffpek->base;
1052
1051
buffpek->file_pos+= length; /* New filepos */
1053
buffpek->count-= count;
1052
buffpek->count-= count;
1054
1053
buffpek->mem_count= count;
1056
1055
return (count*rec_length);
1057
1056
} /* read_to_buffer */
1061
Put all room used by freed buffer to use in adjacent buffer.
1063
Note, that we can't simply distribute memory evenly between all buffers,
1064
because new areas must not overlap with old ones.
1066
@param[in] queue list of non-empty buffers, without freed buffer
1067
@param[in] reuse empty buffer
1068
@param[in] key_length key length
1071
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1059
class compare_functor
1073
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
1074
for (uint i= 0; i < queue->elements; ++i)
1061
qsort2_cmp key_compare;
1062
void *key_compare_arg;
1064
compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
1065
: key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
1066
inline bool operator()(const BUFFPEK *i, const BUFFPEK *j) const
1076
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1077
if (bp->base + bp->max_keys * key_length == reuse->base)
1079
bp->max_keys+= reuse->max_keys;
1082
else if (bp->base == reuse_end)
1084
bp->base= reuse->base;
1085
bp->max_keys+= reuse->max_keys;
1068
int val= key_compare(key_compare_arg,
1111
1093
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1112
IO_CACHE *to_file, uchar *sort_buffer,
1094
IO_CACHE *to_file, unsigned char *sort_buffer,
1113
1095
BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1117
uint rec_length,res_length,offset;
1099
uint32_t rec_length,res_length,offset;
1118
1100
size_t sort_length;
1119
1101
uint32_t maxcount;
1120
1102
ha_rows max_rows,org_max_rows;
1121
1103
my_off_t to_start_filepos;
1104
unsigned char *strpos;
1123
1105
BUFFPEK *buffpek;
1125
1106
qsort2_cmp cmp;
1126
1107
void *first_cmp_arg;
1127
volatile THD::killed_state *killed= ¤t_thd->killed;
1128
THD::killed_state not_killable;
1108
volatile Session::killed_state *killed= ¤t_session->killed;
1109
Session::killed_state not_killable;
1130
status_var_increment(current_thd->status_var.filesort_merge_passes);
1111
status_var_increment(current_session->status_var.filesort_merge_passes);
1131
1112
if (param->not_killable)
1133
1114
killed= ¬_killable;
1134
not_killable= THD::NOT_KILLED;
1115
not_killable= Session::NOT_KILLED;
1157
1138
cmp= get_ptr_compare(sort_length);
1158
1139
first_cmp_arg= (void*) &sort_length;
1160
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1161
(queue_compare) cmp, first_cmp_arg))
1162
return(1); /* purecov: inspected */
1141
priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor >
1142
queue(compare_functor(cmp, first_cmp_arg));
1163
1143
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1165
1145
buffpek->base= strpos;
1166
1146
buffpek->max_keys= maxcount;
1167
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1147
strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
1169
1149
if (error == -1)
1170
1150
goto err; /* purecov: inspected */
1171
1151
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
1172
queue_insert(&queue, (uchar*) buffpek);
1152
queue.push(buffpek);
1175
1155
if (param->unique_buff)
1178
1158
Called by Unique::get()
1179
1159
Copy the first argument to param->unique_buff for unique removal.
1180
1160
Store it also in 'to_file'.
1211
buffpek= (BUFFPEK*) queue_top(&queue);
1193
buffpek= queue.top();
1212
1194
if (cmp) // Remove duplicates
1214
1196
if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1215
(uchar**) &buffpek->key))
1197
(unsigned char**) &buffpek->key))
1216
1198
goto skip_duplicate;
1217
1199
memcpy(param->unique_buff, buffpek->key, rec_length);
1221
if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1203
if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
1223
1205
error=1; goto err; /* purecov: inspected */
1228
if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1210
if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
1230
1212
error=1; goto err; /* purecov: inspected */
1243
1225
if (!(error= (int) read_to_buffer(from_file,buffpek,
1246
VOID(queue_remove(&queue,0));
1247
reuse_freed_buff(&queue, buffpek, rec_length);
1248
1229
break; /* One buffer have been removed */
1250
1231
else if (error == -1)
1251
1232
goto err; /* purecov: inspected */
1253
queue_replaced(&queue); /* Top element has been replaced */
1234
/* Top element has been replaced */
1236
queue.push(buffpek);
1256
buffpek= (BUFFPEK*) queue_top(&queue);
1239
buffpek= queue.top();
1257
1240
buffpek->base= sort_buffer;
1258
1241
buffpek->max_keys= param->keys;
1275
1258
if ((ha_rows) buffpek->mem_count > max_rows)
1276
1259
{ /* Don't write too many records */
1277
buffpek->mem_count= (uint) max_rows;
1260
buffpek->mem_count= (uint32_t) max_rows;
1278
1261
buffpek->count= 0; /* Don't read more */
1280
1263
max_rows-= buffpek->mem_count;
1283
if (my_b_write(to_file,(uchar*) buffpek->key,
1266
if (my_b_write(to_file,(unsigned char*) buffpek->key,
1284
1267
(rec_length*buffpek->mem_count)))
1286
1269
error= 1; goto err; /* purecov: inspected */
1308
1291
lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1309
1292
lastbuff->file_pos= to_start_filepos;
1311
delete_queue(&queue);
1313
1295
} /* merge_buffers */
1316
1298
/* Do a merge to output-file (save only positions) */
1318
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
1319
BUFFPEK *buffpek, uint maxbuffer,
1300
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1301
BUFFPEK *buffpek, uint32_t maxbuffer,
1320
1302
IO_CACHE *tempfile, IO_CACHE *outfile)
1322
1304
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1446
1426
The function first finds out what fields are used in the result set.
1447
1427
Then it calculates the length of the buffer to store the values of
1448
these fields together with the value of sort values.
1428
these fields together with the value of sort values.
1449
1429
If the calculated length is not greater than max_length_for_sort_data
1450
1430
the function allocates memory for an array of descriptors containing
1451
1431
layouts for the values of the non-sorted fields in the buffer and
1454
@param thd Current thread
1434
@param session Current thread
1455
1435
@param ptabfield Array of references to the table fields
1456
1436
@param sortlength Total length of sorted fields
1457
1437
@param[out] plength Total length of appended fields
1605
1584
if (tmp[0] & 128) /* Negative */
1606
1585
{ /* make complement */
1608
1587
for (i=0 ; i < sizeof(nr); i++)
1609
tmp[i]=tmp[i] ^ (uchar) 255;
1588
tmp[i]=tmp[i] ^ (unsigned char) 255;
1612
1591
{ /* Set high and move exponent one up */
1613
ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
1615
exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
1616
tmp[0]= (uchar) (exp_part >> 8);
1617
tmp[1]= (uchar) exp_part;
1592
uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1594
exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1595
tmp[0]= (unsigned char) (exp_part >> 8);
1596
tmp[1]= (unsigned char) exp_part;