~drizzle-trunk/drizzle/development

660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1
/* Copyright (C) 2000-2006 MySQL AB
1 by brian
clean slate
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
17
/**
18
  @file
19
20
  @brief
21
  Sorts a database
22
*/
23
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
24
#include <config.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
25
26
#include <float.h>
1241.9.59 by Monty Taylor
Removed the first mystrings header.
27
#include <limits.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
28
29
#include <queue>
30
#include <algorithm>
1996.2.1 by Brian Aker
uuid type code.
31
#include <iostream>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
32
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
33
#include <drizzled/drizzled.h>
34
#include <drizzled/sql_sort.h>
35
#include <drizzled/filesort.h>
36
#include <drizzled/error.h>
37
#include <drizzled/probes.h>
38
#include <drizzled/session.h>
39
#include <drizzled/table.h>
40
#include <drizzled/table_list.h>
41
#include <drizzled/optimizer/range.h>
42
#include <drizzled/records.h>
43
#include <drizzled/internal/iocache.h>
44
#include <drizzled/internal/my_sys.h>
45
#include <plugin/myisam/myisam.h>
46
#include <drizzled/plugin/transactional_storage_engine.h>
47
#include <drizzled/atomics.h>
48
#include <drizzled/global_buffer.h>
2154.2.22 by Brian Aker
Shift CopyField out to its own file.
49
#include <drizzled/sort_field.h>
2198.1.2 by Olaf van der Spek
Refactor includes
50
#include <drizzled/item/subselect.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
51
#include <drizzled/statistics_variables.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
52
#include <drizzled/system_variables.h>
1905.1.1 by Brian Aker
Adding FileSort class.
53
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
54
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
55
2198.1.2 by Olaf van der Spek
Refactor includes
56
namespace drizzled {
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
57
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
58
/* Defines used by filesort and uniques */
59
#define MERGEBUFF		7
60
#define MERGEBUFF2		15
61
62
class BufferCompareContext
63
{
64
public:
65
  qsort_cmp2 key_compare;
66
  void *key_compare_arg;
67
68
  BufferCompareContext() :
69
    key_compare(0),
70
    key_compare_arg(0)
71
  { }
72
73
};
74
75
class SortParam {
76
public:
77
  uint32_t rec_length;          /* Length of sorted records */
78
  uint32_t sort_length;			/* Length of sorted columns */
79
  uint32_t ref_length;			/* Length of record ref. */
80
  uint32_t addon_length;        /* Length of added packed fields */
81
  uint32_t res_length;          /* Length of records in final sorted file/buffer */
82
  uint32_t keys;				/* Max keys / buffer */
83
  ha_rows max_rows,examined_rows;
84
  Table *sort_form;			/* For quicker make_sortkey */
85
  SortField *local_sortorder;
86
  SortField *end;
87
  sort_addon_field *addon_field; /* Descriptors for companion fields */
88
  unsigned char *unique_buff;
89
  bool not_killable;
90
  char *tmp_buffer;
91
  /* The fields below are used only by Unique class */
92
  qsort2_cmp compare;
93
  BufferCompareContext cmp_context;
94
95
  SortParam() :
96
    rec_length(0),
97
    sort_length(0),
98
    ref_length(0),
99
    addon_length(0),
100
    res_length(0),
101
    keys(0),
102
    max_rows(0),
103
    examined_rows(0),
104
    sort_form(0),
105
    local_sortorder(0),
106
    end(0),
107
    addon_field(0),
108
    unique_buff(0),
109
    not_killable(0),
110
    tmp_buffer(0),
111
    compare(0)
112
  {
113
  }
114
115
  ~SortParam()
116
  {
2318.4.9 by Olaf van der Spek
Refactor
117
    free(tmp_buffer);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
118
  }
119
120
  int write_keys(unsigned char * *sort_keys,
121
                 uint32_t count,
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
122
                 internal::io_cache_st *buffer_file,
123
                 internal::io_cache_st *tempfile);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
124
125
  void make_sortkey(unsigned char *to,
126
                    unsigned char *ref_pos);
127
  void register_used_fields();
2318.4.9 by Olaf van der Spek
Refactor
128
  void save_index(unsigned char **sort_keys,
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
129
                  uint32_t count,
130
                  filesort_info *table_sort);
131
132
};
133
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
134
/* functions defined in this file */
1 by brian
clean slate
135
2170.5.1 by Olaf van der Spek
Remove register keyword
136
static char **make_char_array(char **old_pos, uint32_t fields,
641.3.7 by Monty Taylor
More my_malloc removal.
137
                              uint32_t length);
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
138
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
139
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffer_file,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
140
                                             uint32_t count,
141
                                             unsigned char *buf);
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
142
438.1.13 by Brian Aker
uint cleanup.
143
static uint32_t suffix_length(uint32_t string_length);
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
144
static void unpack_addon_fields(sort_addon_field *addon_field,
481 by Brian Aker
Remove all of uchar.
145
                                unsigned char *buff);
1905.1.1 by Brian Aker
Adding FileSort class.
146
147
FileSort::FileSort(Session &arg) :
148
  _session(arg)
149
{ 
150
}
151
1 by brian
clean slate
152
/**
153
  Sort a table.
154
  Creates a set of pointers that can be used to read the rows
155
  in sorted order. This should be done with the functions
156
  in records.cc.
157
158
  Before calling filesort, one must have done
159
  table->file->info(HA_STATUS_VARIABLE)
160
161
  The result set is stored in table->io_cache or
162
  table->record_pointers.
163
164
  @param table		Table to sort
165
  @param sortorder	How to sort the table
166
  @param s_length	Number of elements in sortorder
167
  @param select		condition to apply to the rows
168
  @param max_rows	Return only this many rows
169
  @param sort_positions	Set to 1 if we want to force sorting by position
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
170
			(Needed by UPDATE/INSERT or ALTER Table)
1 by brian
clean slate
171
  @param examined_rows	Store number of examined rows here
172
173
  @todo
174
    check why we do this (param.keys--)
175
  @note
176
    If we sort by position (like if sort_positions is 1) filesort() will
177
    call table->prepare_for_position().
178
179
  @retval
180
    HA_POS_ERROR	Error
181
  @retval
182
    \#			Number of rows
183
  @retval
184
    examined_rows	will be set to number of examined rows
185
*/
186
1905.1.1 by Brian Aker
Adding FileSort class.
187
ha_rows FileSort::run(Table *table, SortField *sortorder, uint32_t s_length,
188
                      optimizer::SqlSelect *select, ha_rows max_rows,
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
189
                      bool sort_positions, ha_rows &examined_rows)
1 by brian
clean slate
190
{
1909 by Brian Aker
Filesort encapsulation, plus modification to copy contructor
191
  int error= 1;
1796.4.1 by Andrew Hutchings
Add initial template work and test
192
  uint32_t memavl= 0, min_sort_memory;
438.1.13 by Brian Aker
uint cleanup.
193
  uint32_t maxbuffer;
1796.4.6 by Andrew Hutchings
Fix global sort buffer usage calculation
194
  size_t allocated_sort_memory= 0;
1909 by Brian Aker
Filesort encapsulation, plus modification to copy contructor
195
  buffpek *buffpek_inst= 0;
1 by brian
clean slate
196
  ha_rows records= HA_POS_ERROR;
481 by Brian Aker
Remove all of uchar.
197
  unsigned char **sort_keys= 0;
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
198
  internal::io_cache_st tempfile;
199
  internal::io_cache_st buffpek_pointers;
200
  internal::io_cache_st *selected_records_file;
201
  internal::io_cache_st *outfile;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
202
  SortParam param;
1 by brian
clean slate
203
  bool multi_byte_charset;
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
204
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
205
  /*
206
    Don't use table->sort in filesort as it is also used by
207
    QuickIndexMergeSelect. Work with a copy and put it back at the end
208
    when index_merge select has finished with it.
209
  */
210
  filesort_info table_sort(table->sort);
211
  table->sort.io_cache= NULL;
212
327.2.4 by Brian Aker
Refactoring table.h
213
  TableList *tab= table->pos_in_table_list;
1 by brian
clean slate
214
  Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
215
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
216
  DRIZZLE_FILESORT_START(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1 by brian
clean slate
217
218
  /*
219
   Release InnoDB's adaptive hash index latch (if holding) before
220
   running a sort.
221
  */
1905.1.1 by Brian Aker
Adding FileSort class.
222
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(&getSession());
1 by brian
clean slate
223
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
224
1 by brian
clean slate
225
  outfile= table_sort.io_cache;
1909 by Brian Aker
Filesort encapsulation, plus modification to copy contructor
226
  assert(tempfile.buffer == 0);
227
  assert(buffpek_pointers.buffer == 0);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
228
1905.1.1 by Brian Aker
Adding FileSort class.
229
  param.sort_length= sortlength(sortorder, s_length, &multi_byte_charset);
1208.3.2 by brian
Update for Cursor renaming.
230
  param.ref_length= table->cursor->ref_length;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
231
1233.1.5 by Brian Aker
More table_flags converted.
232
  if (!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) && !sort_positions)
1 by brian
clean slate
233
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
234
    /*
235
      Get the descriptors of all fields whose values are appended
1 by brian
clean slate
236
      to sorted fields and get its total length in param.spack_length.
237
    */
1905.1.1 by Brian Aker
Adding FileSort class.
238
    param.addon_field= get_addon_fields(table->getFields(),
1 by brian
clean slate
239
                                        param.sort_length,
240
                                        &param.addon_length);
241
  }
