~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/records.cc

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  Functions for easy reading of records, possible through a cache
22
22
*/
23
23
#include <drizzled/server_includes.h>
 
24
#include <drizzled/error.h>
 
25
#include <drizzled/table.h>
 
26
#include <drizzled/session.h>
24
27
 
25
28
static int rr_quick(READ_RECORD *info);
26
29
int rr_sequential(READ_RECORD *info);
29
32
static int rr_unpack_from_buffer(READ_RECORD *info);
30
33
static int rr_from_pointers(READ_RECORD *info);
31
34
static int rr_from_cache(READ_RECORD *info);
32
 
static int init_rr_cache(THD *thd, READ_RECORD *info);
 
35
static int init_rr_cache(Session *session, READ_RECORD *info);
33
36
static int rr_cmp(unsigned char *a,unsigned char *b);
34
37
static int rr_index_first(READ_RECORD *info);
35
38
static int rr_index(READ_RECORD *info);
44
47
    join_read_first/next functions.
45
48
 
46
49
  @param info         READ_RECORD structure to initialize.
47
 
  @param thd          Thread handle
 
50
  @param session          Thread handle
48
51
  @param table        Table to be accessed
49
52
  @param print_error  If true, call table->file->print_error() if an error
50
53
                      occurs (except for end-of-records error)
51
54
  @param idx          index to scan
52
55
*/
53
56
 
54
 
