~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/filesort.cc

  • Committer: Monty Taylor
  • Date: 2008-07-05 18:10:38 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: monty@inaugust.com-20080705181038-0ih0nnamu5qrut0y
Fixed prototypes. Cleaned define a little bit.

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>
 
24
#include "mysql_priv.h"
 
25
#ifdef HAVE_STDDEF_H
 
26
#include <stddef.h>                     /* for macro offsetof */
 
27
#endif
 
28
#include <m_ctype.h>
25
29
#include "sql_sort.h"
26
 
#include <drizzled/drizzled_error_messages.h>
 
30
 
 
31
/// How to write record_ref.
 
32
#define WRITE_REF(file,from) \
 
33
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
 
34
  DBUG_RETURN(1);
27
35
 
28
36
        /* functions defined in this file */
29
37
 
30
 
static char **make_char_array(char **old_pos, register uint32_t fields,
31
 
                              uint32_t length, myf my_flag);
32
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
33
 
                                     unsigned char *buf);
 
38
static char **make_char_array(char **old_pos, register uint fields,
 
39
                              uint length, myf my_flag);
 
40
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
 
41
                                     uchar *buf);
34
42
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
35
 
                             unsigned char * *sort_keys, IO_CACHE *buffer_file,
 
43
                             uchar * *sort_keys, IO_CACHE *buffer_file,
36
44
                             IO_CACHE *tempfile,IO_CACHE *indexfile);
37
 
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
38
 
                      uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
39
 
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
 
45
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
 
46
                      uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
 
47
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
40
48
static void register_used_fields(SORTPARAM *param);
41
 
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
 
49
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
42
50
                       BUFFPEK *buffpek,
43
 
                       uint32_t maxbuffer,IO_CACHE *tempfile,
 
51
                       uint maxbuffer,IO_CACHE *tempfile,
44
52
                       IO_CACHE *outfile);
45
 
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count, 
46
 
                       filesort_info_st *table_sort);
47
 
static uint32_t suffix_length(uint32_t string_length);
48
 
static uint32_t sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
 
53
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count, 
 
54
                       FILESORT_INFO *table_sort);
 
55
static uint suffix_length(ulong string_length);
 
56
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
49
57
                       bool *multi_byte_charset);
50
58
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
51
 
                                          uint32_t sortlength, uint32_t *plength);
 
59
                                          uint sortlength, uint *plength);
52
60
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
53
 
                                unsigned char *buff);
 
61
                                uchar *buff);
54
62
/**
55
63
  Sort a table.
56
64
  Creates a set of pointers that can be used to read the rows
70
78
  @param select         condition to apply to the rows
71
79
  @param max_rows       Return only this many rows
72
80
  @param sort_positions Set to 1 if we want to force sorting by position
73
 
                        (Needed by UPDATE/INSERT or ALTER Table)
 
81
                        (Needed by UPDATE/INSERT or ALTER TABLE)
74
82
  @param examined_rows  Store number of examined rows here
75
83
 
76
84
  @todo
87
95
    examined_rows       will be set to number of examined rows
88
96
*/
89
97
 
90
 
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
 
98
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
91
99
                 SQL_SELECT *select, ha_rows max_rows,
92
100
                 bool sort_positions, ha_rows *examined_rows)
93
101
{
94
102
  int error;
95
 
  uint32_t memavl, min_sort_memory;
96
 
  uint32_t maxbuffer;
 
103
  ulong memavl, min_sort_memory;
 
104
  uint maxbuffer;
97
105
  BUFFPEK *buffpek;
98
106
  ha_rows records= HA_POS_ERROR;
99
 
  unsigned char **sort_keys= 0;
 
107
  uchar **sort_keys= 0;
100
108
  IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile; 
101
109
  SORTPARAM param;
102
110
  bool multi_byte_charset;
103
 
 
104
 
  filesort_info_st table_sort;
105
 
  TableList *tab= table->pos_in_table_list;
 
111
  DBUG_ENTER("filesort");
 
112
  DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length););
 
113
#ifdef SKIP_DBUG_IN_FILESORT
 
114
  DBUG_PUSH("");                /* No DBUG here */
 
115
#endif
 
116
  FILESORT_INFO table_sort;
 
117
  TABLE_LIST *tab= table->pos_in_table_list;
106
118
  Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
107
119
 
108
 
  DRIZZLE_FILESORT_START();
 
120
  MYSQL_FILESORT_START();
109
121
 
110
122
  /*
111
123
   Release InnoDB's adaptive hash index latch (if holding) before
118
130
    QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end 
119
131
    when index_merge select has finished with it.
120
132
  */
121
 
  memcpy(&table_sort, &table->sort, sizeof(filesort_info_st));
 
133
  memcpy(&table_sort, &table->sort, sizeof(FILESORT_INFO));
122
134
  table->sort.io_cache= NULL;
123
135
  
124
136
  outfile= table_sort.io_cache;
126
138
  my_b_clear(&buffpek_pointers);
127
139
  buffpek=0;
128
140
  error= 1;
129
 
  memset(&param, 0, sizeof(param));
 
141
  bzero((char*) &param,sizeof(param));
130
142
  param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
131
143
  param.ref_length= table->file->ref_length;
132
144
  param.addon_field= 0;
133
145
  param.addon_length= 0;
134
 
  if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !sort_positions)
 
146
  if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
 
147
      !table->fulltext_searched && !sort_positions)