242
243
  table_sort.addon_buf= 0;
244
  table_sort.addon_length= param.addon_length;
245
  table_sort.addon_field= param.addon_field;
246
  table_sort.unpack= unpack_addon_fields;
247
  if (param.addon_field)
248
  {
249
    param.res_length= param.addon_length;
2318.4.8 by Olaf van der Spek
Remove malloc NULL check. Just die.
250
    table_sort.addon_buf= (unsigned char *) malloc(param.addon_length);
1 by brian
clean slate
251
  }
252
  else
253
  {
254
    param.res_length= param.ref_length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
255
    /*
256
      The reference to the record is considered
1 by brian
clean slate
257
      as an additional sorted field
258
    */
259
    param.sort_length+= param.ref_length;
260
  }
261
  param.rec_length= param.sort_length+param.addon_length;
262
  param.max_rows= max_rows;
263
264
  if (select && select->quick)
265
  {
1905.1.1 by Brian Aker
Adding FileSort class.
266
    getSession().status_var.filesort_range_count++;
1 by brian
clean slate
267
  }
268
  else
269
  {
1905.1.1 by Brian Aker
Adding FileSort class.
270
    getSession().status_var.filesort_scan_count++;
1 by brian
clean slate
271
  }
272
#ifdef CAN_TRUST_RANGE
273
  if (select && select->quick && select->quick->records > 0L)
274
  {
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
275
    records= min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
1208.3.2 by brian
Update for Cursor renaming.
276
                 table->cursor->stats.records)+EXTRA_RECORDS;
1 by brian
clean slate
277
    selected_records_file=0;
278
  }
279
  else
280
#endif
281
  {
1208.3.2 by brian
Update for Cursor renaming.
282
    records= table->cursor->estimate_rows_upper_bound();
1 by brian
clean slate
283
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
284
      If number of records is not known, use as much of sort buffer
285
      as possible.
1 by brian
clean slate
286
    */
287
    if (records == HA_POS_ERROR)
288
      records--;  // we use 'records+1' below.
289
    selected_records_file= 0;
290
  }
291
2318.4.8 by Olaf van der Spek
Remove malloc NULL check. Just die.
292
  if (multi_byte_charset)
293
    param.tmp_buffer= (char*) malloc(param.sort_length);
1 by brian
clean slate
294
1905.1.1 by Brian Aker
Adding FileSort class.
295
  memavl= getSession().variables.sortbuff_size;
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
296
  min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
1 by brian
clean slate
297
  while (memavl >= min_sort_memory)
298
  {
308 by Brian Aker
ulong conversion
299
    uint32_t old_memavl;
300
    uint32_t keys= memavl/(param.rec_length+sizeof(char*));
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
301
    param.keys= (uint32_t) min(records+1, (ha_rows)keys);
1796.4.8 by Andrew Hutchings
Change default setting
302
303
    allocated_sort_memory= param.keys * param.rec_length;
304
    if (not global_sort_buffer.add(allocated_sort_memory))
305
    {
306
      my_error(ER_OUT_OF_GLOBAL_SORTMEMORY, MYF(ME_ERROR+ME_WAITTANG));
307
      goto err;
308
    }
309
1 by brian
clean slate
310
    if ((table_sort.sort_keys=
481 by Brian Aker
Remove all of uchar.
311
	 (unsigned char **) make_char_array((char **) table_sort.sort_keys,
641.3.7 by Monty Taylor
More my_malloc removal.
312
                                            param.keys, param.rec_length)))
1 by brian
clean slate
313
      break;
1796.4.8 by Andrew Hutchings
Change default setting
314
315
    global_sort_buffer.sub(allocated_sort_memory);
1034.1.6 by Brian Aker
Increase the default sort buffer size.
316
    old_memavl= memavl;
317
    if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
1 by brian
clean slate
318
      memavl= min_sort_memory;
319
  }
320
  sort_keys= table_sort.sort_keys;
321
  if (memavl < min_sort_memory)
322
  {
323
    my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
324
    goto err;
325
  }
1796.4.1 by Andrew Hutchings
Add initial template work and test
326
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
327
  if (buffpek_pointers.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
328
  {
1 by brian
clean slate
329
    goto err;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
330
  }
1 by brian
clean slate
331
332
  param.keys--;  			/* TODO: check why we do this */
333
  param.sort_form= table;
334
  param.end=(param.local_sortorder=sortorder)+s_length;
1905.1.1 by Brian Aker
Adding FileSort class.
335
  if ((records= find_all_keys(&param,select,sort_keys, &buffpek_pointers,
336
                              &tempfile, selected_records_file)) == HA_POS_ERROR)
337
  {
1 by brian
clean slate
338
    goto err;
1905.1.1 by Brian Aker
Adding FileSort class.
339
  }
2385.3.12 by Olaf van der Spek
Refactor iocache
340
  maxbuffer= (uint32_t)(buffpek_pointers.tell() / sizeof(*buffpek_inst));
1 by brian
clean slate
341
342
  if (maxbuffer == 0)			// The whole set is in memory
343
  {
2318.4.9 by Olaf van der Spek
Refactor
344
    param.save_index(sort_keys,(uint32_t) records, &table_sort);
1 by brian
clean slate
345
  }
346
  else
347
  {
348
    if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
349
    {
2318.4.9 by Olaf van der Spek
Refactor
350
      free(table_sort.buffpek);
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
351
      table_sort.buffpek = 0;
1 by brian
clean slate
352
    }
353
    if (!(table_sort.buffpek=
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
354
          (unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer, table_sort.buffpek)))
355
    {
1 by brian
clean slate
356
      goto err;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
357
    }
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
358
    buffpek_inst= (buffpek *) table_sort.buffpek;
1 by brian
clean slate
359
    table_sort.buffpek_len= maxbuffer;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
360
    buffpek_pointers.close_cached_file();
1 by brian
clean slate
361
	/* Open cached file if it isn't open */
2385.3.10 by Olaf van der Spek
Refactor iocache
362
    if (not outfile->inited() && outfile->open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,READ_RECORD_BUFFER, MYF(MY_WME)))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
363
    {
1 by brian
clean slate
364
      goto err;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
365
    }
366
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
367
    if (outfile->reinit_io_cache(internal::WRITE_CACHE,0L,0,0))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
368
    {
1 by brian
clean slate
369
      goto err;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
370
    }
1 by brian
clean slate
371
372
    /*
373
      Use also the space previously used by string pointers in sort_buffer
374
      for temporary key storage.
375
    */
1996.2.1 by Brian Aker
uuid type code.
376
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) / param.rec_length-1);
377
1 by brian
clean slate
378
    maxbuffer--;				// Offset from 0
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
379
    if (merge_many_buff(&param,(unsigned char*) sort_keys,buffpek_inst,&maxbuffer, &tempfile))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
380
    {
381
      goto err;
382
    }
383
2385.3.9 by Olaf van der Spek
Move flush() into iocache
384
    if (tempfile.flush() || tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
385
    {
386
      goto err;
387
    }
388
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
389
    if (merge_index(&param,(unsigned char*) sort_keys,buffpek_inst,maxbuffer,&tempfile, outfile))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
390
    {
1 by brian
clean slate
391
      goto err;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
392
    }
1 by brian
clean slate
393
  }
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
394
1 by brian
clean slate
395
  if (records > param.max_rows)
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
396
  {
1909 by Brian Aker
Filesort encapsulation, plus modification to copy contructor
397
    records= param.max_rows;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
398
  }
1 by brian
clean slate
399
  error =0;
400
401
 err:
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
402
  if (not subselect || not subselect->is_uncacheable())
1 by brian
clean slate
403
  {
1510.3.3 by mordred
Fixed note from cppcheck - passing NULL to free is valid, so the check for non-null here is redundant. Also, casting to unsigned char * is pretty pointless.
404
    free(sort_keys);
1 by brian
clean slate
405
    table_sort.sort_keys= 0;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
406
    free(buffpek_inst);
1 by brian
clean slate
407
    table_sort.buffpek= 0;
408
    table_sort.buffpek_len= 0;
409
  }
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
410
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
411
  tempfile.close_cached_file();
412
  buffpek_pointers.close_cached_file();
1996.2.1 by Brian Aker
uuid type code.
413
2385.3.10 by Olaf van der Spek
Refactor iocache
414
  if (outfile->inited())
1 by brian
clean slate
415
  {
2385.3.9 by Olaf van der Spek
Move flush() into iocache
416
    if (outfile->flush())
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
417
    {
2385.3.10 by Olaf van der Spek
Refactor iocache
418
      error= 1;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
419
    }
1 by brian
clean slate
420
    {
1996.2.1 by Brian Aker
uuid type code.
421
      internal::my_off_t save_pos= outfile->pos_in_file;
1 by brian
clean slate
422
      /* For following reads */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
423
      if (outfile->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
424
      {
2385.3.10 by Olaf van der Spek
Refactor iocache
425
        error=1;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
426
      }
1 by brian
clean slate
427
      outfile->end_of_file=save_pos;
428
    }
429
  }
1996.2.1 by Brian Aker
uuid type code.
430
1 by brian
clean slate
431
  if (error)
1689.5.1 by Joseph Daly
remove increment calls
432
  {
1 by brian
clean slate
433
    my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
434
               MYF(ME_ERROR+ME_WAITTANG));
1689.5.1 by Joseph Daly
remove increment calls
435
  }
