~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/records.cc

  • Committer: brian
  • Date: 2008-07-03 12:39:14 UTC
  • Revision ID: brian@localhost.localdomain-20080703123914-lry82qf74f6cbyzs
Disabling myisam tools until incomming link patch from Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
  @brief
21
21
  Functions for easy reading of records, possible through a cache
22
22
*/
23
 
#include <drizzled/server_includes.h>
 
23
 
 
24
#include "mysql_priv.h"
24
25
 
25
26
static int rr_quick(READ_RECORD *info);
26
27
int rr_sequential(READ_RECORD *info);
30
31
static int rr_from_pointers(READ_RECORD *info);
31
32
static int rr_from_cache(READ_RECORD *info);
32
33
static int init_rr_cache(THD *thd, READ_RECORD *info);
33
 
static int rr_cmp(unsigned char *a,unsigned char *b);
 
34
static int rr_cmp(uchar *a,uchar *b);
34
35
static int rr_index_first(READ_RECORD *info);
35
36
static int rr_index(READ_RECORD *info);
36
37
 
51
52
  @param idx          index to scan
52
53
*/
53
54
 
54
 
void init_read_record_idx(READ_RECORD *info,
55
 
                          THD *thd __attribute__((unused)),
56
 
                          Table *table,
57
 
                          bool print_error, uint32_t idx)
 
55
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
 
56
                          bool print_error, uint idx)
