summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/multi_range_read.cc100
-rw-r--r--sql/multi_range_read.h109
2 files changed, 54 insertions, 155 deletions
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index f577d4598e3..72099bb0967 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -283,7 +283,7 @@ scan_it_again:
}
-/***** MRR_impl classes ****************************************************/
+/***** Mrr_*_reader classes **************************************************/
int Mrr_simple_index_reader::get_next(char **range_info)
{
@@ -355,24 +355,8 @@ int Mrr_ordered_index_reader::get_next(char **range_info_arg)
{
if (key_buffer->is_empty())
{
- /*if (auto_refill)
- {
- int res;
- if ((res= refill_buffer()))
- DBUG_RETURN(res);
- if (key_buffer->is_empty())
- {
- index_scan_eof= TRUE;
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- }
- else
- */
- {
- /* Buffer refills are managed by somebody else for us */
- index_scan_eof= TRUE;
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
+ index_scan_eof= TRUE;
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
}
}
scanning_key_val_iter= TRUE;
@@ -427,23 +411,7 @@ int Mrr_ordered_index_reader::refill_buffer()
is_mrr_assoc? (uchar**)&range_info_ptr : NULL,
sizeof(uchar*));
}
-#if 0
- if (know_key_tuple_params)
- {
- if (do_rndpos_scan && rowid_buffer.is_empty())
- {
- /*
- We're using two buffers and both of them are empty now. Restore the
- original sizes
- */
- rowid_buffer.set_buffer_space(full_buf, rowid_buffer_end);
- key_buffer= &backward_key_buf;
- key_buffer->set_buffer_space(rowid_buffer_end, full_buf_end);
- }
- }
- is all of the ifdef-ed stuff is handled above?
-#endif
while ((!know_key_tuple_params || key_buffer->can_write()) &&
!(res= mrr_funcs.next(mrr_iter, &cur_range)))
{
@@ -478,7 +446,7 @@ int Mrr_ordered_index_reader::refill_buffer()
key_buffer->write();
}
- no_more_keys= test(res);
+ bool no_more_keys= test(res);
key_buffer->sort((key_buffer->type() == Lifo_buffer::FORWARD)?
(qsort2_cmp)Mrr_ordered_index_reader::key_tuple_cmp_reverse :
@@ -521,15 +489,8 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
h= h_arg;
index_reader= index_reader_arg;
rowid_buffer= buf;
- is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
- //rowid_buff_elem_size= h->ref_length;
- //if (!(mode & HA_MRR_NO_ASSOCIATION))
- // rowid_buff_elem_size += sizeof(char*);
-
+ is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
index_reader_exhausted= FALSE;
- ///int res= index_reader->refill_buffer();
- ///if (res && res!=HA_ERR_END_OF_FILE)
- /// return res;
return 0;
}
@@ -552,7 +513,6 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
@retval other Error
*/
-
int Mrr_ordered_rndpos_reader::refill_buffer()
{
int res;
@@ -651,31 +611,6 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
while (1)
{
-#if 0
- if (rowid_buffer->is_empty()) /* We're out of rowids */
- {
- /* First, finish off the sorted keys we have */
- if (!index_reader->eof())
- {
- res= refill_buffer();
- if (res && res != HA_ERR_END_OF_FILE)
- return res;
- }
-
- if (rowid_buffer->is_empty())
- {
- /*
- Ok neither index_reader nor us have any records. Refill index
- reader, then refill us.
- */
- // TODO: if key buffer is empty, too, redistribute the buffer space.
- if ((res= index_reader->refill_buffer()) ||
- (res= refill_buffer()))
- return res;
- }
- }
-#endif
-
last_identical_rowid= NULL;
/* Return eof if there are no rowids in the buffer after re-fill attempt */
@@ -723,9 +658,7 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
}
-
-
-/************ MRR_impl classes end *********************************************/
+/************ Mrr_*_reader classes end ***************************************/
/****************************************************************************
@@ -768,7 +701,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if ((mode & HA_MRR_USE_DEFAULT_IMPL) || (mode & HA_MRR_SORTED))
{
DBUG_ASSERT(h->inited == handler::INDEX);
- Mrr_simple_index_reader *s= &strategy_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, this);
strategy= s;
DBUG_RETURN(res);
@@ -785,10 +718,10 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if ((mode & HA_MRR_SINGLE_POINT) &&
optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS))
{
- index_strategy= ordered_idx_reader= &strategy_factory.ordered_index_reader;
+ index_strategy= ordered_idx_reader= &reader_factory.ordered_index_reader;
}
else
- index_strategy= &strategy_factory.simple_index_reader;
+ index_strategy= &reader_factory.simple_index_reader;
strategy= index_strategy;
/*
@@ -806,7 +739,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
Mrr_ordered_rndpos_reader *disk_strategy= NULL;
if (!(keyno == table->s->primary_key && h_idx->primary_key_is_clustered()))
{
- strategy= disk_strategy= &strategy_factory.ordered_rndpos_reader;
+ strategy= disk_strategy= &reader_factory.ordered_rndpos_reader;
}
if (is_mrr_assoc)
@@ -817,8 +750,6 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if (strategy == index_strategy)
{
- ///if (ordered_idx_reader)
- // ordered_idx_reader->auto_refill= TRUE;
/* Index strategy serves it all. We don't need two handlers, etc */
/* Give the buffer to index strategy */
if ((res= index_strategy->init(h, seq_funcs, seq_init_param, n_ranges,
@@ -837,9 +768,6 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if ((res= setup_two_handlers()))
DBUG_RETURN(res);
- ///if (ordered_idx_reader)
- /// ordered_idx_reader->auto_refill= FALSE;
-
if ((res= index_strategy->init(h2, seq_funcs, seq_init_param, n_ranges,
mode, this)) ||
(res= disk_strategy->init(h, index_strategy, mode, &rowid_buffer)))
@@ -959,8 +887,8 @@ int DsMrr_impl::setup_two_handlers()
goto error;
}
DBUG_RETURN(0);
+
error:
- //close_second_handler(); -- caller does that
DBUG_RETURN(res);
}
@@ -1131,6 +1059,7 @@ void DsMrr_impl::reset_buffer_sizes()
}
}
+
/**
Take unused space from the key buffer and give it to the rowid buffer
*/
@@ -1143,14 +1072,9 @@ void DsMrr_impl::reallocate_buffer_space()
}
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
bool Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
{
int res;
- //h= h_arg;
- //param= param_arg;
owner= owner_arg;
identical_key_it.init(owner->key_buffer);
diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h
index 14bcdd5de6c..aed8c2c1fa1 100644
--- a/sql/multi_range_read.h
+++ b/sql/multi_range_read.h
@@ -49,7 +49,10 @@
#include "sql_lifo_buffer.h"
class DsMrr_impl;
+class Mrr_ordered_index_reader;
+
+/* A structure with key parameters that's shared among several classes */
class Key_parameters
{
public:
@@ -70,79 +73,75 @@ public:
bool use_key_pointers;
};
+
/**
- Iterator over (record, range_id) pairs that match given key value.
+ A class to enumerate (record, range_id) pairs that match given key value.
- We may need to scan multiple (key_val, range_id) pairs with the same
- key value. A key value may have multiple matching records, so we'll need to
- produce a cross-product of sets of matching records and range_id-s.
+ The idea is that we have an array of
+
+ (key, range_id1), (key, range_id2) ... (key, range_idN)
+
+ pairs, i.e. multiple identical key values with their different range_id-s,
+ and also we have ha_engine object where we can find matches for the key
+ value.
+
+ What this class does is produces all combinations of (key_match_record_X,
+ range_idN) pairs.
*/
-class Mrr_ordered_index_reader;
+
class Key_value_records_iterator
{
- /* Scan parameters */
- Key_parameters *param;
+ /* Use this to get table handler, key buffer and other parameters */
+ Mrr_ordered_index_reader *owner;
Lifo_buffer_iterator identical_key_it;
+
uchar *last_identical_key_ptr;
bool get_next_row;
- //handler *h;
- /* TRUE <=> We can get at most one index tuple for a lookup key */
- //bool index_ranges_unique;
- Mrr_ordered_index_reader *owner;
- /* key_buffer.read() reads to here */
- uchar *cur_index_tuple;
+ uchar *cur_index_tuple; /* key_buffer.read() reads to here */
public:
bool init(Mrr_ordered_index_reader *owner_arg);
-
- /*
- Get next (key_val, range_id) pair.
- */
int get_next();
-
void close();
- friend class Mrr_ordered_index_reader;
};
/*
- Something that will manage buffers for those that call it
+ Buffer manager interface. Mrr_reader objects use it to inqure DsMrr_impl
+ to manage buffer space for them.
*/
class Buffer_manager
{
public:
- virtual void reset_buffer_sizes()= 0;
virtual void setup_buffer_sizes(uint key_size_in_keybuf,
key_part_map key_tuple_map)=0;
+ virtual void reset_buffer_sizes()= 0;
virtual Lifo_buffer* get_key_buffer()= 0;
- virtual ~Buffer_manager(){}
+ virtual ~Buffer_manager(){} /* Shut up the compiler */
};
/*
- Abstract MRR execution strategy
-
- An object of this class produces (R, range_info) pairs where R can be an
- index tuple or a table record.
+ DS-MRR execution strategy abstraction.
- Getting HA_ERR_END_OF_FILE from get_next() means that the source should be
- re-filled.
-
- Was:
- if eof() returns true after refill attempt, then the end of
- stream has been reached and get_next() must not be called anymore.
+ A reader produces ([index]_record, range_info) pairs, and requires periodic
+ refill operations.
- Now:
- if refill_buffer() returns HA_ERR_END_OF_FILE that means the stream is
- really exhausted.
+ - one starts using the reader by calling reader->get_next(),
+ - when a get_next() call returns HA_ERR_END_OF_FILE, one must call
+ refill_buffer() before they can make more get_next() calls.
+ - when refill_buffer() returns HA_ERR_END_OF_FILE, this means the real
+ end of stream and get_next() should not be called anymore.
+ Both functions can return other error codes, these mean unrecoverable errors
+ after which one cannot continue.
*/
class Mrr_reader
{
public:
virtual int get_next(char **range_info) = 0;
- virtual int refill_buffer()=0;
+ virtual int refill_buffer() = 0;
virtual ~Mrr_reader() {}; /* just to remove compiler warning */
};
@@ -157,7 +156,6 @@ public:
virtual int init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
void *seq_init_param, uint n_ranges,
uint mode, Buffer_manager *buf_manager_arg) = 0;
- virtual bool eof() = 0;
virtual uchar *get_rowid_ptr()= 0;
virtual bool skip_record(char *range_id, uchar *rowid)=0;
};
@@ -177,7 +175,6 @@ public:
uint mode, Buffer_manager *buf_manager_arg);
int get_next(char **range_info);
int refill_buffer() { return HA_ERR_END_OF_FILE; }
- bool eof() { return test(res); }
uchar *get_rowid_ptr() { return h->ref; }
bool skip_record(char *range_id, uchar *rowid)
{
@@ -200,7 +197,6 @@ public:
uint mode, Buffer_manager *buf_manager_arg);
int get_next(char **range_info);
int refill_buffer();
- bool eof() { return index_scan_eof; }
uchar *get_rowid_ptr() { return h->ref; }
bool skip_record(char *range_info, uchar *rowid)
@@ -223,23 +219,18 @@ private:
/* Initially FALSE, becomes TRUE when we've set key_tuple_xxx members */
bool know_key_tuple_params;
- // bool use_key_pointers;
-
Key_parameters keypar;
+
/* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
bool is_mrr_assoc;
- bool no_more_keys;
RANGE_SEQ_IF mrr_funcs;
range_seq_t mrr_iter;
- //bool auto_refill;
-
bool index_scan_eof;
static int key_tuple_cmp(void* arg, uchar* key1, uchar* key2);
static int key_tuple_cmp_reverse(void* arg, uchar* key1, uchar* key2);
- //void cleanup();
friend class Key_value_records_iterator;
friend class DsMrr_impl;
@@ -256,8 +247,6 @@ public:
Lifo_buffer *buf);
int get_next(char **range_info);
int refill_buffer();
- int refill2();
- void cleanup();
private:
handler *h;
@@ -273,14 +262,14 @@ private:
uchar *last_identical_rowid;
Lifo_buffer *rowid_buffer;
- /* = h->ref_length [ + sizeof(range_assoc_info) ] */
- //uint rowid_buff_elem_size;
-
/* rowid_buffer.read() will set the following: */
uchar *rowid;
uchar *rowids_range_id;
+
+ int refill2();
};
+
class Mrr_reader_factory
{
public:
@@ -289,6 +278,7 @@ public:
Mrr_simple_index_reader simple_index_reader;
};
+
/*
DS-MRR implementation for one table. Create/use one object of this class for
each ha_{myisam/innobase/etc} object. That object will be further referred to
@@ -458,17 +448,11 @@ private:
*/
handler *h2;
- /** Properties of current MRR scan **/
-
uint keyno; /* index we're running the scan on */
/* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */
bool is_mrr_assoc;
- /* TRUE <=> sort the keys before making index lookups */
- //bool do_sort_keys;
- /* TRUE <=> sort rowids and use rnd_pos() to get and return full records */
- //bool do_rndpos_scan;
- Mrr_reader_factory strategy_factory;
+ Mrr_reader_factory reader_factory;
Mrr_reader *strategy;
Mrr_index_reader *index_strategy;
@@ -484,8 +468,6 @@ private:
*/
uchar *rowid_buffer_end;
- /** Index scaning and key buffer-related members **/
-
/*
One of the following two is used for key buffer: forward is used when
we only need key buffer, backward is used when we need both key and rowid
@@ -494,18 +476,11 @@ private:
Forward_lifo_buffer forward_key_buf;
Backward_lifo_buffer backward_key_buf;
- Forward_lifo_buffer rowid_buffer;
-
- /* = key_size_in_keybuf [ + sizeof(range_assoc_info) ] */
- //uint key_buff_elem_size_;
-
- /** rnd_pos() scan and rowid buffer-related members **/
-
/*
Buffer to store (rowid, range_id) pairs, or just rowids if
is_mrr_assoc==FALSE
*/
- //Forward_lifo_buffer rowid_buffer;
+ Forward_lifo_buffer rowid_buffer;
bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
COST_VECT *cost);