135
148
  {
136
149
    /* 
137
150
      Get the descriptors of all fields whose values are appended 
149
162
  if (param.addon_field)
150
163
  {
151
164
    param.res_length= param.addon_length;
152
 
    if (!(table_sort.addon_buf= (unsigned char *) my_malloc(param.addon_length,
 
165
    if (!(table_sort.addon_buf= (uchar *) my_malloc(param.addon_length,
153
166
                                                    MYF(MY_WME))))
154
167
      goto err;
155
168
  }
176
189
#ifdef CAN_TRUST_RANGE
177
190
  if (select && select->quick && select->quick->records > 0L)
178
191
  {
179
 
    records=cmin((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
 
192
    records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
180
193
                table->file->stats.records)+EXTRA_RECORDS;
181
194
    selected_records_file=0;
182
195
  }
198
211
    goto err;
199
212
 
200
213
  memavl= thd->variables.sortbuff_size;
201
 
  min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
 
214
  min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
202
215
  while (memavl >= min_sort_memory)
203
216
  {
204
 
    uint32_t old_memavl;
205
 
    uint32_t keys= memavl/(param.rec_length+sizeof(char*));
206
 
    param.keys=(uint32_t) cmin(records+1, keys);
 
217
    ulong old_memavl;
 
218
    ulong keys= memavl/(param.rec_length+sizeof(char*));
 
219
    param.keys=(uint) min(records+1, keys);
207
220
    if ((table_sort.sort_keys=
208
 
         (unsigned char **) make_char_array((char **) table_sort.sort_keys,
 
221
         (uchar **) make_char_array((char **) table_sort.sort_keys,
209
222
                                    param.keys, param.rec_length, MYF(0))))
210
223
      break;
211
224
    old_memavl=memavl;
229
242
                             &tempfile, selected_records_file)) ==
230
243
      HA_POS_ERROR)
231
244
    goto err;
232
 
  maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
 
245
  maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
233
246
 
234
247
  if (maxbuffer == 0)                   // The whole set is in memory
235
248
  {
236
 
    if (save_index(&param,sort_keys,(uint32_t) records, &table_sort))
 
249
    if (save_index(&param,sort_keys,(uint) records, &table_sort))
237
250
      goto err;
238
251
  }
239
252
  else
240
253
  {
241
254
    if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
242
255
    {
243
 
      if (table_sort.buffpek)
244
 
        free(table_sort.buffpek);
 
256
      x_free(table_sort.buffpek);
245
257
      table_sort.buffpek= 0;
246
258
    }
247
259
    if (!(table_sort.buffpek=
248
 
          (unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
 
260
          (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
249
261
                                 table_sort.buffpek)))
250
262
      goto err;
251
263
    buffpek= (BUFFPEK *) table_sort.buffpek;
266
278
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
267
279
                param.rec_length-1);
268
280
    maxbuffer--;                                // Offset from 0
269
 
    if (merge_many_buff(&param,(unsigned char*) sort_keys,buffpek,&maxbuffer,
 
281
    if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
270
282
                        &tempfile))
271
283
      goto err;
272
284
    if (flush_io_cache(&tempfile) ||
273
285
        reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
274
286
      goto err;
275
 
    if (merge_index(&param,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
 
287
    if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
276
288
                    outfile))
277
289
      goto err;
278
290
  }
282
294
 
283
295
 err:
284
296
  if (param.tmp_buffer)
285
 
    if (param.tmp_buffer)
286
 
      free(param.tmp_buffer);
 
297
    x_free(param.tmp_buffer);
287
298
  if (!subselect || !subselect->is_uncacheable())
288
299
  {
289
 
    if ((unsigned char*) sort_keys)
290
 
      free((unsigned char*) sort_keys);
 
300
    x_free((uchar*) sort_keys);
291
301
    table_sort.sort_keys= 0;
292
 
    if ((unsigned char*) buffpek)
293
 
      free((unsigned char*) buffpek);
 
302
    x_free((uchar*) buffpek);
294
303
    table_sort.buffpek= 0;
295
304
    table_sort.buffpek_len= 0;
296
305
  }
313
322
               MYF(ME_ERROR+ME_WAITTANG));
314
323
  else
315
324
    statistic_add(thd->status_var.filesort_rows,
316
 
                  (uint32_t) records, &LOCK_status);
 
325
                  (ulong) records, &LOCK_status);
317
326
  *examined_rows= param.examined_rows;
318
 
  memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
319
 
  DRIZZLE_FILESORT_END();
320
 
  return(error ? HA_POS_ERROR : records);
 
327
#ifdef SKIP_DBUG_IN_FILESORT
 
328
  DBUG_POP();                   /* Ok to DBUG */
 
329
#endif
 
330
  memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
 
331
  DBUG_PRINT("exit",("records: %ld", (long) records));
 
332
  MYSQL_FILESORT_END();
 
333
  DBUG_RETURN(error ? HA_POS_ERROR : records);
321
334
} /* filesort */
322
335
 
323
336
 
324
 
void filesort_free_buffers(Table *table, bool full)
 
337
void filesort_free_buffers(TABLE *table, bool full)
325
338
{
326
339
  if (table->sort.record_pointers)
327
340
  {
328
 
    free((unsigned char*) table->sort.record_pointers);
 
341
    my_free((uchar*) table->sort.record_pointers,MYF(0));
329
342
    table->sort.record_pointers=0;
330
343
  }
331
344
  if (full)
332
345
  {
333
346
    if (table->sort.sort_keys )
334
347
    {
335
 
      if ((unsigned char*) table->sort.sort_keys)
336
 
        free((unsigned char*) table->sort.sort_keys);
 
348
      x_free((uchar*) table->sort.sort_keys);
337
349
      table->sort.sort_keys= 0;
338
350
    }
339
351
    if (table->sort.buffpek)
340
352
    {
341
 
      if ((unsigned char*) table->sort.buffpek)
342
 
        free((unsigned char*) table->sort.buffpek);
 
353
      x_free((uchar*) table->sort.buffpek);
343
354
      table->sort.buffpek= 0;
344
355
      table->sort.buffpek_len= 0;
345
356
    }
346
357
  }
347
358
  if (table->sort.addon_buf)
348
359
  {
349
 
    free((char *) table->sort.addon_buf);
350
 
    free((char *) table->sort.addon_field);
 
360
    my_free((char *) table->sort.addon_buf, MYF(0));
 
361
    my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
351
362
    table->sort.addon_buf=0;
352
363
    table->sort.addon_field=0;
353
364
  }
355
366
 
356
367
/** Make a array of string pointers. */
357
368
 
358
 
static char **make_char_array(char **old_pos, register uint32_t fields,
359
 
                              uint32_t length, myf my_flag)
 
369
static char **make_char_array(char **old_pos, register uint fields,
 
370
                              uint length, myf my_flag)
360
371
{
361
372
  register char **pos;
362
373
  char *char_pos;
 
374
  DBUG_ENTER("make_char_array");
363
375
 
364
376
  if (old_pos ||
365
 
      (old_pos= (char**) my_malloc((uint32_t) fields*(length+sizeof(char*)),
 
377
      (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
366
378
                                   my_flag)))
367
379
  {
368
380
    pos=old_pos; char_pos=((char*) (pos+fields)) -length;
369
381
    while (fields--) *(pos++) = (char_pos+= length);
370
382
  }
371
383
 
372
 
  return(old_pos);
 
384
  DBUG_RETURN(old_pos);
373
385
} /* make_char_array */
374
386
 
375
387
 
376
388
/** Read 'count' number of buffer pointers into memory. */
377
389
 
378
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
379
 
                                     unsigned char *buf)
 
390
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
 
391
                                     uchar *buf)
