20
20
Functions for easy reading of records, possible through a cache
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"
22
#include <drizzled/server_includes.h>
23
#include <drizzled/error.h>
24
#include <drizzled/table.h>
25
#include <drizzled/session.h>
34
27
int rr_sequential(READ_RECORD *info);
35
28
static int rr_quick(READ_RECORD *info);
43
36
static int rr_index_first(READ_RECORD *info);
44
37
static int rr_index(READ_RECORD *info);
40
Initialize READ_RECORD structure to perform full index scan (in forward
41
direction) using read_record.read_record() interface.
43
This function has been added at late stage and is used only by
44
UPDATE/DELETE. Other statements perform index scans using
45
join_read_first/next functions.
47
@param info READ_RECORD structure to initialize.
48
@param session Thread handle
49
@param table Table to be accessed
50
@param print_error If true, call table->file->print_error() if an error
51
occurs (except for end-of-records error)
52
@param idx index to scan
46
54
void init_read_record_idx(READ_RECORD *info,
52
60
table->emptyRecord();
53
61
memset(info, 0, sizeof(*info));
54
62
info->table= table;
55
info->cursor= table->cursor;
63
info->file= table->file;
56
64
info->record= table->record[0];
57
65
info->print_error= print_error;
59
67
table->status=0; /* And it's always found */
60
if (!table->cursor->inited)
61
table->cursor->ha_index_init(idx, 1);
68
if (!table->file->inited)
69
table->file->ha_index_init(idx, 1);
62
70
/* read_record will be changed to rr_index in rr_index_first */
63
71
info->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.
67
142
void init_read_record(READ_RECORD *info,
70
optimizer::SqlSelect *select,
146
int use_record_cache,
74
internal::IO_CACHE *tempfile;
76
151
memset(info, 0, sizeof(*info));
77
152
info->session=session;
78
153
info->table=table;
79
info->cursor= table->cursor;
154
info->file= table->file;
80
155
info->forms= &info->table; /* Only one table */
82
157
if (table->sort.addon_field)
89
164
table->emptyRecord();
90
165
info->record= table->record[0];
91
info->ref_length= table->cursor->ref_length;
166
info->ref_length= table->file->ref_length;
93
168
info->select=select;
94
info->print_error= print_error;
169
info->print_error=print_error;
95
170
info->ignore_not_found_rows= 0;
96
171
table->status=0; /* And it's always found */
98
if (select && my_b_inited(select->file))
99
tempfile= select->file;
173
if (select && my_b_inited(&select->file))
174
tempfile= &select->file;
101
176
tempfile= table->sort.io_cache;
102
177
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
104
179
info->read_record= (table->sort.addon_field ?
105
180
rr_unpack_from_tempfile : rr_from_tempfile);
106
181
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
if (!table->cursor->inited)
110
table->cursor->ha_rnd_init(0);
182
reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
183
info->ref_pos=table->file->ref;
184
if (!table->file->inited)
185
table->file->ha_rnd_init(0);
113
188
table->sort.addon_field is checked because if we use addon fields,
117
192
if (!table->sort.addon_field &&
118
193
session->variables.read_rnd_buff_size &&
119
!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
194
!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
120
195
(table->db_stat & HA_READ_ONLY ||
121
196
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
122
(uint64_t) table->s->reclength* (table->cursor->stats.records+
123
table->cursor->stats.deleted) >
197
(uint64_t) table->s->reclength* (table->file->stats.records+
198
table->file->stats.deleted) >
124
199
(uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
125
200
info->io_cache->end_of_file/info->ref_length * table->s->reclength >
126
(internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
201
(my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
127
202
!table->s->blob_fields &&
128
203
info->ref_length <= MAX_REFLENGTH)
151
info->read_record= rr_sequential;
152
table->cursor->ha_rnd_init(1);
226
info->read_record=rr_sequential;
227
table->file->ha_rnd_init(1);
153
228
/* We can use record cache if we don't update dynamic length tables */
154
229
if (!table->no_cache &&
155
230
(use_record_cache > 0 ||
156
231
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
157
!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD)))
158
table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
232
!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
233
(use_record_cache < 0 &&
234
!(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
235
table->file->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
162
239
} /* init_read_record */
165
241
void end_read_record(READ_RECORD *info)
166
242
{ /* free cache if used */