Commit 1c7c67d5 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#121-125 DS-MRR improvements

- Address Monty's review feedback, part 6: rename "handler *h" variable in all
  DS-MRR classes to something else.
parent 799a1b16
...@@ -293,20 +293,20 @@ int Mrr_simple_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -293,20 +293,20 @@ int Mrr_simple_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
Buffer_manager *buf_manager_arg) Buffer_manager *buf_manager_arg)
{ {
HANDLER_BUFFER no_buffer = {NULL, NULL, NULL}; HANDLER_BUFFER no_buffer = {NULL, NULL, NULL};
h= h_arg; file= h_arg;
return h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges, return file->handler::multi_range_read_init(seq_funcs, seq_init_param,
mode, &no_buffer); n_ranges, mode, &no_buffer);
} }
int Mrr_simple_index_reader::get_next(char **range_info) int Mrr_simple_index_reader::get_next(char **range_info)
{ {
int res; int res;
while (!(res= h->handler::multi_range_read_next(range_info))) while (!(res= file->handler::multi_range_read_next(range_info)))
{ {
KEY_MULTI_RANGE *curr_range= &h->handler::mrr_cur_range; KEY_MULTI_RANGE *curr_range= &file->handler::mrr_cur_range;
if (!h->mrr_funcs.skip_index_tuple || if (!file->mrr_funcs.skip_index_tuple ||
!h->mrr_funcs.skip_index_tuple(h->mrr_iter, curr_range->ptr)) !file->mrr_funcs.skip_index_tuple(file->mrr_iter, curr_range->ptr))
break; break;
} }
return res; return res;
...@@ -430,12 +430,12 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -430,12 +430,12 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
Lifo_buffer *key_buffer_arg, Lifo_buffer *key_buffer_arg,
Buffer_manager *buf_manager_arg) Buffer_manager *buf_manager_arg)
{ {
h= h_arg; file= h_arg;
key_buffer= key_buffer_arg; key_buffer= key_buffer_arg;
buf_manager= buf_manager_arg; buf_manager= buf_manager_arg;
keypar= *key_par_arg; keypar= *key_par_arg;
KEY *key_info= &h->get_table()->key_info[h->active_index]; KEY *key_info= &file->get_table()->key_info[file->active_index];
keypar.index_ranges_unique= test(key_info->flags & HA_NOSAME && keypar.index_ranges_unique= test(key_info->flags & HA_NOSAME &&
key_info->key_parts == key_info->key_parts ==
my_count_bits(keypar.key_tuple_map)); my_count_bits(keypar.key_tuple_map));
...@@ -456,8 +456,8 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -456,8 +456,8 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
case it will make an index lookup only for the first such element, case it will make an index lookup only for the first such element,
for subsequent elements it will only return the new range_id. for subsequent elements it will only return the new range_id.
The problem here is that h->table->record[0] is shared with the part that The problem here is that file->table->record[0] is shared with the part
does full record retrieval with rnd_pos() calls, and if we have the that does full record retrieval with rnd_pos() calls, and if we have the
following scenario: following scenario:
1. We scan ranges {(key_value, range_id1), (key_value, range_id2)} 1. We scan ranges {(key_value, range_id1), (key_value, range_id2)}
...@@ -484,9 +484,9 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -484,9 +484,9 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
} }
static int rowid_cmp_reverse(void *h, uchar *a, uchar *b) static int rowid_cmp_reverse(void *file, uchar *a, uchar *b)
{ {
return - ((handler*)h)->cmp_ref(a, b); return - ((handler*)file)->cmp_ref(a, b);
} }
...@@ -495,7 +495,7 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg, ...@@ -495,7 +495,7 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
uint mode, uint mode,
Lifo_buffer *buf) Lifo_buffer *buf)
{ {
h= h_arg; file= h_arg;
index_reader= index_reader_arg; index_reader= index_reader_arg;
rowid_buffer= buf; rowid_buffer= buf;
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION); is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
...@@ -546,7 +546,7 @@ int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) ...@@ -546,7 +546,7 @@ int Mrr_ordered_rndpos_reader::refill_buffer(bool initial)
void Mrr_index_reader::position() void Mrr_index_reader::position()
{ {
h->position(h->get_table()->record[0]); file->position(file->get_table()->record[0]);
} }
...@@ -565,7 +565,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader() ...@@ -565,7 +565,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
DBUG_ASSERT(rowid_buffer->is_empty()); DBUG_ASSERT(rowid_buffer->is_empty());
index_rowid= index_reader->get_rowid_ptr(); index_rowid= index_reader->get_rowid_ptr();
rowid_buffer->reset(); rowid_buffer->reset();
rowid_buffer->setup_writing(&index_rowid, h->ref_length, rowid_buffer->setup_writing(&index_rowid, file->ref_length,
is_mrr_assoc? (uchar**)&range_info_ptr: NULL, is_mrr_assoc? (uchar**)&range_info_ptr: NULL,
sizeof(void*)); sizeof(void*));
...@@ -590,9 +590,9 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader() ...@@ -590,9 +590,9 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
} }
/* Sort the buffer contents by rowid */ /* Sort the buffer contents by rowid */
rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)h); rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)file);
rowid_buffer->setup_reading(&rowid, h->ref_length, rowid_buffer->setup_reading(&rowid, file->ref_length,
is_mrr_assoc? (uchar**)&rowids_range_id: NULL, is_mrr_assoc? (uchar**)&rowids_range_id: NULL,
sizeof(void*)); sizeof(void*));
DBUG_RETURN(rowid_buffer->is_empty()? HA_ERR_END_OF_FILE : 0); DBUG_RETURN(rowid_buffer->is_empty()? HA_ERR_END_OF_FILE : 0);
...@@ -653,7 +653,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -653,7 +653,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
continue; continue;
} }
res= h->ha_rnd_pos(h->get_table()->record[0], rowid); res= file->ha_rnd_pos(file->get_table()->record[0], rowid);
if (res == HA_ERR_RECORD_DELETED) if (res == HA_ERR_RECORD_DELETED)
{ {
...@@ -681,7 +681,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -681,7 +681,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
it.init(rowid_buffer); it.init(rowid_buffer);
while (!it.read()) // reads to (rowid, ...) while (!it.read()) // reads to (rowid, ...)
{ {
if (h->cmp_ref(rowid, cur_rowid)) if (file->cmp_ref(rowid, cur_rowid))
break; break;
last_identical_rowid= rowid; last_identical_rowid= rowid;
} }
...@@ -699,7 +699,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -699,7 +699,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
Initialize and start the MRR scan. Depending on the mode parameter, this Initialize and start the MRR scan. Depending on the mode parameter, this
may use default or DS-MRR implementation. may use default or DS-MRR implementation.
@param h Table handler to be used @param h_arg Table handler to be used
@param key Index to be used @param key Index to be used
@param seq_funcs Interval sequence enumeration functions @param seq_funcs Interval sequence enumeration functions
@param seq_init_param Interval sequence enumeration parameter @param seq_init_param Interval sequence enumeration parameter
...@@ -728,7 +728,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -728,7 +728,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
index_merge may invoke a scan on an object for which dsmrr_info[_const] index_merge may invoke a scan on an object for which dsmrr_info[_const]
has not been called, so set the owner handler here as well. has not been called, so set the owner handler here as well.
*/ */
h= h_arg; primary_file= h_arg;
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION); is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
strategy_exhausted= FALSE; strategy_exhausted= FALSE;
...@@ -760,11 +760,12 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -760,11 +760,12 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
- We're doing a scan on clustered primary key - We're doing a scan on clustered primary key
- [In the future] We're doing an index_only read - [In the future] We're doing an index_only read
*/ */
DBUG_ASSERT(h->inited == handler::INDEX || DBUG_ASSERT(primary_file->inited == handler::INDEX ||
(h->inited == handler::RND && h2 && (primary_file->inited == handler::RND &&
h2->inited == handler::INDEX)); secondary_file &&
secondary_file->inited == handler::INDEX));
h_idx= (h->inited == handler::INDEX)? h: h2; h_idx= (primary_file->inited == handler::INDEX)? primary_file: secondary_file;
keyno= h_idx->active_index; keyno= h_idx->active_index;
if (!(keyno == table->s->primary_key && h_idx->primary_key_is_clustered())) if (!(keyno == table->s->primary_key && h_idx->primary_key_is_clustered()))
...@@ -805,7 +806,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -805,7 +806,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if (do_sort_keys && !key_buffer->have_space_for(key_buff_elem_size)) if (do_sort_keys && !key_buffer->have_space_for(key_buff_elem_size))
goto use_default_impl; goto use_default_impl;
if ((res= index_strategy->init(h, seq_funcs, seq_init_param, n_ranges, if ((res= index_strategy->init(primary_file, seq_funcs, seq_init_param, n_ranges,
mode, &keypar, key_buffer, &buf_manager))) mode, &keypar, key_buffer, &buf_manager)))
goto error; goto error;
} }
...@@ -825,7 +826,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -825,7 +826,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
{ {
/* index strategy doesn't need buffer, give all space to rowids*/ /* index strategy doesn't need buffer, give all space to rowids*/
rowid_buffer.set_buffer_space(full_buf, full_buf_end); rowid_buffer.set_buffer_space(full_buf, full_buf_end);
if (!rowid_buffer.have_space_for(h->ref_length + if (!rowid_buffer.have_space_for(primary_file->ref_length +
(int)is_mrr_assoc * sizeof(char*))) (int)is_mrr_assoc * sizeof(char*)))
goto use_default_impl; goto use_default_impl;
} }
...@@ -833,9 +834,11 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -833,9 +834,11 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if ((res= setup_two_handlers())) if ((res= setup_two_handlers()))
goto error; goto error;
if ((res= index_strategy->init(h2, seq_funcs, seq_init_param, n_ranges, if ((res= index_strategy->init(secondary_file, seq_funcs, seq_init_param,
mode, &keypar, key_buffer, &buf_manager)) || n_ranges, mode, &keypar, key_buffer,
(res= disk_strategy->init(h, index_strategy, mode, &rowid_buffer))) &buf_manager)) ||
(res= disk_strategy->init(primary_file, index_strategy, mode,
&rowid_buffer)))
{ {
goto error; goto error;
} }
...@@ -865,10 +868,11 @@ error: ...@@ -865,10 +868,11 @@ error:
DBUG_RETURN(1); DBUG_RETURN(1);
use_default_impl: use_default_impl:
DBUG_ASSERT(h->inited == handler::INDEX); DBUG_ASSERT(primary_file->inited == handler::INDEX);
/* Call correct init function and assign to top level object */ /* Call correct init function and assign to top level object */
Mrr_simple_index_reader *s= &reader_factory.simple_index_reader; Mrr_simple_index_reader *s= &reader_factory.simple_index_reader;
res= s->init(h, seq_funcs, seq_init_param, n_ranges, mode, NULL, NULL, NULL); res= s->init(primary_file, seq_funcs, seq_init_param, n_ranges, mode, NULL,
NULL, NULL);
strategy= s; strategy= s;
DBUG_RETURN(res); DBUG_RETURN(res);
} }
...@@ -876,8 +880,8 @@ use_default_impl: ...@@ -876,8 +880,8 @@ use_default_impl:
/* /*
Whatever the current state is, make it so that we have two handler objects: Whatever the current state is, make it so that we have two handler objects:
- h (the primary) - initialized for rnd_pos() scan - primary_file - initialized for rnd_pos() scan
- h2 (the secondary) - initialized for scanning the index specified in - secondary_file - initialized for scanning the index specified in
this->keyno this->keyno
RETURN RETURN
0 OK 0 OK
...@@ -887,13 +891,13 @@ use_default_impl: ...@@ -887,13 +891,13 @@ use_default_impl:
int DsMrr_impl::setup_two_handlers() int DsMrr_impl::setup_two_handlers()
{ {
int res; int res;
THD *thd= h->get_table()->in_use; THD *thd= primary_file->get_table()->in_use;
DBUG_ENTER("DsMrr_impl::setup_two_handlers"); DBUG_ENTER("DsMrr_impl::setup_two_handlers");
if (!h2) if (!secondary_file)
{ {
handler *new_h2; handler *new_h2;
Item *pushed_cond= NULL; Item *pushed_cond= NULL;
DBUG_ASSERT(h->inited == handler::INDEX); DBUG_ASSERT(primary_file->inited == handler::INDEX);
/* Create a separate handler object to do rnd_pos() calls. */ /* Create a separate handler object to do rnd_pos() calls. */
/* /*
::clone() takes up a lot of stack, especially on 64 bit platforms. ::clone() takes up a lot of stack, especially on 64 bit platforms.
...@@ -903,65 +907,65 @@ int DsMrr_impl::setup_two_handlers() ...@@ -903,65 +907,65 @@ int DsMrr_impl::setup_two_handlers()
DBUG_RETURN(1); DBUG_RETURN(1);
/* Create a separate handler object to do rnd_pos() calls. */ /* Create a separate handler object to do rnd_pos() calls. */
if (!(new_h2= h->clone(thd->mem_root)) || if (!(new_h2= primary_file->clone(thd->mem_root)) ||
new_h2->ha_external_lock(thd, F_RDLCK)) new_h2->ha_external_lock(thd, F_RDLCK))
{ {
delete new_h2; delete new_h2;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (keyno == h->pushed_idx_cond_keyno) if (keyno == primary_file->pushed_idx_cond_keyno)
pushed_cond= h->pushed_idx_cond; pushed_cond= primary_file->pushed_idx_cond;
Mrr_reader *save_strategy= strategy; Mrr_reader *save_strategy= strategy;
strategy= NULL; strategy= NULL;
/* /*
Caution: this call will invoke this->dsmrr_close(). Do not put the Caution: this call will invoke this->dsmrr_close(). Do not put the
created secondary table handler new_h2 into this->h2 or it will delete created secondary table handler new_h2 into this->secondary_file or it
it. Also, save the picked strategy will delete it. Also, save the picked strategy
*/ */
res= h->ha_index_end(); res= primary_file->ha_index_end();
strategy= save_strategy; strategy= save_strategy;
h2= new_h2; /* Ok, now can put it into h2 */ secondary_file= new_h2;
if (res || (res= (h->ha_rnd_init(FALSE)))) if (res || (res= (primary_file->ha_rnd_init(FALSE))))
goto error; goto error;
table->prepare_for_position(); table->prepare_for_position();
h2->extra(HA_EXTRA_KEYREAD); secondary_file->extra(HA_EXTRA_KEYREAD);
h2->mrr_iter= h->mrr_iter; secondary_file->mrr_iter= primary_file->mrr_iter;
if ((res= h2->ha_index_init(keyno, FALSE))) if ((res= secondary_file->ha_index_init(keyno, FALSE)))
goto error; goto error;
if (pushed_cond) if (pushed_cond)
h2->idx_cond_push(keyno, pushed_cond); secondary_file->idx_cond_push(keyno, pushed_cond);
} }
else else
{ {
DBUG_ASSERT(h2 && h2->inited==handler::INDEX); DBUG_ASSERT(secondary_file && secondary_file->inited==handler::INDEX);
/* /*
We get here when the access alternates betwen MRR scan(s) and non-MRR We get here when the access alternates betwen MRR scan(s) and non-MRR
scans. scans.
Calling h->index_end() will invoke dsmrr_close() for this object, Calling primary_file->index_end() will invoke dsmrr_close() for this object,
which will delete h2. We need to keep it, so put it away and dont which will delete secondary_file. We need to keep it, so put it away and dont
let it be deleted: let it be deleted:
*/ */
if (h->inited == handler::INDEX) if (primary_file->inited == handler::INDEX)
{ {
handler *save_h2= h2; handler *save_h2= secondary_file;
Mrr_reader *save_strategy= strategy; Mrr_reader *save_strategy= strategy;
h2= NULL; secondary_file= NULL;
strategy= NULL; strategy= NULL;
res= h->ha_index_end(); res= primary_file->ha_index_end();
h2= save_h2; secondary_file= save_h2;
strategy= save_strategy; strategy= save_strategy;
if (res) if (res)
goto error; goto error;
} }
if ((h->inited != handler::RND) && h->ha_rnd_init(FALSE)) if ((primary_file->inited != handler::RND) && primary_file->ha_rnd_init(FALSE))
goto error; goto error;
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -973,13 +977,13 @@ error: ...@@ -973,13 +977,13 @@ error:
void DsMrr_impl::close_second_handler() void DsMrr_impl::close_second_handler()
{ {
if (h2) if (secondary_file)
{ {
h2->ha_index_or_rnd_end(); secondary_file->ha_index_or_rnd_end();
h2->ha_external_lock(current_thd, F_UNLCK); secondary_file->ha_external_lock(current_thd, F_UNLCK);
h2->close(); secondary_file->close();
delete h2; delete secondary_file;
h2= NULL; secondary_file= NULL;
} }
} }
...@@ -1000,8 +1004,8 @@ void DsMrr_impl::dsmrr_close() ...@@ -1000,8 +1004,8 @@ void DsMrr_impl::dsmrr_close()
int Mrr_ordered_index_reader::compare_keys(void* arg, uchar* key1, uchar* key2) int Mrr_ordered_index_reader::compare_keys(void* arg, uchar* key1, uchar* key2)
{ {
Mrr_ordered_index_reader *reader= (Mrr_ordered_index_reader*)arg; Mrr_ordered_index_reader *reader= (Mrr_ordered_index_reader*)arg;
TABLE *table= reader->h->get_table(); TABLE *table= reader->file->get_table();
KEY_PART_INFO *part= table->key_info[reader->h->active_index].key_part; KEY_PART_INFO *part= table->key_info[reader->file->active_index].key_part;
if (reader->keypar.use_key_pointers) if (reader->keypar.use_key_pointers)
{ {
...@@ -1038,12 +1042,12 @@ bool DsMrr_impl::setup_buffer_sharing(uint key_size_in_keybuf, ...@@ -1038,12 +1042,12 @@ bool DsMrr_impl::setup_buffer_sharing(uint key_size_in_keybuf,
uint key_buff_elem_size= key_size_in_keybuf + uint key_buff_elem_size= key_size_in_keybuf +
(int)is_mrr_assoc * sizeof(void*); (int)is_mrr_assoc * sizeof(void*);
KEY *key_info= &h->get_table()->key_info[keyno]; KEY *key_info= &primary_file->get_table()->key_info[keyno];
/* /*
Ok if we got here we need to allocate one part of the buffer Ok if we got here we need to allocate one part of the buffer
for keys and another part for rowids. for keys and another part for rowids.
*/ */
ulonglong rowid_buf_elem_size= h->ref_length + ulonglong rowid_buf_elem_size= primary_file->ref_length +
(int)is_mrr_assoc * sizeof(char*); (int)is_mrr_assoc * sizeof(char*);
/* /*
...@@ -1171,7 +1175,7 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg) ...@@ -1171,7 +1175,7 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
} }
identical_key_it.init(owner->key_buffer); identical_key_it.init(owner->key_buffer);
cur_index_tuple= save_cur_index_tuple; cur_index_tuple= save_cur_index_tuple;
res= owner->h->ha_index_read_map(owner->h->get_table()->record[0], res= owner->file->ha_index_read_map(owner->file->get_table()->record[0],
cur_index_tuple, cur_index_tuple,
owner->keypar.key_tuple_map, owner->keypar.key_tuple_map,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
...@@ -1199,7 +1203,7 @@ int Key_value_records_iterator::get_next() ...@@ -1199,7 +1203,7 @@ int Key_value_records_iterator::get_next()
return HA_ERR_END_OF_FILE; return HA_ERR_END_OF_FILE;
} }
handler *h= owner->h; handler *h= owner->file;
if ((res= h->ha_index_next_same(h->get_table()->record[0], if ((res= h->ha_index_next_same(h->get_table()->record[0],
cur_index_tuple, cur_index_tuple,
owner->keypar.key_tuple_length))) owner->keypar.key_tuple_length)))
...@@ -1265,8 +1269,9 @@ ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, ...@@ -1265,8 +1269,9 @@ ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows,
uint def_bufsz= *bufsz; uint def_bufsz= *bufsz;
/* Get cost/flags/mem_usage of default MRR implementation */ /* Get cost/flags/mem_usage of default MRR implementation */
res= h->handler::multi_range_read_info(keyno, n_ranges, rows, key_parts, res= primary_file->handler::multi_range_read_info(keyno, n_ranges, rows,
&def_bufsz, &def_flags, cost); key_parts, &def_bufsz,
&def_flags, cost);
DBUG_ASSERT(!res); DBUG_ASSERT(!res);
if ((*flags & HA_MRR_USE_DEFAULT_IMPL) || if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
...@@ -1298,9 +1303,11 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, ...@@ -1298,9 +1303,11 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
uint def_flags= *flags; uint def_flags= *flags;
uint def_bufsz= *bufsz; uint def_bufsz= *bufsz;
/* Get cost/flags/mem_usage of default MRR implementation */ /* Get cost/flags/mem_usage of default MRR implementation */
rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param, rows= primary_file->handler::multi_range_read_info_const(keyno, seq,
n_ranges, &def_bufsz, seq_init_param,
&def_flags, cost); n_ranges,
&def_bufsz,
&def_flags, cost);
if (rows == HA_POS_ERROR) if (rows == HA_POS_ERROR)
{ {
/* Default implementation can't perform MRR scan => we can't either */ /* Default implementation can't perform MRR scan => we can't either */
...@@ -1372,11 +1379,10 @@ bool key_uses_partial_cols(TABLE *table, uint keyno) ...@@ -1372,11 +1379,10 @@ bool key_uses_partial_cols(TABLE *table, uint keyno)
bool DsMrr_impl::check_cpk_scan(THD *thd, uint keyno, uint mrr_flags) bool DsMrr_impl::check_cpk_scan(THD *thd, uint keyno, uint mrr_flags)
{ {
return test((mrr_flags & HA_MRR_SINGLE_POINT) && // check return test((mrr_flags & HA_MRR_SINGLE_POINT) &&
// !(mrr_flags & HA_MRR_SORTED) &&
keyno == table->s->primary_key && keyno == table->s->primary_key &&
h->primary_key_is_clustered() && primary_file->primary_key_is_clustered() &&
optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS)); //check optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS));
} }
...@@ -1413,7 +1419,7 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, ...@@ -1413,7 +1419,7 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
bool doing_cpk_scan= check_cpk_scan(thd, keyno, *flags); bool doing_cpk_scan= check_cpk_scan(thd, keyno, *flags);
bool using_cpk= test(keyno == table->s->primary_key && bool using_cpk= test(keyno == table->s->primary_key &&
h->primary_key_is_clustered()); primary_file->primary_key_is_clustered());
if (thd->variables.optimizer_use_mrr == 2 || *flags & HA_MRR_INDEX_ONLY || if (thd->variables.optimizer_use_mrr == 2 || *flags & HA_MRR_INDEX_ONLY ||
(using_cpk && !doing_cpk_scan) || key_uses_partial_cols(table, keyno)) (using_cpk && !doing_cpk_scan) || key_uses_partial_cols(table, keyno))
{ {
...@@ -1422,7 +1428,7 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, ...@@ -1422,7 +1428,7 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
return TRUE; return TRUE;
} }
uint add_len= table->key_info[keyno].key_length + h->ref_length; uint add_len= table->key_info[keyno].key_length + primary_file->ref_length;
*bufsz -= add_len; *bufsz -= add_len;
if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost)) if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
return TRUE; return TRUE;
...@@ -1484,7 +1490,8 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, ...@@ -1484,7 +1490,8 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
uint n_full_steps; uint n_full_steps;
double index_read_cost; double index_read_cost;
elem_size= h->ref_length + sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION)); elem_size= primary_file->ref_length +
sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION));
max_buff_entries = *buffer_size / elem_size; max_buff_entries = *buffer_size / elem_size;
if (!max_buff_entries) if (!max_buff_entries)
...@@ -1512,7 +1519,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, ...@@ -1512,7 +1519,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
cost->zero(); cost->zero();
*buffer_size= max(*buffer_size, *buffer_size= max(*buffer_size,
(size_t)(1.2*rows_in_last_step) * elem_size + (size_t)(1.2*rows_in_last_step) * elem_size +
h->ref_length + table->key_info[keynr].key_length); primary_file->ref_length + table->key_info[keynr].key_length);
} }
COST_VECT last_step_cost; COST_VECT last_step_cost;
...@@ -1525,7 +1532,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, ...@@ -1525,7 +1532,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
cost->mem_cost= (double)rows_in_last_step * elem_size; cost->mem_cost= (double)rows_in_last_step * elem_size;
/* Total cost of all index accesses */ /* Total cost of all index accesses */
index_read_cost= h->keyread_time(keynr, 1, (double)rows); index_read_cost= primary_file->keyread_time(keynr, 1, (double)rows);
cost->add_io(index_read_cost, 1 /* Random seeks */); cost->add_io(index_read_cost, 1 /* Random seeks */);
return FALSE; return FALSE;
} }
......
...@@ -129,7 +129,7 @@ class Key_value_records_iterator ...@@ -129,7 +129,7 @@ class Key_value_records_iterator
/* /*
FALSE <=> we're right after the init() call, the record has been already FALSE <=> we're right after the init() call, the record has been already
read with owner->h->index_read_map() call read with owner->file->index_read_map() call
*/ */
bool get_next_row; bool get_next_row;
...@@ -200,7 +200,7 @@ public: ...@@ -200,7 +200,7 @@ public:
class Mrr_index_reader : public Mrr_reader class Mrr_index_reader : public Mrr_reader
{ {
protected: protected:
handler *h; /* Handler object to use */ handler *file; /* Handler object to use */
public: public:
virtual int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, virtual int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
void *seq_init_param, uint n_ranges, void *seq_init_param, uint n_ranges,
...@@ -232,11 +232,11 @@ public: ...@@ -232,11 +232,11 @@ public:
Buffer_manager *buf_manager_arg); Buffer_manager *buf_manager_arg);
int get_next(char **range_info); int get_next(char **range_info);
int refill_buffer(bool initial) { return initial? 0: HA_ERR_END_OF_FILE; } int refill_buffer(bool initial) { return initial? 0: HA_ERR_END_OF_FILE; }
uchar *get_rowid_ptr() { return h->ref; } uchar *get_rowid_ptr() { return file->ref; }
bool skip_record(char *range_id, uchar *rowid) bool skip_record(char *range_id, uchar *rowid)
{ {
return (h->mrr_funcs.skip_record && return (file->mrr_funcs.skip_record &&
h->mrr_funcs.skip_record(h->mrr_iter, range_id, rowid)); file->mrr_funcs.skip_record(file->mrr_iter, range_id, rowid));
} }
}; };
...@@ -255,7 +255,7 @@ public: ...@@ -255,7 +255,7 @@ public:
Buffer_manager *buf_manager_arg); Buffer_manager *buf_manager_arg);
int get_next(char **range_info); int get_next(char **range_info);
int refill_buffer(bool initial); int refill_buffer(bool initial);
uchar *get_rowid_ptr() { return h->ref; } uchar *get_rowid_ptr() { return file->ref; }
bool skip_record(char *range_info, uchar *rowid) bool skip_record(char *range_info, uchar *rowid)
{ {
...@@ -318,12 +318,12 @@ private: ...@@ -318,12 +318,12 @@ private:
class Mrr_ordered_rndpos_reader : public Mrr_reader class Mrr_ordered_rndpos_reader : public Mrr_reader
{ {
public: public:
int init(handler *h, Mrr_index_reader *index_reader, uint mode, int init(handler *file, Mrr_index_reader *index_reader, uint mode,
Lifo_buffer *buf); Lifo_buffer *buf);
int get_next(char **range_info); int get_next(char **range_info);
int refill_buffer(bool initial); int refill_buffer(bool initial);
private: private:
handler *h; /* Handler to use */ handler *file; /* Handler to use */
/* This what we get (rowid, range_info) pairs from */ /* This what we get (rowid, range_info) pairs from */
Mrr_index_reader *index_reader; Mrr_index_reader *index_reader;
...@@ -503,15 +503,16 @@ public: ...@@ -503,15 +503,16 @@ public:
typedef void (handler::*range_check_toggle_func_t)(bool on); typedef void (handler::*range_check_toggle_func_t)(bool on);
DsMrr_impl() DsMrr_impl()
: h2(NULL) {}; : secondary_file(NULL) {};
void init(handler *h_arg, TABLE *table_arg) void init(handler *h_arg, TABLE *table_arg)
{ {
h= h_arg; primary_file= h_arg;
table= table_arg; table= table_arg;
} }
int dsmrr_init(handler *h, RANGE_SEQ_IF *seq_funcs, void *seq_init_param, int dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
uint n_ranges, uint mode, HANDLER_BUFFER *buf); void *seq_init_param, uint n_ranges, uint mode,
HANDLER_BUFFER *buf);
void dsmrr_close(); void dsmrr_close();
int dsmrr_next(char **range_info); int dsmrr_next(char **range_info);
...@@ -529,14 +530,14 @@ private: ...@@ -529,14 +530,14 @@ private:
The "owner" handler object (the one that is expected to "own" this object The "owner" handler object (the one that is expected to "own" this object
and call its functions). and call its functions).
*/ */
handler *h; handler *primary_file;
TABLE *table; /* Always equal to h->table */ TABLE *table; /* Always equal to primary_file->table */
/* /*
Secondary handler object. (created when needed, we need it when we need Secondary handler object. (created when needed, we need it when we need
to run both index scan and rnd_pos() scan at the same time) to run both index scan and rnd_pos() scan at the same time)
*/ */
handler *h2; handler *secondary_file;
uint keyno; /* index we're running the scan on */ uint keyno; /* index we're running the scan on */
/* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment