~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  Sorts a database
22
22
*/
23
23
 
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>
31
 
 
32
 
/* functions defined in this file */
33
 
 
34
 
static char **make_char_array(char **old_pos, register uint32_t fields,
35
 
                              uint32_t length, myf my_flag);
36
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
37
 
                                     unsigned char *buf);
 
24
#include "mysql_priv.h"
 
25
#include "sql_sort.h"
 
26
#include <drizzled/drizzled_error_messages.h>
 
27
 
 
28
/// How to write record_ref.
 
29
#define WRITE_REF(file,from) \
 
30
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
 
31
  return(1);
 
32
 
 
33
        /* functions defined in this file */
 
34
 
 
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,
 
38
                                     uchar *buf);
38
39
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
39
 
                             unsigned char * *sort_keys, IO_CACHE *buffer_file,
 
40
                             uchar * *sort_keys, IO_CACHE *buffer_file,
40
41
                             IO_CACHE *tempfile,IO_CACHE *indexfile);
41
 
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
42
 
                      uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
43
 
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
 
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);
44
45
static void register_used_fields(SORTPARAM *param);
45
 
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
 
46
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
46
47
                       BUFFPEK *buffpek,
47
 
                       uint32_t maxbuffer,IO_CACHE *tempfile,
 
48
                       uint maxbuffer,IO_CACHE *tempfile,
48
49
                       IO_CACHE *outfile);
49
 
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count, 
50
 
                       filesort_info_st *table_sort);
51
 
static uint32_t suffix_length(uint32_t string_length);
52
 
static uint32_t sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
50
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count, 
 
51
                       FILESORT_INFO *table_sort);
 
52
static uint suffix_length(ulong string_length);
 
53
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
53
54
                       bool *multi_byte_charset);
54
 
static SORT_ADDON_FIELD *get_addon_fields(Session *session, Field **ptabfield,
55
 
                                          uint32_t sortlength, uint32_t *plength);
 
55
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
 
56
                                          uint sortlength, uint *plength);
56
57
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
57
 
                                unsigned char *buff);
 
58
                                uchar *buff);
58
59
/**
59
60
  Sort a table.
60
61
  Creates a set of pointers that can be used to read the rows
67
68
  The result set is stored in table->io_cache or
68
69
  table->record_pointers.
69
70
 
70
 
  @param session           Current thread
 
71
  @param thd           Current thread
71
72
  @param table          Table to sort
72
73
  @param sortorder      How to sort the table
73
74
  @param s_length       Number of elements in sortorder
74
75
  @param select         condition to apply to the rows
75
76
  @param max_rows       Return only this many rows
76
77
  @param sort_positions Set to 1 if we want to force sorting by position
77
 
                        (Needed by UPDATE/INSERT or ALTER Table)
 
78
                        (Needed by UPDATE/INSERT or ALTER TABLE)
78
79
  @param examined_rows  Store number of examined rows here
79
80
 
80
81
  @todo
91
92
    examined_rows       will be set to number of examined rows
92
93
*/
93
94
 
94
 
ha_rows filesort(Session *session, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
 
95
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
95
96
                 SQL_SELECT *select, ha_rows max_rows,
96
97
                 bool sort_positions, ha_rows *examined_rows)
97
98
{
98
99
  int error;
99
 
  uint32_t memavl, min_sort_memory;
100
 
  uint32_t maxbuffer;
 
100
  ulong memavl, min_sort_memory;
 
101
  uint maxbuffer;
101
102
  BUFFPEK *buffpek;
102
103
  ha_rows records= HA_POS_ERROR;
103
 
  unsigned char **sort_keys= 0;
 
104
  uchar **sort_keys= 0;
104
105
  IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile; 
105
106
  SORTPARAM param;
106
107
  bool multi_byte_charset;
107
108
 
108
 
  filesort_info_st table_sort;
109
 
  TableList *tab= table->pos_in_table_list;
 
109
  FILESORT_INFO table_sort;
 
110
  TABLE_LIST *tab= table->pos_in_table_list;
110
111
  Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
111
112
 
112
 
  DRIZZLE_FILESORT_START();
 
113
  MYSQL_FILESORT_START();
113
114
 
114
115
  /*
115
116
   Release InnoDB's adaptive hash index latch (if holding) before
116
117
   running a sort.
117
118
  */
118
 
  ha_release_temporary_latches(session);
 
119
  ha_release_temporary_latches(thd);
119
120
 
120
121
  /* 
121
122
    Don't use table->sort in filesort as it is also used by 
122
123
    QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end 
123
124
    when index_merge select has finished with it.
124
125
  */
125
 
  memcpy(&table_sort, &table->sort, sizeof(filesort_info_st));
 
126
  memcpy(&table_sort, &table->sort, sizeof(FILESORT_INFO));
126
127
  table->sort.io_cache= NULL;
127
128
  
128
129
  outfile= table_sort.io_cache;
130
131
  my_b_clear(&buffpek_pointers);
131
132
  buffpek=0;
132
133
  error= 1;
133
 
  memset(&param, 0, sizeof(param));
134
 
  param.sort_length= sortlength(session, sortorder, s_length, &multi_byte_charset);
 
134
  memset((char*) &param, 0, sizeof(param));
 
135
  param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
135
136
  param.ref_length= table->file->ref_length;
136
137
  param.addon_field= 0;
137
138
  param.addon_length= 0;
141
142
      Get the descriptors of all fields whose values are appended 
142
143
      to sorted fields and get its total length in param.spack_length.
143
144
    */
144
 
    param.addon_field= get_addon_fields(session, table->field, 
 
145
    param.addon_field= get_addon_fields(thd, table->field, 
145
146
                                        param.sort_length,
146
147
                                        &param.addon_length);
147
148
  }
153
154
  if (param.addon_field)
154
155
  {
155
156
    param.res_length= param.addon_length;
156
 
    if (!(table_sort.addon_buf= (unsigned char *) my_malloc(param.addon_length,
 
157
    if (!(table_sort.addon_buf= (uchar *) my_malloc(param.addon_length,
157
158
                                                    MYF(MY_WME))))
158
159
      goto err;
159
160
  }
171
172
 
172
173
  if (select && select->quick)
173
174
  {
174
 
    status_var_increment(session->status_var.filesort_range_count);
 
175
    status_var_increment(thd->status_var.filesort_range_count);
175
176
  }
176
177
  else
177
178
  {
178
 
    status_var_increment(session->status_var.filesort_scan_count);
 
179
    status_var_increment(thd->status_var.filesort_scan_count);
179
180
  }
180
181
#ifdef CAN_TRUST_RANGE
181
182
  if (select && select->quick && select->quick->records > 0L)
182
183
  {
183
 
    records=cmin((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
 
184
    records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
184
185
                table->file->stats.records)+EXTRA_RECORDS;
185
186
    selected_records_file=0;
186
187
  }
201
202
      !(param.tmp_buffer= (char*) my_malloc(param.sort_length,MYF(MY_WME))))
202
203
    goto err;
203
204
 
204
 
  memavl= session->variables.sortbuff_size;
205
 
  min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
 
205
  memavl= thd->variables.sortbuff_size;
 
206
  min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
206
207
  while (memavl >= min_sort_memory)
207
208
  {
208
 
    uint32_t old_memavl;
209
 
    uint32_t keys= memavl/(param.rec_length+sizeof(char*));
210
 
    param.keys=(uint32_t) cmin(records+1, keys);
 
209
    ulong old_memavl;
 
210
    ulong keys= memavl/(param.rec_length+sizeof(char*));
 
211
    param.keys=(uint) min(records+1, keys);
211
212
    if ((table_sort.sort_keys=
212
 
         (unsigned char **) make_char_array((char **) table_sort.sort_keys,
 
213
         (uchar **) make_char_array((char **) table_sort.sort_keys,
213
214
                                    param.keys, param.rec_length, MYF(0))))
214
215
      break;
215
216
    old_memavl=memavl;
222
223
    my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
223
224
    goto err;
224
225
  }
225
 
  if (open_cached_file(&buffpek_pointers,drizzle_tmpdir,TEMP_PREFIX,
 
226
  if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
226
227
                       DISK_BUFFER_SIZE, MYF(MY_WME)))
227
228
    goto err;
228
229
 
233
234
                             &tempfile, selected_records_file)) ==
234
235
      HA_POS_ERROR)
235
236
    goto err;
236
 
  maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
 
237
  maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
237
238
 
238
239
  if (maxbuffer == 0)                   // The whole set is in memory
239
240
  {
240
 
    if (save_index(&param,sort_keys,(uint32_t) records, &table_sort))
 
241
    if (save_index(&param,sort_keys,(uint) records, &table_sort))
241
242
      goto err;
242
243
  }
243
244
  else
244
245
  {
245
246
    if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
246
247
    {
247
 
      if (table_sort.buffpek)
248
 
        free(table_sort.buffpek);
 
248
      x_free(table_sort.buffpek);
249
249
      table_sort.buffpek= 0;
250
250
    }
251
251
    if (!(table_sort.buffpek=
252
 
          (unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
 
252
          (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
253
253
                                 table_sort.buffpek)))
254
254
      goto err;
255
255
    buffpek= (BUFFPEK *) table_sort.buffpek;
257
257
    close_cached_file(&buffpek_pointers);
258
258
        /* Open cached file if it isn't open */
259
259
    if (! my_b_inited(outfile) &&
260
 
        open_cached_file(outfile,drizzle_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
 
260
        open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
261
261
                          MYF(MY_WME)))
262
262
      goto err;
263
263
    if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0))
270
270
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
271
271
                param.rec_length-1);
272
272
    maxbuffer--;                                // Offset from 0
273
 
    if (merge_many_buff(&param,(unsigned char*) sort_keys,buffpek,&maxbuffer,
 
273
    if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
274
274
                        &tempfile))
275
275
      goto err;
276
276
    if (flush_io_cache(&tempfile) ||
277
277
        reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
278
278
      goto err;
279
 
    if (merge_index(&param,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
 
279
    if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
280
280
                    outfile))
281
281
      goto err;
282
282
  }
286
286
 
287
287
 err:
288
288
  if (param.tmp_buffer)
289
 
    if (param.tmp_buffer)
290
 
      free(param.tmp_buffer);
 
289
    x_free(param.tmp_buffer);
291
290
  if (!subselect || !subselect->is_uncacheable())
292
291
  {
293
 
    if ((unsigned char*) sort_keys)
294
 
      free((unsigned char*) sort_keys);
 
292
    x_free((uchar*) sort_keys);
295
293
    table_sort.sort_keys= 0;
296
 
    if ((unsigned char*) buffpek)
297
 
      free((unsigned char*) buffpek);
 
294
    x_free((uchar*) buffpek);
298
295
    table_sort.buffpek= 0;
299
296
    table_sort.buffpek_len= 0;
300
297
  }
316
313
    my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
317
314
               MYF(ME_ERROR+ME_WAITTANG));
318
315
  else
319
 
    statistic_add(session->status_var.filesort_rows,
320
 
                  (uint32_t) records, &LOCK_status);
 