380
392
{
381
 
  uint32_t length= sizeof(BUFFPEK)*count;
382
 
  unsigned char *tmp= buf;
 
393
  ulong length= sizeof(BUFFPEK)*count;
 
394
  uchar *tmp= buf;
 
395
  DBUG_ENTER("read_buffpek_from_file");
383
396
  if (count > UINT_MAX/sizeof(BUFFPEK))
384
397
    return 0; /* sizeof(BUFFPEK)*count will overflow */
385
398
  if (!tmp)
386
 
    tmp= (unsigned char *)my_malloc(length, MYF(MY_WME));
 
399
    tmp= (uchar *)my_malloc(length, MYF(MY_WME));
387
400
  if (tmp)
388
401
  {
389
402
    if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
390
 
        my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
 
403
        my_b_read(buffpek_pointers, (uchar*) tmp, length))
391
404
    {
392
 
      free((char*) tmp);
 
405
      my_free((char*) tmp, MYF(0));
393
406
      tmp=0;
394
407
    }
395
408
  }
396
 
  return(tmp);
 
409
  DBUG_RETURN(tmp);
397
410
}
398
411
 
399
412
 
435
448
*/
436
449
 
437
450
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
438
 
                             unsigned char **sort_keys,
 
451
                             uchar **sort_keys,
439
452
                             IO_CACHE *buffpek_pointers,
440
453
                             IO_CACHE *tempfile, IO_CACHE *indexfile)
441
454
{
442
455
  int error,flag,quick_select;
443
 
  uint32_t idx,indexpos,ref_length;
444
 
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
 
456
  uint idx,indexpos,ref_length;
 
457
  uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
445
458
  my_off_t record;
446
 
  Table *sort_form;
 
459
  TABLE *sort_form;
447
460
  THD *thd= current_thd;
448
461
  volatile THD::killed_state *killed= &thd->killed;
449
462
  handler *file;
450
463
  MY_BITMAP *save_read_set, *save_write_set;
 
464
  DBUG_ENTER("find_all_keys");
 
465
  DBUG_PRINT("info",("using: %s",
 
466
                     (select ? select->quick ? "ranges" : "where":
 
467
                      "every row")));
451
468
 
452
469
  idx=indexpos=0;
453
470
  error=quick_select=0;
464
481
  next_pos=ref_pos;
465
482
  if (! indexfile && ! quick_select)
466
483
  {
467
 
    next_pos=(unsigned char*) 0;                        /* Find records in sequence */
 
484
    next_pos=(uchar*) 0;                        /* Find records in sequence */
468
485
    file->ha_rnd_init(1);
469
486
    file->extra_opt(HA_EXTRA_CACHE,
470
487
                    current_thd->variables.read_buff_size);
474
491
  if (quick_select)
475
492
  {
476
493
    if (select->quick->reset())
477
 
      return(HA_POS_ERROR);
 
494
      DBUG_RETURN(HA_POS_ERROR);
478
495
    init_read_record(&read_record_info, current_thd, select->quick->head,
479
496
                     select, 1, 1);
480
497
  }
489
506
  register_used_fields(param);
490
507
  if (select && select->cond)
491
508
    select->cond->walk(&Item::register_field_in_read_map, 1,
492
 
                       (unsigned char*) sort_form);
 
509
                       (uchar*) sort_form);
493
510
  sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set);
494
511
 
495
512
  for (;;)
507
524
    {
508
525
      if (indexfile)
509
526
      {
510
 
        if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length)) /* purecov: deadcode */
 
527
        if (my_b_read(indexfile,(uchar*) ref_pos,ref_length)) /* purecov: deadcode */