1 by brian
clean slate
436
  else
1689.5.1 by Joseph Daly
remove increment calls
437
  {
1905.1.1 by Brian Aker
Adding FileSort class.
438
    getSession().status_var.filesort_rows+= (uint32_t) records;
1689.5.1 by Joseph Daly
remove increment calls
439
  }
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
440
  examined_rows= param.examined_rows;
1796.4.6 by Andrew Hutchings
Fix global sort buffer usage calculation
441
  global_sort_buffer.sub(allocated_sort_memory);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
442
  table->sort= table_sort;
1126.10.9 by Padraig O'Sullivan
Added calls to the filesort dtrace probes.
443
  DRIZZLE_FILESORT_DONE(error, records);
444
  return (error ? HA_POS_ERROR : records);
1 by brian
clean slate
445
} /* filesort */
446
447
/** Make a array of string pointers. */
448
2170.5.1 by Olaf van der Spek
Remove register keyword
449
static char **make_char_array(char **old_pos, uint32_t fields,
641.3.7 by Monty Taylor
More my_malloc removal.
450
                              uint32_t length)
1 by brian
clean slate
451
{
2318.6.1 by Olaf van der Spek
Refactor
452
  if (not old_pos)
453
    old_pos= (char**) malloc((uint32_t) fields * (length + sizeof(char*)));
454
  char** pos= old_pos; 
455
  char* char_pos= ((char*) (pos+fields)) - length;
456
  while (fields--) 
457
    *(pos++) = (char_pos+= length);
458
459
  return old_pos;
1 by brian
clean slate
460
} /* make_char_array */
461
462
463
/** Read 'count' number of buffer pointers into memory. */
464
2385.3.13 by Olaf van der Spek
Refactor iocache
465
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffpek_pointers, uint32_t count, unsigned char *buf)
1 by brian
clean slate
466
{
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
467
  uint32_t length= sizeof(buffpek)*count;
481 by Brian Aker
Remove all of uchar.
468
  unsigned char *tmp= buf;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
469
  if (count > UINT_MAX/sizeof(buffpek))
470
    return 0; /* sizeof(buffpek)*count will overflow */
1 by brian
clean slate
471
  if (!tmp)
641.3.7 by Monty Taylor
More my_malloc removal.
472
    tmp= (unsigned char *)malloc(length);
1 by brian
clean slate
473
  {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
474
    if (buffpek_pointers->reinit_io_cache(internal::READ_CACHE,0L,0,0) ||
2385.3.13 by Olaf van der Spek
Refactor iocache
475
      buffpek_pointers->read(tmp, length))
1 by brian
clean slate
476
    {
2385.3.13 by Olaf van der Spek
Refactor iocache
477
      free(tmp);
478
      tmp= 0;
1 by brian
clean slate
479
    }
480
  }
2385.3.13 by Olaf van der Spek
Refactor iocache
481
  return tmp;
1 by brian
clean slate
482
}
483
484
485
/**
486
  Search after sort_keys and write them into tempfile.
487
  All produced sequences are guaranteed to be non-empty.
488
489
  @param param             Sorting parameter
490
  @param select            Use this to get source data
491
  @param sort_keys         Array of pointers to sort key + addon buffers.
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
492
  @param buffpek_pointers  File to write buffpeks describing sorted segments
1 by brian
clean slate
493
                           in tempfile.
494
  @param tempfile          File to write sorted sequences of sortkeys to.
495
  @param indexfile         If !NULL, use it for source data (contains rowids)
496
497
  @note
498
    Basic idea:
499
    @verbatim
500
     while (get_next_sortkey())
501
     {
502
       if (no free space in sort_keys buffers)
503
       {
504
         sort sort_keys buffer;
505
         dump sorted sequence to 'tempfile';
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
506
         dump buffpek describing sequence location into 'buffpek_pointers';
1 by brian
clean slate
507
       }
508
       put sort key into 'sort_keys';
509
     }
510
     if (sort_keys has some elements && dumped at least once)
511
       sort-dump-dump as above;
512
     else
513
       don't sort, leave sort_keys array to be sorted by caller.
514
  @endverbatim
515
516
  @retval
517
    Number of records written on success.
518
  @retval
519
    HA_POS_ERROR on error.
520
*/
521
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
522
ha_rows FileSort::find_all_keys(SortParam *param, 
1905.1.1 by Brian Aker
Adding FileSort class.
523
                                optimizer::SqlSelect *select,
524
                                unsigned char **sort_keys,
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
525
                                internal::io_cache_st *buffpek_pointers,
526
                                internal::io_cache_st *tempfile, internal::io_cache_st *indexfile)
1 by brian
clean slate
527
{
528
  int error,flag,quick_select;
438.1.13 by Brian Aker
uint cleanup.
529
  uint32_t idx,indexpos,ref_length;
481 by Brian Aker
Remove all of uchar.
530
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
531
  internal::my_off_t record;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
532
  Table *sort_form;
1910.2.8 by Brian Aker
Enapsulate Kill.
533
  volatile Session::killed_state_t *killed= getSession().getKilledPtr();
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
534
  Cursor *file;
1802.16.8 by Padraig O'Sullivan
Removal of all MyBitmap from the code base. Compiles but test failures exist now.
535
  boost::dynamic_bitset<> *save_read_set= NULL;
536
  boost::dynamic_bitset<> *save_write_set= NULL;
1 by brian
clean slate
537
538
  idx=indexpos=0;
539
  error=quick_select=0;
540
  sort_form=param->sort_form;
1208.3.2 by brian
Update for Cursor renaming.
541
  file= sort_form->cursor;
1 by brian
clean slate
542
  ref_length=param->ref_length;
543
  ref_pos= ref_buff;
544
  quick_select=select && select->quick;
545
  record=0;
1220.2.1 by Brian Aker
Move cursor flags up to storage engine flags. These need to be merged.
546
  flag= ((!indexfile && ! file->isOrdered())
1 by brian
clean slate
547
	 || quick_select);
548
  if (indexfile || flag)
549
    ref_pos= &file->ref[0];
550
  next_pos=ref_pos;
551
  if (! indexfile && ! quick_select)
552
  {
481 by Brian Aker
Remove all of uchar.
553
    next_pos=(unsigned char*) 0;			/* Find records in sequence */
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
554
    if (file->startTableScan(1))
555
      return(HA_POS_ERROR);
1905.1.1 by Brian Aker
Adding FileSort class.
556
    file->extra_opt(HA_EXTRA_CACHE, getSession().variables.read_buff_size);
1 by brian
clean slate
557
  }
558
1538 by Brian Aker
Code shuffle on ReadRecord
559
  ReadRecord read_record_info;
1 by brian
clean slate
560
  if (quick_select)
561
  {
562
    if (select->quick->reset())
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
563
      return(HA_POS_ERROR);
1538 by Brian Aker
Code shuffle on ReadRecord
564
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
565
    if (read_record_info.init_read_record(&getSession(), select->quick->head, select, 1, 1))
566
      return(HA_POS_ERROR);
1 by brian
clean slate
567
  }
568
569
  /* Remember original bitmaps */
570
  save_read_set=  sort_form->read_set;
571
  save_write_set= sort_form->write_set;
572
  /* Set up temporary column read map for columns used by sort */
1802.16.8 by Padraig O'Sullivan
Removal of all MyBitmap from the code base. Compiles but test failures exist now.
573
  sort_form->tmp_set.reset();
1 by brian
clean slate
574
  /* Temporary set for register_used_fields and register_field_in_read_map */
575
  sort_form->read_set= &sort_form->tmp_set;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
576
  param->register_used_fields();
1 by brian
clean slate
577
  if (select && select->cond)
578
    select->cond->walk(&Item::register_field_in_read_map, 1,
481 by Brian Aker
Remove all of uchar.
579
                       (unsigned char*) sort_form);
1802.16.8 by Padraig O'Sullivan
Removal of all MyBitmap from the code base. Compiles but test failures exist now.
580
  sort_form->column_bitmaps_set(sort_form->tmp_set, sort_form->tmp_set);
1 by brian
clean slate
581
582
  for (;;)
583
  {
584
    if (quick_select)
585
    {
586
      if ((error= read_record_info.read_record(&read_record_info)))
587
      {
588
        error= HA_ERR_END_OF_FILE;
589
        break;
590
      }
1672.3.6 by Brian Aker
First pass in encapsulating row
591
      file->position(sort_form->getInsertRecord());
1 by brian
clean slate
592
    }
593
    else					/* Not quick-select */
594
    {
595
      if (indexfile)
596
      {
2385.3.13 by Olaf van der Spek
Refactor iocache
597
	if (indexfile->read(ref_pos, ref_length))
1 by brian
clean slate
598
	{
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
599
	  error= errno ? errno : -1;		/* Abort */
1 by brian
clean slate
600
	  break;
601
	}
1672.3.6 by Brian Aker
First pass in encapsulating row
602
	error=file->rnd_pos(sort_form->getInsertRecord(),next_pos);
1 by brian
clean slate
603
      }
604
      else
605
      {
1672.3.6 by Brian Aker
First pass in encapsulating row
606
	error=file->rnd_next(sort_form->getInsertRecord());
383.7.1 by Andrey Zhakov
Initial submit of code and tests
607
1 by brian
clean slate
608
	if (!flag)
609
	{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
610
	  internal::my_store_ptr(ref_pos,ref_length,record); // Position to row
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
611
	  record+= sort_form->getShare()->db_record_offset;
1 by brian
clean slate
612
	}
613
	else if (!error)
1672.3.6 by Brian Aker
First pass in encapsulating row
614
	  file->position(sort_form->getInsertRecord());
1 by brian
clean slate
615
      }
616
      if (error && error != HA_ERR_RECORD_DELETED)
617
	break;
618
    }
619
620
    if (*killed)
621
    {
622
      if (!indexfile && !quick_select)
623
      {
624
        (void) file->extra(HA_EXTRA_NO_CACHE);
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
625
        file->endTableScan();
1 by brian
clean slate
626
      }
971.6.11 by Eric Day
Removed purecov messages.
627
      return(HA_POS_ERROR);
1 by brian
clean slate
628
    }
629
    if (error == 0)
630
      param->examined_rows++;
631
    if (error == 0 && (!select || select->skip_record() == 0))
632
    {
633
      if (idx == param->keys)
634
      {
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
635
	if (param->write_keys(sort_keys, idx, buffpek_pointers, tempfile))
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
636
	  return(HA_POS_ERROR);
1 by brian
clean slate
637
	idx=0;
638
	indexpos++;
639
      }
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
640
      param->make_sortkey(sort_keys[idx++], ref_pos);
1 by brian
clean slate
641
    }
642
    else
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
643
    {
1 by brian
clean slate
644
      file->unlock_row();
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
645
    }
646
1 by brian
clean slate
647
    /* It does not make sense to read more keys in case of a fatal error */
1905.1.1 by Brian Aker
Adding FileSort class.
648
    if (getSession().is_error())
1 by brian
clean slate
649
      break;
650
  }
651
  if (quick_select)
652
  {
653
    /*
654
      index_merge quick select uses table->sort when retrieving rows, so free
655
      resoures it has allocated.
656
    */
1538 by Brian Aker
Code shuffle on ReadRecord
657
    read_record_info.end_read_record();
1 by brian
clean slate
658
  }
659
  else
660
  {
661
    (void) file->extra(HA_EXTRA_NO_CACHE);	/* End cacheing of records */
662
    if (!next_pos)
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
663
      file->endTableScan();
1 by brian
clean slate
664
  }
665
1905.1.1 by Brian Aker
Adding FileSort class.
666
  if (getSession().is_error())
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
667
    return(HA_POS_ERROR);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
668
1 by brian
clean slate
669
  /* Signal we should use orignal column read and write maps */
1802.16.8 by Padraig O'Sullivan
Removal of all MyBitmap from the code base. Compiles but test failures exist now.
670
  sort_form->column_bitmaps_set(*save_read_set, *save_write_set);
1 by brian
clean slate
671
672
  if (error != HA_ERR_END_OF_FILE)
673
  {
1216.1.1 by Brian Aker
Move print_error up to Engine.
674
    sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
971.6.11 by Eric Day
Removed purecov messages.
675
    return(HA_POS_ERROR);
1 by brian
clean slate
676
  }
1996.2.1 by Brian Aker
uuid type code.
677
678
  if (indexpos && idx && param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
679
  {
971.6.11 by Eric Day
Removed purecov messages.
680
    return(HA_POS_ERROR);
1996.2.1 by Brian Aker
uuid type code.
681
  }
682
2385.3.12 by Olaf van der Spek
Refactor iocache
683
  return tempfile->inited() ? (ha_rows) (tempfile->tell() / param->rec_length) : idx;
1 by brian
clean slate
684
} /* find_all_keys */
685
686
687
/**
688
  @details
689
  Sort the buffer and write:
690
  -# the sorted sequence to tempfile
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
691
  -# a buffpek describing the sorted sequence position to buffpek_pointers
1 by brian
clean slate
692
693
    (was: Skriver en buffert med nycklar till filen)
694
695
  @param param             Sort parameters
696
  @param sort_keys         Array of pointers to keys to sort
697
  @param count             Number of elements in sort_keys array
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
698
  @param buffpek_pointers  One 'buffpek' struct will be written into this file.
699
                           The buffpek::{file_pos, count} will indicate where
1 by brian
clean slate
700
                           the sorted data was stored.
701
  @param tempfile          The sorted sequence will be written into this file.
702
703
  @retval
704
    0 OK
705
  @retval
706
    1 Error
707
*/
708
2170.5.1 by Olaf van der Spek
Remove register keyword
709
int SortParam::write_keys(unsigned char **sort_keys, uint32_t count,
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
710
                          internal::io_cache_st *buffpek_pointers, internal::io_cache_st *tempfile)
1 by brian
clean slate
711
{
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
712
  buffpek buffpek;
1 by brian
clean slate
713
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
714
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
2385.3.10 by Olaf van der Spek
Refactor iocache
715
  if (not tempfile->inited() &&
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
716
      tempfile->open_cached_file(drizzle_tmpdir.c_str(), TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
1864.3.19 by Brian Aker
Update to remove additional goto.
717
  {
718
    return 1;
719
  }
1 by brian
clean slate
720
  /* check we won't have more buffpeks than we can possibly keep in memory */
2385.3.12 by Olaf van der Spek
Refactor iocache
721
  if (buffpek_pointers->tell() + sizeof(buffpek) > UINT_MAX)
1864.3.19 by Brian Aker
Update to remove additional goto.
722
  {
723
    return 1;
724
  }
725
2385.3.12 by Olaf van der Spek
Refactor iocache
726
  buffpek.file_pos= tempfile->tell();
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
727
  if ((ha_rows) count > max_rows)
728
    count=(uint32_t) max_rows;
729
1 by brian
clean slate
730
  buffpek.count=(ha_rows) count;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
731
732
  for (unsigned char **ptr= sort_keys + count ; sort_keys != ptr ; sort_keys++)
1864.3.19 by Brian Aker
Update to remove additional goto.
733
  {
2385.3.13 by Olaf van der Spek
Refactor iocache
734
    if (tempfile->write(*sort_keys, rec_length))
1864.3.19 by Brian Aker
Update to remove additional goto.
735
    {
736
      return 1;
737
    }
738
  }
739
2385.3.13 by Olaf van der Spek
Refactor iocache
740
  if (buffpek_pointers->write(&buffpek, sizeof(buffpek)))
1864.3.19 by Brian Aker
Update to remove additional goto.
741
  {
742
    return 1;
743
  }
1 by brian
clean slate
744
1864.3.19 by Brian Aker
Update to remove additional goto.
745
  return 0;
1 by brian
clean slate
746
} /* write_keys */
747
748
749
/**
750
  Store length as suffix in high-byte-first order.
751
*/
752
481 by Brian Aker
Remove all of uchar.
753
static inline void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
1 by brian
clean slate
754
{
755
  switch (pack_length) {
756
  case 1:
481 by Brian Aker
Remove all of uchar.
757
    *to= (unsigned char) length;
1 by brian
clean slate
758
    break;
759
  case 2:
760
    mi_int2store(to, length);
761
    break;
762
  case 3:
763
    mi_int3store(to, length);
764
    break;
765
  default:
766
    mi_int4store(to, length);
767
    break;
768
  }
769
}
770
771
772
/** Make a sort-key from record. */
773
2170.5.1 by Olaf van der Spek
Remove register keyword
774
void SortParam::make_sortkey(unsigned char *to, unsigned char *ref_pos)
1 by brian
clean slate
775
{
1711.6.1 by Brian Aker
Style on structure cleanup
776
  Field *field;
777
  SortField *sort_field;
937.2.7 by Stewart Smith
typesafe set_if_smaller/set_if_greater fixes from Solaris
778
  size_t length;
1 by brian
clean slate
779
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
780
  for (sort_field= local_sortorder ;
781
       sort_field != end ;
1 by brian
clean slate
782
       sort_field++)
783
  {
784
    bool maybe_null=0;
785
    if ((field=sort_field->field))
786
    {						// Field
787
      if (field->maybe_null())
788
      {
789
	if (field->is_null())
790
	{
791
	  if (sort_field->reverse)
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
792
	    memset(to, 255, sort_field->length+1);
1 by brian
clean slate
793
	  else
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
794
	    memset(to, 0, sort_field->length+1);
1 by brian
clean slate
795
	  to+= sort_field->length+1;
796
	  continue;
797
	}
798
	else
799
	  *to++=1;
800
      }
801
      field->sort_string(to, sort_field->length);
802
    }
803
    else
804
    {						// Item
805
      Item *item=sort_field->item;
806
      maybe_null= item->maybe_null;
2008 by Brian Aker
Formatting + remove default from switch/case.
807
1 by brian
clean slate
808
      switch (sort_field->result_type) {
809
      case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
810
        {
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
811
          const charset_info_st * const cs=item->collation.collation;
2008 by Brian Aker
Formatting + remove default from switch/case.
812
          char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
813
          int diff;
814
          uint32_t sort_field_length;
1 by brian
clean slate
815
816
          if (maybe_null)
2008 by Brian Aker
Formatting + remove default from switch/case.
817
            *to++=1;
818
          /* All item->str() to use some extra byte for end null.. */
819
          String tmp((char*) to,sort_field->length+4,cs);
820
          String *res= item->str_result(&tmp);
821
          if (!res)
822
          {
823
            if (maybe_null)
824
              memset(to-1, 0, sort_field->length+1);
825
            else
826
            {
827
              /*
828
                This should only happen during extreme conditions if we run out
829
                of memory or have an item marked not null when it can be null.
830
                This code is here mainly to avoid a hard crash in this case.
831
              */
832
              assert(0);
833
              memset(to, 0, sort_field->length);	// Avoid crash
834
            }
835
            break;
836
          }
837
          length= res->length();
838
          sort_field_length= sort_field->length - sort_field->suffix_length;
839
          diff=(int) (sort_field_length - length);
840
          if (diff < 0)
841
          {
842
            diff=0;
843
            length= sort_field_length;
844
          }
845
          if (sort_field->suffix_length)
846
          {
847
            /* Store length last in result_string */
848
            store_length(to + sort_field_length, length,
849
                         sort_field->suffix_length);
850
          }
851
          if (sort_field->need_strxnfrm)
852
          {
853
            char *from=(char*) res->ptr();
854
            uint32_t tmp_length;
855
            if ((unsigned char*) from == to)
856
            {
857
              set_if_smaller(length,sort_field->length);
858
              memcpy(tmp_buffer,from,length);
859
              from= tmp_buffer;
860
            }
2445.1.4 by Olaf van der Spek
Refactor
861
            tmp_length= cs->strnxfrm(to,sort_field->length, (unsigned char*) from, length);
2008 by Brian Aker
Formatting + remove default from switch/case.
862
            assert(tmp_length == sort_field->length);
863
          }
1 by brian
clean slate
864
          else
865
          {
2445.1.4 by Olaf van der Spek
Refactor
866
            cs->strnxfrm((unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
2008 by Brian Aker
Formatting + remove default from switch/case.
867
            cs->cset->fill(cs, (char *)to+length,diff,fill_char);
1 by brian
clean slate
868
          }
869
          break;
870
        }
871
      case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
872
        {
152 by Brian Aker
longlong replacement
873
          int64_t value= item->val_int_result();
1 by brian
clean slate
874
          if (maybe_null)
875
          {
2008 by Brian Aker
Formatting + remove default from switch/case.
876
            *to++=1;
1 by brian
clean slate
877
            if (item->null_value)
878
            {
879
              if (maybe_null)
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
880
                memset(to-1, 0, sort_field->length+1);
1 by brian
clean slate
881
              else
882
              {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
883
                memset(to, 0, sort_field->length);
1 by brian
clean slate
884
              }
885
              break;
886
            }
887
          }
2008 by Brian Aker
Formatting + remove default from switch/case.
888
          to[7]= (unsigned char) value;
889
          to[6]= (unsigned char) (value >> 8);
890
          to[5]= (unsigned char) (value >> 16);
891
          to[4]= (unsigned char) (value >> 24);
892
          to[3]= (unsigned char) (value >> 32);
893
          to[2]= (unsigned char) (value >> 40);
894
          to[1]= (unsigned char) (value >> 48);
1 by brian
clean slate
895
          if (item->unsigned_flag)                    /* Fix sign */
481 by Brian Aker
Remove all of uchar.
896
            to[0]= (unsigned char) (value >> 56);
1 by brian
clean slate
897
          else
481 by Brian Aker
Remove all of uchar.
898
            to[0]= (unsigned char) (value >> 56) ^ 128;	/* Reverse signbit */
2008 by Brian Aker
Formatting + remove default from switch/case.
899
          break;
900
        }
1 by brian
clean slate
901
      case DECIMAL_RESULT:
902
        {
2030.1.4 by Brian Aker
Change my_decimal to Decimal
903
          type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
1 by brian
clean slate
904
          if (maybe_null)
905
          {
906
            if (item->null_value)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
907
            {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
908
              memset(to, 0, sort_field->length+1);
1 by brian
clean slate
909
              to++;
910
              break;
911
            }
912
            *to++=1;
913
          }
2034.2.3 by Brian Aker
More encapsulation around Decimal.
914
          dec_val->val_binary(E_DEC_FATAL_ERROR, to,
915
                              item->max_length - (item->decimals ? 1:0),
916
                              item->decimals);
2008 by Brian Aker
Formatting + remove default from switch/case.
917
          break;
1 by brian
clean slate
918
        }
919
      case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
920
        {
1 by brian
clean slate
921
          double value= item->val_result();
2008 by Brian Aker
Formatting + remove default from switch/case.
922
          if (maybe_null)
1 by brian
clean slate
923
          {
924
            if (item->null_value)
925
            {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
926
              memset(to, 0, sort_field->length+1);
1 by brian
clean slate
927
              to++;
928
              break;
929
            }
2008 by Brian Aker
Formatting + remove default from switch/case.
930
            *to++=1;
1 by brian
clean slate
931
          }
2008 by Brian Aker
Formatting + remove default from switch/case.
932
          change_double_for_sort(value,(unsigned char*) to);
933
          break;
934
        }
1 by brian
clean slate
935
      case ROW_RESULT:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
936
      default:
2008 by Brian Aker
Formatting + remove default from switch/case.
937
        // This case should never be choosen
938
        assert(0);
939
        break;
1 by brian
clean slate
940
      }
941
    }
2008 by Brian Aker
Formatting + remove default from switch/case.
942
1 by brian
clean slate
943
    if (sort_field->reverse)
944
    {							/* Revers key */
945
      if (maybe_null)
946
        to[-1]= ~to[-1];
947
      length=sort_field->length;
948
      while (length--)
949
      {
481 by Brian Aker
Remove all of uchar.
950
	*to = (unsigned char) (~ *to);
1 by brian
clean slate
951
	to++;
952
      }
953
    }
954
    else
2008 by Brian Aker
Formatting + remove default from switch/case.
955
    {
1 by brian
clean slate
956
      to+= sort_field->length;
2008 by Brian Aker
Formatting + remove default from switch/case.
957
    }
1 by brian
clean slate
958
  }
959
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
960
  if (addon_field)
1 by brian
clean slate
961
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
962
    /*
1 by brian
clean slate
963
      Save field values appended to sorted fields.
964
      First null bit indicators are appended then field values follow.
965
      In this implementation we use fixed layout for field values -
966
      the same for all records.
967
    */
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
968
    sort_addon_field *addonf= addon_field;
481 by Brian Aker
Remove all of uchar.
969
    unsigned char *nulls= to;
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
970
    assert(addonf != 0);
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
971
    memset(nulls, 0, addonf->offset);
1 by brian
clean slate
972
    to+= addonf->offset;
973
    for ( ; (field= addonf->field) ; addonf++)
974
    {
975
      if (addonf->null_bit && field->is_null())
976
      {
977
        nulls[addonf->null_offset]|= addonf->null_bit;
1859.2.14 by Brian Aker
Add support for --with-valgrind
978
#ifdef HAVE_VALGRIND
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
979
	memset(to, 0, addonf->length);
1 by brian
clean slate
980
#endif
981
      }
982
      else
983
      {
1859.2.14 by Brian Aker
Add support for --with-valgrind
984
#ifdef HAVE_VALGRIND
481 by Brian Aker
Remove all of uchar.
985
        unsigned char *end= field->pack(to, field->ptr);
1859.2.14 by Brian Aker
Add support for --with-valgrind
986
	uint32_t local_length= (uint32_t) ((to + addonf->length) - end);
987
	assert((int) local_length >= 0);
988
	if (local_length)
989
	  memset(end, 0, local_length);
1 by brian
clean slate
990
#else
991
        (void) field->pack(to, field->ptr);
992
#endif
993
      }
994
      to+= addonf->length;
995
    }
996
  }
997
  else
998
  {
999
    /* Save filepos last */
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1000
    memcpy(to, ref_pos, (size_t) ref_length);
1 by brian
clean slate
1001
  }
1002
}
1003
1004
1005
/*
2170.5.1 by Olaf van der Spek
Remove register keyword
1006
  fields used by sorting in the sorted table's read set
1 by brian
clean slate
1007
*/
1008
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1009
void SortParam::register_used_fields()
1 by brian
clean slate
1010
{
1711.6.1 by Brian Aker
Style on structure cleanup
1011
  SortField *sort_field;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1012
  Table *table= sort_form;
1 by brian
clean slate
1013
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1014
  for (sort_field= local_sortorder ;
1015
       sort_field != end ;
1 by brian
clean slate
1016
       sort_field++)
1017
  {
1018
    Field *field;
1019
    if ((field= sort_field->field))
1020
    {
1660.1.3 by Brian Aker
Encapsulate Table in field
1021
      if (field->getTable() == table)
1999.4.2 by Brian Aker
Encapsulate the field's position.
1022
        table->setReadSet(field->position());
1 by brian
clean slate
1023
    }
1024
    else
1025
    {						// Item
1026
      sort_field->item->walk(&Item::register_field_in_read_map, 1,
481 by Brian Aker
Remove all of uchar.
1027
                             (unsigned char *) table);
1 by brian
clean slate
1028
    }
1029
  }
1030
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1031
  if (addon_field)
1 by brian
clean slate
1032
  {
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1033
    sort_addon_field *addonf= addon_field;
1 by brian
clean slate
1034
    Field *field;
1035
    for ( ; (field= addonf->field) ; addonf++)
1999.4.2 by Brian Aker
Encapsulate the field's position.
1036
      table->setReadSet(field->position());
1 by brian
clean slate
1037
  }
1038
  else
1039
  {
1040
    /* Save filepos last */
1041
    table->prepare_for_position();
1042
  }
1043
}
1044
1045
2318.4.9 by Olaf van der Spek
Refactor
1046
void SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1 by brian
clean slate
1047
{
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1048
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
2318.4.9 by Olaf van der Spek
Refactor
1049
  uint32_t offset= rec_length - res_length;
1996.2.1 by Brian Aker
uuid type code.
1050
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1051
  if ((ha_rows) count > max_rows)
1052
    count=(uint32_t) max_rows;
1996.2.1 by Brian Aker
uuid type code.
1053
2318.4.9 by Olaf van der Spek
Refactor
1054
  unsigned char* to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1055
1056
  for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1 by brian
clean slate
1057
  {
1058
    memcpy(to, *sort_keys+offset, res_length);
1059
    to+= res_length;
1060
  }
1061
}
1062
1063
1064
/** Merge buffers to make < MERGEBUFF2 buffers. */
1065
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1066
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
1067
                              buffpek *buffpek_inst, uint32_t *maxbuffer, internal::io_cache_st *t_file)
1 by brian
clean slate
1068
{
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
1069
  internal::io_cache_st t_file2,*from_file,*to_file,*temp;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1070
  buffpek *lastbuff;
1 by brian
clean slate
1071
1072
  if (*maxbuffer < MERGEBUFF2)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1073
    return 0;
2385.3.9 by Olaf van der Spek
Move flush() into iocache
1074
  if (t_file->flush() ||
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
1075
      t_file2.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,DISK_BUFFER_SIZE, MYF(MY_WME)))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1076
  {
1077
    return 1;
1078
  }
1 by brian
clean slate
1079
1080
  from_file= t_file ; to_file= &t_file2;
1081
  while (*maxbuffer >= MERGEBUFF2)
1082
  {
2385.3.9 by Olaf van der Spek
Move flush() into iocache
1083
    if (from_file->reinit_io_cache(internal::READ_CACHE, 0, 0, 0)
1084
      || to_file->reinit_io_cache(internal::WRITE_CACHE, 0, 0, 0))
1085
      break;
1086
1087
    uint32_t i= 0;
1088
    lastbuff= buffpek_inst;
1089
    for (; i <= *maxbuffer - MERGEBUFF * 3 / 2; i += MERGEBUFF)
1090
    {
1091
      if (merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, buffpek_inst + i, buffpek_inst + i + MERGEBUFF - 1, 0))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1092
      {
1093
        goto cleanup;
1094
      }
1 by brian
clean slate
1095
    }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1096
2385.3.9 by Olaf van der Spek
Move flush() into iocache
1097
    if (merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, buffpek_inst + i, buffpek_inst + *maxbuffer, 0)
1098
      || to_file->flush())
1099
      break;
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1100
1 by brian
clean slate
1101
    temp=from_file; from_file=to_file; to_file=temp;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1102
    from_file->setup_io_cache();
1103
    to_file->setup_io_cache();
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1104
    *maxbuffer= (uint32_t) (lastbuff-buffpek_inst)-1;
1 by brian
clean slate
1105
  }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1106
1 by brian
clean slate
1107
cleanup:
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1108
  to_file->close_cached_file();			// This holds old result
1 by brian
clean slate
1109
  if (to_file == t_file)
1110
  {
1111
    *t_file=t_file2;				// Copy result file
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1112
    t_file->setup_io_cache();
1 by brian
clean slate
1113
  }
1114
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
1115
  return(*maxbuffer >= MERGEBUFF2);	/* Return 1 if interrupted */
1 by brian
clean slate
1116
} /* merge_many_buff */
1117
1118
1119
/**
1120
  Read data to buffer.
1121
1122
  @retval
438.1.13 by Brian Aker
uint cleanup.
1123
    (uint32_t)-1 if something goes wrong
1 by brian
clean slate
1124
*/
1125
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
1126
uint32_t FileSort::read_to_buffer(internal::io_cache_st *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1 by brian
clean slate
1127
{
2170.5.1 by Olaf van der Spek
Remove register keyword
1128
  uint32_t count;
438.1.13 by Brian Aker
uint cleanup.
1129
  uint32_t length;
1 by brian
clean slate
1130
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1131
  if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1 by brian
clean slate
1132
  {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1133
    if (pread(fromfile->file,(unsigned char*) buffpek_inst->base, (length= rec_length*count),buffpek_inst->file_pos) == 0)
971.6.11 by Eric Day
Removed purecov messages.
1134
      return((uint32_t) -1);
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1135
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1136
    buffpek_inst->key= buffpek_inst->base;
1137
    buffpek_inst->file_pos+= length;			/* New filepos */
1138
    buffpek_inst->count-= count;
1139
    buffpek_inst->mem_count= count;
1 by brian
clean slate
1140
  }
1141
  return (count*rec_length);
1142
} /* read_to_buffer */
1143
1144
897.1.11 by Padraig
Giving function object a better name for this scenario.
1145
class compare_functor
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1146
{
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
1147
  qsort2_cmp key_compare;
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1148
  void *key_compare_arg;
1996.2.1 by Brian Aker
uuid type code.
1149
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1150
  public:
1996.2.1 by Brian Aker
uuid type code.
1151
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg) :
1152
    key_compare(in_key_compare),
1153
    key_compare_arg(in_compare_arg)
1154
  { }
1155
  
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1156
  inline bool operator()(const buffpek *i, const buffpek *j) const
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1157
  {
1996.2.1 by Brian Aker
uuid type code.
1158
    int val= key_compare(key_compare_arg, &i->key, &j->key);
1159
897.1.18 by Padraig O'Sullivan
Cleaning up my function object a little bit.
1160
    return (val >= 0);
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1161
  }
1162
};
1163
1 by brian
clean slate
1164
1165
/**
1166
  Merge buffers to one buffer.
1167
1168
  @param param        Sort parameter
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1169
  @param from_file    File with source data (buffpeks point to this file)
1 by brian
clean slate
1170
  @param to_file      File to write the sorted result data.
1171
  @param sort_buffer  Buffer for data to store up to MERGEBUFF2 sort keys.
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1172
  @param lastbuff     OUT Store here buffpek describing data written to to_file
1173
  @param Fb           First element in source buffpeks array
1174
  @param Tb           Last element in source buffpeks array
1 by brian
clean slate
1175
  @param flag
1176
1177
  @retval
1178
    0      OK
1179
  @retval
1180
    other  error
1181
*/
1182
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
1183
int FileSort::merge_buffers(SortParam *param, internal::io_cache_st *from_file,
1184
                            internal::io_cache_st *to_file, unsigned char *sort_buffer,
1905.1.2 by Brian Aker
Filesort fix.
1185
                            buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1186
                            int flag)