316
    statistic_add(thd->status_var.filesort_rows,
 
317
                  (ulong) records, &LOCK_status);
321
318
  *examined_rows= param.examined_rows;
322
 
  memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
323
 
  DRIZZLE_FILESORT_END();
 
319
  memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
 
320
  MYSQL_FILESORT_END();
324
321
  return(error ? HA_POS_ERROR : records);
325
322
} /* filesort */
326
323
 
327
324
 
328
 
void filesort_free_buffers(Table *table, bool full)
 
325
void filesort_free_buffers(TABLE *table, bool full)
329
326
{
330
327
  if (table->sort.record_pointers)
331
328
  {
332
 
    free((unsigned char*) table->sort.record_pointers);
 
329
    my_free((uchar*) table->sort.record_pointers,MYF(0));
333
330
    table->sort.record_pointers=0;
334
331
  }
335
332
  if (full)
336
333
  {
337
334
    if (table->sort.sort_keys )
338
335
    {
339
 
      if ((unsigned char*) table->sort.sort_keys)
340
 
        free((unsigned char*) table->sort.sort_keys);
 
336
      x_free((uchar*) table->sort.sort_keys);
341
337
      table->sort.sort_keys= 0;
342
338
    }
343
339
    if (table->sort.buffpek)
344
340
    {
345
 
      if ((unsigned char*) table->sort.buffpek)
346
 
        free((unsigned char*) table->sort.buffpek);
 
341
      x_free((uchar*) table->sort.buffpek);
347
342
      table->sort.buffpek= 0;
348
343
      table->sort.buffpek_len= 0;
349
344
    }
350
345
  }
351
346
  if (table->sort.addon_buf)
352
347
  {
353
 
    free((char *) table->sort.addon_buf);
354
 
    free((char *) table->sort.addon_field);
 
348
    my_free((char *) table->sort.addon_buf, MYF(0));
 
349
    my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
355
350
    table->sort.addon_buf=0;
356
351
    table->sort.addon_field=0;
357
352
  }
359
354
 
360
355
/** Make a array of string pointers. */
361
356
 
362
 
static char **make_char_array(char **old_pos, register uint32_t fields,
363
 
                              uint32_t length, myf my_flag)
 
357
static char **make_char_array(char **old_pos, register uint fields,
 
358
                              uint length, myf my_flag)
364
359
{
365
360
  register char **pos;
366
361
  char *char_pos;
367
362
 
368
363
  if (old_pos ||
369
 
      (old_pos= (char**) my_malloc((uint32_t) fields*(length+sizeof(char*)),
 
364
      (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
370
365
                                   my_flag)))
371
366
  {
372
367
    pos=old_pos; char_pos=((char*) (pos+fields)) -length;
379
374
 
380
375
/** Read 'count' number of buffer pointers into memory. */
381
376
 
382
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
383
 
                                     unsigned char *buf)
 
377
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
 
378
                                     uchar *buf)
384
379
{
385
 
  uint32_t length= sizeof(BUFFPEK)*count;
386
 
  unsigned char *tmp= buf;
 
380
  ulong length= sizeof(BUFFPEK)*count;
 
381
  uchar *tmp= buf;
387
382
  if (count > UINT_MAX/sizeof(BUFFPEK))
388
383
    return 0; /* sizeof(BUFFPEK)*count will overflow */
389
384
  if (!tmp)
390
 
    tmp= (unsigned char *)my_malloc(length, MYF(MY_WME));
 
385
    tmp= (uchar *)my_malloc(length, MYF(MY_WME));
391
386
  if (tmp)
392
387
  {
393
388
    if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
394
 
        my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
 
389
        my_b_read(buffpek_pointers, (uchar*) tmp, length))
395
390
    {
396
 
      free((char*) tmp);
 
391
      my_free((char*) tmp, MYF(0));
397
392
      tmp=0;
398
393
    }
399
394
  }
439
434
*/
440
435
 
441
436
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
442
 
                             unsigned char **sort_keys,
 
437
                             uchar **sort_keys,
443
438
                             IO_CACHE *buffpek_pointers,
444
439
                             IO_CACHE *tempfile, IO_CACHE *indexfile)
445
440
{
446
441
  int error,flag,quick_select;
447
 
  uint32_t idx,indexpos,ref_length;
448
 
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
 
442
  uint idx,indexpos,ref_length;
 
443
  uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
449
444
  my_off_t record;
450
 
  Table *sort_form;
451
 
  Session *session= current_session;
452
 
  volatile Session::killed_state *killed= &session->killed;
 
445
  TABLE *sort_form;
 
446
  THD *thd= current_thd;
 
447
  volatile THD::killed_state *killed= &thd->killed;
453
448
  handler *file;
454
449
  MY_BITMAP *save_read_set, *save_write_set;
455
450
 
468
463
  next_pos=ref_pos;
469
464
  if (! indexfile && ! quick_select)
470
465
  {
471
 
    next_pos=(unsigned char*) 0;                        /* Find records in sequence */
 
466
    next_pos=(uchar*) 0;                        /* Find records in sequence */
472
467
    file->ha_rnd_init(1);
473
468
    file->extra_opt(HA_EXTRA_CACHE,
474
 
                    current_session->variables.read_buff_size);
 
469
                    current_thd->variables.read_buff_size);
475
470
  }
476
471
 
477
472
  READ_RECORD read_record_info;
479
474
  {
480
475
    if (select->quick->reset())
481
476
      return(HA_POS_ERROR);
482
 
    init_read_record(&read_record_info, current_session, select->quick->head,
 
477
    init_read_record(&read_record_info, current_thd, select->quick->head,
483
478
                     select, 1, 1);
484
479
  }
485
480
 
493
488
  register_used_fields(param);
494
489
  if (select && select->cond)
495
490
    select->cond->walk(&Item::register_field_in_read_map, 1,
496
 
                       (unsigned char*) sort_form);
 
491
                       (uchar*) sort_form);
497
492
  sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set);
