~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Mark Atwood
  • Date: 2008-10-16 11:33:16 UTC
  • mto: (520.1.13 drizzle)
  • mto: This revision was merged to the branch mainline in revision 530.
  • Revision ID: mark@fallenpegasus.com-20081016113316-ff6jdt31ck90sjdh
an implemention of the errmsg plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
*/
23
23
 
24
24
#include <drizzled/server_includes.h>
25
 
#include <drizzled/sql_sort.h>
26
 
#include <drizzled/error.h>
27
 
#include <drizzled/probes.h>
28
 
#include <drizzled/session.h>
29
 
#include <drizzled/table.h>
30
 
#include <drizzled/table_list.h>
 
25
#include "sql_sort.h"
 
26
#include <drizzled/drizzled_error_messages.h>
31
27
 
32
 
/* functions defined in this file */
 
28
        /* functions defined in this file */
33
29
 
34
30
static char **make_char_array(char **old_pos, register uint32_t fields,
35
31
                              uint32_t length, myf my_flag);
49
45
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count, 
50
46
                       filesort_info_st *table_sort);
51
47
static uint32_t suffix_length(uint32_t string_length);
52
 
static uint32_t sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
48
static uint32_t sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
53
49
                       bool *multi_byte_charset);
54
 
static SORT_ADDON_FIELD *get_addon_fields(Session *session, Field **ptabfield,
 
50
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
55
51
                                          uint32_t sortlength, uint32_t *plength);
56
52
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
57
53
                                unsigned char *buff);
67
63
  The result set is stored in table->io_cache or
68
64
  table->record_pointers.
69
65
 
70
 
  @param session           Current thread
 
66
  @param thd           Current thread
71
67
  @param table          Table to sort
72
68
  @param sortorder      How to sort the table
73
69
  @param s_length       Number of elements in sortorder
91
87
    examined_rows       will be set to number of examined rows
92
88
*/
93
89
 
94
 
ha_rows filesort(Session *session, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
 
90
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
95
91
                 SQL_SELECT *select, ha_rows max_rows,
96
92
                 bool sort_positions, ha_rows *examined_rows)
97
93
{
115
111
   Release InnoDB's adaptive hash index latch (if holding) before
116
112
   running a sort.
117
113
  */
118
 
  ha_release_temporary_latches(session);
 
114
  ha_release_temporary_latches(thd);
119
115
 
120
116
  /* 
121
117
    Don't use table->sort in filesort as it is also used by 
131
127
  buffpek=0;
132
128
  error= 1;
133
129
  memset(&param, 0, sizeof(param));
134
 
  param.sort_length= sortlength(session, sortorder, s_length, &multi_byte_charset);
 
130
  param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
135
131
  param.ref_length= table->file->ref_length;
136
132
  param.addon_field= 0;
137
133
  param.addon_length= 0;
141
137
      Get the descriptors of all fields whose values are appended 
142
138
      to sorted fields and get its total length in param.spack_length.
143
139
    */
144
 
    param.addon_field= get_addon_fields(session, table->field, 
 
140
    param.addon_field= get_addon_fields(thd, table->field, 
145
141
                                        param.sort_length,
146
142
                                        &param.addon_length);
147
143
  }
171
167
 
172
168
  if (select && select->quick)
173
169
  {
174
 
    status_var_increment(session->status_var.filesort_range_count);
 
170
    status_var_increment(thd->status_var.filesort_range_count);
175
171
  }
176
172
  else
177
173
  {
178
 
    status_var_increment(session->status_var.filesort_scan_count);
 
174
    status_var_increment(thd->status_var.filesort_scan_count);
179
175
  }
180
176
#ifdef CAN_TRUST_RANGE
181
177
  if (select && select->quick && select->quick->records > 0L)
201
197
      !(param.tmp_buffer= (char*) my_malloc(param.sort_length,MYF(MY_WME))))
202
198
    goto err;
203
199
 
204
 
  memavl= session->variables.sortbuff_size;
 
200
  memavl= thd->variables.sortbuff_size;
205
201
  min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
206
202
  while (memavl >= min_sort_memory)
207
203
  {
222
218
    my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
223
219
    goto err;
224
220
  }
225
 
  if (open_cached_file(&buffpek_pointers,drizzle_tmpdir,TEMP_PREFIX,
 
221
  if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
226
222
                       DISK_BUFFER_SIZE, MYF(MY_WME)))
227
223
    goto err;
228
224
 
257
253
    close_cached_file(&buffpek_pointers);
258
254
        /* Open cached file if it isn't open */
259
255
    if (! my_b_inited(outfile) &&
260
 
        open_cached_file(outfile,drizzle_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
 
256
        open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
261
257
                          MYF(MY_WME)))
262
258
      goto err;
263
259
    if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0))
316
312
    my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
317
313
               MYF(ME_ERROR+ME_WAITTANG));
318
314
  else
319
 
    statistic_add(session->status_var.filesort_rows,
 
315
    statistic_add(thd->status_var.filesort_rows,
320
316
                  (uint32_t) records, &LOCK_status);
321
317
  *examined_rows= param.examined_rows;
322
318
  memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
448
444
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
449
445
  my_off_t record;
450
446
  Table *sort_form;
451
 
  Session *session= current_session;
452
 
  volatile Session::killed_state *killed= &session->killed;
 
447
  THD *thd= current_thd;
 
448
  volatile THD::killed_state *killed= &thd->killed;
453
449
  handler *file;
454
450
  MY_BITMAP *save_read_set, *save_write_set;
455
451
 
471
467
    next_pos=(unsigned char*) 0;                        /* Find records in sequence */
472
468
    file->ha_rnd_init(1);
473
469
    file->extra_opt(HA_EXTRA_CACHE,
474
 
                    current_session->variables.read_buff_size);
 
470
                    current_thd->variables.read_buff_size);
