~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  Sorts a database
22
22
*/
23
23
 
24
 
#include "config.h"
25
 
 
26
 
#include <float.h>
27
 
#include <limits.h>
 
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>
28
31
 
29
32
#include <queue>
30
 
#include <algorithm>
31
 
 
32
 
#include "drizzled/sql_sort.h"
33
 
#include "drizzled/error.h"
34
 
#include "drizzled/probes.h"
35
 
#include "drizzled/session.h"
36
 
#include "drizzled/table.h"
37
 
#include "drizzled/table_list.h"
38
 
#include "drizzled/optimizer/range.h"
39
 
#include "drizzled/records.h"
40
 
#include "drizzled/internal/iocache.h"
41
 
#include "drizzled/internal/my_sys.h"
42
 
#include "plugin/myisam/myisam.h"
43
 
#include "drizzled/plugin/transactional_storage_engine.h"
 
33
#include <bitset>
44
34
 
45
35
using namespace std;
46
36
 
47
 
namespace drizzled
48
 
{
49
 
 
50
37
/* functions defined in this file */
51
38
 
52
39
static char **make_char_array(char **old_pos, register uint32_t fields,
53
40
                              uint32_t length);
54
 
 
55
 
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
56
 
                                             uint32_t count,
57
 
                                             unsigned char *buf);
58
 
 
59
 
static ha_rows find_all_keys(SORTPARAM *param,
60
 
                             optimizer::SqlSelect *select,
61
 
                             unsigned char * *sort_keys, 
62
 
                             internal::IO_CACHE *buffer_file,
63
 
                             internal::IO_CACHE *tempfile,
64
 
                             internal::IO_CACHE *indexfile);
65
 
 
66
 
static int write_keys(SORTPARAM *param,
67
 
                      unsigned char * *sort_keys,
68
 
                      uint32_t count,
69
 
                      internal::IO_CACHE *buffer_file,
70
 
                      internal::IO_CACHE *tempfile);
71
 
 
72
 
static void make_sortkey(SORTPARAM *param,
73
 
                         unsigned char *to,
74
 
                         unsigned char *ref_pos);
 
41
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
 
42
                                     unsigned char *buf);
 
43
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
 
44
                             unsigned char * *sort_keys, IO_CACHE *buffer_file,
 
45
                             IO_CACHE *tempfile,IO_CACHE *indexfile);
 
46
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
 
47
                      uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
 
48
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
75
49
static void register_used_fields(SORTPARAM *param);
76
 
static int merge_index(SORTPARAM *param,
77
 
                       unsigned char *sort_buffer,
 
50
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
78
51
                       BUFFPEK *buffpek,
79
 
                       uint32_t maxbuffer,
80
 
                       internal::IO_CACHE *tempfile,
81
 
                       internal::IO_CACHE *outfile);
82
 
static bool save_index(SORTPARAM *param,
83
 
                       unsigned char **sort_keys,
84
 
                       uint32_t count,
 
52
                       uint32_t maxbuffer,IO_CACHE *tempfile,
 
53
                       IO_CACHE *outfile);
 
54
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count,
85
55
                       filesort_info_st *table_sort);
86
56
static uint32_t suffix_length(uint32_t string_length);
87
 
static uint32_t sortlength(Session *session,
88
 
                           SORT_FIELD *sortorder,
89
 
                           uint32_t s_length,
90
 
                           bool *multi_byte_charset);
91
 
static SORT_ADDON_FIELD *get_addon_fields(Session *session,
92
 
                                          Field **ptabfield,
93
 
                                          uint32_t sortlength,
94
 
                                          uint32_t *plength);
 
57
static uint32_t sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
58
                       bool *multi_byte_charset);
 
59
static SORT_ADDON_FIELD *get_addon_fields(Session *session, Field **ptabfield,
 
60
                                          uint32_t sortlength, uint32_t *plength);
95
61
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
96
62
                                unsigned char *buff);
97
63
/**
131
97
*/
132
98
 
