~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 */
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
567
    if (file->startTableScan(1))
568
      return(HA_POS_ERROR);
1905.1.1 by Brian Aker
Adding FileSort class.
569
    file->extra_opt(HA_EXTRA_CACHE, getSession().variables.read_buff_size);
1 by brian
clean slate
570
  }
571
1538 by Brian Aker
Code shuffle on ReadRecord
572
  ReadRecord read_record_info;
1 by brian
clean slate
573
  if (quick_select)
574
  {
575
    if (select->quick->reset())
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
576
      return(HA_POS_ERROR);
1538 by Brian Aker
Code shuffle on ReadRecord
577
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
578
    if (read_record_info.init_read_record(&getSession(), select->quick->head, select, 1, 1))
579
      return(HA_POS_ERROR);
1 by brian
clean slate
580
  }
581
582
  /* Remember original bitmaps */
583
  save_read_set=  sort_form->read_set;
584
  save_write_set= sort_form->write_set;
585
  /* 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.
586
  sort_form->tmp_set.reset();
1 by brian
clean slate
587
  /* Temporary set for register_used_fields and register_field_in_read_map */
588
  sort_form->read_set= &sort_form->tmp_set;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
589
  param->register_used_fields();
1 by brian
clean slate
590
  if (select && select->cond)