498
493
 
499
494
  for (;;)
511
506
    {
512
507
      if (indexfile)
513
508
      {
514
 
        if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length)) /* purecov: deadcode */
 
509
        if (my_b_read(indexfile,(uchar*) ref_pos,ref_length)) /* purecov: deadcode */
515
510
        {
516
511
          error= my_errno ? my_errno : -1;              /* Abort */
517
512
          break;
521
516
      else
522
517
      {
523
518
        error=file->rnd_next(sort_form->record[0]);
524
 
        if (!error)
525
 
          update_virtual_fields_marked_for_write(sort_form);
526
 
 
527
519
        if (!flag)
528
520
        {
529
521
          my_store_ptr(ref_pos,ref_length,record); // Position to row
561
553
    else
562
554
      file->unlock_row();
563
555
    /* It does not make sense to read more keys in case of a fatal error */
564
 
    if (session->is_error())
 
556
    if (thd->is_error())
565
557
      break;
566
558
  }
567
559
  if (quick_select)
579
571
      file->ha_rnd_end();
580
572
  }
581
573
 
582
 
  if (session->is_error())
 
574
  if (thd->is_error())
583
575
    return(HA_POS_ERROR);
584
576
  
585
577
  /* Signal we should use orignal column read and write maps */
622
614
*/
623
615
 
624
616
static int
625
 
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
 
617
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
626
618
           IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
627
619
{
628
620
  size_t sort_length, rec_length;
629
 
  unsigned char **end;
 
621
  uchar **end;
630
622
  BUFFPEK buffpek;
631
623
 
632
624
  sort_length= param->sort_length;
633
625
  rec_length= param->rec_length;
634
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
 
626
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
635
627
  if (!my_b_inited(tempfile) &&
636
 
      open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
 
628
      open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
637
629
                       MYF(MY_WME)))
638
630
    goto err;                                   /* purecov: inspected */
639
631
  /* check we won't have more buffpeks than we can possibly keep in memory */
641
633
    goto err;
642
634
  buffpek.file_pos= my_b_tell(tempfile);
643
635
  if ((ha_rows) count > param->max_rows)
644
 
    count=(uint32_t) param->max_rows;               /* purecov: inspected */
 
636
    count=(uint) param->max_rows;               /* purecov: inspected */
645
637
  buffpek.count=(ha_rows) count;
646
638
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
647
 
    if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
 
639
    if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
648
640
      goto err;
649
 
  if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
 
641
  if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
650
642
    goto err;
651
643
  return(0);
652
644
 
659
651
  Store length as suffix in high-byte-first order.
660
652
*/
661
653
 
662
 
static inline void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
 
654
static inline void store_length(uchar *to, uint length, uint pack_length)
663
655
{
664
656
  switch (pack_length) {
665
657
  case 1:
666
 
    *to= (unsigned char) length;
 
658
    *to= (uchar) length;
667
659
    break;
668
660
  case 2:
669
661
    mi_int2store(to, length);
681
673
/** Make a sort-key from record. */
682
674
 
683
675
static void make_sortkey(register SORTPARAM *param,
684
 
                         register unsigned char *to, unsigned char *ref_pos)
 
676
                         register uchar *to, uchar *ref_pos)
685
677
{
686
678
  register Field *field;
687
679
  register SORT_FIELD *sort_field;
688
 
  register uint32_t length;
 
680
  register uint length;
689
681
 
690
682
  for (sort_field=param->local_sortorder ;
691
683
       sort_field != param->end ;
701
693
          if (sort_field->reverse)
702
694
            memset(to, 255, sort_field->length+1);
703
695
          else
704
 
            memset(to, 0, sort_field->length+1);
 
696
            memset((char*) to, 0, sort_field->length+1);
705
697
          to+= sort_field->length+1;
706
698
          continue;
707
699
        }
717
709
      switch (sort_field->result_type) {
718
710
      case STRING_RESULT:
719
711
      {
720
 
        const CHARSET_INFO * const cs=item->collation.collation;
 
712
        CHARSET_INFO *cs=item->collation.collation;
721
713
        char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
722
714
        int diff;
723
 
        uint32_t sort_field_length;
 
715
        uint sort_field_length;
724
716
 
725
717
        if (maybe_null)
726
718
          *to++=1;
730
722
        if (!res)
731
723
        {
732
724
          if (maybe_null)
733
 
            memset(to-1, 0, sort_field->length+1);
 
725
            memset((char*) to-1, 0, sort_field->length+1);
734
726
          else
735
727
          {
736
728
            /* purecov: begin deadcode */
740
732
              This code is here mainly to avoid a hard crash in this case.
741
733
            */
742
734
            assert(0);
743
 
            memset(to, 0, sort_field->length);  // Avoid crash
 
735
            memset((char*) to, 0, sort_field->length);  // Avoid crash
744
736
            /* purecov: end */
745
737
          }
746
738
          break;
762
754
        if (sort_field->need_strxnfrm)
763
755
        {
764
756
          char *from=(char*) res->ptr();
765
 
          uint32_t tmp_length;
766
 
          if ((unsigned char*) from == to)
 
757
          uint tmp_length;
 
758
          if ((uchar*) from == to)
767
759
          {
768
760
            set_if_smaller(length,sort_field->length);
769
761
            memcpy(param->tmp_buffer,from,length);
770
762
            from=param->tmp_buffer;
771
763
          }
772
764
          tmp_length= my_strnxfrm(cs,to,sort_field->length,
773
 
                                  (unsigned char*) from, length);
 
765
                                  (uchar*) from, length);
774
766
          assert(tmp_length == sort_field->length);
775
767
        }
776
768
        else
777
769
        {
778
 
          my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
 
770
          my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
779
771
          cs->cset->fill(cs, (char *)to+length,diff,fill_char);
780
772
        }
781
773
        break;
789
781
            if (item->null_value)
790
782
            {
791
783
              if (maybe_null)
792
 
                memset(to-1, 0, sort_field->length+1);
 
784
                memset((char*) to-1, 0, sort_field->length+1);
793
785
              else
794
786
              {
795
 
                memset(to, 0, sort_field->length);
 
787
                memset((char*) to, 0, sort_field->length);
796
788
              }
797
789
              break;
798
790
            }
799
791
          }
800
 
          to[7]= (unsigned char) value;
801
 
          to[6]= (unsigned char) (value >> 8);
802
 
          to[5]= (unsigned char) (value >> 16);
803
 
          to[4]= (unsigned char) (value >> 24);
804
 
          to[3]= (unsigned char) (value >> 32);
805
 
          to[2]= (unsigned char) (value >> 40);
806
 
          to[1]= (unsigned char) (value >> 48);
807
 
          if (item->unsigned_flag)                    /* Fix sign */
808
 
            to[0]= (unsigned char) (value >> 56);
809
 
          else
810
 
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
 
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);
 
802
          else
 
803
            to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
 
804
#else
 
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);
 
810
          else
 
811
            to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
 
812
#endif
811
813
          break;
812
814
        }
813
815
      case DECIMAL_RESULT:
817
819
          {
818
820
            if (item->null_value)
819
821
            { 
820
 
              memset(to, 0, sort_field->length+1);
 
822
              memset((char*)to, 0, sort_field->length+1);
821
823
              to++;
822
824
              break;
823
825
            }
835
837
          {
836
838
            if (item->null_value)
837
839
            {
838
 
              memset(to, 0, sort_field->length+1);
 
840
              memset((char*) to, 0, sort_field->length+1);
839
841
              to++;
840
842
              break;
841
843
            }
842
844
            *to++=1;
843
845
          }
844
 
          change_double_for_sort(value,(unsigned char*) to);
 
846
          change_double_for_sort(value,(uchar*) to);
845
847
          break;
846
848
        }
847
849
      case ROW_RESULT:
858
860
      length=sort_field->length;
859
861
      while (length--)
860
862
      {
861
 
        *to = (unsigned char) (~ *to);
 
863
        *to = (uchar) (~ *to);
862
864
        to++;
863
865
      }
864
866
    }