1 by brian
clean slate
1187
{
1188
  int error;
438.1.13 by Brian Aker
uint cleanup.
1189
  uint32_t rec_length,res_length,offset;
1 by brian
clean slate
1190
  size_t sort_length;
308 by Brian Aker
ulong conversion
1191
  uint32_t maxcount;
1 by brian
clean slate
1192
  ha_rows max_rows,org_max_rows;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1193
  internal::my_off_t to_start_filepos;
481 by Brian Aker
Remove all of uchar.
1194
  unsigned char *strpos;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1195
  buffpek *buffpek_inst;
1 by brian
clean slate
1196
  qsort2_cmp cmp;
1197
  void *first_cmp_arg;
1910.2.8 by Brian Aker
Enapsulate Kill.
1198
  volatile Session::killed_state_t *killed= getSession().getKilledPtr();
1199
  Session::killed_state_t not_killable;
1 by brian
clean slate
1200
1905.1.2 by Brian Aker
Filesort fix.
1201
  getSession().status_var.filesort_merge_passes++;
1 by brian
clean slate
1202
  if (param->not_killable)
1203
  {
1204
    killed= &not_killable;
520.1.21 by Brian Aker
THD -> Session rename
1205
    not_killable= Session::NOT_KILLED;
1 by brian
clean slate
1206
  }
1207
1208
  error=0;
1209
  rec_length= param->rec_length;
1210
  res_length= param->res_length;
1211
  sort_length= param->sort_length;
1212
  offset= rec_length-res_length;
438.1.13 by Brian Aker
uint cleanup.
1213
  maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
2385.3.12 by Olaf van der Spek
Refactor iocache
1214
  to_start_filepos= to_file->tell();
481 by Brian Aker
Remove all of uchar.
1215
  strpos= (unsigned char*) sort_buffer;
1 by brian
clean slate
1216
  org_max_rows=max_rows= param->max_rows;
1217
1218
  /* The following will fire if there is not enough space in sort_buffer */
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
1219
  assert(maxcount!=0);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1220
1 by brian
clean slate
1221
  if (param->unique_buff)
1222
  {
1223
    cmp= param->compare;
1224
    first_cmp_arg= (void *) &param->cmp_context;
1225
  }
1226
  else
1227
  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1228
    cmp= internal::get_ptr_compare(sort_length);
1 by brian
clean slate
1229
    first_cmp_arg= (void*) &sort_length;
1230
  }
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1231
  priority_queue<buffpek *, vector<buffpek *>, compare_functor >
