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);
46
void init_read_record_idx(READ_RECORD *info,
53
memset(info, 0, sizeof(*info));
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);
45
void ReadRecord::init_reard_record_sequential()
47
read_record= rr_sequential;
50
void ReadRecord::init_read_record_idx(Session *,
55
table_arg->emptyRecord();
57
cursor= table->cursor;
58
record= table->getInsertRecord();
59
print_error= print_error_arg;
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;
67
void init_read_record(READ_RECORD *info,
70
optimizer::SqlSelect *select,
69
void ReadRecord::init_read_record(Session *session_arg,
71
optimizer::SqlSelect *select_arg,
74
75
internal::IO_CACHE *tempfile;
76
memset(info, 0, sizeof(*info));
77
info->session=session;
79
info->cursor= table->cursor;
80
info->forms= &info->table; /* Only one table */
79
cursor= table->cursor;
80
forms= &table; /* Only one table */
82
82
if (table->sort.addon_field)
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;
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;
94
info->print_error= print_error;
95
info->ignore_not_found_rows= 0;
94
print_error= print_error_arg;
95
ignore_not_found_rows= 0;
96
96
table->status=0; /* And it's always found */
98
98
if (select && my_b_inited(select->file))
99
100
tempfile= select->file;
101
104
tempfile= table->sort.io_cache;
102
107
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
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);
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);
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)
130
if (! init_rr_cache(session, info))
132
info->read_record=rr_from_cache;
138
read_record= rr_from_cache;
136
142
else if (select && select->quick)
138
info->read_record=rr_quick;
144
read_record= rr_quick;
140
146
else if (table->sort.record_pointers)
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);
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)))
158
163
table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
162
168
} /* init_read_record */
165
void end_read_record(READ_RECORD *info)
171
void ReadRecord::end_read_record()
166
172
{ /* free cache if used */
169
free((char*) info->cache);
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();
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();
182
static int rr_handle_error(READ_RECORD *info, int error)
189
static int rr_handle_error(ReadRecord *info, int error)
184
191
if (error == HA_ERR_END_OF_FILE)
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()
384
uint32_t rec_cache_size;
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);
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;
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);
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;
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)))
406
if (cache_records <= 2 ||
407
!(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
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);
407
info->read_positions=info->cache+rec_cache_size;
408
info->cache_pos=info->cache_end=info->cache;
415
read_positions= cache + local_rec_cache_size;
416
cache_pos= cache_end= cache;
410
419
} /* init_rr_cache */
412
static int rr_from_cache(READ_RECORD *info)
421
static int rr_from_cache(ReadRecord *info)
416
424
internal::my_off_t rest_of_file;
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());
436
info->cache_pos+=info->reclength;
444
info->cache_pos+= info->reclength;
437
445
return ((int) error);
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)
442
451
length= (uint32_t) rest_of_file;
443
if (!length || my_b_read(info->io_cache,info->cache,length))
454
if (!length || my_b_read(info->io_cache, info->getCache(), length))
445
456
return -1; /* End of cursor */
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)
453
464
memcpy(ref_position,position,(size_t) info->ref_length);
454
465
ref_position+=MAX_REFLENGTH;