~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/records.cc

  • Committer: Stewart Smith
  • Date: 2010-08-05 16:41:55 UTC
  • mfrom: (1638.9.13)
  • mto: (1720.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 1721.
  • Revision ID: stewart@flamingspork.com-20100805164155-7olu6iv6rwoxfsne
Merged store-foreign-key-in-table-proto into show-create-table-using-table-message.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
namespace drizzled
32
32
{
33
33
 
34
 
int rr_sequential(READ_RECORD *info);
35
 
static int rr_quick(READ_RECORD *info);
36
 
static int rr_from_tempfile(READ_RECORD *info);
37
 
static int rr_unpack_from_tempfile(READ_RECORD *info);
38
 
static int rr_unpack_from_buffer(READ_RECORD *info);
39
 
static int rr_from_pointers(READ_RECORD *info);
40
 
static int rr_from_cache(READ_RECORD *info);
41
 
static int init_rr_cache(Session *session, READ_RECORD *info);
 
34
static int rr_sequential(ReadRecord *info);
 
35
static int rr_quick(ReadRecord *info);
 
36
static int rr_from_tempfile(ReadRecord *info);
 
37
static int rr_unpack_from_tempfile(ReadRecord *info);
 
38
static int rr_unpack_from_buffer(ReadRecord *info);
 
39
static int rr_from_pointers(ReadRecord *info);
 
40
static int rr_from_cache(ReadRecord *info);
42
41
static int rr_cmp(unsigned char *a,unsigned char *b);
43
 
static int rr_index_first(READ_RECORD *info);
44
 
static int rr_index(READ_RECORD *info);
45
 
 
46
 
void init_read_record_idx(READ_RECORD *info, 
47
 
                          Session *, 
48
 
                          Table *table,
49
 
                          bool print_error, 
50
 
                          uint32_t idx)
51
 
{
52
 
  table->emptyRecord();
53
 
  memset(info, 0, sizeof(*info));
54
 
  info->table= table;
55
 
  info->cursor=  table->cursor;
56
 
  info->record= table->record[0];
57
 
  info->print_error= print_error;
 
42
static int rr_index_first(ReadRecord *info);
 
43
static int rr_index(ReadRecord *info);
 
44
 
 
45
void ReadRecord::init_reard_record_sequential()
 
46
{
 
47
  read_record= rr_sequential;
 
48
}
 
49
 
 
50
void ReadRecord::init_read_record_idx(Session *, 
 
51
                                      Table *table_arg,
 
52
                                      bool print_error_arg, 
 
53
                                      uint32_t idx)
 
54
{
 
55
  table_arg->emptyRecord();
 
56
  memset(this, 0, sizeof(*this));
 
57
  table= table_arg;
 
58
  cursor=  table->cursor;
 
59
  record= table->getInsertRecord();
 
60
  print_error= print_error_arg;
58
61
 
59
62
  table->status=0;                      /* And it's always found */
60
 
  if (!table->cursor->inited)
61
 
    table->cursor->ha_index_init(idx, 1);
 
63
  if (not table->cursor->inited)
 
64
    table->cursor->startIndexScan(idx, 1);
62
65
  /* read_record will be changed to rr_index in rr_index_first */
63
 
  info->read_record= rr_index_first;
 
66
  read_record= rr_index_first;
64
67
}
65
68
 
66
69
 
67
 
void init_read_record(READ_RECORD *info,
68
 
                      Session *session, 
69
 
                      Table *table,
70
 
                      optimizer::SqlSelect *select,
71
 
                      int use_record_cache, 
72
 
                      bool print_error)
 
70
void ReadRecord::init_read_record(Session *session_arg, 
 
71
                                  Table *table_arg,
 
72
                                  optimizer::SqlSelect *select_arg,
 
73
                                  int use_record_cache, 
 
74
                                  bool print_error_arg)
73
75
{
74
76
  internal::IO_CACHE *tempfile;
75
77
 
76
 
  memset(info, 0, sizeof(*info));
77
 
  info->session=session;
78
 
  info->table=table;
79
 
  info->cursor= table->cursor;
80
 
  info->forms= &info->table;            /* Only one table */
 
78
  memset(this, 0, sizeof(*this));
 
79
  session= session_arg;
 
80
  table= table_arg;
 
81
  cursor= table->cursor;
 
82
  forms= &table;                /* Only one table */
81
83
 
82
84
  if (table->sort.addon_field)
83
85
  {
84
 
    info->rec_buf= table->sort.addon_buf;
85
 
    info->ref_length= table->sort.addon_length;
 
86
    rec_buf= table->sort.addon_buf;
 
87
    ref_length= table->sort.addon_length;
86
88
  }
87
89
  else
88
90
  {
89
91
    table->emptyRecord();
90
 
    info->record= table->record[0];
91
 
    info->ref_length= table->cursor->ref_length;
 
92
    record= table->getInsertRecord();
 
93
    ref_length= table->cursor->ref_length;
92
94
  }
93
 
  info->select=select;
94
 
  info->print_error= print_error;
95
 
  info->ignore_not_found_rows= 0;
 
95
  select= select_arg;
 
96
  print_error= print_error_arg;
 
97
  ignore_not_found_rows= 0;
96
98
  table->status=0;                      /* And it's always found */
97
99
 
98
100
  if (select && my_b_inited(select->file))
 
101
  {
99
102
    tempfile= select->file;
 
103
  }
100
104
  else
 
105
  {
101
106
    tempfile= table->sort.io_cache;
 
107
  }
 
108
 
102
109
  if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
103
110
  {
104
 
    info->read_record= (table->sort.addon_field ?
105
 
                        rr_unpack_from_tempfile : rr_from_tempfile);
106
 
    info->io_cache=tempfile;
107
 
    reinit_io_cache(info->io_cache,internal::READ_CACHE,0L,0,0);
108
 
    info->ref_pos=table->cursor->ref;
 
111
    read_record= (table->sort.addon_field ?
 
112
                  rr_unpack_from_tempfile : rr_from_tempfile);
 
113
 
 
114
    io_cache=tempfile;
 
115
    reinit_io_cache(io_cache,internal::READ_CACHE,0L,0,0);
 
116
    ref_pos=table->cursor->ref;
109
117
    if (!table->cursor->inited)
110
 
      table->cursor->ha_rnd_init(0);
 
118
      table->cursor->startTableScan(0);
111
119
 
112
120
    /*
113
121
      table->sort.addon_field is checked because if we use addon fields,
119
127
        !(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
120
128
        (table->db_stat & HA_READ_ONLY ||
121
129
        table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
122
 
        (uint64_t) table->s->reclength* (table->cursor->stats.records+
 
130
        (uint64_t) table->getShare()->getRecordLength() * (table->cursor->stats.records+
123
131
                                                table->cursor->stats.deleted) >
124
132
        (uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
125
 
        info->io_cache->end_of_file/info->ref_length * table->s->reclength >
 
133
        io_cache->end_of_file/ref_length * table->getShare()->getRecordLength() >
126
134
        (internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
127
 
        !table->s->blob_fields &&
128
 
        info->ref_length <= MAX_REFLENGTH)
 
135
        !table->getShare()->blob_fields &&
 
136
        ref_length <= MAX_REFLENGTH)
129
137
    {
130
 
      if (! init_rr_cache(session, info))
 
138
      if (init_rr_cache())
131
139
      {
132
 
        info->read_record=rr_from_cache;
 
140
        read_record= rr_from_cache;
133
141
      }
134
142
    }
135
143
  }
136
144
  else if (select && select->quick)
137
145
  {
138
 
    info->read_record=rr_quick;
 
146
    read_record= rr_quick;
139
147
  }
140
148
  else if (table->sort.record_pointers)
141
149
  {
142
 
    table->cursor->ha_rnd_init(0);
143
 
    info->cache_pos=table->sort.record_pointers;
144
 
    info->cache_end=info->cache_pos+
145
 
                    table->sort.found_records*info->ref_length;
146
 
    info->read_record= (table->sort.addon_field ?
147
 
                        rr_unpack_from_buffer : rr_from_pointers);
 
150
    table->cursor->startTableScan(0);
 
151
    cache_pos=table->sort.record_pointers;
 
152
    cache_end= cache_pos+ table->sort.found_records * ref_length;
 
153
    read_record= (table->sort.addon_field ?  rr_unpack_from_buffer : rr_from_pointers);
148
154
  }
149
155
  else
150
156
  {
151
 
    info->read_record= rr_sequential;
152
 
    table->cursor->ha_rnd_init(1);
 
157
    read_record= rr_sequential;
 
158
    table->cursor->startTableScan(1);
153
159
    /* We can use record cache if we don't update dynamic length tables */
154
160
    if (!table->no_cache &&
155
161
        (use_record_cache > 0 ||
156
162
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
157
 
        !(table->s->db_options_in_use & HA_OPTION_PACK_RECORD)))
 
163
        !(table->getShare()->db_options_in_use & HA_OPTION_PACK_RECORD)))
 
164
    {
158
165
      table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
 
166
    }
159
167
  }
160
168
 
161
169
  return;
162
170
} /* init_read_record */
163
171
 
164
172
 
165
 
void end_read_record(READ_RECORD *info)
 
173
void ReadRecord::end_read_record()
166
174
{                   /* free cache if used */
167
 
  if (info->cache)
 
175
  if (cache)
168
176
  {
169
 
    free((char*) info->cache);
170
 
    info->cache=0;
 
177
    free((char*) cache);
 
178
    cache= NULL;
171
179
  }
172
 
  if (info->table)
 
180
  if (table)
173
181
  {
174
 
    info->table->filesort_free_buffers();
175
 
    (void) info->cursor->extra(HA_EXTRA_NO_CACHE);
176
 
    if (info->read_record != rr_quick) // otherwise quick_range does it
177
 
      (void) info->cursor->ha_index_or_rnd_end();
178
 
    info->table=0;
 
182
    table->filesort_free_buffers();
 
183
    (void) cursor->extra(HA_EXTRA_NO_CACHE);
 
184
    if (read_record != rr_quick) // otherwise quick_range does it
 
185
      (void) cursor->ha_index_or_rnd_end();
 
186
 
 
187
    table= NULL;
179
188
  }
180
189
}
181
190
 
182
 
static int rr_handle_error(READ_RECORD *info, int error)
 
191
static int rr_handle_error(ReadRecord *info, int error)
183
192
{
184
193
  if (error == HA_ERR_END_OF_FILE)
185
194
    error= -1;
194
203
}
195
204
 
196
205
/** Read a record from head-database. */
197
 
static int rr_quick(READ_RECORD *info)
 
206
static int rr_quick(ReadRecord *info)
198
207
{
199
208
  int tmp;
200
209
  while ((tmp= info->select->quick->get_next()))
226
235
  @retval
227
236
    1   Error
228
237
*/
229
 
static int rr_index_first(READ_RECORD *info)
 
238
static int rr_index_first(ReadRecord *info)
230
239
{
231
240
  int tmp= info->cursor->index_first(info->record);
232
241
  info->read_record= rr_index;
250
259
  @retval
251
260
    1   Error
252
261
*/
253
 
static int rr_index(READ_RECORD *info)
 
262
static int rr_index(ReadRecord *info)
254
263
{
255
264
  int tmp= info->cursor->index_next(info->record);
256
265
  if (tmp)
258
267
  return tmp;
259
268
}
260
269
 
261
 
int rr_sequential(READ_RECORD *info)
 
270
int rr_sequential(ReadRecord *info)
262
271
{
263
272
  int tmp;
264
273
  while ((tmp= info->cursor->rnd_next(info->record)))
283
292
  return tmp;
284
293
}
285
294
 
286
 
static int rr_from_tempfile(READ_RECORD *info)
 
295
static int rr_from_tempfile(ReadRecord *info)
287
296
{
288
297
  int tmp;
289
298
  for (;;)
317
326
  @retval
318
327
    -1   There is no record to be read anymore.
319
328
*/
320
 
static int rr_unpack_from_tempfile(READ_RECORD *info)
 
329
static int rr_unpack_from_tempfile(ReadRecord *info)
321
330
{
322
331
  if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
323
332
    return -1;
327
336
  return 0;
328
337
}
329
338
 
330
 
static int rr_from_pointers(READ_RECORD *info)
 
339
static int rr_from_pointers(ReadRecord *info)
331
340
{
332
341
  int tmp;
333
342
  unsigned char *cache_pos;
334
343
 
 
344
 
335
345
  for (;;)
336
346
  {
337
347
    if (info->cache_pos == info->cache_end)
367
377
  @retval
368
378
    -1   There is no record to be read anymore.
369
379
*/
370
 
static int rr_unpack_from_buffer(READ_RECORD *info)
 
380
static int rr_unpack_from_buffer(ReadRecord *info)
371
381
{
372
382
  if (info->cache_pos == info->cache_end)
373
383
    return -1;                      /* End of buffer */
379
389
}
380
390
 
381
391
/* cacheing of records from a database */
382
 
static int init_rr_cache(Session *session, READ_RECORD *info)
 
392
bool ReadRecord::init_rr_cache()
383
393
{
384
 
  uint32_t rec_cache_size;
385
 
 
386
 
  info->struct_length= 3+MAX_REFLENGTH;
387
 
  info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
388
 
  if (info->reclength < info->struct_length)
389
 
    info->reclength= ALIGN_SIZE(info->struct_length);
390
 
 
391
 
  info->error_offset= info->table->s->reclength;
392
 
  info->cache_records= (session->variables.read_rnd_buff_size /
393
 
                        (info->reclength+info->struct_length));
394
 
  rec_cache_size= info->cache_records*info->reclength;
395
 
  info->rec_cache_size= info->cache_records*info->ref_length;
 
394
  uint32_t local_rec_cache_size;
 
395
 
 
396
  struct_length= 3 + MAX_REFLENGTH;
 
397
  reclength= ALIGN_SIZE(table->getShare()->getRecordLength() + 1);
 
398
  if (reclength < struct_length)
 
399
    reclength= ALIGN_SIZE(struct_length);
 
400
 
 
401
  error_offset= table->getShare()->getRecordLength();
 
402
  cache_records= (session->variables.read_rnd_buff_size /
 
403
                        (reclength + struct_length));
 
404
  local_rec_cache_size= cache_records * reclength;
 
405
  rec_cache_size= cache_records * ref_length;
396
406
 
397
407
  // We have to allocate one more byte to use uint3korr (see comments for it)
398
 
  if (info->cache_records <= 2 ||
399
 
      !(info->cache=(unsigned char*) malloc(rec_cache_size+info->cache_records*
400
 
                                            info->struct_length+1)))
401
 
    return(1);
 
408
  if (cache_records <= 2 ||
 
409
      !(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
 
410
  {
 
411
    return false;
 
412
  }
402
413
#ifdef HAVE_purify
403
414
  // Avoid warnings in qsort
404
 
  memset(info->cache, 0,
405
 
         rec_cache_size+info->cache_records* info->struct_length+1);
 
415
  memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
406
416
#endif
407
 
  info->read_positions=info->cache+rec_cache_size;
408
 
  info->cache_pos=info->cache_end=info->cache;
409
 
  return(0);
 
417
  read_positions= cache + local_rec_cache_size;
 
418
  cache_pos= cache_end= cache;
 
419
 
 
420
  return true;
410
421
} /* init_rr_cache */
411
422
 
412
 
static int rr_from_cache(READ_RECORD *info)
 
423
static int rr_from_cache(ReadRecord *info)
413
424
{
414
425
  register uint32_t i;
415
426
  uint32_t length;
431
442
      else
432
443
      {
433
444
        error=0;
434
 
        memcpy(info->record,info->cache_pos, (size_t) info->table->s->reclength);
 
445
        memcpy(info->record,info->cache_pos, (size_t) info->table->getShare()->getRecordLength());
435
446
      }
436
 
      info->cache_pos+=info->reclength;
 
447
      info->cache_pos+= info->reclength;
437
448
      return ((int) error);
438
449
    }
439
450
    length=info->rec_cache_size;
440
 
    rest_of_file=info->io_cache->end_of_file - my_b_tell(info->io_cache);
 
451
    rest_of_file= info->io_cache->end_of_file - my_b_tell(info->io_cache);
441
452
    if ((internal::my_off_t) length > rest_of_file)
 
453
    {
442
454
      length= (uint32_t) rest_of_file;
443
 
    if (!length || my_b_read(info->io_cache,info->cache,length))
 
455
    }
 
456
 
 
457
    if (!length || my_b_read(info->io_cache, info->getCache(), length))
444
458
    {
445
459
      return -1;                        /* End of cursor */
446
460
    }
447
461
 
448
462
    length/=info->ref_length;
449
 
    position=info->cache;
 
463
    position=info->getCache();
450
464
    ref_position=info->read_positions;
451
465
    for (i=0 ; i < length ; i++,position+=info->ref_length)
452
466
    {
461
475
    position=info->read_positions;
462
476
    for (i=0 ; i < length ; i++)
463
477
    {
464
 
      memcpy(info->ref_pos,position,(size_t) info->ref_length);
 
478
      memcpy(info->ref_pos, position, (size_t)info->ref_length);
465
479
      position+=MAX_REFLENGTH;
466
480
      record=uint3korr(position);
467
481
      position+=3;
468
 
      record_pos=info->cache+record*info->reclength;
 
482
      record_pos= info->getCache() + record * info->reclength;
469
483
      if ((error=(int16_t) info->cursor->rnd_pos(record_pos,info->ref_pos)))
470
484
      {
471
485
        record_pos[info->error_offset]=1;
474
488
      else
475
489
        record_pos[info->error_offset]=0;
476
490
    }
477
 
    info->cache_end=(info->cache_pos=info->cache)+length*info->reclength;
 
491
    info->cache_end= (info->cache_pos= info->getCache())+length*info->reclength;
478
492
  }
479
493
} /* rr_from_cache */
480
494