897.1.11 by Padraig
Giving function object a better name for this scenario.
1232
    queue(compare_functor(cmp, first_cmp_arg));
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1233
  for (buffpek_inst= Fb ; buffpek_inst <= Tb ; buffpek_inst++)
1 by brian
clean slate
1234
  {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1235
    buffpek_inst->base= strpos;
1236
    buffpek_inst->max_keys= maxcount;
1237
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek_inst,
1 by brian
clean slate
1238
                                                                         rec_length));
1239
    if (error == -1)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1240
      return -1;
1241
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1242
    buffpek_inst->max_keys= buffpek_inst->mem_count;	// If less data in buffers than expected
1243
    queue.push(buffpek_inst);
1 by brian
clean slate
1244
  }
1245
1246
  if (param->unique_buff)
1247
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1248
    /*
1 by brian
clean slate
1249
       Called by Unique::get()
1250
       Copy the first argument to param->unique_buff for unique removal.
1251
       Store it also in 'to_file'.
1252
1253
       This is safe as we know that there is always more than one element
1254
       in each block to merge (This is guaranteed by the Unique:: algorithm
1255
    */
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1256
    buffpek_inst= queue.top();
1257
    memcpy(param->unique_buff, buffpek_inst->key, rec_length);
2385.3.13 by Olaf van der Spek
Refactor iocache
1258
    if (to_file->write(buffpek_inst->key, rec_length))