591
    select->cond->walk(&Item::register_field_in_read_map, 1,
481 by Brian Aker
Remove all of uchar.
592
                       (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.
593
  sort_form->column_bitmaps_set(sort_form->tmp_set, sort_form->tmp_set);
1 by brian
clean slate
594
595
  for (;;)
596
  {
597
    if (quick_select)
598
    {
599
      if ((error= read_record_info.read_record(&read_record_info)))
600
      {
601
        error= HA_ERR_END_OF_FILE;
602
        break;
603
      }
1672.3.6 by Brian Aker
First pass in encapsulating row
604
      file->position(sort_form->getInsertRecord());
1 by brian
clean slate
605
    }
606
    else					/* Not quick-select */
607
    {
608
      if (indexfile)
609
      {
971.6.11 by Eric Day
Removed purecov messages.
610
	if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length))
1 by brian
clean slate
611
	{
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
612
	  error= errno ? errno : -1;		/* Abort */
1 by brian
clean slate
613
	  break;
614
	}
1672.3.6 by Brian Aker
First pass in encapsulating row
615
	error=file->rnd_pos(sort_form->getInsertRecord(),next_pos);
1 by brian
clean slate
616
      }
617
      else
618
      {
1672.3.6 by Brian Aker
First pass in encapsulating row
619
	error=file->rnd_next(sort_form->getInsertRecord());
383.7.1 by Andrey Zhakov
Initial submit of code and tests
620
1 by brian
clean slate
621
	if (!flag)
622
	{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
623
	  internal::my_store_ptr(ref_pos,ref_length,record); // Position to row
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
624
	  record+= sort_form->getShare()->db_record_offset;
1 by brian
clean slate
625
	}
626
	else if (!error)
1672.3.6 by Brian Aker
First pass in encapsulating row
627
	  file->position(sort_form->getInsertRecord());
1 by brian
clean slate
628
      }
629
      if (error && error != HA_ERR_RECORD_DELETED)
630
	break;
631
    }
632
633
    if (*killed)
634
    {
635
      if (!indexfile && !quick_select)
636
      {
637
        (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
638
        file->endTableScan();
1 by brian
clean slate
639
      }
971.6.11 by Eric Day
Removed purecov messages.
640
      return(HA_POS_ERROR);
1 by brian
clean slate
641
    }
642
    if (error == 0)
643
      param->examined_rows++;
644
    if (error == 0 && (!select || select->skip_record() == 0))
645
    {
646
      if (idx == param->keys)
647
      {
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
648
	if (param->write_keys(sort_keys, idx, buffpek_pointers, tempfile))
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
649
	  return(HA_POS_ERROR);
1 by brian
clean slate
650
	idx=0;
651
	indexpos++;
652
      }
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
653
      param->make_sortkey(sort_keys[idx++], ref_pos);
1 by brian
clean slate
654
    }
655
    else
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
656
    {
1 by brian
clean slate
657
      file->unlock_row();
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
658
    }
659
1 by brian
clean slate
660
    /* It does not make sense to read more keys in case of a fatal error */
1905.1.1 by Brian Aker
Adding FileSort class.
661
    if (getSession().is_error())
1 by brian
clean slate
662
      break;
663
  }
664
  if (quick_select)
665
  {
666
    /*
667
      index_merge quick select uses table->sort when retrieving rows, so free
668
      resoures it has allocated.
669
    */
1538 by Brian Aker
Code shuffle on ReadRecord
670
    read_record_info.end_read_record();
1 by brian
clean slate
671
  }
672
  else
673
  {
674
    (void) file->extra(HA_EXTRA_NO_CACHE);	/* End cacheing of records */
675
    if (!next_pos)
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
676
      file->endTableScan();
1 by brian
clean slate
677
  }
678
1905.1.1 by Brian Aker
Adding FileSort class.
679
  if (getSession().is_error())
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
680
    return(HA_POS_ERROR);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
681
1 by brian
clean slate
682
  /* 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.
683
  sort_form->column_bitmaps_set(*save_read_set, *save_write_set);
1 by brian
clean slate
684
685
  if (error != HA_ERR_END_OF_FILE)
686
  {
1216.1.1 by Brian Aker
Move print_error up to Engine.
687
    sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
971.6.11 by Eric Day
Removed purecov messages.
688
    return(HA_POS_ERROR);
1 by brian
clean slate
689
  }
1996.2.1 by Brian Aker
uuid type code.
690
691
  if (indexpos && idx && param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
692
  {
971.6.11 by Eric Day
Removed purecov messages.
693
    return(HA_POS_ERROR);
1996.2.1 by Brian Aker
uuid type code.
694
  }
695
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
696
  return(my_b_inited(tempfile) ?
1 by brian
clean slate
697
	      (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
698
	      idx);
699
} /* find_all_keys */
700
701
702
/**
703
  @details
704
  Sort the buffer and write:
705
  -# 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.
706
  -# a buffpek describing the sorted sequence position to buffpek_pointers
1 by brian
clean slate
707
708
    (was: Skriver en buffert med nycklar till filen)
709
710
  @param param             Sort parameters
711
  @param sort_keys         Array of pointers to keys to sort
712
  @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.
713
  @param buffpek_pointers  One 'buffpek' struct will be written into this file.
714
                           The buffpek::{file_pos, count} will indicate where
1 by brian
clean slate
715
                           the sorted data was stored.
716
  @param tempfile          The sorted sequence will be written into this file.
717
718
  @retval
719
    0 OK
720
  @retval
721
    1 Error
722
*/
723
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
724
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
725
                          internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
1 by brian
clean slate
726
{
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.
727
  buffpek buffpek;
1 by brian
clean slate
728
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
729
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1 by brian
clean slate
730
  if (!my_b_inited(tempfile) &&
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
731
      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.
732
  {
733
    return 1;
734
  }
1 by brian
clean slate
735
  /* 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.
736
  if (my_b_tell(buffpek_pointers) + sizeof(buffpek) > (uint64_t)UINT_MAX)
1864.3.19 by Brian Aker
Update to remove additional goto.
737
  {
738
    return 1;
739
  }
740
1 by brian
clean slate
741
  buffpek.file_pos= my_b_tell(tempfile);
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
742
  if ((ha_rows) count > max_rows)
743
    count=(uint32_t) max_rows;
744
1 by brian
clean slate
745
  buffpek.count=(ha_rows) count;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
746
747
  for (unsigned char **ptr= sort_keys + count ; sort_keys != ptr ; sort_keys++)
1864.3.19 by Brian Aker
Update to remove additional goto.
748
  {
481 by Brian Aker
Remove all of uchar.
749
    if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
1864.3.19 by Brian Aker
Update to remove additional goto.
750
    {
751
      return 1;
752
    }
753
  }
754
481 by Brian Aker
Remove all of uchar.
755
  if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
1864.3.19 by Brian Aker
Update to remove additional goto.
756
  {
757
    return 1;
758
  }
1 by brian
clean slate
759
1864.3.19 by Brian Aker
Update to remove additional goto.
760
  return 0;
1 by brian
clean slate
761
} /* write_keys */
762
763
764
/**
765
  Store length as suffix in high-byte-first order.
766
*/
767
481 by Brian Aker
Remove all of uchar.
768
static inline void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
1 by brian
clean slate
769
{
770
  switch (pack_length) {
771
  case 1:
481 by Brian Aker
Remove all of uchar.
772
    *to= (unsigned char) length;
1 by brian
clean slate
773
    break;
774
  case 2:
775
    mi_int2store(to, length);
776
    break;
777
  case 3:
778
    mi_int3store(to, length);
779
    break;
780
  default:
781
    mi_int4store(to, length);
782
    break;
783
  }
784
}
785
786
787
/** Make a sort-key from record. */
788
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
789
void SortParam::make_sortkey(register unsigned char *to, unsigned char *ref_pos)
1 by brian
clean slate
790
{
1711.6.1 by Brian Aker
Style on structure cleanup
791
  Field *field;
792
  SortField *sort_field;
937.2.7 by Stewart Smith
typesafe set_if_smaller/set_if_greater fixes from Solaris
793
  size_t length;
1 by brian
clean slate
794
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
795
  for (sort_field= local_sortorder ;
796
       sort_field != end ;
1 by brian
clean slate
797
       sort_field++)
798
  {
799
    bool maybe_null=0;
800
    if ((field=sort_field->field))
801
    {						// Field
802
      if (field->maybe_null())
803
      {
804
	if (field->is_null())
805
	{
806
	  if (sort_field->reverse)
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
807
	    memset(to, 255, sort_field->length+1);
1 by brian
clean slate
808
	  else
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
809
	    memset(to, 0, sort_field->length+1);
1 by brian
clean slate
810
	  to+= sort_field->length+1;
811
	  continue;
812
	}
813
	else
814
	  *to++=1;
815
      }
816
      field->sort_string(to, sort_field->length);
817
    }
818
    else
819
    {						// Item
820
      Item *item=sort_field->item;
821
      maybe_null= item->maybe_null;
2008 by Brian Aker
Formatting + remove default from switch/case.
822
1 by brian
clean slate
823
      switch (sort_field->result_type) {
824
      case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
825
        {
826
          const CHARSET_INFO * const cs=item->collation.collation;
827
          char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
828
          int diff;
829
          uint32_t sort_field_length;
1 by brian
clean slate
830
831
          if (maybe_null)
2008 by Brian Aker
Formatting + remove default from switch/case.
832
            *to++=1;
833
          /* All item->str() to use some extra byte for end null.. */
834
          String tmp((char*) to,sort_field->length+4,cs);
835
          String *res= item->str_result(&tmp);
836
          if (!res)
837
          {
838
            if (maybe_null)
839
              memset(to-1, 0, sort_field->length+1);
840
            else
841
            {
842
              /*
843
                This should only happen during extreme conditions if we run out
844
                of memory or have an item marked not null when it can be null.
845
                This code is here mainly to avoid a hard crash in this case.
846
              */
847
              assert(0);
848
              memset(to, 0, sort_field->length);	// Avoid crash
849
            }
850
            break;
851
          }
852
          length= res->length();
853
          sort_field_length= sort_field->length - sort_field->suffix_length;
854
          diff=(int) (sort_field_length - length);
855
          if (diff < 0)
856
          {
857
            diff=0;
858
            length= sort_field_length;
859
          }
860
          if (sort_field->suffix_length)
861
          {
862
            /* Store length last in result_string */
863
            store_length(to + sort_field_length, length,
864
                         sort_field->suffix_length);
865
          }
866
          if (sort_field->need_strxnfrm)
867
          {
868
            char *from=(char*) res->ptr();
869
            uint32_t tmp_length;
870
            if ((unsigned char*) from == to)
871
            {
872
              set_if_smaller(length,sort_field->length);
873
              memcpy(tmp_buffer,from,length);
874
              from= tmp_buffer;
875
            }
876
            tmp_length= my_strnxfrm(cs,to,sort_field->length,
877
                                    (unsigned char*) from, length);
878
            assert(tmp_length == sort_field->length);
879
          }
1 by brian
clean slate
880
          else
881
          {
2008 by Brian Aker
Formatting + remove default from switch/case.
882
            my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
883
            cs->cset->fill(cs, (char *)to+length,diff,fill_char);
1 by brian
clean slate
884
          }
885
          break;
886
        }
887
      case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
888
        {
152 by Brian Aker
longlong replacement
889
          int64_t value= item->val_int_result();
1 by brian
clean slate
890
          if (maybe_null)
891
          {
2008 by Brian Aker
Formatting + remove default from switch/case.
892
            *to++=1;
1 by brian
clean slate
893
            if (item->null_value)
894
            {
895
              if (maybe_null)
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
896
                memset(to-1, 0, sort_field->length+1);
1 by brian
clean slate
897
              else
898
              {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
899
                memset(to, 0, sort_field->length);
1 by brian
clean slate
900
              }
901
              break;
902
            }
903
          }
2008 by Brian Aker
Formatting + remove default from switch/case.
904
          to[7]= (unsigned char) value;
905
          to[6]= (unsigned char) (value >> 8);
906
          to[5]= (unsigned char) (value >> 16);
907
          to[4]= (unsigned char) (value >> 24);
908
          to[3]= (unsigned char) (value >> 32);
909
          to[2]= (unsigned char) (value >> 40);
910
          to[1]= (unsigned char) (value >> 48);
1 by brian
clean slate
911
          if (item->unsigned_flag)                    /* Fix sign */
481 by Brian Aker
Remove all of uchar.
912
            to[0]= (unsigned char) (value >> 56);
1 by brian
clean slate
913
          else
481 by Brian Aker
Remove all of uchar.
914
            to[0]= (unsigned char) (value >> 56) ^ 128;	/* Reverse signbit */
2008 by Brian Aker
Formatting + remove default from switch/case.
915
          break;
916
        }
1 by brian
clean slate
917
      case DECIMAL_RESULT:
918
        {
2030.1.4 by Brian Aker
Change my_decimal to Decimal
919
          type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
1 by brian
clean slate
920
          if (maybe_null)
921
          {
922
            if (item->null_value)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
923
            {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
924
              memset(to, 0, sort_field->length+1);
1 by brian
clean slate
925
              to++;
926
              break;
927
            }
928
            *to++=1;
929
          }
2034.2.3 by Brian Aker
More encapsulation around Decimal.
930
          dec_val->val_binary(E_DEC_FATAL_ERROR, to,
931
                              item->max_length - (item->decimals ? 1:0),
932
                              item->decimals);
2008 by Brian Aker
Formatting + remove default from switch/case.
933
          break;
1 by brian
clean slate
934
        }
935
      case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
936
        {
1 by brian
clean slate
937
          double value= item->val_result();
2008 by Brian Aker
Formatting + remove default from switch/case.
938
          if (maybe_null)
1 by brian
clean slate
939
          {
940
            if (item->null_value)
941
            {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
942
              memset(to, 0, sort_field->length+1);
1 by brian
clean slate
943
              to++;
944
              break;
945
            }
2008 by Brian Aker
Formatting + remove default from switch/case.
946
            *to++=1;
1 by brian
clean slate
947
          }
2008 by Brian Aker
Formatting + remove default from switch/case.
948
          change_double_for_sort(value,(unsigned char*) to);
949
          break;
950
        }
1 by brian
clean slate
951
      case ROW_RESULT:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
952
      default:
2008 by Brian Aker
Formatting + remove default from switch/case.
953
        // This case should never be choosen
954
        assert(0);
955
        break;
1 by brian
clean slate
956
      }
957
    }
2008 by Brian Aker
Formatting + remove default from switch/case.
958
1 by brian
clean slate
959
    if (sort_field->reverse)
960
    {							/* Revers key */
961
      if (maybe_null)
962
        to[-1]= ~to[-1];
963
      length=sort_field->length;
964
      while (length--)
965
      {
481 by Brian Aker
Remove all of uchar.
966
	*to = (unsigned char) (~ *to);
1 by brian
clean slate
967
	to++;
968
      }
969
    }
970
    else
2008 by Brian Aker
Formatting + remove default from switch/case.
971
    {
1 by brian
clean slate
972
      to+= sort_field->length;
2008 by Brian Aker
Formatting + remove default from switch/case.
973
    }
1 by brian
clean slate
974
  }
975
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
976
  if (addon_field)
1 by brian
clean slate
977
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
978
    /*
1 by brian
clean slate
979
      Save field values appended to sorted fields.
980
      First null bit indicators are appended then field values follow.
981
      In this implementation we use fixed layout for field values -
982
      the same for all records.
983
    */
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
984
    sort_addon_field *addonf= addon_field;
481 by Brian Aker
Remove all of uchar.
985
    unsigned char *nulls= to;
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
986
    assert(addonf != 0);
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
987
    memset(nulls, 0, addonf->offset);
1 by brian
clean slate
988
    to+= addonf->offset;
989
    for ( ; (field= addonf->field) ; addonf++)
990
    {
991
      if (addonf->null_bit && field->is_null())
992
      {
993
        nulls[addonf->null_offset]|= addonf->null_bit;
1859.2.14 by Brian Aker
Add support for --with-valgrind
994
#ifdef HAVE_VALGRIND
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
995
	memset(to, 0, addonf->length);
1 by brian
clean slate
996
#endif
997
      }
998
      else
999
      {
1859.2.14 by Brian Aker
Add support for --with-valgrind
1000
#ifdef HAVE_VALGRIND
481 by Brian Aker
Remove all of uchar.
1001
        unsigned char *end= field->pack(to, field->ptr);
1859.2.14 by Brian Aker
Add support for --with-valgrind
1002
	uint32_t local_length= (uint32_t) ((to + addonf->length) - end);
1003
	assert((int) local_length >= 0);
1004
	if (local_length)
1005
	  memset(end, 0, local_length);
1 by brian
clean slate
1006
#else
1007
        (void) field->pack(to, field->ptr);
1008
#endif
1009
      }
1010
      to+= addonf->length;
1011
    }
1012
  }
1013
  else
1014
  {
1015
    /* Save filepos last */
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1016
    memcpy(to, ref_pos, (size_t) ref_length);
1 by brian
clean slate
1017
  }
1018
}
1019
1020
1021
/*
1022
  Register fields used by sorting in the sorted table's read set
1023
*/
1024
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1025
void SortParam::register_used_fields()
1 by brian
clean slate
1026
{
1711.6.1 by Brian Aker
Style on structure cleanup
1027
  SortField *sort_field;
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1028
  Table *table= sort_form;
1 by brian
clean slate
1029
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1030
  for (sort_field= local_sortorder ;
1031
       sort_field != end ;
1 by brian
clean slate
1032
       sort_field++)
1033
  {
1034
    Field *field;
1035
    if ((field= sort_field->field))
1036
    {
1660.1.3 by Brian Aker
Encapsulate Table in field
1037
      if (field->getTable() == table)
1999.4.2 by Brian Aker
Encapsulate the field's position.
1038
        table->setReadSet(field->position());
1 by brian
clean slate
1039
    }
1040
    else
1041
    {						// Item
1042
      sort_field->item->walk(&Item::register_field_in_read_map, 1,
481 by Brian Aker
Remove all of uchar.
1043
                             (unsigned char *) table);
1 by brian
clean slate
1044
    }
1045
  }
1046
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1047
  if (addon_field)
1 by brian
clean slate
1048
  {
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1049
    sort_addon_field *addonf= addon_field;
1 by brian
clean slate
1050
    Field *field;
1051
    for ( ; (field= addonf->field) ; addonf++)
1999.4.2 by Brian Aker
Encapsulate the field's position.
1052
      table->setReadSet(field->position());
1 by brian
clean slate
1053
  }
1054
  else
1055
  {
1056
    /* Save filepos last */
1057
    table->prepare_for_position();
1058
  }
1059
}
1060
1061
1996.2.1 by Brian Aker
uuid type code.
1062
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1 by brian
clean slate
1063
{
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1064
  uint32_t offset;
481 by Brian Aker
Remove all of uchar.
1065
  unsigned char *to;
1 by brian
clean slate
1066
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1067
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1068
  offset= rec_length - res_length;
1996.2.1 by Brian Aker
uuid type code.
1069
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1070
  if ((ha_rows) count > max_rows)
1071
    count=(uint32_t) max_rows;
1996.2.1 by Brian Aker
uuid type code.
1072
1073
  if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1074
    return true;
1075
1076
  for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1 by brian
clean slate
1077
  {
1078
    memcpy(to, *sort_keys+offset, res_length);
1079
    to+= res_length;
1080
  }
1996.2.1 by Brian Aker
uuid type code.
1081
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1082
  return false;
1 by brian
clean slate
1083
}
1084
1085
1086
/** Merge buffers to make < MERGEBUFF2 buffers. */
1087
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1088
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1905.1.2 by Brian Aker
Filesort fix.
1089
                              buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1 by brian
clean slate
1090
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1091
  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.
1092
  buffpek *lastbuff;
1 by brian
clean slate
1093
1094
  if (*maxbuffer < MERGEBUFF2)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1095
    return 0;
1 by brian
clean slate
1096
  if (flush_io_cache(t_file) ||
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
1097
      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).
1098
  {
1099
    return 1;
1100
  }
1 by brian
clean slate
1101
1102
  from_file= t_file ; to_file= &t_file2;
1103
  while (*maxbuffer >= MERGEBUFF2)
1104
  {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1105
    register uint32_t i;
1106
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1107
    if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1108
    {
1109
      break;
1110
    }
1111
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1112
    if (to_file->reinit_io_cache(internal::WRITE_CACHE,0L,0,0))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1113
    {
1114
      break;
1115
    }
1116
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.
1117
    lastbuff=buffpek_inst;
1 by brian
clean slate
1118
    for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
1119
    {
1120
      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.
1121
			buffpek_inst+i,buffpek_inst+i+MERGEBUFF-1,0))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1122
      {
1123
        goto cleanup;
1124
      }
1 by brian
clean slate
1125
    }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1126
1 by brian
clean slate
1127
    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.
1128
		      buffpek_inst+i,buffpek_inst+ *maxbuffer,0))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1129
    {
971.6.11 by Eric Day
Removed purecov messages.
1130
      break;
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1131
    }
