diff --git a/sql/handler.h b/sql/handler.h index f2cc50de38a..3e173905f66 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1168,9 +1168,9 @@ void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, COST_VECT *cost); /* - The below two are not used (and not handled) in this milestone of this WL - entry because there seems to be no use for them at this stage of - implementation. + Indicates that all scanned ranges will be singlepoint (aka equality) ranges. + The ranges may not use the full key but all of them will use the same number + of key parts. */ #define HA_MRR_SINGLE_POINT 1 #define HA_MRR_FIXED_KEY 2 @@ -1755,7 +1755,7 @@ public: uint key_parts, uint *bufsz, uint *flags, COST_VECT *cost); virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, + uint n_ranges, uint mode, HANDLER_BUFFER *buf); virtual int multi_range_read_next(char **range_info); virtual int read_range_first(const key_range *start_key, diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 9c0a0233e0e..c86143c4a12 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -1,4 +1,5 @@ #include "mysql_priv.h" +#include #include "sql_select.h" /**************************************************************************** @@ -203,8 +204,7 @@ ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows, int handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf) + uint n_ranges, uint mode, HANDLER_BUFFER *buf) { DBUG_ENTER("handler::multi_range_read_init"); mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode); @@ -306,8 +306,7 @@ scan_it_again: */ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, - void *seq_init_param, uint n_ranges, uint key_parts, - uint mode, + void *seq_init_param, uint n_ranges, uint mode, HANDLER_BUFFER *buf) { uint elem_size; @@ -324,8 +323,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, { use_default_impl= TRUE; const int retval= - h->handler::multi_range_read_init(seq_funcs, seq_init_param, - n_ranges, key_parts, mode, buf); + h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges, + mode, buf); DBUG_RETURN(retval); } mrr_buf= buf->buffer; @@ -337,51 +336,25 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, mrr_buf_end= buf->buffer_end; - - doing_cpk_scan= check_cpk_scan(h->active_index, mode); - if (doing_cpk_scan) + if ((doing_cpk_scan= check_cpk_scan(h->active_index, mode))) { - /* - When doing a scan on CPK, the buffer stores {lookup_tuple, range_id} - pairs - */ - uint keylen=0; - DBUG_ASSERT(key_parts != 0); - for (uint kp= 0; kp < key_parts; kp++) - keylen += table->key_info[h->active_index].key_part[kp].store_length; - - cpk_tuple_length= keylen; - cpk_is_unique_scan= test(table->key_info[h->active_index].key_parts == - key_parts); + /* It's a DS-MRR/CPK scan */ + cpk_tuple_length= 0; /* dummy value telling it needs to be inited */ cpk_have_range= FALSE; - elem_size= keylen + (int)is_mrr_assoc * sizeof(void*); use_default_impl= FALSE; - } - else - { - /* In regular DS-MRR, buffer stores {rowid, range_id} pairs */ - elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*); - } - - mrr_buf_last= mrr_buf + - ((mrr_buf_end - mrr_buf)/ elem_size)* - elem_size; - mrr_buf_end= mrr_buf_last; - - if (doing_cpk_scan) - { - /* - DS-MRR/CPK: fill buffer with lookup tuples and sort; also we don't need a - secondary handler object. - */ h->mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode); h->mrr_funcs= *seq_funcs; dsmrr_fill_buffer_cpk(); - if (dsmrr_eof) + if (dsmrr_eof) buf->end_of_used_area= mrr_buf_last; DBUG_RETURN(0); /* nothing could go wrong while filling the buffer */ } + /* In regular DS-MRR, buffer stores {rowid, range_id} pairs */ + elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*); + mrr_buf_last= mrr_buf + ((mrr_buf_end - mrr_buf)/ elem_size)* elem_size; + mrr_buf_end= mrr_buf_last; + /* There can be two cases: - This is the first call since index_init(), h2==NULL @@ -454,8 +427,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, goto error; } - if (h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges, - key_parts, mode, buf) || + if (h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges, + mode, buf) || dsmrr_fill_buffer()) { goto error; @@ -604,6 +577,9 @@ int DsMrr_impl::key_tuple_cmp(void* arg, uchar* key1, uchar* key2) /* DS-MRR/CPK: Fill the buffer with (lookup_tuple, range_id) pairs and sort + + SYNOPSIS + DsMrr_impl::dsmrr_fill_buffer_cpk() DESCRIPTION DS-MRR/CPK: Fill the buffer with (lookup_tuple, range_id) pairs and sort @@ -623,7 +599,18 @@ void DsMrr_impl::dsmrr_fill_buffer_cpk() !(res= h->mrr_funcs.next(h->mrr_iter, &cur_range))) { DBUG_ASSERT(cur_range.range_flag & EQ_RANGE); - DBUG_ASSERT(cpk_tuple_length == cur_range.start_key.length); + DBUG_ASSERT(!cpk_tuple_length || + cpk_tuple_length == cur_range.start_key.length); + if (!cpk_tuple_length) + { + cpk_tuple_length= cur_range.start_key.length; + cpk_is_unique_scan= test(table->key_info[h->active_index].key_parts == + my_count_bits(cur_range.start_key.keypart_map)); + uint elem_size= cpk_tuple_length + (int)is_mrr_assoc * sizeof(void*); + mrr_buf_last= mrr_buf + ((mrr_buf_end - mrr_buf)/elem_size) * elem_size; + mrr_buf_end= mrr_buf_last; + } + /* Put key, or {key, range_id} pair into the buffer */ memcpy(mrr_buf_cur, cur_range.start_key.key, cpk_tuple_length); mrr_buf_cur += cpk_tuple_length; diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index 5dd2e0d6adf..7a5e57e490e 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -87,8 +87,7 @@ public: table= table_arg; } int dsmrr_init(handler *h, RANGE_SEQ_IF *seq_funcs, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf); + uint n_ranges, uint mode, HANDLER_BUFFER *buf); void dsmrr_close(); int dsmrr_next(char **range_info); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 25c4259295f..ad0f9301b7f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8368,7 +8368,6 @@ int QUICK_RANGE_SELECT::reset() RANGE_SEQ_IF seq_funcs= {quick_range_seq_init, quick_range_seq_next, 0, 0}; error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements, - uint(-1), mrr_flags, mrr_buf_desc? mrr_buf_desc: &empty_buf); DBUG_RETURN(error); diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 120b109d8ff..c536026214c 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2376,8 +2376,7 @@ JOIN_CACHE_BKA::init_join_matching_records(RANGE_SEQ_IF *seq_funcs, uint ranges) */ if (!file->inited) file->ha_index_init(join_tab->ref.key, 1); - if ((error= file->multi_range_read_init(seq_funcs, (void*) this, ranges, - join_tab->ref.key_parts, + if ((error= file->multi_range_read_init(seq_funcs, (void*) this, ranges, mrr_mode, &mrr_buff))) rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 43c6cd6606a..e27983989d8 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -3501,11 +3501,10 @@ static SHOW_VAR status_variables[]= { ***************************************************************************/ int ha_maria::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf) + uint n_ranges, uint mode, + HANDLER_BUFFER *buf) { - return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, key_parts, - mode, buf); + return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf); } int ha_maria::multi_range_read_next(char **range_info) diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 177008f422a..6901229bb44 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -174,8 +174,7 @@ public: * Multi Range Read interface */ int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf); + uint n_ranges, uint mode, HANDLER_BUFFER *buf); int multi_range_read_next(char **range_info); ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index bb6ac446a4f..95ab5cb167e 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2217,10 +2217,10 @@ static int myisam_init(void *p) ***************************************************************************/ int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, + uint n_ranges, uint mode, HANDLER_BUFFER *buf) { - return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, key_parts, mode, buf); + return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf); } int ha_myisam::multi_range_read_next(char **range_info) diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index d37870b861b..f5428e653c4 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -162,8 +162,7 @@ public: * Multi Range Read interface */ int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf); + uint n_ranges, uint mode, HANDLER_BUFFER *buf); int multi_range_read_next(char **range_info); ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index a8ccb426aa5..8aff0103e20 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -11025,10 +11025,10 @@ test_innobase_convert_name() */ int ha_innobase::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, + uint n_ranges, uint mode, HANDLER_BUFFER *buf) { - return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, key_parts, mode, buf); + return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf); } int ha_innobase::multi_range_read_next(char **range_info) diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 0c1f2b42dd6..41a073e4374 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -210,8 +210,7 @@ public: * Multi Range Read interface */ int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint key_parts, uint mode, - HANDLER_BUFFER *buf); + uint n_ranges, uint mode, HANDLER_BUFFER *buf); int multi_range_read_next(char **range_info); ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param,