875
877
      the same for all records.
876
878
    */
877
879
    SORT_ADDON_FIELD *addonf= param->addon_field;
878
 
    unsigned char *nulls= to;
 
880
    uchar *nulls= to;
879
881
    assert(addonf != 0);
880
 
    memset(nulls, 0, addonf->offset);
 
882
    memset((char *) nulls, 0, addonf->offset);
881
883
    to+= addonf->offset;
882
884
    for ( ; (field= addonf->field) ; addonf++)
883
885
    {
891
893
      else
892
894
      {
893
895
#ifdef HAVE_purify
894
 
        unsigned char *end= field->pack(to, field->ptr);
895
 
        uint32_t length= (uint32_t) ((to + addonf->length) - end);
 
896
        uchar *end= field->pack(to, field->ptr);
 
897
        uint length= (uint) ((to + addonf->length) - end);
896
898
        assert((int) length >= 0);
897
899
        if (length)
898
900
          memset(end, 0, length);
906
908
  else
907
909
  {
908
910
    /* Save filepos last */
909
 
    memcpy(to, ref_pos, (size_t) param->ref_length);
 
911
    memcpy((uchar*) to, ref_pos, (size_t) param->ref_length);
910
912
  }
911
913
  return;
912
914
}
919
921
static void register_used_fields(SORTPARAM *param)
920
922
{
921
923
  register SORT_FIELD *sort_field;
922
 
  Table *table=param->sort_form;
 
924
  TABLE *table=param->sort_form;
923
925
  MY_BITMAP *bitmap= table->read_set;
924
926
 
925
927
  for (sort_field= param->local_sortorder ;
935
937
    else
936
938
    {                                           // Item
937
939
      sort_field->item->walk(&Item::register_field_in_read_map, 1,
938
 
                             (unsigned char *) table);
 
940
                             (uchar *) table);
939
941
    }
940
942
  }
941
943
 
954
956
}
955
957
 
956
958
 
957
 
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count, 
958
 
                       filesort_info_st *table_sort)
 
959
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count, 
 
960
                       FILESORT_INFO *table_sort)
959
961
{
960
 
  uint32_t offset,res_length;
961
 
  unsigned char *to;
 
962
  uint offset,res_length;
 
963
  uchar *to;
962
964
 
963
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
 
965
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
964
966
  res_length= param->res_length;
965
967
  offset= param->rec_length-res_length;
966
968
  if ((ha_rows) count > param->max_rows)
967
 
    count=(uint32_t) param->max_rows;
 
969
    count=(uint) param->max_rows;
968
970
  if (!(to= table_sort->record_pointers= 
969
 
        (unsigned char*) my_malloc(res_length*count, MYF(MY_WME))))
 
971
        (uchar*) my_malloc(res_length*count, MYF(MY_WME))))
970
972
    return(1);                 /* purecov: inspected */