1132
1 by brian
clean slate
1133
    if (flush_io_cache(to_file))
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1134
    {
971.6.11 by Eric Day
Removed purecov messages.
1135
      break;
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1136
    }
1137
1 by brian
clean slate
1138
    temp=from_file; from_file=to_file; to_file=temp;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1139
    from_file->setup_io_cache();
1140
    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.
1141
    *maxbuffer= (uint32_t) (lastbuff-buffpek_inst)-1;
1 by brian
clean slate
1142
  }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1143
1 by brian
clean slate
1144
cleanup:
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1145
  to_file->close_cached_file();			// This holds old result
1 by brian
clean slate
1146
  if (to_file == t_file)
1147
  {
1148
    *t_file=t_file2;				// Copy result file
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
1149
    t_file->setup_io_cache();
1 by brian
clean slate
1150
  }
1151
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
1152
  return(*maxbuffer >= MERGEBUFF2);	/* Return 1 if interrupted */
1 by brian
clean slate
1153
} /* merge_many_buff */
1154
1155
1156
/**
1157
  Read data to buffer.
1158
1159
  @retval
438.1.13 by Brian Aker
uint cleanup.
1160
    (uint32_t)-1 if something goes wrong
1 by brian
clean slate
1161
*/
1162
1905.1.2 by Brian Aker
Filesort fix.
1163
uint32_t FileSort::read_to_buffer(internal::IO_CACHE *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1 by brian
clean slate
1164
{
438.1.13 by Brian Aker
uint cleanup.
1165
  register uint32_t count;
1166
  uint32_t length;
1 by brian
clean slate
1167
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.
1168
  if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1 by brian
clean slate
1169
  {
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.
1170
    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.
1171
      return((uint32_t) -1);
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1172
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.
1173
    buffpek_inst->key= buffpek_inst->base;
1174
    buffpek_inst->file_pos+= length;			/* New filepos */
1175
    buffpek_inst->count-= count;
1176
    buffpek_inst->mem_count= count;
1 by brian
clean slate
1177
  }
1178
  return (count*rec_length);
1179
} /* read_to_buffer */
1180
1181
897.1.11 by Padraig
Giving function object a better name for this scenario.
1182
class compare_functor
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1183
{
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
1184
  qsort2_cmp key_compare;
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1185
  void *key_compare_arg;
1996.2.1 by Brian Aker
uuid type code.
1186
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1187
  public:
1996.2.1 by Brian Aker
uuid type code.
1188
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg) :
1189
    key_compare(in_key_compare),
1190
    key_compare_arg(in_compare_arg)
1191
  { }
1192
  
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.
1193
  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
1194
  {
1996.2.1 by Brian Aker
uuid type code.
1195
    int val= key_compare(key_compare_arg, &i->key, &j->key);
1196
897.1.18 by Padraig O'Sullivan
Cleaning up my function object a little bit.
1197
    return (val >= 0);
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1198
  }
1199
};
1200
1 by brian
clean slate
1201
1202
/**
1203
  Merge buffers to one buffer.
1204
1205
  @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.
1206
  @param from_file    File with source data (buffpeks point to this file)
1 by brian
clean slate
1207
  @param to_file      File to write the sorted result data.
1208
  @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.
1209
  @param lastbuff     OUT Store here buffpek describing data written to to_file
1210
  @param Fb           First element in source buffpeks array
1211
  @param Tb           Last element in source buffpeks array
1 by brian
clean slate
1212
  @param flag
1213
1214
  @retval
1215
    0      OK
1216
  @retval
1217
    other  error
1218
*/
1219
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1220
int FileSort::merge_buffers(SortParam *param, internal::IO_CACHE *from_file,
1905.1.2 by Brian Aker
Filesort fix.
1221
                            internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1222
                            buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1223
                            int flag)