58
57
{
59
58
  empty_record(table);
60
 
  memset(info, 0, sizeof(*info));
 
59
  bzero((char*) info,sizeof(*info));
61
60
  info->table= table;
62
61
  info->file=  table->file;
63
62
  info->record= table->record[0];
139
138
    This is the most basic access method of a table using rnd_init,
140
139
    rnd_next and rnd_end. No indexes are used.
141
140
*/
142
 
void init_read_record(READ_RECORD *info,THD *thd, Table *table,
 
141
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
143
142
                      SQL_SELECT *select,
144
143
                      int use_record_cache, bool print_error)
145
144
{
146
145
  IO_CACHE *tempfile;
 
146
  DBUG_ENTER("init_read_record");
147
147
 
148
 
  memset(info, 0, sizeof(*info));
 
148
  bzero((char*) info,sizeof(*info));
149
149
  info->thd=thd;
150
150
  info->table=table;
151
151
  info->file= table->file;
153
153
  
154
154
  if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
155
155
      !table->sort.addon_field)
156
 
    table->file->extra(HA_EXTRA_MMAP);
 
156
    VOID(table->file->extra(HA_EXTRA_MMAP));
157
157
  
158
158
  if (table->sort.addon_field)
159
159
  {
177
177
    tempfile= table->sort.io_cache;
178
178
  if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
179
179
  {
 
180
    DBUG_PRINT("info",("using rr_from_tempfile"));
180
181
    info->read_record= (table->sort.addon_field ?
181
182
                        rr_unpack_from_tempfile : rr_from_tempfile);
182
183
    info->io_cache=tempfile;
191
192
      and table->sort.io_cache is read sequentially
192
193
    */
193
194
    if (!table->sort.addon_field &&
 
195
        ! (specialflag & SPECIAL_SAFE_MODE) &&
194
196
        thd->variables.read_rnd_buff_size &&
195
197
        !(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
196
198
        (table->db_stat & HA_READ_ONLY ||
197
199
         table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
198
 
        (uint64_t) table->s->reclength* (table->file->stats.records+
 
200
        (ulonglong) table->s->reclength* (table->file->stats.records+
199
201
                                          table->file->stats.deleted) >
200
 
        (uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
 
202
        (ulonglong) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
201
203
        info->io_cache->end_of_file/info->ref_length * table->s->reclength >
202
204
        (my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
203
205
        !table->s->blob_fields &&
205
207
    {
206
208
      if (! init_rr_cache(thd, info))
207
209
      {
 
210
        DBUG_PRINT("info",("using rr_from_cache"));
208
211
        info->read_record=rr_from_cache;
209
212
      }
210
213
    }
211
214
  }
212
215
  else if (select && select->quick)
213
216
  {
 
217
    DBUG_PRINT("info",("using rr_quick"));
214
218
    info->read_record=rr_quick;
215
219
  }
216
220
  else if (table->sort.record_pointers)
217
221
  {
 
222
    DBUG_PRINT("info",("using record_pointers"));
218
223
    table->file->ha_rnd_init(0);
219
224
    info->cache_pos=table->sort.record_pointers;
220
225
    info->cache_end=info->cache_pos+ 
224
229
  }
225
230
  else
226
231
  {
 
232
    DBUG_PRINT("info",("using rr_sequential"));
227
233
    info->read_record=rr_sequential;
228
234
    table->file->ha_rnd_init(1);
229
235
    /* We can use record cache if we don't update dynamic length tables */
233
239
         !(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
234
240
         (use_record_cache < 0 &&
235
241
          !(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
236
 
      table->file->extra_opt(HA_EXTRA_CACHE, thd->variables.read_buff_size);
 
242
      VOID(table->file->extra_opt(HA_EXTRA_CACHE,
 
243
                                  thd->variables.read_buff_size));
237
244
  }
238
245
  /* 
239
246
    Do condition pushdown for UPDATE/DELETE.
246
253
      !table->file->pushed_cond)
247
254
    table->file->cond_push(select->cond);
248
255
 
249
 
  return;
 
256
  DBUG_VOID_RETURN;
250
257
} /* init_read_record */
251
258
 
252
259
 
255
262
{                   /* free cache if used */
256
263
  if (info->cache)
257
264
  {
258
 
    free((char*) info->cache);
 
265
    my_free_lock((char*) info->cache,MYF(0));
259
266
    info->cache=0;
260
267
  }
261
268
  if (info->table)
301
308
      break;
302
309
    }
303
310
  }
304
 
  update_virtual_fields_marked_for_write(info->table);
305
311
  return tmp;
306
312
}
307
313
 
374
380
      break;
375
381
    }
376
382
  }
377
 
  if (!tmp)
378
 
    update_virtual_fields_marked_for_write(info->table);
379
383
  return tmp;
380
384
}
381
385
 
420
424
{
421
425
  if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
422
426
    return -1;
423
 
  Table *table= info->table;
 
427
  TABLE *table= info->table;
424
428
  (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
425
429
 
426
430
  return 0;
429
433
static int rr_from_pointers(READ_RECORD *info)
430
434
{
431
435
  int tmp;
432
 
  unsigned char *cache_pos;
 
436
  uchar *cache_pos;
433
437
 
434
438
  for (;;)
435
439
  {
471
475
{
472
476
  if (info->cache_pos == info->cache_end)
473
477
    return -1;                      /* End of buffer */
474
 
  Table *table= info->table;
 
478
  TABLE *table= info->table;
475
479
  (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
476
480
  info->cache_pos+= info->ref_length;
477
481
 
481
485
 
482
486
static int init_rr_cache(THD *thd, READ_RECORD *info)
483
487
{
484
 
  uint32_t rec_cache_size;
 
488
  uint rec_cache_size;
 
489
  DBUG_ENTER("init_rr_cache");
485
490
 
486
491
  info->struct_length= 3+MAX_REFLENGTH;
487
492
  info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
496
501
 
497
502
  // We have to allocate one more byte to use uint3korr (see comments for it)
498
503
  if (info->cache_records <= 2 ||
499
 
      !(info->cache=(unsigned char*) my_malloc_lock(rec_cache_size+info->cache_records*
 
504
      !(info->cache=(uchar*) my_malloc_lock(rec_cache_size+info->cache_records*
500
505
                                           info->struct_length+1,
501
506
                                           MYF(0))))
502
 
    return(1);
 
507
    DBUG_RETURN(1);
503
508
#ifdef HAVE_purify
504
509
  // Avoid warnings in qsort
505
 
  memset(info->cache, 0,
506
 
         rec_cache_size+info->cache_records* info->struct_length+1);
 
510
  bzero(info->cache,rec_cache_size+info->cache_records* info->struct_length+1);
507
511
#endif
 
512
  DBUG_PRINT("info",("Allocated buffert for %d records",info->cache_records));
508
513
  info->read_positions=info->cache+rec_cache_size;
509
514
  info->cache_pos=info->cache_end=info->cache;
510
 
  return(0);
 
515
  DBUG_RETURN(0);
511
516
} /* init_rr_cache */
512
517
 
513
518
 
514
519
static int rr_from_cache(READ_RECORD *info)
515
520
{
516
 
  register uint32_t i;
517
 
  uint32_t length;
 
521
  register uint i;
 
522
  ulong length;
518
523
  my_off_t rest_of_file;
519
 
  int16_t error;
520
 
  unsigned char *position,*ref_position,*record_pos;
521
 
  uint32_t record;
 
524
  int16 error;
 
525
  uchar *position,*ref_position,*record_pos;
 
526
  ulong record;
522
527
 
523
528
  for (;;)
524
529
  {
542
547
    length=info->rec_cache_size;
543
548
    rest_of_file=info->io_cache->end_of_file - my_b_tell(info->io_cache);
544
549
    if ((my_off_t) length > rest_of_file)
545
 
      length= (uint32_t) rest_of_file;
 
550
      length= (ulong) rest_of_file;
546
551
    if (!length || my_b_read(info->io_cache,info->cache,length))
547
552
    {
 
553
      DBUG_PRINT("info",("Found end of file"));
548
554
      return -1;                        /* End of file */
549
555
    }
550
556
 
569
575
      record=uint3korr(position);
570
576
      position+=3;
571
577
      record_pos=info->cache+record*info->reclength;
572
 
      if ((error=(int16_t) info->file->rnd_pos(record_pos,info->ref_pos)))
 
578
      if ((error=(int16) info->file->rnd_pos(record_pos,info->ref_pos)))
573
579
      {
574
580
        record_pos[info->error_offset]=1;
575
581
        shortstore(record_pos,error);
 
582
        DBUG_PRINT("error",("Got error: %d:%d when reading row",
 
583
                            my_errno, error));
576
584
      }
577
585
      else
578
586
        record_pos[info->error_offset]=0;
582
590
} /* rr_from_cache */
583
591
 
584
592
 
585
 
static int rr_cmp(unsigned char *a,unsigned char *b)
 
593
static int rr_cmp(uchar *a,uchar *b)
586
594
{
587
595
  if (a[0] != b[0])
588
596
    return (int) a[0] - (int) b[0];