Commit 44be131c authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#121-125 DS-MRR improvements

- Address Monty's review feedback, part 5
parent f2abf5f6
...@@ -71,6 +71,9 @@ select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or ...@@ -71,6 +71,9 @@ select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or
# #
# Now try different keypart types and special values # Now try different keypart types and special values
# #
--disable_warnings
drop table if exists t4;
--enable_warnings
create table t4 (a varchar(10), b int, c char(10), filler char(200), create table t4 (a varchar(10), b int, c char(10), filler char(200),
key idx1 (a, b, c)); key idx1 (a, b, c));
......
...@@ -168,6 +168,7 @@ c-1020=w filler ...@@ -168,6 +168,7 @@ c-1020=w filler
c-1021=w filler c-1021=w filler
c-1022=w filler c-1022=w filler
c-1023=w filler c-1023=w filler
drop table if exists t4;
create table t4 (a varchar(10), b int, c char(10), filler char(200), create table t4 (a varchar(10), b int, c char(10), filler char(200),
key idx1 (a, b, c)); key idx1 (a, b, c));
insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15; insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
......
...@@ -169,6 +169,7 @@ c-1020=w filler ...@@ -169,6 +169,7 @@ c-1020=w filler
c-1021=w filler c-1021=w filler
c-1022=w filler c-1022=w filler
c-1023=w filler c-1023=w filler
drop table if exists t4;
create table t4 (a varchar(10), b int, c char(10), filler char(200), create table t4 (a varchar(10), b int, c char(10), filler char(200),
key idx1 (a, b, c)); key idx1 (a, b, c));
insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15; insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
......
drop table if exists t1, t2, t3; drop table if exists t0, t1, t2, t3;
set @mrr_buffer_size_save= @@mrr_buffer_size; set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=79; set mrr_buffer_size=79;
Warnings: Warnings:
...@@ -170,6 +170,7 @@ c-1020=w filler ...@@ -170,6 +170,7 @@ c-1020=w filler
c-1021=w filler c-1021=w filler
c-1022=w filler c-1022=w filler
c-1023=w filler c-1023=w filler
drop table if exists t4;
create table t4 (a varchar(10), b int, c char(10), filler char(200), create table t4 (a varchar(10), b int, c char(10), filler char(200),
key idx1 (a, b, c)); key idx1 (a, b, c));
insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15; insert into t4 (filler) select concat('NULL-', 15-a) from t2 order by a limit 15;
...@@ -432,8 +433,8 @@ a a b ...@@ -432,8 +433,8 @@ a a b
1 1 1 1 1 1
2 2 2 2 2 2
NULL NULL 1234 NULL NULL 1234
NULL NULL 1234
NULL NULL 5678 NULL NULL 5678
NULL NULL 1234
NULL NULL 5678 NULL NULL 5678
set @@join_cache_level=@save_join_cache_level; set @@join_cache_level=@save_join_cache_level;
drop table t0, t1; drop table t0, t1;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
--disable_warnings --disable_warnings
drop table if exists t1, t2, t3; drop table if exists t0, t1, t2, t3;
--enable_warnings --enable_warnings
set @mrr_buffer_size_save= @@mrr_buffer_size; set @mrr_buffer_size_save= @@mrr_buffer_size;
......
...@@ -1154,6 +1154,23 @@ typedef void *range_seq_t; ...@@ -1154,6 +1154,23 @@ typedef void *range_seq_t;
typedef struct st_range_seq_if typedef struct st_range_seq_if
{ {
/*
Get key information
SYNOPSIS
get_key_info()
init_params The seq_init_param parameter
length OUT length of the keys in this range sequence
map OUT key_part_map of the keys in this range sequence
DESCRIPTION
This function is set only when using HA_MRR_FIXED_KEY mode. In that mode,
all ranges are single-point equality ranges that use the same set of key
parts. This function allows the MRR implementation to get the length of
a key, and which keyparts it uses.
*/
void (*get_key_info)(void *init_params, uint *length, key_part_map *map);
/* /*
Initialize the traversal of range sequence Initialize the traversal of range sequence
......
This diff is collapsed.
...@@ -56,9 +56,6 @@ class Mrr_ordered_index_reader; ...@@ -56,9 +56,6 @@ class Mrr_ordered_index_reader;
class Key_parameters class Key_parameters
{ {
public: public:
/* TRUE <=> We can get at most one index tuple for a lookup key */
bool index_ranges_unique;
uint key_tuple_length; /* Length of index lookup tuple, in bytes */ uint key_tuple_length; /* Length of index lookup tuple, in bytes */
key_part_map key_tuple_map; /* keyparts used in index lookup tuples */ key_part_map key_tuple_map; /* keyparts used in index lookup tuples */
...@@ -71,6 +68,9 @@ public: ...@@ -71,6 +68,9 @@ public:
/* TRUE <=> don't copy key values, use pointers to them instead. */ /* TRUE <=> don't copy key values, use pointers to them instead. */
bool use_key_pointers; bool use_key_pointers;
/* TRUE <=> We can get at most one index tuple for a lookup key */
bool index_ranges_unique;
}; };
...@@ -145,28 +145,27 @@ public: ...@@ -145,28 +145,27 @@ public:
Buffer manager interface. Mrr_reader objects use it to inqure DsMrr_impl Buffer manager interface. Mrr_reader objects use it to inqure DsMrr_impl
to manage buffer space for them. to manage buffer space for them.
*/ */
class Buffer_manager typedef struct st_buffer_manager
{ {
public: public:
/* /* Opaque value to be passed as the first argument to all member functions */
Index-based reader calls this when it gets the first key, so we get to know void *arg;
key length and
/*
This is called when we've freed more space from the rowid buffer. The
callee will get the unused space from the rowid buffer and give it to the
key buffer.
*/ */
virtual void setup_buffer_sizes(uint key_size_in_keybuf, void (*redistribute_buffer_space)(void *arg);
key_part_map key_tuple_map) = 0;
virtual void redistribute_buffer_space() = 0;
/* /*
This is called when both key and rowid buffers are empty, and so it's time This is called when both key and rowid buffers are empty, and so it's time
to reset them to their original size (They've lost their original size, to reset them to their original size (They've lost their original size,
because we were dynamically growing rowid buffer and shrinking key buffer). because we were dynamically growing rowid buffer and shrinking key buffer).
*/ */
virtual void reset_buffer_sizes() = 0; void (*reset_buffer_sizes)(void *arg);
virtual Lifo_buffer* get_key_buffer() = 0; } Buffer_manager;
virtual ~Buffer_manager(){} /* Shut up the compiler */
};
/* /*
...@@ -205,7 +204,9 @@ protected: ...@@ -205,7 +204,9 @@ protected:
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,
uint mode, Buffer_manager *buf_manager_arg) = 0; uint mode, Key_parameters *key_par,
Lifo_buffer *key_buffer,
Buffer_manager *buf_manager_arg) = 0;
/* Get pointer to place where every get_next() call will put rowid */ /* Get pointer to place where every get_next() call will put rowid */
virtual uchar *get_rowid_ptr() = 0; virtual uchar *get_rowid_ptr() = 0;
...@@ -224,9 +225,11 @@ public: ...@@ -224,9 +225,11 @@ public:
class Mrr_simple_index_reader : public Mrr_index_reader class Mrr_simple_index_reader : public Mrr_index_reader
{ {
public: public:
int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
void *seq_init_param, uint n_ranges, void *seq_init_param, uint n_ranges,
uint mode, Buffer_manager *buf_manager_arg); uint mode, Key_parameters *key_par,
Lifo_buffer *key_buffer,
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 h->ref; }
...@@ -247,7 +250,9 @@ class Mrr_ordered_index_reader : public Mrr_index_reader ...@@ -247,7 +250,9 @@ class Mrr_ordered_index_reader : public Mrr_index_reader
public: public:
int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
void *seq_init_param, uint n_ranges, void *seq_init_param, uint n_ranges,
uint mode, Buffer_manager *buf_manager_arg); uint mode, Key_parameters *key_par,
Lifo_buffer *key_buffer,
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 h->ref; }
...@@ -278,12 +283,6 @@ private: ...@@ -278,12 +283,6 @@ private:
/* This manages key buffer allocation and sizing for us */ /* This manages key buffer allocation and sizing for us */
Buffer_manager *buf_manager; Buffer_manager *buf_manager;
/*
Initially FALSE, becomes TRUE when we saw the first lookup key and set
keypar's member.
*/
bool know_key_tuple_params;
Key_parameters keypar; /* index scan and lookup tuple parameters */ Key_parameters keypar; /* index scan and lookup tuple parameters */
/* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
...@@ -498,7 +497,7 @@ public: ...@@ -498,7 +497,7 @@ public:
*/ */
class DsMrr_impl : public Buffer_manager class DsMrr_impl
{ {
public: public:
typedef void (handler::*range_check_toggle_func_t)(bool on); typedef void (handler::*range_check_toggle_func_t)(bool on);
...@@ -582,10 +581,14 @@ private: ...@@ -582,10 +581,14 @@ private:
uint *buffer_size, COST_VECT *cost); uint *buffer_size, COST_VECT *cost);
bool check_cpk_scan(THD *thd, uint keyno, uint mrr_flags); bool check_cpk_scan(THD *thd, uint keyno, uint mrr_flags);
/* Buffer_manager implementation */ bool setup_buffer_sharing(uint key_size_in_keybuf, key_part_map key_tuple_map);
void setup_buffer_sizes(uint key_size_in_keybuf, key_part_map key_tuple_map);
void redistribute_buffer_space(); /* Buffer_manager and its member functions */
void reset_buffer_sizes(); Buffer_manager buf_manager;
static void redistribute_buffer_space(void *dsmrr_arg);
static void reset_buffer_sizes(void *dsmrr_arg);
static void do_nothing(void *dsmrr_arg);
Lifo_buffer* get_key_buffer() { return key_buffer; } Lifo_buffer* get_key_buffer() { return key_buffer; }
friend class Key_value_records_iterator; friend class Key_value_records_iterator;
......
...@@ -7449,7 +7449,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, ...@@ -7449,7 +7449,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
uint *mrr_flags, uint *bufsize, COST_VECT *cost) uint *mrr_flags, uint *bufsize, COST_VECT *cost)
{ {
SEL_ARG_RANGE_SEQ seq; SEL_ARG_RANGE_SEQ seq;
RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0}; RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0};
handler *file= param->table->file; handler *file= param->table->file;
ha_rows rows; ha_rows rows;
uint keynr= param->real_keynr[idx]; uint keynr= param->real_keynr[idx];
...@@ -8377,7 +8377,7 @@ int QUICK_RANGE_SELECT::reset() ...@@ -8377,7 +8377,7 @@ int QUICK_RANGE_SELECT::reset()
if (!mrr_buf_desc) if (!mrr_buf_desc)
empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL; empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
RANGE_SEQ_IF seq_funcs= {quick_range_seq_init, quick_range_seq_next, 0, 0}; RANGE_SEQ_IF seq_funcs= {NULL, 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,
mrr_flags, mrr_buf_desc? mrr_buf_desc: mrr_flags, mrr_buf_desc? mrr_buf_desc:
&empty_buf); &empty_buf);
......
...@@ -3597,6 +3597,16 @@ int JOIN_TAB_SCAN_MRR::next() ...@@ -3597,6 +3597,16 @@ int JOIN_TAB_SCAN_MRR::next()
} }
static
void bka_range_seq_key_info(void *init_params, uint *length,
key_part_map *map)
{
TABLE_REF *ref= &(((JOIN_CACHE*)init_params)->join_tab->ref);
*length= ref->key_length;
*map= (key_part_map(1) << ref->key_parts) - 1;
}
/* /*
Initialize retrieval of range sequence for BKA join algorithm Initialize retrieval of range sequence for BKA join algorithm
...@@ -3876,7 +3886,8 @@ int JOIN_CACHE_BKA::init() ...@@ -3876,7 +3886,8 @@ int JOIN_CACHE_BKA::init()
int res; int res;
bool check_only_first_match= join_tab->check_only_first_match(); bool check_only_first_match= join_tab->check_only_first_match();
RANGE_SEQ_IF rs_funcs= { bka_range_seq_init, RANGE_SEQ_IF rs_funcs= { bka_range_seq_key_info,
bka_range_seq_init,
bka_range_seq_next, bka_range_seq_next,
check_only_first_match ? check_only_first_match ?
bka_range_seq_skip_record : 0, bka_range_seq_skip_record : 0,
...@@ -4265,7 +4276,8 @@ int JOIN_CACHE_BKAH::init() ...@@ -4265,7 +4276,8 @@ int JOIN_CACHE_BKAH::init()
no_association= test(mrr_mode & HA_MRR_NO_ASSOCIATION); no_association= test(mrr_mode & HA_MRR_NO_ASSOCIATION);
RANGE_SEQ_IF rs_funcs= { bkah_range_seq_init, RANGE_SEQ_IF rs_funcs= { bka_range_seq_key_info,
bkah_range_seq_init,
bkah_range_seq_next, bkah_range_seq_next,
check_only_first_match && !no_association ? check_only_first_match && !no_association ?
bkah_range_seq_skip_record : 0, bkah_range_seq_skip_record : 0,
......
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