971
 
  for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
 
973
  for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
972
974
  {
973
975
    memcpy(to, *sort_keys+offset, res_length);
974
976
    to+= res_length;
979
981
 
980
982
/** Merge buffers to make < MERGEBUFF2 buffers. */
981
983
 
982
 
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
983
 
                    BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
 
984
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
 
985
                    BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
984
986
{
985
 
  register uint32_t i;
 
987
  register uint i;
986
988
  IO_CACHE t_file2,*from_file,*to_file,*temp;
987
989
  BUFFPEK *lastbuff;
988
990
 
989
991
  if (*maxbuffer < MERGEBUFF2)
990
992
    return(0);                          /* purecov: inspected */
991
993
  if (flush_io_cache(t_file) ||
992
 
      open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
 
994
      open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
993
995
                        MYF(MY_WME)))
994
996
    return(1);                          /* purecov: inspected */
995
997
 
1015
1017
    temp=from_file; from_file=to_file; to_file=temp;
1016
1018
    setup_io_cache(from_file);
1017
1019
    setup_io_cache(to_file);
1018
 
    *maxbuffer= (uint32_t) (lastbuff-buffpek)-1;
 
1020
    *maxbuffer= (uint) (lastbuff-buffpek)-1;
1019
1021
  }
1020
1022
cleanup:
1021
1023
  close_cached_file(to_file);                   // This holds old result
1033
1035
  Read data to buffer.
1034
1036
 
1035
1037
  @retval
1036
 
    (uint32_t)-1 if something goes wrong
 
1038
    (uint)-1 if something goes wrong
1037
1039
*/
1038
1040
 
1039
 
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1040
 
                    uint32_t rec_length)
 
1041
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
 
1042
                    uint rec_length)
1041
1043
{
1042
 
  register uint32_t count;
1043
 
  uint32_t length;
 
1044
  register uint count;
 
1045
  uint length;
1044
1046
 
1045
 
  if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
 
1047
  if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1046
1048
  {
1047
 
    if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1048
 
      return((uint32_t) -1);                    /* purecov: inspected */
 
1049
    if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
 
1050
      return((uint) -1);                        /* purecov: inspected */
1049
1051
    buffpek->key=buffpek->base;
1050
1052
    buffpek->file_pos+= length;                 /* New filepos */
1051
1053
    buffpek->count-=    count;
1066
1068
  @param[in] key_length key length
1067
1069
*/
1068
1070
 
1069
 
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint32_t key_length)
 
1071
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1070
1072
{
1071
 
  unsigned char *reuse_end= reuse->base + reuse->max_keys * key_length;
1072
 
  for (uint32_t i= 0; i < queue->elements; ++i)
 
1073
  uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
 
1074
  for (uint i= 0; i < queue->elements; ++i)
1073
1075
  {
1074
1076
    BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1075
1077
    if (bp->base + bp->max_keys * key_length == reuse->base)
1107
1109
*/
1108
1110
 
1109
1111
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1110
 
                  IO_CACHE *to_file, unsigned char *sort_buffer,
 
1112
                  IO_CACHE *to_file, uchar *sort_buffer,
1111
1113
                  BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1112
1114
                  int flag)
1113
1115
{
1114
1116
  int error;
1115
 
  uint32_t rec_length,res_length,offset;
 
1117
  uint rec_length,res_length,offset;
1116
1118
  size_t sort_length;
1117
 
  uint32_t maxcount;
 
1119
  ulong maxcount;
1118
1120
  ha_rows max_rows,org_max_rows;
1119
1121
  my_off_t to_start_filepos;
1120
 
  unsigned char *strpos;
 
1122
  uchar *strpos;
1121
1123
  BUFFPEK *buffpek;
1122
1124
  QUEUE queue;
1123
1125
  qsort2_cmp cmp;
1124
1126
  void *first_cmp_arg;
1125
 
  volatile Session::killed_state *killed= &current_session->killed;
1126
 
  Session::killed_state not_killable;
 
1127
  volatile THD::killed_state *killed= &current_thd->killed;
 
1128
  THD::killed_state not_killable;
1127
1129
 
1128
 
  status_var_increment(current_session->status_var.filesort_merge_passes);
 
1130
  status_var_increment(current_thd->status_var.filesort_merge_passes);
1129
1131
  if (param->not_killable)
1130
1132
  {
1131
1133
    killed= &not_killable;
1132
 
    not_killable= Session::NOT_KILLED;
 
1134
    not_killable= THD::NOT_KILLED;
1133
1135
  }
1134
1136
 
1135
1137
  error=0;
1137
1139
  res_length= param->res_length;
1138
1140
  sort_length= param->sort_length;
1139
1141
  offset= rec_length-res_length;
1140
 
  maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
 
1142
  maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
1141
1143
  to_start_filepos= my_b_tell(to_file);
1142
 
  strpos= (unsigned char*) sort_buffer;
 
1144
  strpos= (uchar*) sort_buffer;
1143
1145
  org_max_rows=max_rows= param->max_rows;
1144
1146
 
1145
1147
  /* The following will fire if there is not enough space in sort_buffer */
1155
1157
    cmp= get_ptr_compare(sort_length);
1156
1158
    first_cmp_arg= (void*) &sort_length;
1157
1159
  }
1158
 
  if (init_queue(&queue, (uint32_t) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
 
1160
  if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1159
1161
                 (queue_compare) cmp, first_cmp_arg))
1160
1162
    return(1);                                /* purecov: inspected */
1161
1163
  for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1162
1164
  {
1163
1165
    buffpek->base= strpos;
1164
1166
    buffpek->max_keys= maxcount;
1165
 
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
 
1167
    strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1166
1168
                                                                         rec_length));
1167
1169
    if (error == -1)
1168
1170
      goto err;                                 /* purecov: inspected */
1169
1171
    buffpek->max_keys= buffpek->mem_count;      // If less data in buffers than expected
1170
 
    queue_insert(&queue, (unsigned char*) buffpek);
 
1172
    queue_insert(&queue, (uchar*) buffpek);
1171
1173
  }