1 by brian
clean slate
1224
{
1225
  int error;
438.1.13 by Brian Aker
uint cleanup.
1226
  uint32_t rec_length,res_length,offset;
1 by brian
clean slate
1227
  size_t sort_length;
308 by Brian Aker
ulong conversion
1228
  uint32_t maxcount;
1 by brian
clean slate
1229
  ha_rows max_rows,org_max_rows;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1230
  internal::my_off_t to_start_filepos;
481 by Brian Aker
Remove all of uchar.
1231
  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.
1232
  buffpek *buffpek_inst;
1 by brian
clean slate
1233
  qsort2_cmp cmp;
1234
  void *first_cmp_arg;
1910.2.8 by Brian Aker
Enapsulate Kill.
1235
  volatile Session::killed_state_t *killed= getSession().getKilledPtr();
1236
  Session::killed_state_t not_killable;
1 by brian
clean slate
1237
1905.1.2 by Brian Aker
Filesort fix.
1238
  getSession().status_var.filesort_merge_passes++;
1 by brian
clean slate
1239
  if (param->not_killable)
1240
  {
1241
    killed= &not_killable;
520.1.21 by Brian Aker
THD -> Session rename
1242
    not_killable= Session::NOT_KILLED;
1 by brian
clean slate
1243
  }
1244
1245
  error=0;
1246
  rec_length= param->rec_length;
1247
  res_length= param->res_length;
1248
  sort_length= param->sort_length;
1249
  offset= rec_length-res_length;
438.1.13 by Brian Aker
uint cleanup.
1250
  maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
1 by brian
clean slate
1251
  to_start_filepos= my_b_tell(to_file);
481 by Brian Aker
Remove all of uchar.
1252
  strpos= (unsigned char*) sort_buffer;
1 by brian
clean slate
1253
  org_max_rows=max_rows= param->max_rows;
1254
1255
  /* The following will fire if there is not enough space in sort_buffer */
51.1.12 by Jay Pipes
Removed/replaced DBUG symbols
1256
  assert(maxcount!=0);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1257
1 by brian
clean slate
1258
  if (param->unique_buff)
1259
  {
1260
    cmp= param->compare;
1261
    first_cmp_arg= (void *) &param->cmp_context;
1262
  }
1263
  else
1264
  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1265
    cmp= internal::get_ptr_compare(sort_length);
1 by brian
clean slate
1266
    first_cmp_arg= (void*) &sort_length;
1267
  }
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.
1268
  priority_queue<buffpek *, vector<buffpek *>, compare_functor >