511
528
        {
512
529
          error= my_errno ? my_errno : -1;              /* Abort */
513
530
          break;
517
534
      else
518
535
      {
519
536
        error=file->rnd_next(sort_form->record[0]);
520
 
        if (!error)
521
 
          update_virtual_fields_marked_for_write(sort_form);
522
 
 
523
537
        if (!flag)
524
538
        {
525
539
          my_store_ptr(ref_pos,ref_length,record); // Position to row
534
548
 
535
549
    if (*killed)
536
550
    {
 
551
      DBUG_PRINT("info",("Sort killed by user"));
537
552
      if (!indexfile && !quick_select)
538
553
      {
539
554
        (void) file->extra(HA_EXTRA_NO_CACHE);
540
555
        file->ha_rnd_end();
541
556
      }
542
 
      return(HA_POS_ERROR);             /* purecov: inspected */
 
557
      DBUG_RETURN(HA_POS_ERROR);                /* purecov: inspected */
543
558
    }
544
559
    if (error == 0)
545
560
      param->examined_rows++;
548
563
      if (idx == param->keys)
549
564
      {
550
565
        if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
551
 
          return(HA_POS_ERROR);
 
566
          DBUG_RETURN(HA_POS_ERROR);
552
567
        idx=0;
553
568
        indexpos++;
554
569
      }
576
591
  }
577
592
 
578
593
  if (thd->is_error())
579
 
    return(HA_POS_ERROR);
 
594
    DBUG_RETURN(HA_POS_ERROR);
580
595
  
581
596
  /* Signal we should use orignal column read and write maps */
582
597
  sort_form->column_bitmaps_set(save_read_set, save_write_set);
583
598
 
 
599
  DBUG_PRINT("test",("error: %d  indexpos: %d",error,indexpos));
584
600
  if (error != HA_ERR_END_OF_FILE)
585
601
  {
586
602
    file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
587
 
    return(HA_POS_ERROR);                       /* purecov: inspected */
 
603
    DBUG_RETURN(HA_POS_ERROR);                  /* purecov: inspected */
588
604
  }
589
605
  if (indexpos && idx &&
590
606
      write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
591
 
    return(HA_POS_ERROR);                       /* purecov: inspected */
592
 
  return(my_b_inited(tempfile) ?
 
607
    DBUG_RETURN(HA_POS_ERROR);                  /* purecov: inspected */
 
608
  DBUG_RETURN(my_b_inited(tempfile) ?
593
609
              (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
594
610
              idx);
595
611
} /* find_all_keys */
618
634
*/
619
635
 
620
636
static int
621
 
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
 
637
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
622
638
           IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
623
639
{
624
640
  size_t sort_length, rec_length;
625
 
  unsigned char **end;
 
641
  uchar **end;
626
642
  BUFFPEK buffpek;
 
643
  DBUG_ENTER("write_keys");
627
644
 
628
645
  sort_length= param->sort_length;
629
646
  rec_length= param->rec_length;
630
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
 
647
#ifdef MC68000
 
648
  quicksort(sort_keys,count,sort_length);
 
649
#else
 
650
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
 
651
#endif
631
652
  if (!my_b_inited(tempfile) &&
632
653
      open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
633
654
                       MYF(MY_WME)))
634
655
    goto err;                                   /* purecov: inspected */
635
656
  /* check we won't have more buffpeks than we can possibly keep in memory */
636
 
  if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
 
657
  if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (ulonglong)UINT_MAX)
637
658
    goto err;
638
659
  buffpek.file_pos= my_b_tell(tempfile);
639
660
  if ((ha_rows) count > param->max_rows)
640
 
    count=(uint32_t) param->max_rows;               /* purecov: inspected */
 
661
    count=(uint) param->max_rows;               /* purecov: inspected */
641
662
  buffpek.count=(ha_rows) count;
642
663
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
643
 
    if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
 
664
    if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
644
665
      goto err;
645
 
  if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
 
666
  if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
646
667
    goto err;
647
 
  return(0);
 
668
  DBUG_RETURN(0);
648
669
 
649
670
err:
650
 
  return(1);
 
671
  DBUG_RETURN(1);
651
672
} /* write_keys */
652
673
 
653
674
 
655
676
  Store length as suffix in high-byte-first order.
656
677
*/
657
678
 
658
 
static inline void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
 
679
static inline void store_length(uchar *to, uint length, uint pack_length)
659
680
{
660
681
  switch (pack_length) {
661
682
  case 1:
662
 
    *to= (unsigned char) length;
 
683
    *to= (uchar) length;
663
684
    break;
664
685
  case 2:
665
686
    mi_int2store(to, length);
677
698
/** Make a sort-key from record. */
678
699
 
679
700
static void make_sortkey(register SORTPARAM *param,
680
 
                         register unsigned char *to, unsigned char *ref_pos)
 
701
                         register uchar *to, uchar *ref_pos)
681
702
{
682
703
  register Field *field;
683
704
  register SORT_FIELD *sort_field;
684
 
  register uint32_t length;
 
705
  register uint length;
685
706
 
686
707
  for (sort_field=param->local_sortorder ;
687
708
       sort_field != param->end ;
695
716
        if (field->is_null())
696
717
        {
697
718
          if (sort_field->reverse)
698
 
            memset(to, 255, sort_field->length+1);
 
719
            bfill(to,sort_field->length+1,(char) 255);
699
720
          else
700
 
            memset(to, 0, sort_field->length+1);
 
721
            bzero((char*) to,sort_field->length+1);
701
722
          to+= sort_field->length+1;
702
723
          continue;
703
724
        }
713
734
      switch (sort_field->result_type) {
714
735
      case STRING_RESULT:
715
736
      {
716
 
        const CHARSET_INFO * const cs=item->collation.collation;
 
737
        CHARSET_INFO *cs=item->collation.collation;
717
738
        char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
718
739
        int diff;
719
 
        uint32_t sort_field_length;
 
740
        uint sort_field_length;
720
741
 
721
742
        if (maybe_null)
722
743
          *to++=1;
726
747
        if (!res)
727
748
        {
728
749
          if (maybe_null)
729
 
            memset(to-1, 0, sort_field->length+1);
 
750
            bzero((char*) to-1,sort_field->length+1);
730
751
          else
731
752
          {
732
753
            /* purecov: begin deadcode */
735
756
              of memory or have an item marked not null when it can be null.
736
757
              This code is here mainly to avoid a hard crash in this case.
737
758
            */
738
 
            assert(0);
739
 
            memset(to, 0, sort_field->length);  // Avoid crash
 
759
            DBUG_ASSERT(0);
 
760
            DBUG_PRINT("warning",
 
761
                       ("Got null on something that shouldn't be null"));
 
762
            bzero((char*) to,sort_field->length);       // Avoid crash
740
763
            /* purecov: end */
741
764
          }
742
765
          break;
758
781
        if (sort_field->need_strxnfrm)
759
782
        {
760
783
          char *from=(char*) res->ptr();
761
 
          uint32_t tmp_length;
762
 
          if ((unsigned char*) from == to)
 
784
          uint tmp_length;
 
785
          if ((uchar*) from == to)
763
786
          {
764
787
            set_if_smaller(length,sort_field->length);
765
788
            memcpy(param->tmp_buffer,from,length);
766
789
            from=param->tmp_buffer;
767
790
          }
768
791
          tmp_length= my_strnxfrm(cs,to,sort_field->length,
769
 
                                  (unsigned char*) from, length);
770
 
          assert(tmp_length == sort_field->length);
 
792
                                  (uchar*) from, length);
 
793
          DBUG_ASSERT(tmp_length == sort_field->length);
771
794
        }
772
795
        else
773
796
        {
774
 
          my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
 
797
          my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
775
798
          cs->cset->fill(cs, (char *)to+length,diff,fill_char);
776
799
        }
777
800
        break;
778
801
      }
779
802
      case INT_RESULT:
780
803
        {
781
 
          int64_t value= item->val_int_result();
 
804
          longlong value= item->val_int_result();
782
805
          if (maybe_null)
783
806
          {
784
807
            *to++=1;                            /* purecov: inspected */
785
808
            if (item->null_value)
786
809
            {
787
810
              if (maybe_null)
788
 
                memset(to-1, 0, sort_field->length+1);
 
811
                bzero((char*) to-1,sort_field->length+1);
789
812
              else
790
813
              {
791
 
                memset(to, 0, sort_field->length);
 
814
                DBUG_PRINT("warning",
 
815
                           ("Got null on something that shouldn't be null"));
 
816
                bzero((char*) to,sort_field->length);
792
817
              }
793
818
              break;
794
819
            }
795
820
          }
796
 
          to[7]= (unsigned char) value;
797
 
          to[6]= (unsigned char) (value >> 8);
798
 
          to[5]= (unsigned char) (value >> 16);
799
 
          to[4]= (unsigned char) (value >> 24);
800
 
          to[3]= (unsigned char) (value >> 32);
801
 
          to[2]= (unsigned char) (value >> 40);
802
 
          to[1]= (unsigned char) (value >> 48);
803
 
          if (item->unsigned_flag)                    /* Fix sign */
804
 
            to[0]= (unsigned char) (value >> 56);
805
 
          else
806
 
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
 
821
#if SIZEOF_LONG_LONG > 4
 
822
          to[7]= (uchar) value;
 
823
          to[6]= (uchar) (value >> 8);
 
824
          to[5]= (uchar) (value >> 16);
 
825
          to[4]= (uchar) (value >> 24);
 
826
          to[3]= (uchar) (value >> 32);
 
827
          to[2]= (uchar) (value >> 40);
 
828
          to[1]= (uchar) (value >> 48);
 
829
          if (item->unsigned_flag)                    /* Fix sign */
 
830
            to[0]= (uchar) (value >> 56);
 
831
          else
 
832
            to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
 
833
#else
 
834
          to[3]= (uchar) value;
 
835
          to[2]= (uchar) (value >> 8);
 
836
          to[1]= (uchar) (value >> 16);
 
837
          if (item->unsigned_flag)                    /* Fix sign */
 
838
            to[0]= (uchar) (value >> 24);
 
839
          else
 
840
            to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
 
841
#endif
807
842
          break;
808
843
        }
809
844
      case DECIMAL_RESULT:
813
848
          {
814
849
            if (item->null_value)
815
850
            { 
816
 
              memset(to, 0, sort_field->length+1);
 
851
              bzero((char*)to, sort_field->length+1);
817
852
              to++;
818
853
              break;
819
854
            }
831
866
          {
832
867
            if (item->null_value)
833
868
            {
834
 
              memset(to, 0, sort_field->length+1);
 
869
              bzero((char*) to,sort_field->length+1);
835
870
              to++;
836
871
              break;
837
872
            }
838
873
            *to++=1;
839
874
          }
840
 
          change_double_for_sort(value,(unsigned char*) to);
 
875
          change_double_for_sort(value,(uchar*) to);
841
876
          break;
842
877
        }
843
878
      case ROW_RESULT:
844
879
      default: 
845
880
        // This case should never be choosen
846
 
        assert(0);
 
881
        DBUG_ASSERT(0);
847
882
        break;
848
883
      }
849
884
    }
854
889
      length=sort_field->length;
855
890
      while (length--)
856
891
      {
857
 
        *to = (unsigned char) (~ *to);
 
892
        *to = (uchar) (~ *to);
858
893
        to++;
859
894
      }
860
895
    }
871
906
      the same for all records.
872
907
    */
873
908
    SORT_ADDON_FIELD *addonf= param->addon_field;
874
 
    unsigned char *nulls= to;
875
 
    assert(addonf != 0);
876
 
    memset(nulls, 0, addonf->offset);
 
909
    uchar *nulls= to;
 
910
    DBUG_ASSERT(addonf != 0);
 
911
    bzero((char *) nulls, addonf->offset);
877
912
    to+= addonf->offset;
878
913
    for ( ; (field= addonf->field) ; addonf++)
879
914
    {
881
916
      {
882
917
        nulls[addonf->null_offset]|= addonf->null_bit;
883
918
#ifdef HAVE_purify
884
 
        memset(to, 0, addonf->length);
 
919
        bzero(to, addonf->length);
885
920
#endif
886
921
      }
887
922
      else
888
923
      {
889
924
#ifdef HAVE_purify
890
 
        unsigned char *end= field->pack(to, field->ptr);
891
 
        uint32_t length= (uint32_t) ((to + addonf->length) - end);
892
 
        assert((int) length >= 0);
 
925
        uchar *end= field->pack(to, field->ptr);
 
926
        uint length= (uint) ((to + addonf->length) - end);
 
927
        DBUG_ASSERT((int) length >= 0);
893
928
        if (length)
894
 
          memset(end, 0, length);
 
929
          bzero(end, length);
895
930
#else
896
931
        (void) field->pack(to, field->ptr);
897
932
#endif
902
937
  else
903
938
  {
904
939
    /* Save filepos last */
905
 
    memcpy(to, ref_pos, (size_t) param->ref_length);
 
940
    memcpy((uchar*) to, ref_pos, (size_t) param->ref_length);
906
941
  }
907
942
  return;
908
943
}
915
950
static void register_used_fields(SORTPARAM *param)
916
951
{
917
952
  register SORT_FIELD *sort_field;
918
 
  Table *table=param->sort_form;
 
953
  TABLE *table=param->sort_form;
919
954
  MY_BITMAP *bitmap= table->read_set;
920
955
 
921
956
  for (sort_field= param->local_sortorder ;
931
966
    else
932
967
    {                                           // Item
933
968
      sort_field->item->walk(&Item::register_field_in_read_map, 1,
934
 
                             (unsigned char *) table);
 
969
                             (uchar *) table);
935
970
    }
936
971
  }
937
972
 
950
985
}
951
986
 
952
987
 
953
 
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count, 
954
 
                       filesort_info_st *table_sort)
 
988
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count, 
 
989
                       FILESORT_INFO *table_sort)
955
990
{
956
 
  uint32_t offset,res_length;
957
 
  unsigned char *to;
 
991
  uint offset,res_length;
 
992
  uchar *to;
 
993
  DBUG_ENTER("save_index");
958
994
 
959
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
 
995
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
960
996
  res_length= param->res_length;
961
997
  offset= param->rec_length-res_length;
962
998
  if ((ha_rows) count > param->max_rows)
963
 
    count=(uint32_t) param->max_rows;
 
999
    count=(uint) param->max_rows;
964
1000
  if (!(to= table_sort->record_pointers= 
965
 
        (unsigned char*) my_malloc(res_length*count, MYF(MY_WME))))
966
 
    return(1);                 /* purecov: inspected */
967
 
  for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
 
1001
        (uchar*) my_malloc(res_length*count, MYF(MY_WME))))
 
