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= cmax((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) cmin(records+1, 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)))
216
219
old_memavl=memavl;
217
220
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
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
MY_BITMAP *save_read_set, *save_write_set;
457
bitset<MAX_FIELDS> *save_read_set, *save_write_set;
452
460
error=quick_select=0;
482
490
save_read_set= sort_form->read_set;
483
491
save_write_set= sort_form->write_set;
484
492
/* Set up temporary column read map for columns used by sort */
485
bitmap_clear_all(&sort_form->tmp_set);
493
sort_form->tmp_set.reset();
486
494
/* Temporary set for register_used_fields and register_field_in_read_map */
487
495
sort_form->read_set= &sort_form->tmp_set;
488
496
register_used_fields(param);
489
497
if (select && select->cond)
490
498
select->cond->walk(&Item::register_field_in_read_map, 1,
499
(unsigned char*) sort_form);
492
500
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set);
617
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
628
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
618
629
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
620
631
size_t sort_length, rec_length;
624
635
sort_length= param->sort_length;
625
636
rec_length= param->rec_length;
626
my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
637
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
627
638
if (!my_b_inited(tempfile) &&
628
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
639
open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
630
641
goto err; /* purecov: inspected */
631
642
/* check we won't have more buffpeks than we can possibly keep in memory */
634
645
buffpek.file_pos= my_b_tell(tempfile);
635
646
if ((ha_rows) count > param->max_rows)
636
count=(uint) param->max_rows; /* purecov: inspected */
647
count=(uint32_t) param->max_rows; /* purecov: inspected */
637
648
buffpek.count=(ha_rows) count;
638
649
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
639
if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
650
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
641
if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
652
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
754
765
if (sort_field->need_strxnfrm)
756
767
char *from=(char*) res->ptr();
758
if ((uchar*) from == to)
769
if ((unsigned char*) from == to)
760
771
set_if_smaller(length,sort_field->length);
761
772
memcpy(param->tmp_buffer,from,length);
762
773
from=param->tmp_buffer;
764
775
tmp_length= my_strnxfrm(cs,to,sort_field->length,
765
(uchar*) from, length);
776
(unsigned char*) from, length);
766
777
assert(tmp_length == sort_field->length);
770
my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
781
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
771
782
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 */
803
to[7]= (unsigned char) value;
804
to[6]= (unsigned char) (value >> 8);
805
to[5]= (unsigned char) (value >> 16);
806
to[4]= (unsigned char) (value >> 24);
807
to[3]= (unsigned char) (value >> 32);
808
to[2]= (unsigned char) (value >> 40);
809
to[1]= (unsigned char) (value >> 48);
810
if (item->unsigned_flag) /* Fix sign */
811
to[0]= (unsigned char) (value >> 56);
813
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
815
816
case DECIMAL_RESULT:
959
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
960
FILESORT_INFO *table_sort)
960
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
961
filesort_info_st *table_sort)
962
uint offset,res_length;
963
uint32_t offset,res_length;
965
my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
966
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
966
967
res_length= param->res_length;
967
968
offset= param->rec_length-res_length;
968
969
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))))
970
count=(uint32_t) param->max_rows;
971
if (!(to= table_sort->record_pointers=
972
(unsigned char*) malloc(res_length*count)))
972
973
return(1); /* purecov: inspected */
973
for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
974
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
975
976
memcpy(to, *sort_keys+offset, res_length);
982
983
/** 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)
985
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
986
BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
988
989
IO_CACHE t_file2,*from_file,*to_file,*temp;
989
990
BUFFPEK *lastbuff;
991
992
if (*maxbuffer < MERGEBUFF2)
992
993
return(0); /* purecov: inspected */
993
994
if (flush_io_cache(t_file) ||
994
open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
995
open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
996
997
return(1); /* purecov: inspected */
1035
1036
Read data to buffer.
1038
(uint)-1 if something goes wrong
1039
(uint32_t)-1 if something goes wrong
1041
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1042
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1043
uint32_t rec_length)
1044
register uint count;
1045
register uint32_t count;
1047
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1048
if ((count=(uint32_t) cmin((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 */
1050
if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1051
return((uint32_t) -1); /* purecov: inspected */
1051
1052
buffpek->key=buffpek->base;
1052
1053
buffpek->file_pos+= length; /* New filepos */
1053
1054
buffpek->count-= count;
1057
1058
} /* 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)
1061
class compare_functor
1073
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
1074
for (uint i= 0; i < queue->elements; ++i)
1063
qsort2_cmp key_compare;
1064
void *key_compare_arg;
1066
compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
1067
: key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
1068
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;
1070
int val= key_compare(key_compare_arg,
1111
1095
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1112
IO_CACHE *to_file, uchar *sort_buffer,
1096
IO_CACHE *to_file, unsigned char *sort_buffer,
1113
1097
BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1117
uint rec_length,res_length,offset;
1101
uint32_t rec_length,res_length,offset;
1118
1102
size_t sort_length;
1119
1103
uint32_t maxcount;
1120
1104
ha_rows max_rows,org_max_rows;
1121
1105
my_off_t to_start_filepos;
1106
unsigned char *strpos;
1123
1107
BUFFPEK *buffpek;
1125
1108
qsort2_cmp cmp;
1126
1109
void *first_cmp_arg;
1127
volatile THD::killed_state *killed= ¤t_thd->killed;
1128
THD::killed_state not_killable;
1110
volatile Session::killed_state *killed= ¤t_session->killed;
1111
Session::killed_state not_killable;
1130
status_var_increment(current_thd->status_var.filesort_merge_passes);
1113
status_var_increment(current_session->status_var.filesort_merge_passes);
1131
1114
if (param->not_killable)
1133
1116
killed= ¬_killable;
1134
not_killable= THD::NOT_KILLED;
1117
not_killable= Session::NOT_KILLED;
1157
1140
cmp= get_ptr_compare(sort_length);
1158
1141
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 */
1143
priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor >
1144
queue(compare_functor(cmp, first_cmp_arg));
1163
1145
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1165
1147
buffpek->base= strpos;
1166
1148
buffpek->max_keys= maxcount;
1167
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1149
strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
1169
1151
if (error == -1)
1170
1152
goto err; /* purecov: inspected */
1171
1153
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
1172
queue_insert(&queue, (uchar*) buffpek);
1154
queue.push(buffpek);
1175
1157
if (param->unique_buff)
1178
1160
Called by Unique::get()
1179
1161
Copy the first argument to param->unique_buff for unique removal.
1180
1162
Store it also in 'to_file'.
1211
buffpek= (BUFFPEK*) queue_top(&queue);
1195
buffpek= queue.top();
1212
1196
if (cmp) // Remove duplicates
1214
1198
if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1215
(uchar**) &buffpek->key))
1199
(unsigned char**) &buffpek->key))
1216
1200
goto skip_duplicate;
1217
1201
memcpy(param->unique_buff, buffpek->key, rec_length);
1221
if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1205
if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
1223
1207
error=1; goto err; /* purecov: inspected */
1228
if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1212
if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
1230
1214
error=1; goto err; /* purecov: inspected */
1243
1227
if (!(error= (int) read_to_buffer(from_file,buffpek,
1246
VOID(queue_remove(&queue,0));
1247
reuse_freed_buff(&queue, buffpek, rec_length);
1248
1231
break; /* One buffer have been removed */
1250
1233
else if (error == -1)
1251
1234
goto err; /* purecov: inspected */
1253
queue_replaced(&queue); /* Top element has been replaced */
1236
/* Top element has been replaced */
1238
queue.push(buffpek);
1256
buffpek= (BUFFPEK*) queue_top(&queue);
1241
buffpek= queue.top();
1257
1242
buffpek->base= sort_buffer;
1258
1243
buffpek->max_keys= param->keys;
1275
1260
if ((ha_rows) buffpek->mem_count > max_rows)
1276
1261
{ /* Don't write too many records */
1277
buffpek->mem_count= (uint) max_rows;
1262
buffpek->mem_count= (uint32_t) max_rows;
1278
1263
buffpek->count= 0; /* Don't read more */
1280
1265
max_rows-= buffpek->mem_count;
1283
if (my_b_write(to_file,(uchar*) buffpek->key,
1268
if (my_b_write(to_file,(unsigned char*) buffpek->key,
1284
1269
(rec_length*buffpek->mem_count)))
1286
1271
error= 1; goto err; /* purecov: inspected */
1305
1290
!= -1 && error != 0);
1308
lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1293
lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
1309
1294
lastbuff->file_pos= to_start_filepos;
1311
delete_queue(&queue);
1313
1297
} /* merge_buffers */
1316
1300
/* Do a merge to output-file (save only positions) */
1318
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
1319
BUFFPEK *buffpek, uint maxbuffer,
1302
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1303
BUFFPEK *buffpek, uint32_t maxbuffer,
1320
1304
IO_CACHE *tempfile, IO_CACHE *outfile)
1322
1306
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1446
1428
The function first finds out what fields are used in the result set.
1447
1429
Then it calculates the length of the buffer to store the values of
1448
these fields together with the value of sort values.
1430
these fields together with the value of sort values.
1449
1431
If the calculated length is not greater than max_length_for_sort_data
1450
1432
the function allocates memory for an array of descriptors containing
1451
1433
layouts for the values of the non-sorted fields in the buffer and
1454
@param thd Current thread
1436
@param session Current thread
1455
1437
@param ptabfield Array of references to the table fields
1456
1438
@param sortlength Total length of sorted fields
1457
1439
@param[out] plength Total length of appended fields
1605
1587
if (tmp[0] & 128) /* Negative */
1606
1588
{ /* make complement */
1608
1590
for (i=0 ; i < sizeof(nr); i++)
1609
tmp[i]=tmp[i] ^ (uchar) 255;
1591
tmp[i]=tmp[i] ^ (unsigned char) 255;
1612
1594
{ /* 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;
1595
uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1597
exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1598
tmp[0]= (unsigned char) (exp_part >> 8);
1599
tmp[1]= (unsigned char) exp_part;