897.1.11 by Padraig
Giving function object a better name for this scenario.
1269
    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.
1270
  for (buffpek_inst= Fb ; buffpek_inst <= Tb ; buffpek_inst++)
1 by brian
clean slate
1271
  {
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.
1272
    buffpek_inst->base= strpos;
1273
    buffpek_inst->max_keys= maxcount;
1274
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek_inst,
1 by brian
clean slate
1275
                                                                         rec_length));
1276
    if (error == -1)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1277
      return -1;
1278
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.
1279
    buffpek_inst->max_keys= buffpek_inst->mem_count;	// If less data in buffers than expected
1280
    queue.push(buffpek_inst);
1 by brian
clean slate
1281
  }
1282
1283
  if (param->unique_buff)
1284
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1285
    /*
1 by brian
clean slate
1286
       Called by Unique::get()
1287
       Copy the first argument to param->unique_buff for unique removal.
1288
       Store it also in 'to_file'.
1289
1290
       This is safe as we know that there is always more than one element
1291
       in each block to merge (This is guaranteed by the Unique:: algorithm
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= queue.top();
1294
    memcpy(param->unique_buff, buffpek_inst->key, rec_length);
1295
    if (my_b_write(to_file, (unsigned char*) buffpek_inst->key, rec_length))
1 by brian
clean slate
1296
    {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1297
      return 1;
1 by brian
clean slate
1298
    }
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.
1299
    buffpek_inst->key+= rec_length;
1300
    buffpek_inst->mem_count--;
1 by brian
clean slate
1301
    if (!--max_rows)
1302
    {
971.6.11 by Eric Day
Removed purecov messages.
1303
      error= 0;
1304
      goto end;
1 by brian
clean slate
1305
    }
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1306
    /* Top element has been used */