1002
    DBUG_RETURN(1);                 /* purecov: inspected */
 
1003
  for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
968
1004
  {
969
1005
    memcpy(to, *sort_keys+offset, res_length);
970
1006
    to+= res_length;
971
1007
  }
972
 
  return(0);
 
1008
  DBUG_RETURN(0);
973
1009
}
974
1010
 
975
1011
 
976
1012
/** Merge buffers to make < MERGEBUFF2 buffers. */
977
1013
 
978
 
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
979
 
                    BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
 
1014
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
 
1015
                    BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
980
1016
{
981
 
  register uint32_t i;
 
1017
  register uint i;
982
1018
  IO_CACHE t_file2,*from_file,*to_file,*temp;
983
1019
  BUFFPEK *lastbuff;
 
1020
  DBUG_ENTER("merge_many_buff");
984
1021
 
985
1022
  if (*maxbuffer < MERGEBUFF2)
986
 
    return(0);                          /* purecov: inspected */
 
1023
    DBUG_RETURN(0);                             /* purecov: inspected */
987
1024
  if (flush_io_cache(t_file) ||
988
1025
      open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
989
1026
                        MYF(MY_WME)))
990
 
    return(1);                          /* purecov: inspected */
 
1027
    DBUG_RETURN(1);                             /* purecov: inspected */