133
99
ha_rows filesort(Session *session, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
134
 
                 optimizer::SqlSelect *select, ha_rows max_rows,
 
100
                 SQL_SELECT *select, ha_rows max_rows,
135
101
                 bool sort_positions, ha_rows *examined_rows)
136
102
{
137
103
  int error;
140
106
  BUFFPEK *buffpek;
141
107
  ha_rows records= HA_POS_ERROR;
142
108
  unsigned char **sort_keys= 0;
143
 
  internal::IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
 
109
  IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
144
110
  SORTPARAM param;
145
111
  bool multi_byte_charset;
146
112
 
148
114
  TableList *tab= table->pos_in_table_list;
149
115
  Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
150
116
 
151
 
  DRIZZLE_FILESORT_START(table->s->getSchemaName(), table->s->getTableName());
 
117
  DRIZZLE_FILESORT_START();
152
118
 
153
119
  /*
154
120
   Release InnoDB's adaptive hash index latch (if holding) before
155
121
   running a sort.
156
122
  */
157
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
123
  ha_release_temporary_latches(session);
158
124
 
159
125
  /*
160
126
    Don't use table->sort in filesort as it is also used by
161
 
    QuickIndexMergeSelect. Work with a copy and put it back at the end
 
127
    QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
162
128
    when index_merge select has finished with it.
163
129
  */
164
130
  memcpy(&table_sort, &table->sort, sizeof(filesort_info_st));
171
137
  error= 1;
172
138
  memset(&param, 0, sizeof(param));
173
139
  param.sort_length= sortlength(session, sortorder, s_length, &multi_byte_charset);
174
 
  param.ref_length= table->cursor->ref_length;
 
140
  param.ref_length= table->file->ref_length;
175
141
  param.addon_field= 0;
176
142
  param.addon_length= 0;
177
 
  if (!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) && !sort_positions)
 
143
  if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !sort_positions)
178
144
  {
179
145
    /*
180
146
      Get the descriptors of all fields whose values are appended
218
184
#ifdef CAN_TRUST_RANGE
219
185
  if (select && select->quick && select->quick->records > 0L)
220
186
  {
221
 
    records= min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
222
 
                 table->cursor->stats.records)+EXTRA_RECORDS;
 
187
    records=cmin((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
 
188
                table->file->stats.records)+EXTRA_RECORDS;
223
189
    selected_records_file=0;
224
190
  }
225
191
  else
226
192
#endif
227
193
  {
228
 
    records= table->cursor->estimate_rows_upper_bound();
 
194
    records= table->file->estimate_rows_upper_bound();
229
195
    /*
230
196
      If number of records is not known, use as much of sort buffer
231
197
      as possible.
240
206
    goto err;
241
207
 
242
208
  memavl= session->variables.sortbuff_size;
243
 
  min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
 
209
  min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
244
210
  while (memavl >= min_sort_memory)
245
211
  {
246
212
    uint32_t old_memavl;
247
213
    uint32_t keys= memavl/(param.rec_length+sizeof(char*));
248
 
    param.keys= (uint32_t) min(records+1, (ha_rows)keys);
 
214
    param.keys=(uint32_t) cmin(records+1, keys);
249
215
    if ((table_sort.sort_keys=
250
216
         (unsigned char **) make_char_array((char **) table_sort.sort_keys,
251
217
                                            param.keys, param.rec_length)))
252
218
      break;
253
 
    old_memavl= memavl;
254
 
    if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
 
219
    old_memavl=memavl;
 
220
    if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
255
221
      memavl= min_sort_memory;
256
222
  }
257
223
  sort_keys= table_sort.sort_keys;
298
264
        open_cached_file(outfile,drizzle_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
299
265
                          MYF(MY_WME)))
300
266
      goto err;
301
 
    if (reinit_io_cache(outfile,internal::WRITE_CACHE,0L,0,0))
 
267
    if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0))
302
268
      goto err;
303
269
 
304
270
    /*
312
278
                        &tempfile))
313
279
      goto err;
314
280
    if (flush_io_cache(&tempfile) ||
315
 
        reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
 
281
        reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
316
282
      goto err;
317
283
    if (merge_index(&param,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
318
284
                    outfile))
343
309
    if (flush_io_cache(outfile))
344
310
      error=1;
345
311
    {
346
 
      internal::my_off_t save_pos=outfile->pos_in_file;
 
312
      my_off_t save_pos=outfile->pos_in_file;
347
313
      /* For following reads */
348
 
      if (reinit_io_cache(outfile,internal::READ_CACHE,0L,0,0))
 
314
      if (reinit_io_cache(outfile,READ_CACHE,0L,0,0))
349
315
        error=1;
350
316
      outfile->end_of_file=save_pos;
351
317
    }