1307
    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.
1308
    queue.push(buffpek_inst);
1 by brian
clean slate
1309
  }
1310
  else
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1311
  {
1 by brian
clean slate
1312
    cmp= 0;                                        // Not unique
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1313
  }
1 by brian
clean slate
1314
897.1.6 by Padraig
Cleaning up merge_buffers() function a little bit.
1315
  while (queue.size() > 1)
1 by brian
clean slate
1316
  {
1317
    if (*killed)
1318
    {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1319
      return 1;
1 by brian
clean slate
1320
    }
1321
    for (;;)
1322
    {
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
      buffpek_inst= queue.top();
1 by brian
clean slate
1324
      if (cmp)                                        // Remove duplicates
1325
      {
1326
        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.
1327
                    (unsigned char**) &buffpek_inst->key))
1 by brian
clean slate
1328
              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.
1329
            memcpy(param->unique_buff, buffpek_inst->key, rec_length);
1 by brian
clean slate
1330
      }
1331
      if (flag == 0)
1332
      {
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.
1333
        if (my_b_write(to_file,(unsigned char*) buffpek_inst->key, rec_length))
1 by brian
clean slate
1334
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1335
          return 1;
1 by brian
clean slate
1336
        }
1337
      }
1338
      else
1339
      {
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.
1340
        if (my_b_write(to_file, (unsigned char*) buffpek_inst->key+offset, res_length))
1 by brian
clean slate
1341
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1342
          return 1;
1 by brian
clean slate
1343
        }
1344
      }
1345
      if (!--max_rows)
1346
      {
971.6.11 by Eric Day
Removed purecov messages.
1347
        error= 0;
1348
        goto end;
1 by brian
clean slate
1349
      }
1350
1351
    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.
1352
      buffpek_inst->key+= rec_length;
1353
      if (! --buffpek_inst->mem_count)
1 by brian
clean slate
1354
      {
1826.1.1 by tdavies
Bug:621861 Changed C structs to C++ class in the following files: filesort.cc, filesort_info.h, sql_sort.h, table.h. removed the '_st' from the name of some of the classes. For more detail of changes made read the merge proposal notes.
1355
        if (!(error= (int) read_to_buffer(from_file,buffpek_inst,
1 by brian
clean slate
1356
                                          rec_length)))
1357
        {
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1358
          queue.pop();
1 by brian
clean slate
1359
          break;                        /* One buffer have been removed */
1360
        }
1361
        else if (error == -1)
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1362
        {
1363
          return -1;
1364
        }
1 by brian
clean slate
1365
      }
897.1.5 by Padraig
Replacing the instance of QUEUE in the merge_buffers() function in
1366
      /* Top element has been replaced */
1367
      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.
1368
      queue.push(buffpek_inst);
1 by brian
clean slate
1369
    }
1370
  }
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.
1371
  buffpek_inst= queue.top();
1372
  buffpek_inst->base= sort_buffer;
1373
  buffpek_inst->max_keys= param->keys;
1 by brian
clean slate
1374
1375
  /*
1376
    As we know all entries in the buffer are unique, we only have to
1377
    check if the first one is the same as the last one we wrote
1378
  */
1379
  if (cmp)
1380
  {
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.
1381
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (unsigned char**) &buffpek_inst->key))
1 by brian
clean slate
1382
    {
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.
1383
      buffpek_inst->key+= rec_length;         // Remove duplicate
1384
      --buffpek_inst->mem_count;
1 by brian
clean slate
1385
    }
1386
  }
1387
1388
  do
1389
  {
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.
1390
    if ((ha_rows) buffpek_inst->mem_count > max_rows)
1 by brian
clean slate
1391
    {                                        /* 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.
1392
      buffpek_inst->mem_count= (uint32_t) max_rows;
1393
      buffpek_inst->count= 0;                        /* Don't read more */
1 by brian
clean slate
1394
    }
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.
1395
    max_rows-= buffpek_inst->mem_count;
1 by brian
clean slate
1396
    if (flag == 0)
1397
    {
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.
1398
      if (my_b_write(to_file,(unsigned char*) buffpek_inst->key,
1399
                     (rec_length*buffpek_inst->mem_count)))
1 by brian
clean slate
1400
      {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1401
        return 1;
1 by brian
clean slate
1402
      }
1403
    }
1404
    else
1405
    {
481 by Brian Aker
Remove all of uchar.
1406
      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.
1407
      strpos= buffpek_inst->key+offset;
1408
      for (end= strpos+buffpek_inst->mem_count*rec_length ;
1 by brian
clean slate
1409
           strpos != end ;
1410
           strpos+= rec_length)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1411
      {
481 by Brian Aker
Remove all of uchar.
1412
        if (my_b_write(to_file, (unsigned char *) strpos, res_length))
1 by brian
clean slate
1413
        {
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1414
          return 1;
1 by brian
clean slate
1415
        }
1416
      }
1417
    }
1418
  }
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1419
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.
1420
  while ((error=(int) read_to_buffer(from_file,buffpek_inst, rec_length))
1 by brian
clean slate
1421
         != -1 && error != 0);
1422
1423
end:
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1424
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1 by brian
clean slate
1425
  lastbuff->file_pos= to_start_filepos;
1864.3.20 by Brian Aker
Remove goto from filesort (not all).
1426
1427
  return error;
1 by brian
clean slate
1428
} /* merge_buffers */
1429
1430
1431
	/* Do a merge to output-file (save only positions) */
1432
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1433
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1905.1.2 by Brian Aker
Filesort fix.
1434
                          buffpek *buffpek_inst, uint32_t maxbuffer,
1435
                          internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1 by brian