991
1028
 
992
1029
  from_file= t_file ; to_file= &t_file2;
993
1030
  while (*maxbuffer >= MERGEBUFF2)
1011
1048
    temp=from_file; from_file=to_file; to_file=temp;
1012
1049
    setup_io_cache(from_file);
1013
1050
    setup_io_cache(to_file);
1014
 
    *maxbuffer= (uint32_t) (lastbuff-buffpek)-1;
 
1051
    *maxbuffer= (uint) (lastbuff-buffpek)-1;
1015
1052
  }
1016
1053
cleanup:
1017
1054
  close_cached_file(to_file);                   // This holds old result
1021
1058
    setup_io_cache(t_file);
1022
1059
  }
1023
1060
 
1024
 
  return(*maxbuffer >= MERGEBUFF2);     /* Return 1 if interrupted */
 
1061
  DBUG_RETURN(*maxbuffer >= MERGEBUFF2);        /* Return 1 if interrupted */
1025
1062
} /* merge_many_buff */
1026
1063
 
1027
1064
 
1029
1066
  Read data to buffer.
1030
1067
 
1031
1068
  @retval
1032
 
    (uint32_t)-1 if something goes wrong
 
1069
    (uint)-1 if something goes wrong
1033
1070
*/
1034
1071
 
1035
 
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1036
 
                    uint32_t rec_length)
 
1072
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
 
1073
                    uint rec_length)
1037
1074
{
1038
 
  register uint32_t count;
1039
 
  uint32_t length;
 
1075
  register uint count;
 
1076
  uint length;
1040
1077
 
1041
 
  if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
 
1078
  if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1042
1079
  {
1043
 
    if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1044
 
      return((uint32_t) -1);                    /* purecov: inspected */
 
1080
    if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
 
1081
      return((uint) -1);                        /* purecov: inspected */
1045
1082
    buffpek->key=buffpek->base;
1046
1083
    buffpek->file_pos+= length;                 /* New filepos */
1047
1084
    buffpek->count-=    count;
1062
1099
  @param[in] key_length key length
1063
1100
*/
1064
1101
 
1065
 
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint32_t key_length)
 
1102
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1066
1103
{
1067
 
  unsigned char *reuse_end= reuse->base + reuse->max_keys * key_length;
1068
 
  for (uint32_t i= 0; i < queue->elements; ++i)
 
1104
  uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
 
1105
  for (uint i= 0; i < queue->elements; ++i)
1069
1106
  {
1070
1107
    BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1071
1108
    if (bp->base + bp->max_keys * key_length == reuse->base)
1080
1117
      return;
1081
1118
    }
1082
1119
  }
1083
 
  assert(0);
 
1120
  DBUG_ASSERT(0);
1084
1121
}
1085
1122
 
1086
1123
 
1103
1140
*/
1104
1141
 
1105
1142
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1106
 
                  IO_CACHE *to_file, unsigned char *sort_buffer,
 
1143
                  IO_CACHE *to_file, uchar *sort_buffer,
1107
1144
                  BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1108
1145
                  int flag)
