diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-11-23 18:08:11 +0300 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-11-23 18:08:11 +0300 |
commit | fad2ec74999a7ff513c9421cae2c84b2408b7e92 (patch) | |
tree | 4aed42629c316d4a5dbf42f384e54d4530126007 /sql | |
parent | a6c1d56e083bcb8ab2c32f8d89865ef46c0eb70e (diff) | |
download | mariadb-git-fad2ec74999a7ff513c9421cae2c84b2408b7e92.tar.gz |
MWL#121-125 DS-MRR improvements
- Address Monty's review feedback, part 3
Diffstat (limited to 'sql')
-rw-r--r-- | sql/key.cc | 1 | ||||
-rw-r--r-- | sql/multi_range_read.cc | 111 |
2 files changed, 57 insertions, 55 deletions
diff --git a/sql/key.cc b/sql/key.cc index 708f309fbaf..b7f52a5833b 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -590,6 +590,7 @@ int key_tuple_cmp(KEY_PART_INFO *part, uchar *key1, uchar *key2, /* Step over the NULL bytes for key_cmp() call */ key1++; key2++; + len--; } if ((res= part->field->key_cmp(key1, key2))) return res; diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 662f6b3f79e..a82fdb96970 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -343,18 +343,16 @@ int Mrr_ordered_index_reader::get_next(char **range_info) for(;;) { - bool have_record= FALSE; if (scanning_key_val_iter) { if ((res= kv_it.get_next())) { - kv_it.move_to_next_key_value(); scanning_key_val_iter= FALSE; if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE)) DBUG_RETURN(res); + kv_it.move_to_next_key_value(); + continue; } - else - have_record= TRUE; } else { @@ -363,16 +361,16 @@ int Mrr_ordered_index_reader::get_next(char **range_info) if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE)) DBUG_RETURN(res); /* Some fatal error */ - if (key_buffer->is_empty()) + if (key_buffer->is_empty()) //psergey-todo: the problem is here? { DBUG_RETURN(HA_ERR_END_OF_FILE); } } scanning_key_val_iter= TRUE; + continue; } - if (have_record && - !skip_index_tuple(*(char**)cur_range_info) && + if (!skip_index_tuple(*(char**)cur_range_info) && !skip_record(*(char**)cur_range_info, NULL)) { break; @@ -566,6 +564,7 @@ int Mrr_ordered_rndpos_reader::refill_buffer() index_reader_exhausted= TRUE; break; } + index_reader_exhausted= FALSE; } DBUG_RETURN(res); } @@ -637,7 +636,11 @@ int Mrr_ordered_rndpos_reader::refill_from_key_buffer() int Mrr_ordered_rndpos_reader::get_next(char **range_info) { int res; - + + /* + First, check if rowid buffer has elements with the same rowid value as + the previous. + */ while (last_identical_rowid) { /* @@ -645,28 +648,25 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) from a rowid that matched multiple range_ids. Return this record again, with next matching range_id. */ - bool UNINIT_VAR(bres); - bres= rowid_buffer->read(); - DBUG_ASSERT(!bres); - - if (is_mrr_assoc) - memcpy(range_info, rowids_range_id, sizeof(uchar*)); + (void)rowid_buffer->read(); if (rowid == last_identical_rowid) - { last_identical_rowid= NULL; /* reached the last of identical rowids */ - } + if (!is_mrr_assoc) + return 0; + + memcpy(range_info, rowids_range_id, sizeof(uchar*)); if (!index_reader->skip_record((char*)*range_info, rowid)) - { return 0; - } } - + + /* + Ok, last_identical_rowid==NULL, it's time to read next different rowid + value and get record for it. + */ for(;;) { - last_identical_rowid= NULL; - /* Return eof if there are no rowids in the buffer after re-fill attempt */ if (rowid_buffer->read()) return HA_ERR_END_OF_FILE; @@ -674,41 +674,44 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) if (is_mrr_assoc) { memcpy(range_info, rowids_range_id, sizeof(uchar*)); - } - if (index_reader->skip_record(*range_info, rowid)) - continue; + if (index_reader->skip_record(*range_info, rowid)) + continue; + } res= h->ha_rnd_pos(h->get_table()->record[0], rowid); if (res == HA_ERR_RECORD_DELETED) - continue; - - /* - Check if subsequent buffer elements have the same rowid value as this - one. If yes, remember this fact so that we don't make any more rnd_pos() - calls with this value. - */ - if (!res) { - uchar *cur_rowid= rowid; - /* - Note: this implies that SQL layer doesn't touch table->record[0] - between calls. - */ - Lifo_buffer_iterator it; - it.init(rowid_buffer); - while (!it.read()) // reads to (rowid, ...) - { - if (h->cmp_ref(rowid, cur_rowid)) - break; - last_identical_rowid= rowid; - } + /* not likely to get this code with current storage engines, but still */ + continue; } - return 0; + + if (res) + return res; /* Some fatal error */ + + break; /* Got another record */ } - return res; + /* + Check if subsequent buffer elements have the same rowid value as this + one. If yes, remember this fact so that we don't make any more rnd_pos() + calls with this value. + */ + uchar *cur_rowid= rowid; + /* + Note: this implies that SQL layer doesn't touch table->record[0] + between calls. + */ + Lifo_buffer_iterator it; + it.init(rowid_buffer); + while (!it.read()) // reads to (rowid, ...) + { + if (h->cmp_ref(rowid, cur_rowid)) + break; + last_identical_rowid= rowid; + } + return 0; } @@ -749,27 +752,24 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, h= h_arg; is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION); - if ((mode & HA_MRR_USE_DEFAULT_IMPL) || (mode & HA_MRR_SORTED)) + if (mode & (HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED)) { DBUG_ASSERT(h->inited == handler::INDEX); + /* Call correct init function and assign to top level object */ Mrr_simple_index_reader *s= &reader_factory.simple_index_reader; res= s->init(h, seq_funcs, seq_init_param, n_ranges, mode, this); strategy= s; DBUG_RETURN(res); } - /* Neither of strategies used below can handle sorting */ - DBUG_ASSERT(!(mode & HA_MRR_SORTED)); - /* Determine whether we'll need to do key sorting and/or rnd_pos() scan */ index_strategy= NULL; - Mrr_ordered_index_reader *ordered_idx_reader= NULL; if ((mode & HA_MRR_SINGLE_POINT) && optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS)) { - index_strategy= ordered_idx_reader= &reader_factory.ordered_index_reader; + index_strategy= &reader_factory.ordered_index_reader; } else index_strategy= &reader_factory.simple_index_reader; @@ -817,7 +817,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, rowid_buffer.set_buffer_space(buf->buffer, buf->buffer_end); if ((res= setup_two_handlers())) - DBUG_RETURN(res); + goto error; if ((res= index_strategy->init(h2, seq_funcs, seq_init_param, n_ranges, mode, this)) || @@ -842,6 +842,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, DBUG_RETURN(0); error: close_second_handler(); + /* Safety, not really needed but: */ strategy= NULL; DBUG_RETURN(1); } @@ -860,7 +861,7 @@ error: int DsMrr_impl::setup_two_handlers() { int res; - THD *thd= current_thd; + THD *thd= h->get_table()->in_use; DBUG_ENTER("DsMrr_impl::setup_two_handlers"); if (!h2) { |