clean slate
1436
{
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.
1437
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1438
		    buffpek_inst+maxbuffer,1))
1905.1.2 by Brian Aker
Filesort fix.
1439
    return 1;
1440
1441
  return 0;
1 by brian
clean slate
1442
} /* merge_index */
1443
1444
438.1.13 by Brian Aker
uint cleanup.
1445
static uint32_t suffix_length(uint32_t string_length)
1 by brian
clean slate
1446
{
1447
  if (string_length < 256)
1448
    return 1;
1449
  if (string_length < 256L*256L)
1450
    return 2;
1451
  if (string_length < 256L*256L*256L)
1452
    return 3;
1453
  return 4;                                     // Can't sort longer than 4G
1454
}
1455
1456
1457
1458
/**
1459
  Calculate length of sort key.
1460
1461
  @param sortorder		  Order of items to sort
1462
  @param s_length	          Number of items to sort
1463
  @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
1464
                                 (In which case we have to use strxnfrm())
1465
1466
  @note
1467
    sortorder->length is updated for each sort item.
1468
  @n
1469
    sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
1470
1471
  @return
1472
    Total length of sort buffer in bytes
1473
*/
1474
1905.1.1 by Brian Aker
Adding FileSort class.
1475
uint32_t FileSort::sortlength(SortField *sortorder, uint32_t s_length, bool *multi_byte_charset)
1 by brian
clean slate
1476
{
438.1.13 by Brian Aker
uint cleanup.
1477
  register uint32_t length;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1478
  const CHARSET_INFO *cs;
1 by brian
clean slate
1479
  *multi_byte_charset= 0;
1480
1481
  length=0;
1482
  for (; s_length-- ; sortorder++)
1483
  {
1484
    sortorder->need_strxnfrm= 0;
1485
    sortorder->suffix_length= 0;
1486
    if (sortorder->field)
1487
    {
1488
      cs= sortorder->field->sort_charset();
1489
      sortorder->length= sortorder->field->sort_length();
1490
1491
      if (use_strnxfrm((cs=sortorder->field->sort_charset())))
1492
      {
1493
        sortorder->need_strxnfrm= 1;
1494
        *multi_byte_charset= 1;
1495
        sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1496
      }
1497
      if (sortorder->field->maybe_null())
1498
	length++;				// Place for NULL marker
1499
    }
1500
    else
1501
    {
1502
      sortorder->result_type= sortorder->item->result_type();
152 by Brian Aker
longlong replacement
1503
      if (sortorder->item->result_as_int64_t())
1 by brian
clean slate
1504
        sortorder->result_type= INT_RESULT;
2008 by Brian Aker
Formatting + remove default from switch/case.
1505
1 by brian
clean slate
1506
      switch (sortorder->result_type) {
1507
      case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1508
        sortorder->length=sortorder->item->max_length;
892.2.2 by Monty Taylor
More solaris warnings.
1509
        set_if_smaller(sortorder->length,
1905.1.1 by Brian Aker
Adding FileSort class.
1510
                       getSession().variables.max_sort_length);
2008 by Brian Aker
Formatting + remove default from switch/case.
1511
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1512
        {
1 by brian
clean slate
1513
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
2008 by Brian Aker
Formatting + remove default from switch/case.
1514
          sortorder->need_strxnfrm= 1;
1515
          *multi_byte_charset= 1;
1516
        }
1 by brian
clean slate
1517
        else if (cs == &my_charset_bin)
1518
        {
1519
          /* Store length last to be able to sort blob/varbinary */
1520
          sortorder->suffix_length= suffix_length(sortorder->length);
1521
          sortorder->length+= sortorder->suffix_length;
1522
        }
2008 by Brian Aker
Formatting + remove default from switch/case.
1523
        break;
1 by brian
clean slate
1524
      case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1525
        sortorder->length=8;			// Size of intern int64_t
1526
        break;
1 by brian
clean slate
1527
      case DECIMAL_RESULT:
1528
        sortorder->length=
2030.1.2 by Brian Aker
First pass in refactoring of the name of my_decimal.
1529
          class_decimal_get_binary_size(sortorder->item->max_length -
1 by brian
clean slate
1530
                                     (sortorder->item->decimals ? 1 : 0),
1531
                                     sortorder->item->decimals);
1532
        break;
1533
      case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1534
        sortorder->length=sizeof(double);
1535
        break;
1 by brian
clean slate
1536
      case ROW_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
1537
        // This case should never be choosen
1538
        assert(0);
1539
        break;
1 by brian
clean slate
1540
      }
1541
      if (sortorder->item->maybe_null)
2008 by Brian Aker
Formatting + remove default from switch/case.
1542
        length++;				// Place for NULL marker
1 by brian
clean slate
1543
    }
1905.1.1 by Brian Aker
Adding FileSort class.
1544
    set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1 by brian
clean slate
1545
    length+=sortorder->length;
1546
  }
1547
  sortorder->field= (Field*) 0;			// end marker
1548
  return length;
1549
}
1550
1551
1552
/**
1553
  Get descriptors of fields appended to sorted fields and
1554
  calculate its total length.
1555
1556
  The function first finds out what fields are used in the result set.
1557
  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:
1558
  these fields together with the value of sort values.
1 by brian
clean slate
1559
  If the calculated length is not greater than max_length_for_sort_data
1560
  the function allocates memory for an array of descriptors containing
1561
  layouts for the values of the non-sorted fields in the buffer and
1562
  fills them.
1563
1564
  @param ptabfield           Array of references to the table fields
1565
  @param sortlength          Total length of sorted fields
1566
  @param[out] plength        Total length of appended fields
1567
1568
  @note
1569
    The null bits for the appended values are supposed to be put together
1570
    and stored the buffer just ahead of the value of the first field.
1571
1572
  @return
1573
    Pointer to the layout descriptors for the appended fields, if any
1574
  @retval
1575
    NULL   if we do not store field values with sort data.
1576
*/
1577
1905.1.1 by Brian Aker
Adding FileSort class.
1578
sort_addon_field *FileSort::get_addon_fields(Field **ptabfield, uint32_t sortlength_arg, uint32_t *plength)
1 by brian
clean slate
1579
{
1580
  Field **pfield;
1581
  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.
1582
  sort_addon_field *addonf;
438.1.13 by Brian Aker
uint cleanup.
1583
  uint32_t length= 0;
1584
  uint32_t fields= 0;
1585
  uint32_t null_fields= 0;
1 by brian
clean slate
1586
1587
  /*
1588
    If there is a reference to a field in the query add it
1589
    to the the set of appended fields.
1590
    Note for future refinement:
1591
    This this a too strong condition.
1592
    Actually we need only the fields referred in the
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1593
    result set. And for some of them it makes sense to use
1 by brian
clean slate
1594
    the values directly from sorted fields.
1595
  */
1596
  *plength= 0;
1597
1598
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1599
  {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
1600
    if (!(field->isReadSet()))
1 by brian
clean slate
1601
      continue;
1602
    if (field->flags & BLOB_FLAG)
1603
      return 0;
1604
    length+= field->max_packed_col_length(field->pack_length());
1605
    if (field->maybe_null())
1606
      null_fields++;
1607
    fields++;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1608
  }
1 by brian
clean slate
1609
  if (!fields)
1610
    return 0;
1611
  length+= (null_fields+7)/8;
1612
1905.1.1 by Brian Aker
Adding FileSort class.
1613
  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.
1614
      !(addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field)*
641.3.7 by Monty Taylor
More my_malloc removal.
1615
                                            (fields+1))))
