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();
56
memset(this, 0, sizeof(*this));
58
cursor= table->cursor;
59
record= table->getInsertRecord();
60
print_error= print_error_arg;
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;
67
void init_read_record(READ_RECORD *info,
70
optimizer::SqlSelect *select,
70
void ReadRecord::init_read_record(Session *session_arg,
72
optimizer::SqlSelect *select_arg,
74
76
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 */
78
memset(this, 0, sizeof(*this));
81
cursor= table->cursor;
82
forms= &table; /* Only one table */
82
84
if (table->sort.addon_field)
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;
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;
94
info->print_error= print_error;
95
info->ignore_not_found_rows= 0;
96
print_error= print_error_arg;
97
ignore_not_found_rows= 0;
96
98
table->status=0; /* And it's always found */
98
100
if (select && my_b_inited(select->file))
99
102
tempfile= select->file;
101
106
tempfile= table->sort.io_cache;
102
109
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;
111
read_record= (table->sort.addon_field ?
112
rr_unpack_from_tempfile : rr_from_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);
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)
130
if (! init_rr_cache(session, info))
132
info->read_record=rr_from_cache;
140
read_record= rr_from_cache;
136
144
else if (select && select->quick)
138
info->read_record=rr_quick;
146
read_record= rr_quick;
140
148
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);
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);
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)))
158
165
table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
162
170
} /* init_read_record */
165
void end_read_record(READ_RECORD *info)
173
void ReadRecord::end_read_record()
166
174
{ /* 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();
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();
182
static int rr_handle_error(READ_RECORD *info, int error)
191
static int rr_handle_error(ReadRecord *info, int error)
184
193
if (error == HA_ERR_END_OF_FILE)
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()
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;
394
uint32_t local_rec_cache_size;
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);
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;
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)))
408
if (cache_records <= 2 ||
409
!(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
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);
407
info->read_positions=info->cache+rec_cache_size;
408
info->cache_pos=info->cache_end=info->cache;
417
read_positions= cache + local_rec_cache_size;
418
cache_pos= cache_end= cache;
410
421
} /* init_rr_cache */
412
static int rr_from_cache(READ_RECORD *info)
423
static int rr_from_cache(ReadRecord *info)
414
425
register uint32_t i;
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());
436
info->cache_pos+=info->reclength;
447
info->cache_pos+= info->reclength;
437
448
return ((int) error);
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)
442
454
length= (uint32_t) rest_of_file;
443
if (!length || my_b_read(info->io_cache,info->cache,length))
457
if (!length || my_b_read(info->io_cache, info->getCache(), length))
445
459
return -1; /* End of cursor */
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)