475
471
  }
476
472
 
477
473
  READ_RECORD read_record_info;
479
475
  {
480
476
    if (select->quick->reset())
481
477
      return(HA_POS_ERROR);
482
 
    init_read_record(&read_record_info, current_session, select->quick->head,
 
478
    init_read_record(&read_record_info, current_thd, select->quick->head,
483
479
                     select, 1, 1);
484
480
  }
485
481
 
561
557
    else
562
558
      file->unlock_row();
563
559
    /* It does not make sense to read more keys in case of a fatal error */
564
 
    if (session->is_error())
 
560
    if (thd->is_error())
565
561
      break;
566
562
  }
567
563
  if (quick_select)
579
575
      file->ha_rnd_end();
580
576
  }
581
577
 
582
 
  if (session->is_error())
 
578
  if (thd->is_error())
583
579
    return(HA_POS_ERROR);
584
580
  
585
581
  /* Signal we should use orignal column read and write maps */
633
629
  rec_length= param->rec_length;
634
630
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
635
631
  if (!my_b_inited(tempfile) &&
636
 
      open_cached_file(tempfile, drizzle_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
 
632
      open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
637
633
                       MYF(MY_WME)))
638
634
    goto err;                                   /* purecov: inspected */
639
635
  /* check we won't have more buffpeks than we can possibly keep in memory */
989
985
  if (*maxbuffer < MERGEBUFF2)
990
986
    return(0);                          /* purecov: inspected */
991
987
  if (flush_io_cache(t_file) ||
992
 
      open_cached_file(&t_file2,drizzle_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
 
988
      open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
993
989
                        MYF(MY_WME)))
994
990
    return(1);                          /* purecov: inspected */
995
991
 
1122
1118
  QUEUE queue;
1123
1119
  qsort2_cmp cmp;
1124
1120
  void *first_cmp_arg;
1125
 
  volatile Session::killed_state *killed= &current_session->killed;
1126
 
  Session::killed_state not_killable;
 
1121
  volatile THD::killed_state *killed= &current_thd->killed;
 
1122
  THD::killed_state not_killable;
1127
1123
 
1128
 
  status_var_increment(current_session->status_var.filesort_merge_passes);
 
1124
  status_var_increment(current_thd->status_var.filesort_merge_passes);
1129
1125
  if (param->not_killable)
1130
1126
  {
1131
1127
    killed= &not_killable;
1132
 
    not_killable= Session::NOT_KILLED;
 
1128
    not_killable= THD::NOT_KILLED;
1133
1129
  }
1134
1130
 
1135
1131
  error=0;
1340
1336
/**
1341
1337
  Calculate length of sort key.
1342
1338
 
1343
 
  @param session                          Thread handler
 
1339
  @param thd                      Thread handler
1344
1340
  @param sortorder                Order of items to sort
1345
1341
  @param s_length                 Number of items to sort
1346
1342
  @param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
1356
1352
*/
1357
1353
 
1358
1354
static uint32_t
1359
 
sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
1355
sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
1360
1356
           bool *multi_byte_charset)
1361
1357
{
1362
1358
  register uint32_t length;
1390
1386
      switch (sortorder->result_type) {
1391
1387
      case STRING_RESULT:
1392
1388
        sortorder->length=sortorder->item->max_length;
1393
 
        set_if_smaller(sortorder->length, session->variables.max_sort_length);
 
1389
        set_if_smaller(sortorder->length, thd->variables.max_sort_length);
1394
1390
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1395
1391
        { 
1396
1392
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1425
1421
      if (sortorder->item->maybe_null)
1426
1422
        length++;                               // Place for NULL marker
1427
1423
    }
1428
 
    set_if_smaller(sortorder->length, session->variables.max_sort_length);
 
1424
    set_if_smaller(sortorder->length, thd->variables.max_sort_length);
1429
1425
    length+=sortorder->length;
1430
1426
  }
1431
1427
  sortorder->field= (Field*) 0;                 // end marker
1445
1441
  layouts for the values of the non-sorted fields in the buffer and
1446
1442
  fills them.
1447
1443
 
1448
 
  @param session                 Current thread
 
1444
  @param thd                 Current thread
1449
1445
  @param ptabfield           Array of references to the table fields
1450
1446
  @param sortlength          Total length of sorted fields
1451
1447
  @param[out] plength        Total length of appended fields
1461
1457
*/
1462
1458
 
1463
1459
static SORT_ADDON_FIELD *
1464
 
get_addon_fields(Session *session, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
 
1460
get_addon_fields(THD *thd, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
1465
1461
{
1466
1462
  Field **pfield;
1467
1463
  Field *field;
1497
1493
    return 0;
1498
1494
  length+= (null_fields+7)/8;
1499
1495
 
1500
 
  if (length+sortlength > session->variables.max_length_for_sort_data ||
 
1496
  if (length+sortlength > thd->variables.max_length_for_sort_data ||
1501
1497
      !(addonf= (SORT_ADDON_FIELD *) my_malloc(sizeof(SORT_ADDON_FIELD)*
1502
1498
                                               (fields+1), MYF(MY_WME))))
1503
1499
    return 0;