358
324
                  (uint32_t) records, &LOCK_status);
359
325
  *examined_rows= param.examined_rows;
360
326
  memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
361
 
  DRIZZLE_FILESORT_DONE(error, records);
362
 
  return (error ? HA_POS_ERROR : records);
 
327
  DRIZZLE_FILESORT_END();
 
328
  return(error ? HA_POS_ERROR : records);
363
329
} /* filesort */
364
330
 
365
331
 
366
 
void Table::filesort_free_buffers(bool full)
 
332
void filesort_free_buffers(Table *table, bool full)
367
333
{
368
 
  if (sort.record_pointers)
 
334
  if (table->sort.record_pointers)
369
335
  {
370
 
    free((unsigned char*) sort.record_pointers);
371
 
    sort.record_pointers=0;
 
336
    free((unsigned char*) table->sort.record_pointers);
 
337
    table->sort.record_pointers=0;
372
338
  }
373
339
  if (full)
374
340
  {
375
 
    if (sort.sort_keys )
 
341
    if (table->sort.sort_keys )
376
342
    {
377
 
      if ((unsigned char*) sort.sort_keys)
378
 
        free((unsigned char*) sort.sort_keys);
379
 
      sort.sort_keys= 0;
 
343
      if ((unsigned char*) table->sort.sort_keys)
 
344
        free((unsigned char*) table->sort.sort_keys);
 
345
      table->sort.sort_keys= 0;
380
346
    }
381
 
    if (sort.buffpek)
 
347
    if (table->sort.buffpek)
382
348
    {
383
 
      if ((unsigned char*) sort.buffpek)
384
 
        free((unsigned char*) sort.buffpek);
385
 
      sort.buffpek= 0;
386
 
      sort.buffpek_len= 0;
 
349
      if ((unsigned char*) table->sort.buffpek)
 
350
        free((unsigned char*) table->sort.buffpek);
 
351
      table->sort.buffpek= 0;
 
352
      table->sort.buffpek_len= 0;
387
353
    }
388
354
  }
389
 
  if (sort.addon_buf)
 
355
  if (table->sort.addon_buf)
390
356
  {
391
 
    free((char *) sort.addon_buf);
392
 
    free((char *) sort.addon_field);
393
 
    sort.addon_buf=0;
394
 
    sort.addon_field=0;
 
357
    free((char *) table->sort.addon_buf);
 
358
    free((char *) table->sort.addon_field);
 
359
    table->sort.addon_buf=0;
 
360
    table->sort.addon_field=0;
395
361
  }
396
362
}
397
363
 
416
382
 
417
383
/** Read 'count' number of buffer pointers into memory. */
418
384
 
419
 
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffpek_pointers, uint32_t count,
 
385
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
420
386
                                     unsigned char *buf)
