Commit 488d352a authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#121: DS-MRR support for clustered primary keys

- Remove back key_parts from multi_range_read_init() parameters
- Related code simplification/cleanup
parent b45748f0
...@@ -1168,9 +1168,9 @@ void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, ...@@ -1168,9 +1168,9 @@ void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
COST_VECT *cost); COST_VECT *cost);
/* /*
The below two are not used (and not handled) in this milestone of this WL Indicates that all scanned ranges will be singlepoint (aka equality) ranges.
entry because there seems to be no use for them at this stage of The ranges may not use the full key but all of them will use the same number
implementation. of key parts.
*/ */
#define HA_MRR_SINGLE_POINT 1 #define HA_MRR_SINGLE_POINT 1
#define HA_MRR_FIXED_KEY 2 #define HA_MRR_FIXED_KEY 2
...@@ -1755,7 +1755,7 @@ class handler :public Sql_alloc ...@@ -1755,7 +1755,7 @@ class handler :public Sql_alloc
uint key_parts, uint *bufsz, uint key_parts, uint *bufsz,
uint *flags, COST_VECT *cost); uint *flags, COST_VECT *cost);
virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 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); HANDLER_BUFFER *buf);
virtual int multi_range_read_next(char **range_info); virtual int multi_range_read_next(char **range_info);
virtual int read_range_first(const key_range *start_key, virtual int read_range_first(const key_range *start_key,
......
#include "mysql_priv.h" #include "mysql_priv.h"
#include <my_bit.h>
#include "sql_select.h" #include "sql_select.h"
/**************************************************************************** /****************************************************************************
...@@ -203,8 +204,7 @@ ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows, ...@@ -203,8 +204,7 @@ ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows,
int int
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param, handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
uint n_ranges, uint key_parts, uint mode, uint n_ranges, uint mode, HANDLER_BUFFER *buf)
HANDLER_BUFFER *buf)
{ {
DBUG_ENTER("handler::multi_range_read_init"); DBUG_ENTER("handler::multi_range_read_init");
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode); mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
...@@ -306,8 +306,7 @@ int handler::multi_range_read_next(char **range_info) ...@@ -306,8 +306,7 @@ int handler::multi_range_read_next(char **range_info)
*/ */
int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
void *seq_init_param, uint n_ranges, uint key_parts, void *seq_init_param, uint n_ranges, uint mode,
uint mode,
HANDLER_BUFFER *buf) HANDLER_BUFFER *buf)
{ {
uint elem_size; uint elem_size;
...@@ -324,8 +323,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -324,8 +323,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
{ {
use_default_impl= TRUE; use_default_impl= TRUE;
const int retval= const int retval=
h->handler::multi_range_read_init(seq_funcs, seq_init_param, h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
n_ranges, key_parts, mode, buf); mode, buf);
DBUG_RETURN(retval); DBUG_RETURN(retval);
} }
mrr_buf= buf->buffer; mrr_buf= buf->buffer;
...@@ -337,51 +336,25 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -337,51 +336,25 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
mrr_buf_end= buf->buffer_end; mrr_buf_end= buf->buffer_end;
if ((doing_cpk_scan= check_cpk_scan(h->active_index, mode)))
doing_cpk_scan= check_cpk_scan(h->active_index, mode);
if (doing_cpk_scan)
{ {
/* /* It's a DS-MRR/CPK scan */
When doing a scan on CPK, the buffer stores {lookup_tuple, range_id} cpk_tuple_length= 0; /* dummy value telling it needs to be inited */
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);
cpk_have_range= FALSE; cpk_have_range= FALSE;
elem_size= keylen + (int)is_mrr_assoc * sizeof(void*);
use_default_impl= FALSE; 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_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
h->mrr_funcs= *seq_funcs; h->mrr_funcs= *seq_funcs;
dsmrr_fill_buffer_cpk(); dsmrr_fill_buffer_cpk();
if (dsmrr_eof) if (dsmrr_eof)
buf->end_of_used_area= mrr_buf_last; buf->end_of_used_area= mrr_buf_last;
DBUG_RETURN(0); /* nothing could go wrong while filling the buffer */ 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: There can be two cases:
- This is the first call since index_init(), h2==NULL - 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, ...@@ -454,8 +427,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
goto error; goto error;
} }
if (h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges, if (h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
key_parts, mode, buf) || mode, buf) ||
dsmrr_fill_buffer()) dsmrr_fill_buffer())
{ {
goto error; goto error;
...@@ -604,6 +577,9 @@ int DsMrr_impl::key_tuple_cmp(void* arg, uchar* key1, uchar* key2) ...@@ -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 DS-MRR/CPK: Fill the buffer with (lookup_tuple, range_id) pairs and sort
SYNOPSIS
DsMrr_impl::dsmrr_fill_buffer_cpk()
DESCRIPTION DESCRIPTION
DS-MRR/CPK: Fill the buffer with (lookup_tuple, range_id) pairs and sort 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() ...@@ -623,7 +599,18 @@ void DsMrr_impl::dsmrr_fill_buffer_cpk()
!(res= h->mrr_funcs.next(h->mrr_iter, &cur_range))) !(res= h->mrr_funcs.next(h->mrr_iter, &cur_range)))
{ {
DBUG_ASSERT(cur_range.range_flag & EQ_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 */ /* Put key, or {key, range_id} pair into the buffer */
memcpy(mrr_buf_cur, cur_range.start_key.key, cpk_tuple_length); memcpy(mrr_buf_cur, cur_range.start_key.key, cpk_tuple_length);
mrr_buf_cur += cpk_tuple_length; mrr_buf_cur += cpk_tuple_length;
......
...@@ -87,8 +87,7 @@ class DsMrr_impl ...@@ -87,8 +87,7 @@ class DsMrr_impl
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, RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
uint n_ranges, uint key_parts, uint mode, uint n_ranges, uint mode, HANDLER_BUFFER *buf);
HANDLER_BUFFER *buf);
void dsmrr_close(); void dsmrr_close();
int dsmrr_next(char **range_info); int dsmrr_next(char **range_info);
......
...@@ -8368,7 +8368,6 @@ int QUICK_RANGE_SELECT::reset() ...@@ -8368,7 +8368,6 @@ int QUICK_RANGE_SELECT::reset()
RANGE_SEQ_IF seq_funcs= {quick_range_seq_init, quick_range_seq_next, 0, 0}; 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, error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
uint(-1),
mrr_flags, mrr_buf_desc? mrr_buf_desc: mrr_flags, mrr_buf_desc? mrr_buf_desc:
&empty_buf); &empty_buf);
DBUG_RETURN(error); DBUG_RETURN(error);
......
...@@ -2376,8 +2376,7 @@ JOIN_CACHE_BKA::init_join_matching_records(RANGE_SEQ_IF *seq_funcs, uint ranges) ...@@ -2376,8 +2376,7 @@ JOIN_CACHE_BKA::init_join_matching_records(RANGE_SEQ_IF *seq_funcs, uint ranges)
*/ */
if (!file->inited) if (!file->inited)
file->ha_index_init(join_tab->ref.key, 1); file->ha_index_init(join_tab->ref.key, 1);
if ((error= file->multi_range_read_init(seq_funcs, (void*) this, ranges, if ((error= file->multi_range_read_init(seq_funcs, (void*) this, ranges,
join_tab->ref.key_parts,
mrr_mode, &mrr_buff))) mrr_mode, &mrr_buff)))
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR; rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
......
...@@ -3501,11 +3501,10 @@ static SHOW_VAR status_variables[]= { ...@@ -3501,11 +3501,10 @@ static SHOW_VAR status_variables[]= {
***************************************************************************/ ***************************************************************************/
int ha_maria::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, int ha_maria::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) HANDLER_BUFFER *buf)
{ {
return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, key_parts, return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf);
mode, buf);
} }
int ha_maria::multi_range_read_next(char **range_info) int ha_maria::multi_range_read_next(char **range_info)
......
...@@ -174,8 +174,7 @@ class ha_maria :public handler ...@@ -174,8 +174,7 @@ class ha_maria :public handler
* Multi Range Read interface * Multi Range Read interface
*/ */
int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 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);
HANDLER_BUFFER *buf);
int multi_range_read_next(char **range_info); int multi_range_read_next(char **range_info);
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param, void *seq_init_param,
......
...@@ -2217,10 +2217,10 @@ static int myisam_init(void *p) ...@@ -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, 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) 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) int ha_myisam::multi_range_read_next(char **range_info)
......
...@@ -162,8 +162,7 @@ class ha_myisam: public handler ...@@ -162,8 +162,7 @@ class ha_myisam: public handler
* Multi Range Read interface * Multi Range Read interface
*/ */
int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 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);
HANDLER_BUFFER *buf);
int multi_range_read_next(char **range_info); int multi_range_read_next(char **range_info);
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param, void *seq_init_param,
......
...@@ -11025,10 +11025,10 @@ test_innobase_convert_name() ...@@ -11025,10 +11025,10 @@ test_innobase_convert_name()
*/ */
int ha_innobase::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 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) 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) int ha_innobase::multi_range_read_next(char **range_info)
......
...@@ -210,8 +210,7 @@ class ha_innobase: public handler ...@@ -210,8 +210,7 @@ class ha_innobase: public handler
* Multi Range Read interface * Multi Range Read interface
*/ */
int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 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);
HANDLER_BUFFER *buf);
int multi_range_read_next(char **range_info); int multi_range_read_next(char **range_info);
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param, void *seq_init_param,
......
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