summaryrefslogtreecommitdiff
path: root/sql/opt_range.h
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2003-11-21 00:27:54 +0300
committerunknown <sergefp@mysql.com>2003-11-21 00:27:54 +0300
commit075ce1ec5756584dc4f94908c224eb1ba7098c1f (patch)
tree6b4bea3efe528c37d33b93dc225687872b614d11 /sql/opt_range.h
parent50685be51b54985cccaa299cb6d7a43ff1cbe2a1 (diff)
parentbc20df185777934065c1974c90e7f81bc71d89cd (diff)
downloadmariadb-git-075ce1ec5756584dc4f94908c224eb1ba7098c1f.tar.gz
Merged, most likely needs post-merge fix
BitKeeper/etc/logging_ok: auto-union sql/opt_range.h: Auto merged sql/sql_class.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_test.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_update.cc: Auto merged sql/opt_range.cc: Merged sql/sql_select.cc: Merged
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r--sql/opt_range.h193
1 files changed, 175 insertions, 18 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 1c209dc7027..73e30ba642a 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -65,41 +65,198 @@ class QUICK_RANGE :public Sql_alloc {
}
};
+class INDEX_MERGE;
-class QUICK_SELECT {
+/*
+ Quick select interface.
+ This class is parent for all QUICK_*_SELECT and FT_SELECT classes.
+*/
+
+class QUICK_SELECT_I
+{
public:
+ ha_rows records; /* estimate of # of records to be retrieved */
+ double read_time; /* time to perform this retrieval */
+ TABLE *head;
+
+ /*
+ the only index this quick select uses, or MAX_KEY for
+ QUICK_INDEX_MERGE_SELECT
+ */
+ uint index;
+ uint max_used_key_length, used_key_parts;
+
+ QUICK_SELECT_I();
+ virtual ~QUICK_SELECT_I(){};
+ virtual int init() = 0;
+ virtual void reset(void) = 0;
+ virtual int get_next() = 0; /* get next record to retrieve */
+ virtual bool reverse_sorted() = 0;
+ virtual bool unique_key_range() { return false; }
+
+ enum {
+ QS_TYPE_RANGE = 0,
+ QS_TYPE_INDEX_MERGE = 1,
+ QS_TYPE_RANGE_DESC = 2,
+ QS_TYPE_FULLTEXT = 3
+ };
+
+ /* Get type of this quick select - one of the QS_* values */
+ virtual int get_type() = 0;
+};
+
+struct st_qsel_param;
+class SEL_ARG;
+
+class QUICK_RANGE_SELECT : public QUICK_SELECT_I
+{
+protected:
bool next,dont_free;
+public:
int error;
- uint index, max_used_key_length, used_key_parts;
- TABLE *head;
handler *file;
byte *record;
+protected:
+ friend void print_quick_sel_range(QUICK_RANGE_SELECT *quick,
+ key_map needed_reg);
+ friend QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
+ struct st_table_ref *ref);
+ friend bool get_quick_keys(struct st_qsel_param *param,
+ QUICK_RANGE_SELECT *quick,KEY_PART *key,
+ SEL_ARG *key_tree,char *min_key,uint min_key_flag,
+ char *max_key, uint max_key_flag);
+ friend QUICK_RANGE_SELECT *get_quick_select(struct st_qsel_param*,uint idx,
+ SEL_ARG *key_tree,
+ MEM_ROOT *alloc);
+ friend class QUICK_SELECT_DESC;
+
List<QUICK_RANGE> ranges;
List_iterator<QUICK_RANGE> it;
QUICK_RANGE *range;
MEM_ROOT alloc;
-
- KEY_PART *key_parts;
- ha_rows records;
- double read_time;
-
- QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
- virtual ~QUICK_SELECT();
- void reset(void) { next=0; it.rewind(); }
- int init() { return error=file->index_init(index); }
- virtual int get_next();
- virtual bool reverse_sorted() { return 0; }
+ KEY_PART *key_parts;
int cmp_next(QUICK_RANGE *range);
+public:
+ QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0,
+ MEM_ROOT *parent_alloc=NULL);
+ ~QUICK_RANGE_SELECT();
+
+ void reset(void) { next=0; it.rewind(); }
+ int init();
+ int get_next();
+ bool reverse_sorted() { return 0; }
bool unique_key_range();
+ int get_type() { return QS_TYPE_RANGE; }
+};
+
+/*
+ Helper class for keeping track of rows that have been passed to output
+ in index_merge access method.
+
+ NOTES
+ Current implementation uses a temporary table to store ROWIDs of rows that
+ have been passed to output. In the future it might be changed to use more
+ efficient mechanisms, like Unique class.
+*/
+
+class INDEX_MERGE
+{
+public:
+ INDEX_MERGE(THD *thd_arg);
+ ~INDEX_MERGE();
+
+ int init(TABLE *table);
+ int check_record_in();
+ int start_last_quick_select();
+ int error;
+private:
+ /* The only field in temporary table */
+ class Item_rowid : public Item_str_func
+ {
+ TABLE *head; /* source table */
+ public:
+ Item_rowid(TABLE *table) : head(table)
+ {
+ max_length= table->file->ref_length;
+ collation.set(&my_charset_bin);
+ };
+ const char *func_name() const { return "rowid"; }
+ bool const_item() const { return 0; }
+ String *val_str(String *);
+ void fix_length_and_dec()
+ {}
+ };
+
+ /* Check if record has been processed and save it if it wasn't */
+ inline int put_record();
+
+ /* Check if record has been processed without saving it */
+ inline int check_record();
+
+ /* If true, check_record_in does't store ROWIDs it is passed. */
+ bool dont_save;
+
+ THD *thd;
+ TABLE *head; /* source table */
+ TABLE *temp_table; /* temp. table used for values storage */
+ TMP_TABLE_PARAM tmp_table_param; /* temp. table creation parameters */
+ Item_rowid *rowid_item; /* the only field in temp. table */
+ List<Item> fields; /* temp. table fields list
+ (the only element is rowid_item) */
+ ORDER order; /* key for temp. table (rowid_item) */
};
-class QUICK_SELECT_DESC: public QUICK_SELECT
+/*
+ Index merge quick select.
+ It is implemented as a container for several QUICK_RANGE_SELECTs.
+*/
+
+class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
+{
+public:
+ QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table);
+ ~QUICK_INDEX_MERGE_SELECT();
+
+ int init();
+ void reset(void);
+ int get_next();
+ bool reverse_sorted() { return false; }
+ bool unique_key_range() { return false; }
+ int get_type() { return QS_TYPE_INDEX_MERGE; }
+
+ bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
+
+ /* range quick selects this index_merge read consists of */
+ List<QUICK_RANGE_SELECT> quick_selects;
+
+ /* quick select which is currently used for rows retrieval */
+ List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it;
+ QUICK_RANGE_SELECT* cur_quick_select;
+
+ /*
+ Last element in quick_selects list.
+ INDEX_MERGE::start_last_quick_select is called before retrieving
+ rows for it.
+ */
+ QUICK_RANGE_SELECT* last_quick_select;
+
+ /*
+ Used to keep track of what records have been already passed to output
+ when doing index_merge access (NULL means no index_merge)
+ */
+ INDEX_MERGE index_merge;
+
+ MEM_ROOT alloc;
+};
+
+class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
{
public:
- QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts);
+ QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts);
int get_next();
bool reverse_sorted() { return 1; }
+ int get_type() { return QS_TYPE_RANGE_DESC; }
private:
int cmp_prev(QUICK_RANGE *range);
bool range_reads_after_key(QUICK_RANGE *range);
@@ -114,7 +271,7 @@ private:
class SQL_SELECT :public Sql_alloc {
public:
- QUICK_SELECT *quick; // If quick-select used
+ QUICK_SELECT_I *quick; // If quick-select used
COND *cond; // where condition
TABLE *head;
IO_CACHE file; // Positions to used records
@@ -134,7 +291,7 @@ class SQL_SELECT :public Sql_alloc {
ha_rows limit, bool force_quick_range=0);
};
-QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
+QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
struct st_table_ref *ref);
#endif