421
387
{
422
388
  uint32_t length= sizeof(BUFFPEK)*count;
427
393
    tmp= (unsigned char *)malloc(length);
428
394
  if (tmp)
429
395
  {
430
 
    if (reinit_io_cache(buffpek_pointers,internal::READ_CACHE,0L,0,0) ||
 
396
    if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
431
397
        my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
432
398
    {
433
399
      free((char*) tmp);
475
441
    HA_POS_ERROR on error.
476
442
*/
477
443
 
478
 
static ha_rows find_all_keys(SORTPARAM *param, 
479
 
                             optimizer::SqlSelect *select,
 
444
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
480
445
                             unsigned char **sort_keys,
481
 
                             internal::IO_CACHE *buffpek_pointers,
482
 
                             internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
 
446
                             IO_CACHE *buffpek_pointers,
 
447
                             IO_CACHE *tempfile, IO_CACHE *indexfile)
483
448
{
484
449
  int error,flag,quick_select;
485
450
  uint32_t idx,indexpos,ref_length;
486
451
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
487
 
  internal::my_off_t record;
 
452
  my_off_t record;
488
453
  Table *sort_form;
489
454
  Session *session= current_session;
490
455
  volatile Session::killed_state *killed= &session->killed;
491
 
  Cursor *file;
492
 
  MyBitmap *save_read_set, *save_write_set;
 
456
  handler *file;
 
457
  bitset<MAX_FIELDS> *save_read_set, *save_write_set;
493
458
 
494
459
  idx=indexpos=0;
495
460
  error=quick_select=0;
496
461
  sort_form=param->sort_form;
497
 
  file= sort_form->cursor;
 
462
  file=sort_form->file;
498
463
  ref_length=param->ref_length;
499
464
  ref_pos= ref_buff;
500
465
  quick_select=select && select->quick;
501
466
  record=0;
502
 
  flag= ((!indexfile && ! file->isOrdered())
 
467
  flag= ((!indexfile && file->ha_table_flags() & HA_REC_NOT_IN_SEQ)
503
468
         || quick_select);
504
469
  if (indexfile || flag)
505
470
    ref_pos= &file->ref[0];
525
490
  save_read_set=  sort_form->read_set;
526
491
  save_write_set= sort_form->write_set;
527
492
  /* Set up temporary column read map for columns used by sort */
528
 
  sort_form->tmp_set.clearAll();
 
493
  sort_form->tmp_set.reset();
529
494
  /* Temporary set for register_used_fields and register_field_in_read_map */
530
495
  sort_form->read_set= &sort_form->tmp_set;
531
496
  register_used_fields(param);
549
514
    {
550
515
      if (indexfile)
551
516
      {
552
 
        if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length))
 
517
        if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length)) /* purecov: deadcode */
553
518
        {
554
 
          error= errno ? errno : -1;            /* Abort */
 
519
          error= my_errno ? my_errno : -1;              /* Abort */
555
520
          break;
556
521
        }
557
522
        error=file->rnd_pos(sort_form->record[0],next_pos);
559
524
      else
560
525
      {
561
526
        error=file->rnd_next(sort_form->record[0]);
 
527
        if (!error)
 
528
          update_virtual_fields_marked_for_write(sort_form);
562
529
 
563
530
        if (!flag)
564
531
        {
565
 
          internal::my_store_ptr(ref_pos,ref_length,record); // Position to row
 
532
          my_store_ptr(ref_pos,ref_length,record); // Position to row
566
533
          record+= sort_form->s->db_record_offset;
567
534
        }
568
535
        else if (!error)
579
546
        (void) file->extra(HA_EXTRA_NO_CACHE);
580
547
        file->ha_rnd_end();
581
548
      }
582
 
      return(HA_POS_ERROR);
 
549
      return(HA_POS_ERROR);             /* purecov: inspected */
583
550
    }
584
551
    if (error == 0)
585
552
      param->examined_rows++;
623
590
 
624
591
  if (error != HA_ERR_END_OF_FILE)
625
592
  {
626
 
    sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
627
 
    return(HA_POS_ERROR);
 
593
    file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
 
594
    return(HA_POS_ERROR);                       /* purecov: inspected */
628
595
  }
629
596
  if (indexpos && idx &&
630
597
      write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
631
 
    return(HA_POS_ERROR);
 
598
    return(HA_POS_ERROR);                       /* purecov: inspected */
632
599
  return(my_b_inited(tempfile) ?
633
600
              (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
634
601
              idx);
659
626
 
660
627
static int
661
628
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
662
 
           internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
 
629
           IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
663
630
{
664
631
  size_t sort_length, rec_length;
665
632
  unsigned char **end;
667
634
 
668
635
  sort_length= param->sort_length;
669
636
  rec_length= param->rec_length;
670
 
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
 
637
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
671
638
  if (!my_b_inited(tempfile) &&
672
639
      open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
673
640
                       MYF(MY_WME)))
674
 
    goto err;
 
641
    goto err;                                   /* purecov: inspected */
675
642
  /* check we won't have more buffpeks than we can possibly keep in memory */
676
643
  if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
677
644
    goto err;
678
645
  buffpek.file_pos= my_b_tell(tempfile);
679
646
  if ((ha_rows) count > param->max_rows)
680
 
    count=(uint32_t) param->max_rows;
 
647
    count=(uint32_t) param->max_rows;               /* purecov: inspected */
681
648
  buffpek.count=(ha_rows) count;
682
649
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
683
650
    if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
769
736
            memset(to-1, 0, sort_field->length+1);
770
737
          else
771
738
          {
 
739
            /* purecov: begin deadcode */
772
740
            /*
773
741
              This should only happen during extreme conditions if we run out
774
742
              of memory or have an item marked not null when it can be null.
776
744
            */
777
745
            assert(0);
778
746
            memset(to, 0, sort_field->length);  // Avoid crash
 
747
            /* purecov: end */
779
748
          }
780
749
          break;
781
750
        }
819
788
          int64_t value= item->val_int_result();
820
789
          if (maybe_null)
821
790
          {
822
 
            *to++=1;
 
791
            *to++=1;                            /* purecov: inspected */
823
792
            if (item->null_value)
824
793
            {
825
794
              if (maybe_null)
954
923
{
955
924
  register SORT_FIELD *sort_field;
956
925
  Table *table=param->sort_form;
 
926
  bitset<MAX_FIELDS> *bitmap= table->read_set;
957
927
 
958
928
  for (sort_field= param->local_sortorder ;
959
929
       sort_field != param->end ;
963
933
    if ((field= sort_field->field))
964
934
    {
965
935
      if (field->table == table)
966
 
        table->setReadSet(field->field_index);
 
936
        bitmap->set(field->field_index);
967
937
    }
968
938
    else
969
939
    {                                           // Item
977
947
    SORT_ADDON_FIELD *addonf= param->addon_field;
978
948
    Field *field;
979
949
    for ( ; (field= addonf->field) ; addonf++)
980
 
      table->setReadSet(field->field_index);
 
950
      bitmap->set(field->field_index);
981
951
  }
982
952
  else
983
953
  {
993
963
  uint32_t offset,res_length;
994
964
  unsigned char *to;
995
965
 
996
 
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
 
966
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
997
967
  res_length= param->res_length;
998
968
  offset= param->rec_length-res_length;
999
969
  if ((ha_rows) count > param->max_rows)
1000
970
    count=(uint32_t) param->max_rows;
1001
971
  if (!(to= table_sort->record_pointers=
1002
972
        (unsigned char*) malloc(res_length*count)))
1003
 
    return(1);
 
973
    return(1);                 /* purecov: inspected */
1004
974
  for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
1005
975
  {
1006
976
    memcpy(to, *sort_keys+offset, res_length);
1013
983
/** Merge buffers to make < MERGEBUFF2 buffers. */
1014
984
 
1015
985
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
1016
 
                    BUFFPEK *buffpek, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
 
986
                    BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
1017
987
{
1018
988
  register uint32_t i;
1019
 
  internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
 
989
  IO_CACHE t_file2,*from_file,*to_file,*temp;
1020
990
  BUFFPEK *lastbuff;
1021
991
 
1022
992
  if (*maxbuffer < MERGEBUFF2)
1023
 
    return(0);
 
993
    return(0);                          /* purecov: inspected */
1024
994
  if (flush_io_cache(t_file) ||
1025
995
      open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
1026
996
                        MYF(MY_WME)))
1027
 
    return(1);
 
997
    return(1);                          /* purecov: inspected */
1028
998
 
1029
999
  from_file= t_file ; to_file= &t_file2;
1030
1000
  while (*maxbuffer >= MERGEBUFF2)
1031
1001
  {
1032
 
    if (reinit_io_cache(from_file,internal::READ_CACHE,0L,0,0))
 
1002
    if (reinit_io_cache(from_file,READ_CACHE,0L,0,0))
1033
1003
      goto cleanup;
1034
 
    if (reinit_io_cache(to_file,internal::WRITE_CACHE,0L,0,0))
 
1004
    if (reinit_io_cache(to_file,WRITE_CACHE,0L,0,0))
1035
1005
      goto cleanup;
1036
1006
    lastbuff=buffpek;
1037
1007
    for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
1042
1012
    }
1043
1013
    if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
1044
1014
                      buffpek+i,buffpek+ *maxbuffer,0))
1045
 
      break;
 
1015
      break;                                    /* purecov: inspected */
1046
1016
    if (flush_io_cache(to_file))
1047
 
      break;
 
1017
      break;                                    /* purecov: inspected */
1048
1018
    temp=from_file; from_file=to_file; to_file=temp;
1049
1019
    setup_io_cache(from_file);
1050
1020
    setup_io_cache(to_file);
1069
1039
    (uint32_t)-1 if something goes wrong
1070
1040
*/
1071
1041
 
1072
 
uint32_t read_to_buffer(internal::IO_CACHE *fromfile, BUFFPEK *buffpek,
1073
 
                        uint32_t rec_length)
 
1042
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
 
1043
                    uint32_t rec_length)
1074
1044
{
1075
1045
  register uint32_t count;
1076
1046
  uint32_t length;
1077
1047
 
1078
 
  if ((count= (uint32_t) min((ha_rows) buffpek->max_keys,buffpek->count)))
 
1048
  if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
1079
1049
  {
1080
1050
    if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1081
 
      return((uint32_t) -1);
1082
 
 
1083
 
    buffpek->key= buffpek->base;
 
1051
      return((uint32_t) -1);                    /* purecov: inspected */
 
1052
    buffpek->key=buffpek->base;
1084
1053
    buffpek->file_pos+= length;                 /* New filepos */
1085
 
    buffpek->count-= count;
 
1054
    buffpek->count-=    count;
1086
1055
    buffpek->mem_count= count;
1087
1056
  }
1088
1057
  return (count*rec_length);
1123
1092
    other  error
1124
1093
*/
1125
1094
 
1126
 
int merge_buffers(SORTPARAM *param, internal::IO_CACHE *from_file,
1127
 
                  internal::IO_CACHE *to_file, unsigned char *sort_buffer,
 
1095
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
 
1096
                  IO_CACHE *to_file, unsigned char *sort_buffer,
1128
1097
                  BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1129
1098
                  int flag)
1130
1099
{
1133
1102
  size_t sort_length;
1134
1103
  uint32_t maxcount;
1135
1104
  ha_rows max_rows,org_max_rows;
1136
 
  internal::my_off_t to_start_filepos;
 
1105
  my_off_t to_start_filepos;
1137
1106
  unsigned char *strpos;
1138
1107
  BUFFPEK *buffpek;
1139
1108
  qsort2_cmp cmp;
1168
1137
  }
1169
1138
  else
1170
1139
  {
1171
 
    cmp= internal::get_ptr_compare(sort_length);
 
1140
    cmp= get_ptr_compare(sort_length);
1172
1141
    first_cmp_arg= (void*) &sort_length;
1173
1142
  }
1174
1143
  priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor > 
1180
1149
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
1181
1150
                                                                         rec_length));
1182
1151
    if (error == -1)
1183
 
      goto err;
 
1152
      goto err;                                 /* purecov: inspected */
1184
1153
    buffpek->max_keys= buffpek->mem_count;      // If less data in buffers than expected
1185
1154
    queue.push(buffpek);
1186
1155
  }
1199
1168
    memcpy(param->unique_buff, buffpek->key, rec_length);
1200
1169
    if (my_b_write(to_file, (unsigned char*) buffpek->key, rec_length))
1201
1170
    {
1202
 
      error=1; goto err;
 
1171
      error=1; goto err;                        /* purecov: inspected */
1203
1172
    }
1204
1173
    buffpek->key+= rec_length;
1205
1174
    buffpek->mem_count--;
1206
1175
    if (!--max_rows)
1207
1176
    {
1208
 
      error= 0;
1209
 
      goto end;
 
1177
      error= 0;                                       /* purecov: inspected */
 
1178
      goto end;                                       /* purecov: inspected */
1210
1179
    }
1211
1180
    /* Top element has been used */
1212
1181
    queue.pop();
1219
1188
  {
1220
1189
    if (*killed)
1221
1190
    {
1222
 
      error= 1; goto err;
 
1191
      error= 1; goto err;                        /* purecov: inspected */
1223
1192
    }
1224
1193
    for (;;)
1225
1194
    {
1235
1204
      {
1236
1205
        if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
1237
1206
        {
1238
 
          error=1; goto err;
 
1207
          error=1; goto err;                        /* purecov: inspected */
1239
1208
        }
1240
1209
      }
1241
1210
      else
1242
1211
      {
1243
1212
        if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
1244
1213
        {
1245
 
          error=1; goto err;
 
1214
          error=1; goto err;                        /* purecov: inspected */
1246
1215
        }
1247
1216
      }
1248
1217
      if (!--max_rows)
1249
1218
      {
1250
 
        error= 0;
1251
 
        goto end;
 
1219
        error= 0;                               /* purecov: inspected */
 
1220
        goto end;                               /* purecov: inspected */
1252
1221
      }
1253
1222
 
1254
1223
    skip_duplicate:
1262
1231
          break;                        /* One buffer have been removed */
1263
1232
        }
1264
1233
        else if (error == -1)
1265
 
          goto err;
 
1234
          goto err;                        /* purecov: inspected */
1266
1235
      }
1267
1236
      /* Top element has been replaced */
1268
1237
      queue.pop();
1299
1268
      if (my_b_write(to_file,(unsigned char*) buffpek->key,
1300
1269
                     (rec_length*buffpek->mem_count)))
1301
1270
      {
1302
 
        error= 1; goto err;
 
1271
        error= 1; goto err;                        /* purecov: inspected */
1303
1272
      }
1304
1273
    }
1305
1274
    else
1321
1290
         != -1 && error != 0);
1322
1291
 
1323
1292
end:
1324
 
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
 
1293
  lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
1325
1294
  lastbuff->file_pos= to_start_filepos;
1326
1295
err:
1327
1296
  return(error);
1332
1301
 
1333
1302
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1334
1303
                       BUFFPEK *buffpek, uint32_t maxbuffer,
1335
 
                       internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
 
1304
                       IO_CACHE *tempfile, IO_CACHE *outfile)
1336
1305
{
1337
1306
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1338
1307
                    buffpek+maxbuffer,1))
1339
 
    return(1);
 
1308
    return(1);                          /* purecov: inspected */
1340
1309
  return(0);
1341
1310
} /* merge_index */
1342
1311
 
