24 #include <drizzled/drizzled.h>
25 #include <drizzled/error.h>
26 #include <drizzled/internal/iocache.h>
27 #include <drizzled/internal/my_sys.h>
28 #include <drizzled/optimizer/range.h>
29 #include <drizzled/plugin/storage_engine.h>
30 #include <drizzled/records.h>
31 #include <drizzled/session.h>
32 #include <drizzled/table.h>
33 #include <drizzled/system_variables.h>
37 static int rr_sequential(ReadRecord *info);
38 static int rr_quick(ReadRecord *info);
39 static int rr_from_tempfile(ReadRecord *info);
42 static int rr_from_pointers(ReadRecord *info);
43 static int rr_from_cache(ReadRecord *info);
44 static int rr_cmp(
unsigned char *a,
unsigned char *b);
46 static int rr_index(ReadRecord *info);
48 void ReadRecord::init_reard_record_sequential()
50 read_record= rr_sequential;
58 table_arg->emptyRecord();
61 record= table->getInsertRecord();
62 print_error= print_error_arg;
65 if (not table->
cursor->inited)
67 int error= table->
cursor->startIndexScan(idx, 1);
78 int ReadRecord::init_read_record(
Session *session_arg,
92 if (table->sort.addon_field)
94 rec_buf= table->sort.addon_buf;
95 ref_length= table->sort.addon_length;
100 record= table->getInsertRecord();
104 print_error= print_error_arg;
105 ignore_not_found_rows= 0;
108 if (select && select->
file->inited())
110 tempfile= select->
file;
114 tempfile= table->sort.io_cache;
117 if (tempfile && tempfile->inited())
123 ref_pos=table->
cursor->ref;
124 if (!table->
cursor->inited)
126 error= table->
cursor->startTableScan(0);
136 if (!table->sort.addon_field &&
138 !(table->
cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
139 (table->
db_stat & HA_READ_ONLY ||
140 table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
141 (uint64_t) table->getShare()->getRecordLength() * (table->
cursor->stats.records+
142 table->
cursor->stats.deleted) >
143 (uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
144 io_cache->end_of_file/ref_length * table->getShare()->getRecordLength() >
145 (internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
146 !table->getShare()->blob_fields &&
147 ref_length <= MAX_REFLENGTH)
151 read_record= rr_from_cache;
155 else if (select && select->
quick)
159 else if (table->sort.record_pointers)
161 error= table->
cursor->startTableScan(0);
165 cache_pos=table->sort.record_pointers;
166 cache_end= cache_pos+ table->sort.found_records * ref_length;
171 read_record= rr_sequential;
172 error= table->
cursor->startTableScan(1);
177 if (!table->no_cache &&
178 (use_record_cache > 0 ||
179 (
int) table->reginfo.lock_type <= (
int) TL_READ_WITH_SHARED_LOCKS ||
180 !(table->getShare()->db_options_in_use & HA_OPTION_PACK_RECORD)))
182 table->
cursor->extra_opt(HA_EXTRA_CACHE, session->
variables.read_buff_size);
190 void ReadRecord::end_read_record()
194 global_read_rnd_buffer.sub(session->
variables.read_rnd_buff_size);
200 table->filesort_free_buffers();
201 (void) cursor->extra(HA_EXTRA_NO_CACHE);
203 (void) cursor->ha_index_or_rnd_end();
209 static int rr_handle_error(ReadRecord *info,
int error)
211 if (error == HA_ERR_END_OF_FILE)
215 if (info->print_error)
216 info->table->print_error(error, MYF(0));
229 if (info->session->getKilled())
231 my_error(ER_SERVER_SHUTDOWN, MYF(0));
234 if (tmp != HA_ERR_RECORD_DELETED)
236 tmp= rr_handle_error(info, tmp);
258 int tmp= info->cursor->index_first(info->record);
261 tmp= rr_handle_error(info, tmp);
282 int tmp= info->cursor->index_next(info->record);
284 tmp= rr_handle_error(info, tmp);
288 int rr_sequential(ReadRecord *info)
291 while ((tmp= info->cursor->rnd_next(info->record)))
293 if (info->session->getKilled())
295 info->session->send_kill_message();
303 if (tmp != HA_ERR_RECORD_DELETED)
305 tmp= rr_handle_error(info, tmp);
313 static int rr_from_tempfile(ReadRecord *info)
318 if (info->io_cache->read(info->ref_pos, info->ref_length))
320 if (!(tmp=info->cursor->rnd_pos(info->record,info->ref_pos)))
323 if (tmp == HA_ERR_RECORD_DELETED ||
324 (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
326 tmp= rr_handle_error(info, tmp);
349 if (info->io_cache->read(info->rec_buf, info->ref_length))
351 Table *table= info->table;
352 (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
357 static int rr_from_pointers(ReadRecord *info)
360 unsigned char *cache_pos;
365 if (info->cache_pos == info->cache_end)
367 cache_pos= info->cache_pos;
368 info->cache_pos+= info->ref_length;
370 if (!(tmp=info->cursor->rnd_pos(info->record,cache_pos)))
374 if (tmp == HA_ERR_RECORD_DELETED ||
375 (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
377 tmp= rr_handle_error(info, tmp);
400 if (info->cache_pos == info->cache_end)
402 Table *table= info->table;
403 (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
404 info->cache_pos+= info->ref_length;
410 bool ReadRecord::init_rr_cache()
412 uint32_t local_rec_cache_size;
414 struct_length= 3 + MAX_REFLENGTH;
415 reclength= ALIGN_SIZE(table->getShare()->getRecordLength() + 1);
416 if (reclength < struct_length)
417 reclength= ALIGN_SIZE(struct_length);
419 error_offset= table->getShare()->getRecordLength();
420 cache_records= (session->
variables.read_rnd_buff_size /
421 (reclength + struct_length));
422 local_rec_cache_size= cache_records * reclength;
423 rec_cache_size= cache_records * ref_length;
425 if (not global_read_rnd_buffer.add(session->
variables.read_rnd_buff_size))
427 my_error(ER_OUT_OF_GLOBAL_READRNDMEMORY, MYF(ME_ERROR+ME_WAITTANG));
432 if (cache_records <= 2)
434 cache= (
unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1);
437 memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
439 read_positions= cache + local_rec_cache_size;
440 cache_pos= cache_end= cache;
445 static int rr_from_cache(ReadRecord *info)
448 internal::my_off_t rest_of_file;
450 unsigned char *position,*ref_position,*record_pos;
455 if (info->cache_pos != info->cache_end)
457 if (info->cache_pos[info->error_offset])
459 shortget(error,info->cache_pos);
460 if (info->print_error)
461 info->table->print_error(error,MYF(0));
466 memcpy(info->record,info->cache_pos, (
size_t) info->table->getShare()->getRecordLength());
468 info->cache_pos+= info->reclength;
469 return ((
int) error);
471 length=info->rec_cache_size;
472 rest_of_file= info->io_cache->end_of_file - info->io_cache->tell();
473 if ((internal::my_off_t) length > rest_of_file)
475 length= (uint32_t) rest_of_file;
478 if (!length || info->io_cache->read(info->getCache(), length))
483 length/=info->ref_length;
484 position=info->getCache();
485 ref_position=info->read_positions;
486 for (uint32_t i= 0 ; i < length ; i++,position+=info->ref_length)
488 memcpy(ref_position,position,(
size_t) info->ref_length);
489 ref_position+=MAX_REFLENGTH;
490 int3store(ref_position,(
long) i);
493 internal::my_qsort(info->read_positions, length, info->struct_length,
496 position=info->read_positions;
497 for (uint32_t i= 0 ; i < length ; i++)
499 memcpy(info->ref_pos, position, (
size_t)info->ref_length);
500 position+=MAX_REFLENGTH;
501 record=uint3korr(position);
503 record_pos= info->getCache() + record * info->reclength;
504 if ((error=(int16_t) info->cursor->rnd_pos(record_pos,info->ref_pos)))
506 record_pos[info->error_offset]=1;
507 shortstore(record_pos,error);
510 record_pos[info->error_offset]=0;
512 info->cache_end= (info->cache_pos= info->getCache())+length*info->reclength;
516 static int rr_cmp(
unsigned char *a,
unsigned char *b)
519 return (
int) a[0] - (int) b[0];
521 return (
int) a[1] - (int) b[1];
523 return (
int) a[2] - (int) b[2];
524 #if MAX_REFLENGTH == 4
525 return (
int) a[3] - (int) b[3];
528 return (
int) a[3] - (int) b[3];
530 return (
int) a[4] - (int) b[4];
532 return (
int) a[1] - (int) b[5];
534 return (
int) a[6] - (int) b[6];
535 return (
int) a[7] - (int) b[7];
TODO: Rename this file - func.h is stupid.
QuickSelectInterface * quick
static int rr_unpack_from_buffer(ReadRecord *info)
int(* qsort_cmp)(const void *, const void *)
int init_read_record_idx(Session *session, Table *table, bool print_error, uint32_t idx) __attribute__((warn_unused_result))
static int rr_unpack_from_tempfile(ReadRecord *info)
static int rr_quick(ReadRecord *info)
static int rr_index_first(ReadRecord *info)
static int rr_index(ReadRecord *info)
internal::io_cache_st * file
drizzle_system_variables & variables
bool reinit_io_cache(cache_type type_arg, my_off_t seek_offset, bool use_async_io, bool clear_cache)
Reset the cache.