1109
1146
{
1110
1147
  int error;
1111
 
  uint32_t rec_length,res_length,offset;
 
1148
  uint rec_length,res_length,offset;
1112
1149
  size_t sort_length;
1113
 
  uint32_t maxcount;
 
1150
  ulong maxcount;
1114
1151
  ha_rows max_rows,org_max_rows;
1115
1152
  my_off_t to_start_filepos;
1116
 
  unsigned char *strpos;
 
1153
  uchar *strpos;
1117
1154
  BUFFPEK *buffpek;
1118
1155
  QUEUE queue;
1119
1156
  qsort2_cmp cmp;
1120
1157
  void *first_cmp_arg;
1121
1158
  volatile THD::killed_state *killed= &current_thd->killed;
1122
1159
  THD::killed_state not_killable;
 
1160
  DBUG_ENTER("merge_buffers");
1123
1161
 
1124
1162
  status_var_increment(current_thd->status_var.filesort_merge_passes);
1125
1163
  if (param->not_killable)
1133
1171
  res_length= param->res_length;
1134
1172
  sort_length= param->sort_length;
1135
1173
  offset= rec_length-res_length;
1136
 
  maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
 
1174
  maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
1137
1175
  to_start_filepos= my_b_tell(to_file);
1138
 
  strpos= (unsigned char*) sort_buffer;
 
1176
  strpos= (uchar*) sort_buffer;
1139
1177
  org_max_rows=max_rows= param->max_rows;
1140
1178
 
1141
1179
  /* The following will fire if there is not enough space in sort_buffer */
1142
 
  assert(maxcount!=0);
 
1180
  DBUG_ASSERT(maxcount!=0);
1143
1181
  
1144
1182
  if (param->unique_buff)
1145
1183
  {
1151
1189
    cmp= get_ptr_compare(sort_length);
1152
1190
    first_cmp_arg= (void*) &sort_length;
1153
1191
  }
1154
 
  if (init_queue(&queue, (uint32_t) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
 
1192
  if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1155
1193
                 (queue_compare) cmp, first_cmp_arg))
1156
 
    return(1);                                /* purecov: inspected */
 
1194
    DBUG_RETURN(1);                                /* purecov: inspected */
1157
1195
  for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1158
1196
  {
1159
1197
    buffpek->base= strpos;
1160
1198
    buffpek->max_keys= maxcount;
1161
 
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
 
1199
    strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1162
1200
                                                                         rec_length));
1163
1201
    if (error == -1)
1164
1202
      goto err;                                 /* purecov: inspected */
1165
1203
    buffpek->max_keys= buffpek->mem_count;      // If less data in buffers than expected
1166
 
    queue_insert(&queue, (unsigned char*) buffpek);
 
1204
    queue_insert(&queue, (uchar*) buffpek);
1167
1205
  }
1168
1206
 
1169
1207
  if (param->unique_buff)
1178
1216
    */
1179
1217
    buffpek= (BUFFPEK*) queue_top(&queue);
1180
1218
    memcpy(param->unique_buff, buffpek->key, rec_length);
1181
 
    if (my_b_write(to_file, (unsigned char*) buffpek->key, rec_length))
 
1219
    if (my_b_write(to_file, (uchar*) buffpek->key, rec_length))
1182
1220
    {
1183
1221
      error=1; goto err;                        /* purecov: inspected */
1184
1222
    }
1206
1244
      if (cmp)                                        // Remove duplicates
1207
1245
      {
1208
1246
        if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1209
 
                    (unsigned char**) &buffpek->key))
 
1247
                    (uchar**) &buffpek->key))
1210
1248
              goto skip_duplicate;
1211
 
            memcpy(param->unique_buff, buffpek->key, rec_length);
 
1249
            memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
1212
1250
      }
1213
1251
      if (flag == 0)
1214
1252
      {
1215
 
        if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
 
1253
        if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1216
1254
        {
1217
1255
          error=1; goto err;                        /* purecov: inspected */
1218
1256
        }
1219
1257
      }
1220
1258
      else
1221
1259
      {
1222
 
        if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
 
1260
        if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1223
1261
        {
1224
1262
          error=1; goto err;                        /* purecov: inspected */
1225
1263
        }
1237
1275
        if (!(error= (int) read_to_buffer(from_file,buffpek,
1238
1276
                                          rec_length)))
1239
1277
        {
1240
 
          queue_remove(&queue,0);
 
1278
          VOID(queue_remove(&queue,0));
1241
1279
          reuse_freed_buff(&queue, buffpek, rec_length);
1242
1280
          break;                        /* One buffer have been removed */
1243
1281
        }
1257
1295
  */
1258
1296
  if (cmp)
1259
1297
  {
1260
 
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (unsigned char**) &buffpek->key))
 