1 by brian
clean slate
1616
    return 0;
1617
1618
  *plength= length;
1619
  length= (null_fields+7)/8;
1620
  null_fields= 0;
1621
  for (pfield= ptabfield; (field= *pfield) ; pfield++)
1622
  {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
1623
    if (!(field->isReadSet()))
1 by brian
clean slate
1624
      continue;
1625
    addonf->field= field;
1626
    addonf->offset= length;
1627
    if (field->maybe_null())
1628
    {
1629
      addonf->null_offset= null_fields/8;
1630
      addonf->null_bit= 1<<(null_fields & 7);
1631
      null_fields++;
1632
    }
1633
    else
1634
    {
1635
      addonf->null_offset= 0;
1636
      addonf->null_bit= 0;
1637
    }
1638
    addonf->length= field->max_packed_col_length(field->pack_length());
1639
    length+= addonf->length;
1640
    addonf++;
1641
  }
1642
  addonf->field= 0;     // Put end marker
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1643
1 by brian
clean slate
1644
  return (addonf-fields);
1645
}
1646
1647
1648
/**
1649
  Copy (unpack) values appended to sorted fields from a buffer back to
1650
  their regular positions specified by the Field::ptr pointers.
1651
1652
  @param addon_field     Array of descriptors for appended fields
1653
  @param buff            Buffer which to unpack the value from
1654
1655
  @note
1656
    The function is supposed to be used only as a callback function
1657
    when getting field values for the sorted result set.
1658
1659
  @return
1660
    void.
1661
*/
1662
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1663
static void
1891.2.1 by Monty Taylor
Fixed things to make things compile with clang
1664
unpack_addon_fields(sort_addon_field *addon_field, unsigned char *buff)
1 by brian
clean slate
1665
{
1666
  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.
1667
  sort_addon_field *addonf= addon_field;
1 by brian
clean slate
1668
1669
  for ( ; (field= addonf->field) ; addonf++)
1670
  {
1671
    if (addonf->null_bit && (addonf->null_bit & buff[addonf->null_offset]))
1672
    {
1673
      field->set_null();
1674
      continue;
1675
    }
1676
    field->set_notnull();
1677
    field->unpack(field->ptr, buff + addonf->offset);
1678
  }
1679
}
1680
1681
/*
1682
** functions to change a double or float to a sortable string
1683
** The following should work for IEEE
1684
*/
1685
1686
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1687
481 by Brian Aker
Remove all of uchar.
1688
void change_double_for_sort(double nr,unsigned char *to)
1 by brian
clean slate
1689
{
481 by Brian Aker
Remove all of uchar.
1690
  unsigned char *tmp=(unsigned char*) to;
1 by brian
clean slate
1691
  if (nr == 0.0)
1692
  {						/* Change to zero string */
481 by Brian Aker
Remove all of uchar.
1693
    tmp[0]=(unsigned char) 128;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1694
    memset(tmp+1, 0, sizeof(nr)-1);
1 by brian
clean slate
1695
  }
1696
  else
1697
  {
1698
#ifdef WORDS_BIGENDIAN
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
1699
    memcpy(tmp,&nr,sizeof(nr));
1 by brian
clean slate
1700
#else
1701
    {
481 by Brian Aker
Remove all of uchar.
1702
      unsigned char *ptr= (unsigned char*) &nr;
1 by brian
clean slate
1703
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1704
      tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1705
      tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1706
#else
1707
      tmp[0]= ptr[7]; tmp[1]=ptr[6]; tmp[2]= ptr[5]; tmp[3]=ptr[4];
1708
      tmp[4]= ptr[3]; tmp[5]=ptr[2]; tmp[6]= ptr[1]; tmp[7]=ptr[0];
1709
#endif
1710
    }
1711
#endif
1712
    if (tmp[0] & 128)				/* Negative */
1713
    {						/* make complement */
438.1.13 by Brian Aker
uint cleanup.
1714
      uint32_t i;
1 by brian
clean slate
1715
      for (i=0 ; i < sizeof(nr); i++)
481 by Brian Aker
Remove all of uchar.
1716
	tmp[i]=tmp[i] ^ (unsigned char) 255;
1 by brian
clean slate
1717
    }
1718
    else
1719
    {					/* Set high and move exponent one up */
438.1.13 by Brian Aker
uint cleanup.
1720
      uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1721
		       (uint16_t) 32768);
1722
      exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
481 by Brian Aker
Remove all of uchar.
1723
      tmp[0]= (unsigned char) (exp_part >> 8);
1724
      tmp[1]= (unsigned char) exp_part;
1 by brian
clean slate
1725
    }
1726
  }
1727
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1728
1729
} /* namespace drizzled */