13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21
20
Functions for easy reading of records, possible through a cache
23
#include <drizzled/server_includes.h>
25
static int rr_quick(READ_RECORD *info);
26
int rr_sequential(READ_RECORD *info);
27
static int rr_from_tempfile(READ_RECORD *info);
28
static int rr_unpack_from_tempfile(READ_RECORD *info);
29
static int rr_unpack_from_buffer(READ_RECORD *info);
30
static int rr_from_pointers(READ_RECORD *info);
31
static int rr_from_cache(READ_RECORD *info);
32
static int init_rr_cache(THD *thd, READ_RECORD *info);
33
static int rr_cmp(uchar *a,uchar *b);
34
static int rr_index_first(READ_RECORD *info);
35
static int rr_index(READ_RECORD *info);
39
Initialize READ_RECORD structure to perform full index scan (in forward
40
direction) using read_record.read_record() interface.
42
This function has been added at late stage and is used only by
43
UPDATE/DELETE. Other statements perform index scans using
44
join_read_first/next functions.
46
@param info READ_RECORD structure to initialize.
47
@param thd Thread handle
48
@param table Table to be accessed
49
@param print_error If true, call table->file->print_error() if an error
50
occurs (except for end-of-records error)
51
@param idx index to scan
54
void init_read_record_idx(READ_RECORD *info,
55
THD *thd __attribute__((unused)),
57
bool print_error, uint idx)
60
memset(info, 0, sizeof(*info));
62
info->file= table->file;
63
info->record= table->record[0];
64
info->print_error= print_error;
23
#include "drizzled/error.h"
24
#include "drizzled/table.h"
25
#include "drizzled/session.h"
26
#include "drizzled/records.h"
27
#include "drizzled/optimizer/range.h"
28
#include "drizzled/internal/my_sys.h"
29
#include "drizzled/internal/iocache.h"
34
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);
41
static int rr_cmp(unsigned char *a,unsigned char *b);
42
static int rr_index_first(ReadRecord *info);
43
static int rr_index(ReadRecord *info);
45
void ReadRecord::init_read_record_idx(Session *,
50
table_arg->emptyRecord();
51
memset(this, 0, sizeof(*this));
53
cursor= table->cursor;
54
record= table->record[0];
55
print_error= print_error_arg;
66
57
table->status=0; /* And it's always found */
67
if (!table->file->inited)
68
table->file->ha_index_init(idx, 1);
58
if (not table->cursor->inited)
59
table->cursor->startIndexScan(idx, 1);
69
60
/* read_record will be changed to rr_index in rr_index_first */
70
info->read_record= rr_index_first;
61
read_record= rr_index_first;
75
init_read_record is used to scan by using a number of different methods.
76
Which method to use is set-up in this call so that later calls to
77
the info->read_record will call the appropriate method using a function
80
There are five methods that relate completely to the sort function
81
filesort. The result of a filesort is retrieved using read_record
82
calls. The other two methods are used for normal table access.
84
The filesort will produce references to the records sorted, these
85
references can be stored in memory or in a temporary file.
87
The temporary file is normally used when the references doesn't fit into
88
a properly sized memory buffer. For most small queries the references
89
are stored in the memory buffer.
91
The temporary file is also used when performing an update where a key is
94
Methods used when ref's are in memory (using rr_from_pointers):
95
rr_unpack_from_buffer:
96
----------------------
97
This method is used when table->sort.addon_field is allocated.
98
This is allocated for most SELECT queries not involving any BLOB's.
99
In this case the records are fetched from a memory buffer.
102
Used when the above is not true, UPDATE, DELETE and so forth and
103
SELECT's involving BLOB's. It is also used when the addon_field
104
buffer is not allocated due to that its size was bigger than the
105
session variable max_length_for_sort_data.
106
In this case the record data is fetched from the handler using the
107
saved reference using the rnd_pos handler call.
109
Methods used when ref's are in a temporary file (using rr_from_tempfile)
110
rr_unpack_from_tempfile:
111
------------------------
112
Same as rr_unpack_from_buffer except that references are fetched from
113
temporary file. Should obviously not really happen other than in
114
strange configurations.
118
Same as rr_from_pointers except that references are fetched from
119
temporary file instead of from
122
This is a special variant of rr_from_tempfile that can be used for
123
handlers that is not using the HA_FAST_KEY_READ table flag. Instead
124
of reading the references one by one from the temporary file it reads
125
a set of them, sorts them and reads all of them into a buffer which
126
is then used for a number of subsequent calls to rr_from_cache.
127
It is only used for SELECT queries and a number of other conditions
130
All other accesses use either index access methods (rr_quick) or a full
131
table scan (rr_sequential).
134
rr_quick uses one of the QUICK_SELECT classes in opt_range.cc to
135
perform an index scan. There are loads of functionality hidden
136
in these quick classes. It handles all index scans of various kinds.
139
This is the most basic access method of a table using rnd_init,
140
rnd_next and rnd_end. No indexes are used.
142
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
144
int use_record_cache, bool print_error)
65
void ReadRecord::init_read_record(Session *session_arg,
67
optimizer::SqlSelect *select_arg,
148
memset(info, 0, sizeof(*info));
151
info->file= table->file;
152
info->forms= &info->table; /* Only one table */
154
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
155
!table->sort.addon_field)
156
VOID(table->file->extra(HA_EXTRA_MMAP));
71
internal::IO_CACHE *tempfile;
73
memset(this, 0, sizeof(*this));
76
cursor= table->cursor;
77
forms= &table; /* Only one table */
158
79
if (table->sort.addon_field)
160
info->rec_buf= table->sort.addon_buf;
161
info->ref_length= table->sort.addon_length;
81
rec_buf= table->sort.addon_buf;
82
ref_length= table->sort.addon_length;
166
info->record= table->record[0];
167
info->ref_length= table->file->ref_length;
87
record= table->record[0];
88
ref_length= table->cursor->ref_length;
170
info->print_error=print_error;
171
info->ignore_not_found_rows= 0;
91
print_error= print_error_arg;
92
ignore_not_found_rows= 0;
172
93
table->status=0; /* And it's always found */
174
if (select && my_b_inited(&select->file))
175
tempfile= &select->file;
95
if (select && my_b_inited(select->file))
97
tempfile= select->file;
177
101
tempfile= table->sort.io_cache;
178
104
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
180
info->read_record= (table->sort.addon_field ?
106
read_record= (table->sort.addon_field ?
181
107
rr_unpack_from_tempfile : rr_from_tempfile);
182
info->io_cache=tempfile;
183
reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
184
info->ref_pos=table->file->ref;
185
if (!table->file->inited)
186
table->file->ha_rnd_init(0);
109
reinit_io_cache(io_cache,internal::READ_CACHE,0L,0,0);
110
ref_pos=table->cursor->ref;
111
if (!table->cursor->inited)
112
table->cursor->startTableScan(0);
189
115
table->sort.addon_field is checked because if we use addon fields,
191
117
and table->sort.io_cache is read sequentially
193
119
if (!table->sort.addon_field &&
194
! (specialflag & SPECIAL_SAFE_MODE) &&
195
thd->variables.read_rnd_buff_size &&
196
!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
197
(table->db_stat & HA_READ_ONLY ||
198
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
199
(uint64_t) table->s->reclength* (table->file->stats.records+
200
table->file->stats.deleted) >
201
(uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
202
info->io_cache->end_of_file/info->ref_length * table->s->reclength >
203
(my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
204
!table->s->blob_fields &&
205
info->ref_length <= MAX_REFLENGTH)
120
session->variables.read_rnd_buff_size &&
121
!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
122
(table->db_stat & HA_READ_ONLY ||
123
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
124
(uint64_t) table->getShare()->reclength* (table->cursor->stats.records+
125
table->cursor->stats.deleted) >
126
(uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
127
io_cache->end_of_file/ref_length * table->getShare()->reclength >
128
(internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
129
!table->getShare()->blob_fields &&
130
ref_length <= MAX_REFLENGTH)
207
if (! init_rr_cache(thd, info))
209
info->read_record=rr_from_cache;
134
read_record=rr_from_cache;
213
138
else if (select && select->quick)
215
info->read_record=rr_quick;
140
read_record=rr_quick;
217
142
else if (table->sort.record_pointers)
219
table->file->ha_rnd_init(0);
220
info->cache_pos=table->sort.record_pointers;
221
info->cache_end=info->cache_pos+
222
table->sort.found_records*info->ref_length;
223
info->read_record= (table->sort.addon_field ?
224
rr_unpack_from_buffer : rr_from_pointers);
144
table->cursor->startTableScan(0);
145
cache_pos=table->sort.record_pointers;
146
cache_end= cache_pos+ table->sort.found_records * ref_length;
147
read_record= (table->sort.addon_field ? rr_unpack_from_buffer : rr_from_pointers);
228
info->read_record=rr_sequential;
229
table->file->ha_rnd_init(1);
151
read_record= rr_sequential;
152
table->cursor->startTableScan(1);
230
153
/* We can use record cache if we don't update dynamic length tables */
231
154
if (!table->no_cache &&
232
(use_record_cache > 0 ||
233
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
234
!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
235
(use_record_cache < 0 &&
236
!(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
237
VOID(table->file->extra_opt(HA_EXTRA_CACHE,
238
thd->variables.read_buff_size));
155
(use_record_cache > 0 ||
156
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
157
!(table->getShare()->db_options_in_use & HA_OPTION_PACK_RECORD)))
158
table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
241
Do condition pushdown for UPDATE/DELETE.
242
TODO: Remove this from here as it causes two condition pushdown calls
243
when we're running a SELECT and the condition cannot be pushed down.
245
if (thd->variables.engine_condition_pushdown &&
246
select && select->cond &&
247
(select->cond->used_tables() & table->map) &&
248
!table->file->pushed_cond)
249
table->file->cond_push(select->cond);
252
162
} /* init_read_record */
256
void end_read_record(READ_RECORD *info)
165
void ReadRecord::end_read_record()
257
166
{ /* free cache if used */
260
my_free_lock((char*) info->cache,MYF(0));
265
filesort_free_buffers(info->table,0);
266
(void) info->file->extra(HA_EXTRA_NO_CACHE);
267
if (info->read_record != rr_quick) // otherwise quick_range does it
268
(void) info->file->ha_index_or_rnd_end();
174
table->filesort_free_buffers();
175
(void) cursor->extra(HA_EXTRA_NO_CACHE);
176
if (read_record != rr_quick) // otherwise quick_range does it
177
(void) cursor->ha_index_or_rnd_end();
273
static int rr_handle_error(READ_RECORD *info, int error)
183
static int rr_handle_error(ReadRecord *info, int error)
275
185
if (error == HA_ERR_END_OF_FILE)
279
189
if (info->print_error)
280
info->table->file->print_error(error, MYF(0));
190
info->table->print_error(error, MYF(0));
281
191
if (error < 0) // Fix negative BDB errno
288
197
/** Read a record from head-database. */
290
static int rr_quick(READ_RECORD *info)
198
static int rr_quick(ReadRecord *info)
293
201
while ((tmp= info->select->quick->get_next()))
295
if (info->thd->killed)
203
if (info->session->killed)
297
205
my_error(ER_SERVER_SHUTDOWN, MYF(0));
466
369
-1 There is no record to be read anymore.
469
static int rr_unpack_from_buffer(READ_RECORD *info)
371
static int rr_unpack_from_buffer(ReadRecord *info)
471
373
if (info->cache_pos == info->cache_end)
472
374
return -1; /* End of buffer */
473
TABLE *table= info->table;
375
Table *table= info->table;
474
376
(*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
475
377
info->cache_pos+= info->ref_length;
479
/* cacheing of records from a database */
481
static int init_rr_cache(THD *thd, READ_RECORD *info)
382
/* cacheing of records from a database */
383
bool ReadRecord::init_rr_cache()
485
info->struct_length= 3+MAX_REFLENGTH;
486
info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
487
if (info->reclength < info->struct_length)
488
info->reclength= ALIGN_SIZE(info->struct_length);
490
info->error_offset= info->table->s->reclength;
491
info->cache_records= (thd->variables.read_rnd_buff_size /
492
(info->reclength+info->struct_length));
493
rec_cache_size= info->cache_records*info->reclength;
494
info->rec_cache_size= info->cache_records*info->ref_length;
385
uint32_t local_rec_cache_size;
387
struct_length= 3 + MAX_REFLENGTH;
388
reclength= ALIGN_SIZE(table->getShare()->reclength+1);
389
if (reclength < struct_length)
390
reclength= ALIGN_SIZE(struct_length);
392
error_offset= table->getShare()->reclength;
393
cache_records= (session->variables.read_rnd_buff_size /
394
(reclength+struct_length));
395
local_rec_cache_size= cache_records * reclength;
396
rec_cache_size= cache_records * ref_length;
496
398
// We have to allocate one more byte to use uint3korr (see comments for it)
497
if (info->cache_records <= 2 ||
498
!(info->cache=(uchar*) my_malloc_lock(rec_cache_size+info->cache_records*
499
info->struct_length+1,
399
if (cache_records <= 2 ||
400
!(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
502
404
#ifdef HAVE_purify
503
405
// Avoid warnings in qsort
504
memset(info->cache, 0,
505
rec_cache_size+info->cache_records* info->struct_length+1);
406
memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
507
info->read_positions=info->cache+rec_cache_size;
508
info->cache_pos=info->cache_end=info->cache;
408
read_positions= cache + local_rec_cache_size;
409
cache_pos= cache_end= cache;
510
412
} /* init_rr_cache */
513
static int rr_from_cache(READ_RECORD *info)
414
static int rr_from_cache(ReadRecord *info)
517
my_off_t rest_of_file;
418
internal::my_off_t rest_of_file;
519
uchar *position,*ref_position,*record_pos;
420
unsigned char *position,*ref_position,*record_pos;