1 by brian
clean slate
1259
    {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1260
      return 1;
1 by brian
clean slate
1261
    }
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1262
    buffpek_inst->key+= rec_length;
1263
    buffpek_inst->mem_count--;
1 by brian
clean slate
1264
    if (!--max_rows)
1265
    {
971.6.11 by Eric Day
Removed purecov messages.
1266
      error= 0;
1267
      goto end;
1 by brian
clean slate
1268
    }
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1269
    /* Top element has been used */
1270
    queue.pop();
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1271
    queue.push(buffpek_inst);
1 by brian
clean slate
1272
  }
1273
  else
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1274
  {
1 by brian
clean slate
1275
    cmp= 0;                                        // Not unique
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1276
  }
1 by brian
clean slate
1277
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
1278
  while (queue.size() > 1)
1 by brian
clean slate
1279
  {
1280
    if (*killed)
1281
    {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1282
      return 1;
1 by brian
clean slate
1283
    }
1284
    for (;;)
1285
    {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1286
      buffpek_inst= queue.top();
1 by brian
clean slate
1287
      if (cmp)                                        // Remove duplicates
1288
      {
1289
        if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1290
                    (unsigned char**) &buffpek_inst->key))
1 by brian
clean slate
1291
              goto skip_duplicate;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1292
            memcpy(param->unique_buff, buffpek_inst->key, rec_length);
1 by brian
clean slate
1293
      }
1294
      if (flag == 0)
1295
      {
2385.3.13 by Olaf van der Spek
Refactor iocache
1296
        if (to_file->write(buffpek_inst->key, rec_length))
1 by brian
clean slate
1297
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1298
          return 1;
1 by brian
clean slate
1299
        }
1300
      }
1301
      else
1302
      {
2385.3.13 by Olaf van der Spek
Refactor iocache
1303
        if (to_file->write(buffpek_inst->key+offset, res_length))
1 by brian
clean slate
1304
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1305
          return 1;
1 by brian
clean slate
1306
        }
1307
      }
1308
      if (!--max_rows)
1309
      {
971.6.11 by Eric Day
Removed purecov messages.
1310
        error= 0;
1311
        goto end;
1 by brian
clean slate
1312
      }
1313
1314
    skip_duplicate:
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1315
      buffpek_inst->key+= rec_length;
1316
      if (! --buffpek_inst->mem_count)
1 by brian
clean slate
1317
      {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1318
        if (!(error= (int) read_to_buffer(from_file,buffpek_inst,
1 by brian
clean slate
1319
                                          rec_length)))
1320
        {
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1321
          queue.pop();
1 by brian
clean slate
1322
          break;                        /* One buffer have been removed */
1323
        }
1324
        else if (error == -1)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1325
        {
1326
          return -1;
1327
        }
1 by brian
clean slate
1328
      }
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1329
      /* Top element has been replaced */
1330
      queue.pop();
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1331
      queue.push(buffpek_inst);
1 by brian
clean slate
1332
    }
1333
  }
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1334
  buffpek_inst= queue.top();
1335
  buffpek_inst->base= sort_buffer;
1336
  buffpek_inst->max_keys= param->keys;
1 by brian
clean slate
1337
1338
  /*
1339
    As we know all entries in the buffer are unique, we only have to
1340
    check if the first one is the same as the last one we wrote
1341
  */
1342
  if (cmp)
1343
  {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1344
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (unsigned char**) &buffpek_inst->key))
1 by brian
clean slate
1345
    {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1346
      buffpek_inst->key+= rec_length;         // Remove duplicate
1347
      --buffpek_inst->mem_count;
1 by brian
clean slate
1348
    }
1349
  }
1350
1351
  do
1352
  {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1353
    if ((ha_rows) buffpek_inst->mem_count > max_rows)
1 by brian
clean slate
1354
    {                                        /* Don't write too many records */
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1355
      buffpek_inst->mem_count= (uint32_t) max_rows;
1356
      buffpek_inst->count= 0;                        /* Don't read more */
1 by brian
clean slate
1357
    }
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1358
    max_rows-= buffpek_inst->mem_count;
1 by brian
clean slate
1359
    if (flag == 0)
1360
    {
2385.3.13 by Olaf van der Spek
Refactor iocache
1361
      if (to_file->write(buffpek_inst->key, (rec_length*buffpek_inst->mem_count)))
1 by brian
clean slate
1362
      {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1363
        return 1;
1 by brian
clean slate
1364
      }
1365
    }
1366
    else
1367
    {
2170.5.1 by Olaf van der Spek
Remove register keyword
1368
      unsigned char *end;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1369
      strpos= buffpek_inst->key+offset;
1370
      for (end= strpos+buffpek_inst->mem_count*rec_length ;
1 by brian
clean slate
1371
           strpos != end ;
1372
           strpos+= rec_length)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1373
      {
2385.3.13 by Olaf van der Spek
Refactor iocache
1374
        if (to_file->write(strpos, res_length))
1 by brian
clean slate
1375
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1376
          return 1;
1 by brian
clean slate
1377
        }
1378
      }
1379
    }
1380
  }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1381
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1382
  while ((error=(int) read_to_buffer(from_file,buffpek_inst, rec_length))
1 by brian
clean slate
1383
         != -1 && error != 0);
1384
1385
end:
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1386
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1 by brian
clean slate
1387
  lastbuff->file_pos= to_start_filepos;
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1388
1389
  return error;
1 by brian
clean slate
1390
} /* merge_buffers */
1391
1392
1393
	/* Do a merge to output-file (save only positions) */
1394
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1395
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1905.1.2 by Brian Aker
Filesort fix.
1396
                          buffpek *buffpek_inst, uint32_t maxbuffer,
2296.1.1 by Mark Atwood
Merge in Fixes of Brian's IOCACHE.
1397
                          internal::io_cache_st *tempfile, internal::io_cache_st *outfile)
1 by brian
clean slate
1398
{
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1399
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1400
		    buffpek_inst+maxbuffer,1))
1905.1.2 by Brian Aker
Filesort fix.
1401
    return 1;
1402
1403
  return 0;