1357
1326
/**
1358
1327
  Calculate length of sort key.
1359
1328
 
1360
 
  @param session                          Thread Cursor
 
1329
  @param session                          Thread handler
1361
1330
  @param sortorder                Order of items to sort
1362
1331
  @param s_length                 Number of items to sort
1363
1332
  @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
1488
1457
  uint32_t length= 0;
1489
1458
  uint32_t fields= 0;
1490
1459
  uint32_t null_fields= 0;
 
1460
  bitset<MAX_FIELDS> *read_set= (*ptabfield)->table->read_set;
1491
1461
 
1492
1462
  /*
1493
1463
    If there is a reference to a field in the query add it
1502
1472
 
1503
1473
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1504
1474
  {
1505
 
    if (!(field->isReadSet()))
 
1475
    if (!read_set->test(field->field_index))
1506
1476
      continue;
1507
1477
    if (field->flags & BLOB_FLAG)
1508
1478
      return 0;
1525
1495
  null_fields= 0;
1526
1496
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1527
1497
  {
1528
 
    if (!(field->isReadSet()))
 
1498
    if (!read_set->test(field->field_index))
1529
1499
      continue;
1530
1500
    addonf->field= field;
1531
1501
    addonf->offset= length;
1630
1600
    }
1631
1601
  }
1632
1602
}
1633
 
 
1634
 
} /* namespace drizzled */