1172
1174
 
1173
1175
  if (param->unique_buff)
1182
1184
    */
1183
1185
    buffpek= (BUFFPEK*) queue_top(&queue);
1184
1186
    memcpy(param->unique_buff, buffpek->key, rec_length);
1185
 
    if (my_b_write(to_file, (unsigned char*) buffpek->key, rec_length))
 
1187
    if (my_b_write(to_file, (uchar*) buffpek->key, rec_length))
1186
1188
    {
1187
1189
      error=1; goto err;                        /* purecov: inspected */
1188
1190
    }
1210
1212
      if (cmp)                                        // Remove duplicates
1211
1213
      {
1212
1214
        if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1213
 
                    (unsigned char**) &buffpek->key))
 
1215
                    (uchar**) &buffpek->key))
1214
1216
              goto skip_duplicate;
1215
 
            memcpy(param->unique_buff, buffpek->key, rec_length);
 
1217
            memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
1216
1218
      }
1217
1219
      if (flag == 0)
1218
1220
      {
1219
 
        if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
 
1221
        if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1220
1222
        {
1221
1223
          error=1; goto err;                        /* purecov: inspected */
1222
1224
        }
1223
1225
      }
1224
1226
      else
1225
1227
      {
1226
 
        if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
 
1228
        if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1227
1229
        {
1228
1230
          error=1; goto err;                        /* purecov: inspected */
1229
1231
        }
1241
1243
        if (!(error= (int) read_to_buffer(from_file,buffpek,
1242
1244
                                          rec_length)))
1243
1245
        {
1244
 
          queue_remove(&queue,0);
 
1246
          VOID(queue_remove(&queue,0));
1245
1247
          reuse_freed_buff(&queue, buffpek, rec_length);
1246
1248
          break;                        /* One buffer have been removed */
1247
1249
        }
1261
1263
  */
1262
1264
  if (cmp)
1263
1265
  {
1264
 
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (unsigned char**) &buffpek->key))
 