1298
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
1261
1299
    {
1262
1300
      buffpek->key+= rec_length;         // Remove duplicate
1263
1301
      --buffpek->mem_count;
1268
1306
  {
1269
1307
    if ((ha_rows) buffpek->mem_count > max_rows)
1270
1308
    {                                        /* Don't write too many records */
1271
 
      buffpek->mem_count= (uint32_t) max_rows;
 
1309
      buffpek->mem_count= (uint) max_rows;
1272
1310
      buffpek->count= 0;                        /* Don't read more */
1273
1311
    }
1274
1312
    max_rows-= buffpek->mem_count;
1275
1313
    if (flag == 0)
1276
1314
    {
1277
 
      if (my_b_write(to_file,(unsigned char*) buffpek->key,
 
1315
      if (my_b_write(to_file,(uchar*) buffpek->key,
1278
1316
                     (rec_length*buffpek->mem_count)))
1279
1317
      {
1280
1318
        error= 1; goto err;                        /* purecov: inspected */
1282
1320
    }
1283
1321
    else
1284
1322
    {
1285
 
      register unsigned char *end;
 
1323
      register uchar *end;
1286
1324
      strpos= buffpek->key+offset;
1287
1325
      for (end= strpos+buffpek->mem_count*rec_length ;
1288
1326
           strpos != end ;
1289
1327
           strpos+= rec_length)
1290
1328
      {     
1291
 
        if (my_b_write(to_file, (unsigned char *) strpos, res_length))
 
1329
        if (my_b_write(to_file, (uchar *) strpos, res_length))
1292
1330
        {
1293
1331
          error=1; goto err;                        
1294
1332
        }
1299
1337
         != -1 && error != 0);
1300
1338
 
1301
1339
end:
1302
 
  lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
 
1340
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1303
1341
  lastbuff->file_pos= to_start_filepos;
1304
1342
err:
1305
1343
  delete_queue(&queue);
1306
 
  return(error);
 
1344
  DBUG_RETURN(error);
1307
1345
} /* merge_buffers */
1308
1346
 
1309
1347
 
1310
1348
        /* Do a merge to output-file (save only positions) */
1311
1349
 
1312
 
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1313
 
                       BUFFPEK *buffpek, uint32_t maxbuffer,
 
1350
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
 
1351
                       BUFFPEK *buffpek, uint maxbuffer,
1314
1352
                       IO_CACHE *tempfile, IO_CACHE *outfile)
1315
1353
{
 
1354
  DBUG_ENTER("merge_index");
1316
1355
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1317
1356
                    buffpek+maxbuffer,1))
1318
 
    return(1);                          /* purecov: inspected */
1319
 
  return(0);
 
1357
    DBUG_RETURN(1);                             /* purecov: inspected */
 
1358
  DBUG_RETURN(0);
1320
1359
} /* merge_index */
1321
1360
 
1322
1361
 
1323
 
static uint32_t suffix_length(uint32_t string_length)
 
1362
static uint suffix_length(ulong string_length)
1324
1363
{
1325
1364
  if (string_length < 256)
1326
1365
    return 1;
1351
1390
    Total length of sort buffer in bytes
1352
1391
*/
1353
1392
 
1354
 
static uint32_t
1355
 
sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
 
1393
static uint
 
1394
sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
1356
1395
           bool *multi_byte_charset)
1357
1396
{
1358
 
  register uint32_t length;
1359
 
  const CHARSET_INFO *cs;
 
1397
  register uint length;
 
1398
  CHARSET_INFO *cs;
1360
1399
  *multi_byte_charset= 0;
1361
1400
 
1362
1401
  length=0;
1381
1420
    else
1382
1421
    {
1383
1422
      sortorder->result_type= sortorder->item->result_type();
1384
 
      if (sortorder->item->result_as_int64_t())
 
1423
      if (sortorder->item->result_as_longlong())
1385
1424
        sortorder->result_type= INT_RESULT;
1386
1425
      switch (sortorder->result_type) {
1387
1426
      case STRING_RESULT:
1401
1440
        }
1402
1441
        break;
1403
1442
      case INT_RESULT:
1404
 
        sortorder->length=8;                    // Size of intern int64_t
 
1443
#if SIZEOF_LONG_LONG > 4
 
1444
        sortorder->length=8;                    // Size of intern longlong
 
1445
#else
 
1446
        sortorder->length=4;
 
1447
#endif
1405
1448
        break;
1406
1449
      case DECIMAL_RESULT:
1407
1450
        sortorder->length=
1415
1458
      case ROW_RESULT:
1416
1459
      default: 
1417
1460
        // This case should never be choosen
1418
 
        assert(0);
 
1461
        DBUG_ASSERT(0);
1419
1462
        break;
1420
1463
      }
1421
1464
      if (sortorder->item->maybe_null)
1425
1468
    length+=sortorder->length;
1426
1469
  }
1427
1470
  sortorder->field= (Field*) 0;                 // end marker
 
1471
  DBUG_PRINT("info",("sort_length: %d",length));
1428
1472
  return length;
1429
1473
}
1430
1474
 
1457
1501
*/
1458
1502
 
1459
1503
static SORT_ADDON_FIELD *
1460
 
get_addon_fields(THD *thd, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
 
1504
get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
1461
1505
{
1462
1506
  Field **pfield;
1463
1507
  Field *field;
1464
1508
  SORT_ADDON_FIELD *addonf;
1465
 
  uint32_t length= 0;
1466
 
  uint32_t fields= 0;
1467
 
  uint32_t null_fields= 0;
 
1509
  uint length= 0;
 
1510
  uint fields= 0;
 
1511
  uint null_fields= 0;
1468
1512
  MY_BITMAP *read_set= (*ptabfield)->table->read_set;
1469
1513
 
1470
1514
  /*
1524
1568
  }
1525
1569
  addonf->field= 0;     // Put end marker
1526
1570
  
 
1571
  DBUG_PRINT("info",("addon_length: %d",length));
1527
1572
  return (addonf-fields);
1528
1573
}
1529
1574
 
1544
1589
*/
1545
1590
 
1546
1591
static void 
1547
 
unpack_addon_fields(struct st_sort_addon_field *addon_field, unsigned char *buff)
 
1592
unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff)
1548
1593
{
1549
1594
  Field *field;
1550
1595
  SORT_ADDON_FIELD *addonf= addon_field;
1568
1613
 
1569
1614
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1570
1615
 
1571
 
void change_double_for_sort(double nr,unsigned char *to)
 
1616
void change_double_for_sort(double nr,uchar *to)
1572
1617
{
1573
 
  unsigned char *tmp=(unsigned char*) to;
 
1618
  uchar *tmp=(uchar*) to;
1574
1619
  if (nr == 0.0)
1575
1620
  {                                             /* Change to zero string */
1576
 
    tmp[0]=(unsigned char) 128;
1577
 
    memset(tmp+1, 0, sizeof(nr)-1);
 
1621
    tmp[0]=(uchar) 128;
 
1622
    bzero((char*) tmp+1,sizeof(nr)-1);
1578
1623
  }
1579
1624
  else
1580
1625
  {
1581
1626
#ifdef WORDS_BIGENDIAN
1582
 
    memcpy(tmp,&nr,sizeof(nr));
 
1627
    memcpy_fixed(tmp,&nr,sizeof(nr));
1583
1628
#else
1584
1629
    {
1585
 
      unsigned char *ptr= (unsigned char*) &nr;
 
1630
      uchar *ptr= (uchar*) &nr;
1586
1631
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1587
1632
      tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1588
1633
      tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1594
1639
#endif
1595
1640
    if (tmp[0] & 128)                           /* Negative */
1596
1641
    {                                           /* make complement */
1597
 
      uint32_t i;
 
1642
      uint i;
1598
1643
      for (i=0 ; i < sizeof(nr); i++)
1599
 
        tmp[i]=tmp[i] ^ (unsigned char) 255;
 
1644
        tmp[i]=tmp[i] ^ (uchar) 255;
1600
1645
    }
1601
1646
    else
1602
1647
    {                                   /* Set high and move exponent one up */
1603
 
      uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1604
 
                       (uint16_t) 32768);
1605
 
      exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1606
 
      tmp[0]= (unsigned char) (exp_part >> 8);
1607
 
      tmp[1]= (unsigned char) exp_part;
 
1648
      ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
 
1649
                       (ushort) 32768);
 
1650
      exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
 
1651
      tmp[0]= (uchar) (exp_part >> 8);
 
1652
      tmp[1]= (uchar) exp_part;
1608
1653
    }
1609
1654
  }
1610
1655
}