~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/records.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

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