1266
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
1265
1267
    {
1266
1268
      buffpek->key+= rec_length;         // Remove duplicate
1267
1269
      --buffpek->mem_count;
1272
1274
  {
1273
1275
    if ((ha_rows) buffpek->mem_count > max_rows)
1274
1276
    {                                        /* Don't write too many records */
1275
 
      buffpek->mem_count= (uint32_t) max_rows;
 
1277
      buffpek->mem_count= (uint) max_rows;
1276
1278
      buffpek->count= 0;                        /* Don't read more */
1277
1279
    }
1278
1280
    max_rows-= buffpek->mem_count;
1279
1281
    if (flag == 0)
1280
1282
    {
1281
 
      if (my_b_write(to_file,(unsigned char*) buffpek->key,
 
1283
      if (my_b_write(to_file,(uchar*) buffpek->key,
1282
1284
                     (rec_length*buffpek->mem_count)))
1283
1285
      {
1284
1286
        error= 1; goto err;                        /* purecov: inspected */
1286
1288
    }
1287
1289
    else
1288
1290
    {
1289
 
      register unsigned char *end;
 
1291
      register uchar *end;
1290
1292
      strpos= buffpek->key+offset;
1291
1293
      for (end= strpos+buffpek->mem_count*rec_length ;
1292
1294
           strpos != end ;
1293
1295
           strpos+= rec_length)
1294
1296
      {     
1295
 
        if (my_b_write(to_file, (unsigned char *) strpos, res_length))
 
1297
        if (my_b_write(to_file, (uchar *) strpos, res_length))
1296
1298
        {
1297
1299
          error=1; goto err;                        
1298
1300
        }
1303
1305
         != -1 && error != 0);
1304
1306
 
1305
1307
end:
1306
 
  lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
 
1308
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1307
1309
  lastbuff->file_pos= to_start_filepos;
1308
1310
err:
1309
1311
  delete_queue(&queue);
1313
1315
 
1314
1316
        /* Do a merge to output-file (save only positions) */
1315
1317
 
1316
 
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1317
 
                       BUFFPEK *buffpek, uint32_t maxbuffer,
 
1318
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
 
1319
                       BUFFPEK *buffpek, uint maxbuffer,
1318
1320
                       IO_CACHE *tempfile, IO_CACHE *outfile)
1319
1321
{
1320
1322
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1324
1326
} /* merge_index */
1325
1327
 
1326
1328
 
1327
 
static uint32_t suffix_length(uint32_t string_length)
 
1329
static uint suffix_length(ulong string_length)
1328
1330
{
1329
1331
  if (string_length < 256)
1330
1332
    return 1;
1340
1342
/**
1341
1343
  Calculate length of sort key.
1342
1344
 
1343
 
  @param session                          Thread handler
 
1345
  @param thd                      Thread handler
1344
1346
  @param sortorder                Order of items to sort
1345
1347
  @param s_length                 Number of items to sort
1346
1348
  @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
1355
1357
    Total length of sort buffer in bytes
1356
1358
*/
1357
1359
 
1358
 
static uint32_t
1359
 
sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
1360
static uint
 
1361
sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
1360
1362
           bool *multi_byte_charset)
1361
1363
{
1362
 
  register uint32_t length;
1363
 
  const CHARSET_INFO *cs;
 
1364
  register uint length;
 
1365
  CHARSET_INFO *cs;
1364
1366
  *multi_byte_charset= 0;
1365
1367
 
1366
1368
  length=0;
1390
1392
      switch (sortorder->result_type) {
1391
1393
      case STRING_RESULT:
1392
1394
        sortorder->length=sortorder->item->max_length;
1393
 
        set_if_smaller(sortorder->length, session->variables.max_sort_length);
 
1395
        set_if_smaller(sortorder->length, thd->variables.max_sort_length);
1394
1396
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1395
1397
        { 
1396
1398
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1405
1407
        }
1406
1408
        break;
1407
1409
      case INT_RESULT:
 
1410
#if SIZEOF_LONG_LONG > 4
1408
1411
        sortorder->length=8;                    // Size of intern int64_t
 
1412
#else
 
1413
        sortorder->length=4;
 
1414
#endif
1409
1415
        break;
1410
1416
      case DECIMAL_RESULT:
1411
1417
        sortorder->length=
1425
1431
      if (sortorder->item->maybe_null)
1426
1432
        length++;                               // Place for NULL marker
1427
1433
    }
1428
 
    set_if_smaller(sortorder->length, session->variables.max_sort_length);
 
1434
    set_if_smaller(sortorder->length, thd->variables.max_sort_length);
1429
1435
    length+=sortorder->length;
1430
1436
  }
1431
1437
  sortorder->field= (Field*) 0;                 // end marker
1445
1451
  layouts for the values of the non-sorted fields in the buffer and
1446
1452
  fills them.
1447
1453
 
1448
 
  @param session                 Current thread
 
1454
  @param thd                 Current thread
1449
1455
  @param ptabfield           Array of references to the table fields
1450
1456
  @param sortlength          Total length of sorted fields
1451
1457
  @param[out] plength        Total length of appended fields
1461
1467
*/
1462
1468
 
1463
1469
static SORT_ADDON_FIELD *
1464
 
get_addon_fields(Session *session, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
 
1470
get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
1465
1471
{
1466
1472
  Field **pfield;
1467
1473
  Field *field;
1468
1474
  SORT_ADDON_FIELD *addonf;
1469
 
  uint32_t length= 0;
1470
 
  uint32_t fields= 0;
1471
 
  uint32_t null_fields= 0;
 
1475
  uint length= 0;
 
1476
  uint fields= 0;
 
1477
  uint null_fields= 0;
1472
1478
  MY_BITMAP *read_set= (*ptabfield)->table->read_set;
1473
1479
 
1474
1480
  /*
1497
1503
    return 0;
1498
1504
  length+= (null_fields+7)/8;
1499
1505
 
1500
 
  if (length+sortlength > session->variables.max_length_for_sort_data ||
 
1506
  if (length+sortlength > thd->variables.max_length_for_sort_data ||
1501
1507
      !(addonf= (SORT_ADDON_FIELD *) my_malloc(sizeof(SORT_ADDON_FIELD)*
1502
1508
                                               (fields+1), MYF(MY_WME))))
1503
1509
    return 0;
1548
1554
*/
1549
1555
 
1550
1556
static void 
1551
 
unpack_addon_fields(struct st_sort_addon_field *addon_field, unsigned char *buff)
 
1557
unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff)
1552
1558
{
1553
1559
  Field *field;
1554
1560
  SORT_ADDON_FIELD *addonf= addon_field;
1572
1578
 
1573
1579
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1574
1580
 
1575
 
void change_double_for_sort(double nr,unsigned char *to)
 
1581
void change_double_for_sort(double nr,uchar *to)
1576
1582
{
1577
 
  unsigned char *tmp=(unsigned char*) to;
 
1583
  uchar *tmp=(uchar*) to;
1578
1584
  if (nr == 0.0)
1579
1585
  {                                             /* Change to zero string */
1580
 
    tmp[0]=(unsigned char) 128;
1581
 
    memset(tmp+1, 0, sizeof(nr)-1);
 
1586
    tmp[0]=(uchar) 128;
 
1587
    memset((char*) tmp+1, 0, sizeof(nr)-1);
1582
1588
  }
1583
1589
  else
1584
1590
  {
1586
1592
    memcpy(tmp,&nr,sizeof(nr));
1587
1593
#else
1588
1594
    {
1589
 
      unsigned char *ptr= (unsigned char*) &nr;
 
1595
      uchar *ptr= (uchar*) &nr;
1590
1596
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1591
1597
      tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1592
1598
      tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1598
1604
#endif
1599
1605
    if (tmp[0] & 128)                           /* Negative */
1600
1606
    {                                           /* make complement */
1601
 
      uint32_t i;
 
1607
      uint i;
1602
1608
      for (i=0 ; i < sizeof(nr); i++)
1603
 
        tmp[i]=tmp[i] ^ (unsigned char) 255;
 
1609
        tmp[i]=tmp[i] ^ (uchar) 255;
1604
1610
    }
1605
1611
    else
1606
1612
    {                                   /* Set high and move exponent one up */
1607
 
      uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1608
 
                       (uint16_t) 32768);
1609
 
      exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1610
 
      tmp[0]= (unsigned char) (exp_part >> 8);
1611
 
      tmp[1]= (unsigned char) exp_part;
 
1613
      ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
 
1614
                       (ushort) 32768);
 
1615
      exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
 
1616
      tmp[0]= (uchar) (exp_part >> 8);
 
1617
      tmp[1]= (uchar) exp_part;
1612
1618
    }
1613
1619
  }
1614
1620
}