1 by brian
clean slate
1404
} /* merge_index */
1405
1406
438.1.13 by Brian Aker
uint cleanup.
1407
static uint32_t suffix_length(uint32_t string_length)
1 by brian
clean slate
1408
{
1409
  if (string_length < 256)
1410
    return 1;
1411
  if (string_length < 256L*256L)
1412
    return 2;
1413
  if (string_length < 256L*256L*256L)
1414
    return 3;
1415
  return 4;                                     // Can't sort longer than 4G
1416
}
1417
1418
1419
1420
/**
1421
  Calculate length of sort key.
1422
1423
  @param sortorder		  Order of items to sort
1424
  @param s_length	          Number of items to sort
1425
  @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
1426
                                 (In which case we have to use strxnfrm())
1427
1428
  @note
1429
    sortorder->length is updated for each sort item.
1430
  @n
1431
    sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
1432
1433
  @return
1434
    Total length of sort buffer in bytes
1435
*/
1436
1905.1.1 by Brian Aker
Adding FileSort class.
1437
uint32_t FileSort::sortlength(SortField *sortorder, uint32_t s_length, bool *multi_byte_charset)
1 by brian
clean slate
1438
{
2170.5.1 by Olaf van der Spek
Remove register keyword
1439
  uint32_t length;
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
1440
  const charset_info_st *cs;
1 by brian
clean slate
1441
  *multi_byte_charset= 0;
1442
1443
  length=0;
1444
  for (; s_length-- ; sortorder++)
1445
  {
1446
    sortorder->need_strxnfrm= 0;
1447
    sortorder->suffix_length= 0;
1448
    if (sortorder->field)
1449
    {
1450
      cs= sortorder->field->sort_charset();
1451
      sortorder->length= sortorder->field->sort_length();
2445.1.4 by Olaf van der Spek
Refactor
1452
      cs= sortorder->field->sort_charset();
1453
      if (cs->use_strnxfrm())
1 by brian
clean slate
1454
      {
1455
        sortorder->need_strxnfrm= 1;
1456
        *multi_byte_charset= 1;
1457
        sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1458
      }
1459
      if (sortorder->field->maybe_null())
1460
	length++;				// Place for NULL marker
1461
    }
1462
    else
1463
    {
1464
      sortorder->result_type= sortorder->item->result_type();
152 by Brian Aker
longlong replacement
1465
      if (sortorder->item->result_as_int64_t())
1 by brian
clean slate
1466
        sortorder->result_type= INT_RESULT;
2008 by Brian Aker
Formatting + remove default from switch/case.
1467
1 by brian
clean slate
1468
      switch (sortorder->result_type) {
1469
      case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1470
        sortorder->length=sortorder->item->max_length;
2445.1.4 by Olaf van der Spek
Refactor
1471
        set_if_smaller(sortorder->length, getSession().variables.max_sort_length);
1472
        cs= sortorder->item->collation.collation;
1473
        if (cs->use_strnxfrm())
2008 by Brian Aker
Formatting + remove default from switch/case.
1474
        {
1 by brian
clean slate
1475
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
2008 by Brian Aker
Formatting + remove default from switch/case.
1476
          sortorder->need_strxnfrm= 1;
1477
          *multi_byte_charset= 1;
1478
        }
1 by brian
clean slate
1479
        else if (cs == &my_charset_bin)
1480
        {
1481
          /* Store length last to be able to sort blob/varbinary */
1482
          sortorder->suffix_length= suffix_length(sortorder->length);
1483
          sortorder->length+= sortorder->suffix_length;
1484
        }
2008 by Brian Aker
Formatting + remove default from switch/case.
1485
        break;
1 by brian
clean slate
1486
      case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1487
        sortorder->length=8;			// Size of intern int64_t
1488
        break;
1 by brian
clean slate
1489
      case DECIMAL_RESULT:
1490
        sortorder->length=
2030.1.2 by Brian Aker
First pass in refactoring of the name of my_decimal.
1491
          class_decimal_get_binary_size(sortorder->item->max_length -
1 by brian
clean slate
1492
                                     (sortorder->item->decimals ? 1 : 0),
1493
                                     sortorder->item->decimals);
1494
        break;
1495
      case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1496
        sortorder->length=sizeof(double);
1497
        break;
1 by brian
clean slate
1498
      case ROW_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1499
        // This case should never be choosen
1500
        assert(0);
1501
        break;
1 by brian
clean slate
1502
      }
1503
      if (sortorder->item->maybe_null)
2008 by Brian Aker
Formatting + remove default from switch/case.
1504
        length++;				// Place for NULL marker
1 by brian
clean slate
1505
    }
1905.1.1 by Brian Aker
Adding FileSort class.
1506
    set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1 by brian
clean slate
1507
    length+=sortorder->length;
1508
  }
1509
  sortorder->field= (Field*) 0;			// end marker
1510
  return length;
1511
}
1512
1513
1514
/**
1515
  Get descriptors of fields appended to sorted fields and
1516
  calculate its total length.
1517
1518
  The function first finds out what fields are used in the result set.
1519
  Then it calculates the length of the buffer to store the values of
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1520
  these fields together with the value of sort values.
1 by brian
clean slate
1521
  If the calculated length is not greater than max_length_for_sort_data
1522
  the function allocates memory for an array of descriptors containing
1523
  layouts for the values of the non-sorted fields in the buffer and
1524
  fills them.
1525
1526
  @param ptabfield           Array of references to the table fields
1527
  @param sortlength          Total length of sorted fields
1528
  @param[out] plength        Total length of appended fields
1529
1530
  @note
1531
    The null bits for the appended values are supposed to be put together
1532
    and stored the buffer just ahead of the value of the first field.
1533
1534
  @return
1535
    Pointer to the layout descriptors for the appended fields, if any
1536
  @retval
1537
    NULL   if we do not store field values with sort data.
1538
*/
1539
1905.1.1 by Brian Aker
Adding FileSort class.
1540
sort_addon_field *FileSort::get_addon_fields(Field **ptabfield, uint32_t sortlength_arg, uint32_t *plength)
1 by brian
clean slate
1541
{
1542
  Field **pfield;
1543
  Field *field;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1544
  sort_addon_field *addonf;
438.1.13 by Brian Aker
uint cleanup.
1545
  uint32_t length= 0;
1546
  uint32_t fields= 0;
1547
  uint32_t null_fields= 0;
1 by brian
clean slate
1548
1549
  /*
1550
    If there is a reference to a field in the query add it
1551
    to the the set of appended fields.
1552
    Note for future refinement:
1553
    This this a too strong condition.
1554
    Actually we need only the fields referred in the
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1555
    result set. And for some of them it makes sense to use
1 by brian
clean slate
1556
    the values directly from sorted fields.
1557
  */
1558
  *plength= 0;
1559
1560
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1561
  {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
1562
    if (!(field->isReadSet()))
1 by brian
clean slate
1563
      continue;
1564
    if (field->flags & BLOB_FLAG)
1565
      return 0;
1566
    length+= field->max_packed_col_length(field->pack_length());
1567
    if (field->maybe_null())
1568
      null_fields++;
1569
    fields++;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1570
  }
1 by brian
clean slate
1571
  if (!fields)
1572
    return 0;
1573
  length+= (null_fields+7)/8;
1574
2318.4.8 by Olaf van der Spek
Remove malloc NULL check. Just die.
1575
  if (length+sortlength_arg > getSession().variables.max_length_for_sort_data)
1 by brian
clean slate
1576
    return 0;
2318.4.8 by Olaf van der Spek
Remove malloc NULL check. Just die.
1577
  addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field) * (fields+1));
1 by brian
clean slate
1578
1579
  *plength= length;
1580
  length= (null_fields+7)/8;
1581
  null_fields= 0;
1582
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1583
  {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
1584
    if (!(field->isReadSet()))
1 by brian
clean slate
1585
      continue;
1586
    addonf->field= field;
1587
    addonf->offset= length;
1588
    if (field->maybe_null())
1589
    {
1590
      addonf->null_offset= null_fields/8;
1591
      addonf->null_bit= 1<<(null_fields & 7);
1592
      null_fields++;
1593
    }
1594
    else
1595
    {
1596
      addonf->null_offset= 0;
1597
      addonf->null_bit= 0;
1598
    }
1599
    addonf->length= field->max_packed_col_length(field->pack_length());
1600
    length+= addonf->length;
1601
    addonf++;
1602
  }
1603
  addonf->field= 0;     // Put end marker
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1604
1 by brian
clean slate
1605
  return (addonf-fields);
1606
}
1607
1608
1609
/**
1610
  Copy (unpack) values appended to sorted fields from a buffer back to
1611
  their regular positions specified by the Field::ptr pointers.
1612
1613
  @param addon_field     Array of descriptors for appended fields
1614
  @param buff            Buffer which to unpack the value from
1615
1616
  @note
1617
    The function is supposed to be used only as a callback function
1618
    when getting field values for the sorted result set.
1619
1620
  @return
1621
    void.
1622
*/
1623
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1624
static void
1891.2.1 by Monty Taylor
Fixed things to make things compile with clang
1625
unpack_addon_fields(sort_addon_field *addon_field, unsigned char *buff)
1 by brian
clean slate
1626
{
1627
  Field *field;
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1628
  sort_addon_field *addonf= addon_field;
1 by brian
clean slate
1629
1630
  for ( ; (field= addonf->field) ; addonf++)
1631
  {
1632
    if (addonf->null_bit && (addonf->null_bit & buff[addonf->null_offset]))
1633
    {
1634
      field->set_null();
1635
      continue;
1636
    }
1637
    field->set_notnull();
1638
    field->unpack(field->ptr, buff + addonf->offset);
1639
  }
1640
}
1641
1642
/*
1643
** functions to change a double or float to a sortable string
1644
** The following should work for IEEE
1645
*/
1646
1647
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1648
481 by Brian Aker
Remove all of uchar.
1649
void change_double_for_sort(double nr,unsigned char *to)
1 by brian
clean slate
1650
{
481 by Brian Aker
Remove all of uchar.
1651
  unsigned char *tmp=(unsigned char*) to;
1 by brian
clean slate
1652
  if (nr == 0.0)
1653
  {						/* Change to zero string */
481 by Brian Aker
Remove all of uchar.
1654
    tmp[0]=(unsigned char) 128;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1655
    memset(tmp+1, 0, sizeof(nr)-1);
1 by brian
clean slate
1656
  }
1657
  else
1658
  {
1659
#ifdef WORDS_BIGENDIAN
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
1660
    memcpy(tmp,&nr,sizeof(nr));
1 by brian
clean slate
1661
#else
1662
    {
481 by Brian Aker
Remove all of uchar.
1663
      unsigned char *ptr= (unsigned char*) &nr;
1 by brian
clean slate
1664
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1665
      tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1666
      tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1667
#else
1668
      tmp[0]= ptr[7]; tmp[1]=ptr[6]; tmp[2]= ptr[5]; tmp[3]=ptr[4];
1669
      tmp[4]= ptr[3]; tmp[5]=ptr[2]; tmp[6]= ptr[1]; tmp[7]=ptr[0];
1670
#endif
1671
    }
1672
#endif
1673
    if (tmp[0] & 128)				/* Negative */
1674
    {						/* make complement */
438.1.13 by Brian Aker
uint cleanup.
1675
      uint32_t i;
1 by brian
clean slate
1676
      for (i=0 ; i < sizeof(nr); i++)
481 by Brian Aker
Remove all of uchar.
1677
	tmp[i]=tmp[i] ^ (unsigned char) 255;
1 by brian
clean slate
1678
    }
1679
    else
1680
    {					/* Set high and move exponent one up */
438.1.13 by Brian Aker
uint cleanup.
1681
      uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1682
		       (uint16_t) 32768);
1683
      exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
481 by Brian Aker
Remove all of uchar.
1684
      tmp[0]= (unsigned char) (exp_part >> 8);
1685
      tmp[1]= (unsigned char) exp_part;
1 by brian
clean slate
1686
    }
1687
  }
1688
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1689
1690
} /* namespace drizzled */