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