void init_read_record_idx(READ_RECORD *info,
55
 
                          THD *thd __attribute__((unused)),
56
 
                          Table *table,
 
57
void init_read_record_idx(READ_RECORD *info, Session *, Table *table,
57
58
                          bool print_error, uint32_t idx)
58
59
{
59
 
  empty_record(table);
 
60
  table->emptyRecord();
60
61
  memset(info, 0, sizeof(*info));
61
62
  info->table= table;
62
63
  info->file=  table->file;
116
117
    rr_from_tempfile:
117
118
    -----------------
118
119
      Same as rr_from_pointers except that references are fetched from
119
 
      temporary file instead of from 
 
120
      temporary file instead of from
120
121
    rr_from_cache:
121
122
    --------------
122
123
      This is a special variant of rr_from_tempfile that can be used for
139
140
    This is the most basic access method of a table using rnd_init,
140
141
    rnd_next and rnd_end. No indexes are used.
141
142
*/
142
 
void init_read_record(READ_RECORD *info,THD *thd, Table *table,
 
143
void init_read_record(READ_RECORD *info,Session *session, Table *table,
143
144
                      SQL_SELECT *select,
144
145
                      int use_record_cache, bool print_error)
145
146
{
146
147
  IO_CACHE *tempfile;
147
148
 
148
149
  memset(info, 0, sizeof(*info));
149
 
  info->thd=thd;
 
150
  info->session=session;
150
151
  info->table=table;
151
152
  info->file= table->file;
152
153
  info->forms= &info->table;            /* Only one table */
153
 
  
 
154
 
154
155
  if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
155
156
      !table->sort.addon_field)
156
157
    table->file->extra(HA_EXTRA_MMAP);
157
 
  
 
158
 
158
159
  if (table->sort.addon_field)
159
160
  {
160
161
    info->rec_buf= table->sort.addon_buf;
162
163
  }
163
164
  else
164
165
  {
165
 
    empty_record(table);
 
166
    table->emptyRecord();
166
167
    info->record= table->record[0];
167
168
    info->ref_length= table->file->ref_length;
168
169
  }
191
192
      and table->sort.io_cache is read sequentially
192
193
    */
193
194
    if (!table->sort.addon_field &&
194
 
        thd->variables.read_rnd_buff_size &&
 
195
        session->variables.read_rnd_buff_size &&
195
196
        !(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
196
197
        (table->db_stat & HA_READ_ONLY ||
197
198
         table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
203
204
        !table->s->blob_fields &&
204
205
        info->ref_length <= MAX_REFLENGTH)
205
206
    {
206
 
      if (! init_rr_cache(thd, info))
 
207
      if (! init_rr_cache(session, info))
207
208
      {
208
209
        info->read_record=rr_from_cache;
209
210
      }
217
218
  {
218
219
    table->file->ha_rnd_init(0);
219
220
    info->cache_pos=table->sort.record_pointers;
220
 
    info->cache_end=info->cache_pos+ 
 
221
    info->cache_end=info->cache_pos+
221
222
                    table->sort.found_records*info->ref_length;
222
223
    info->read_record= (table->sort.addon_field ?
223
224
                        rr_unpack_from_buffer : rr_from_pointers);
233
234
         !(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
234
235
         (use_record_cache < 0 &&
235
236
          !(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
236
 
      table->file->extra_opt(HA_EXTRA_CACHE, thd->variables.read_buff_size);
 
237
      table->file->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
237
238
  }
238
 
  /* 
 
239
  /*
239
240
    Do condition pushdown for UPDATE/DELETE.
240
 
    TODO: Remove this from here as it causes two condition pushdown calls 
 
241
    TODO: Remove this from here as it causes two condition pushdown calls
241
242
    when we're running a SELECT and the condition cannot be pushed down.
242
243
  */
243
 
  if (thd->variables.engine_condition_pushdown && 
244
 
      select && select->cond && 
 
244
  if (session->variables.engine_condition_pushdown &&
 
245
      select && select->cond &&
245
246
      (select->cond->used_tables() & table->map) &&
246
247
      !table->file->pushed_cond)
247
248
    table->file->cond_push(select->cond);
290
291
  int tmp;
291
292
  while ((tmp= info->select->quick->get_next()))
292
293
  {
293
 
    if (info->thd->killed)
 
294
    if (info->session->killed)
294
295
    {
295
296
      my_error(ER_SERVER_SHUTDOWN, MYF(0));
296
297
      return 1;
301
302
      break;
302
303
    }
303
304
  }
 
305
 
304
306
  return tmp;
305
307
}
306
308
 
356
358
int rr_sequential(READ_RECORD *info)
357
359
{
358
360
  int tmp;
359
 
  while ((tmp=info->file->rnd_next(info->record)))
 
361
  while ((tmp= info->file->rnd_next(info->record)))
360
362
  {
361
 
    if (info->thd->killed)
 
363
    if (info->session->killed)
362
364
    {
363
 
      info->thd->send_kill_message();
 
365
      info->session->send_kill_message();
364
366
      return 1;
365
367
    }
366
368
    /*
 
369
      TODO> Fix this so that engine knows how to behave on its own.
367
370
      rnd_next can return RECORD_DELETED for MyISAM when one thread is
368
371
      reading and another deleting without locks.
369
372
    */
373
376
      break;
374
377
    }
375
378
  }
 
379
 
376
380
  return tmp;
377
381
}
378
382
 
401
405
  Read a result set record from a temporary file after sorting.
402
406
 
403
407
  The function first reads the next sorted record from the temporary file.
404
 
  into a buffer. If a success it calls a callback function that unpacks 
 
408
  into a buffer. If a success it calls a callback function that unpacks
405
409
  the fields values use in the result set from this buffer into their
406
410
  positions in the regular record buffer.
407
411
 
452
456
  Read a result set record from a buffer after sorting.
453
457
 
454
458
  The function first reads the next sorted record from the sort buffer.
455
 
  If a success it calls a callback function that unpacks 
 
459
  If a success it calls a callback function that unpacks
456
460
  the fields values use in the result set from this buffer into their
457
461
  positions in the regular record buffer.
458
462
 
476
480
}
477
481
        /* cacheing of records from a database */
478
482
 
479
 
static int init_rr_cache(THD *thd, READ_RECORD *info)
 
483
static int init_rr_cache(Session *session, READ_RECORD *info)
480
484
{
481
485
  uint32_t rec_cache_size;
482
486
 
486
490
    info->reclength= ALIGN_SIZE(info->struct_length);
487
491
 
488
492
  info->error_offset= info->table->s->reclength;
489
 
  info->cache_records= (thd->variables.read_rnd_buff_size /
 
493
  info->cache_records= (session->variables.read_rnd_buff_size /
490
494
                        (info->reclength+info->struct_length));
491
495
  rec_cache_size= info->cache_records*info->reclength;
492
496
  info->rec_cache_size= info->cache_records*info->ref_length;
493
497
 
494
498
  // We have to allocate one more byte to use uint3korr (see comments for it)
495
499
  if (info->cache_records <= 2 ||
496
 
      !(info->cache=(unsigned char*) my_malloc_lock(rec_cache_size+info->cache_records*
497
 
                                           info->struct_length+1,
498
 
                                           MYF(0))))
 
500
      !(info->cache=(unsigned char*) malloc(rec_cache_size+info->cache_records*
 
501
                                            info->struct_length+1)))
499
502
    return(1);
500
503
#ifdef HAVE_purify
501
504
  // Avoid warnings in qsort