~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/records.cc

  • Committer: Brian Aker
  • Date: 2009-02-07 22:33:25 UTC
  • Revision ID: brian@tangent.org-20090207223325-5ipgldvw1pkghboq
typdef class removal (just... use the name of the class).

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);
33
 
static int rr_cmp(uchar *a,uchar *b);
 
35
static int init_rr_cache(Session *session, READ_RECORD *info);
 
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);
36
39
 
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
 
                          bool print_error, uint idx)
 
57
void init_read_record_idx(READ_RECORD *info, Session *, Table *table,
 
58
                          bool print_error, uint32_t idx)
58
59
{
59
60
  empty_record(table);
60
61
  memset(info, 0, sizeof(*info));
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
 
    VOID(table->file->extra(HA_EXTRA_MMAP));
157
 
  
 
157
    table->file->extra(HA_EXTRA_MMAP);
 
158
 
158
159
  if (table->sort.addon_field)
159
160
  {
160
161
    info->rec_buf= table->sort.addon_buf;
191
192
      and table->sort.io_cache is read sequentially
192
193
    */
193
194
    if (!table->sort.addon_field &&
194
 
        ! (specialflag & SPECIAL_SAFE_MODE) &&
195
 
        thd->variables.read_rnd_buff_size &&
 
195
        session->variables.read_rnd_buff_size &&
196
196
        !(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
197
197
        (table->db_stat & HA_READ_ONLY ||
198
198
         table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
204
204
        !table->s->blob_fields &&
205
205
        info->ref_length <= MAX_REFLENGTH)
206
206
    {
207
 
      if (! init_rr_cache(thd, info))
 
207
      if (! init_rr_cache(session, info))
208
208
      {
209
209
        info->read_record=rr_from_cache;
210
210
      }
218
218
  {
219
219
    table->file->ha_rnd_init(0);
220
220
    info->cache_pos=table->sort.record_pointers;
221
 
    info->cache_end=info->cache_pos+ 
 
221
    info->cache_end=info->cache_pos+
222
222
                    table->sort.found_records*info->ref_length;
223
223
    info->read_record= (table->sort.addon_field ?
224
224
                        rr_unpack_from_buffer : rr_from_pointers);
234
234
         !(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
235
235
         (use_record_cache < 0 &&
236
236
          !(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
237
 
      VOID(table->file->extra_opt(HA_EXTRA_CACHE,
238
 
                                  thd->variables.read_buff_size));
 
237
      table->file->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
239
238
  }
240
 
  /* 
 
239
  /*
241
240
    Do condition pushdown for UPDATE/DELETE.
242
 
    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
243
242
    when we're running a SELECT and the condition cannot be pushed down.
244
243
  */
245
 
  if (thd->variables.engine_condition_pushdown && 
246
 
      select && select->cond && 
 
244
  if (session->variables.engine_condition_pushdown &&
 
245
      select && select->cond &&
247
246
      (select->cond->used_tables() & table->map) &&
248
247
      !table->file->pushed_cond)
249
248
    table->file->cond_push(select->cond);
257
256
{                   /* free cache if used */
258
257
  if (info->cache)
259
258
  {
260
 
    my_free_lock((char*) info->cache,MYF(0));
 
259
    free((char*) info->cache);
261
260
    info->cache=0;
262
261
  }
263
262
  if (info->table)
292
291
  int tmp;
293
292
  while ((tmp= info->select->quick->get_next()))
294
293
  {
295
 
    if (info->thd->killed)
 
294
    if (info->session->killed)
296
295
    {
297
296
      my_error(ER_SERVER_SHUTDOWN, MYF(0));
298
297
      return 1;
303
302
      break;
304
303
    }
305
304
  }
 
305
  update_virtual_fields_marked_for_write(info->table);
306
306
  return tmp;
307
307
}
308
308
 
358
358
int rr_sequential(READ_RECORD *info)
359
359
{
360
360
  int tmp;
361
 
  while ((tmp=info->file->rnd_next(info->record)))
 
361
  while ((tmp= info->file->rnd_next(info->record)))
362
362
  {
363
 
    if (info->thd->killed)
 
363
    if (info->session->killed)
364
364
    {
365
 
      info->thd->send_kill_message();
 
365
      info->session->send_kill_message();
366
366
      return 1;
367
367
    }
368
368
    /*
 
369
      TODO> Fix this so that engine knows how to behave on its own.
369
370
      rnd_next can return RECORD_DELETED for MyISAM when one thread is
370
371
      reading and another deleting without locks.
371
372
    */
375
376
      break;
376
377
    }
377
378
  }
 
379
  if (!tmp)
 
380
    update_virtual_fields_marked_for_write(info->table);
378
381
  return tmp;
379
382
}
380
383
 
403
406
  Read a result set record from a temporary file after sorting.
404
407
 
405
408
  The function first reads the next sorted record from the temporary file.
406
 
  into a buffer. If a success it calls a callback function that unpacks 
 
409
  into a buffer. If a success it calls a callback function that unpacks
407
410
  the fields values use in the result set from this buffer into their
408
411
  positions in the regular record buffer.
409
412
 
419
422
{
420
423
  if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
421
424
    return -1;
422
 
  TABLE *table= info->table;
 
425
  Table *table= info->table;
423
426
  (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
424
427
 
425
428
  return 0;
428
431
static int rr_from_pointers(READ_RECORD *info)
429
432
{
430
433
  int tmp;
431
 
  uchar *cache_pos;
 
434
  unsigned char *cache_pos;
432
435
 
433
436
  for (;;)
434
437
  {
454
457
  Read a result set record from a buffer after sorting.
455
458
 
456
459
  The function first reads the next sorted record from the sort buffer.
457
 
  If a success it calls a callback function that unpacks 
 
460
  If a success it calls a callback function that unpacks
458
461
  the fields values use in the result set from this buffer into their
459
462
  positions in the regular record buffer.
460
463
 
470
473
{
471
474
  if (info->cache_pos == info->cache_end)
472
475
    return -1;                      /* End of buffer */
473
 
  TABLE *table= info->table;
 
476
  Table *table= info->table;
474
477
  (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
475
478
  info->cache_pos+= info->ref_length;
476
479
 
478
481
}
479
482
        /* cacheing of records from a database */
480
483
 
481
 
static int init_rr_cache(THD *thd, READ_RECORD *info)
 
484
static int init_rr_cache(Session *session, READ_RECORD *info)
482
485
{
483
 
  uint rec_cache_size;
 
486
  uint32_t rec_cache_size;
484
487
 
485
488
  info->struct_length= 3+MAX_REFLENGTH;
486
489
  info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
488
491
    info->reclength= ALIGN_SIZE(info->struct_length);
489
492
 
490
493
  info->error_offset= info->table->s->reclength;
491
 
  info->cache_records= (thd->variables.read_rnd_buff_size /
 
494
  info->cache_records= (session->variables.read_rnd_buff_size /
492
495
                        (info->reclength+info->struct_length));
493
496
  rec_cache_size= info->cache_records*info->reclength;
494
497
  info->rec_cache_size= info->cache_records*info->ref_length;
495
498
 
496
499
  // We have to allocate one more byte to use uint3korr (see comments for it)
497
500
  if (info->cache_records <= 2 ||
498
 
      !(info->cache=(uchar*) my_malloc_lock(rec_cache_size+info->cache_records*
499
 
                                           info->struct_length+1,
500
 
                                           MYF(0))))
 
501
      !(info->cache=(unsigned char*) malloc(rec_cache_size+info->cache_records*
 
502
                                            info->struct_length+1)))
501
503
    return(1);
502
504
#ifdef HAVE_purify
503
505
  // Avoid warnings in qsort
512
514
 
513
515
static int rr_from_cache(READ_RECORD *info)
514
516
{
515
 
  register uint i;
 
517
  register uint32_t i;
516
518
  uint32_t length;
517
519
  my_off_t rest_of_file;
518
520
  int16_t error;
519
 
  uchar *position,*ref_position,*record_pos;
 
521
  unsigned char *position,*ref_position,*record_pos;
520
522
  uint32_t record;
521
523
 
522
524
  for (;;)
581
583
} /* rr_from_cache */
582
584
 
583
585
 
584
 
static int rr_cmp(uchar *a,uchar *b)
 
586
static int rr_cmp(unsigned char *a,unsigned char *b)
585
587
{
586
588
  if (a[0] != b[0])
587
589
    return (int) a[0] - (int) b[0];