diff options
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r-- | sql/opt_range.h | 171 |
1 files changed, 110 insertions, 61 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h index 7edd99402fe..1a0a2ee0029 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -193,13 +193,16 @@ class QUICK_RANGE :public Sql_alloc { 4. Delete the select: delete quick; - + + NOTE + quick select doesn't use Sql_alloc/MEM_ROOT allocation because "range + checked for each record" functionality may create/destroy + O(#records_in_some_table) quick selects during query execution. */ class QUICK_SELECT_I { public: - bool sorted; ha_rows records; /* estimate of # of records to be retrieved */ double read_time; /* time to perform this retrieval */ TABLE *head; @@ -272,6 +275,12 @@ public: virtual bool reverse_sorted() = 0; virtual bool unique_key_range() { return false; } + /* + Request that this quick select produces sorted output. Not all quick + selects can do it, the caller is responsible for calling this function + only for those quick selects that can. + */ + virtual void need_sorted_output() = 0; enum { QS_TYPE_RANGE = 0, QS_TYPE_INDEX_INTERSECT = 1, @@ -359,6 +368,22 @@ struct st_qsel_param; class PARAM; class SEL_ARG; + +/* + MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal + context. +*/ +typedef struct st_quick_range_seq_ctx +{ + QUICK_RANGE **first; + QUICK_RANGE **cur; + QUICK_RANGE **last; +} QUICK_RANGE_SEQ_CTX; + +range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags); +bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range); + + /* Quick select that does a range scan on a single key. The records are returned in key order. @@ -366,73 +391,47 @@ class SEL_ARG; class QUICK_RANGE_SELECT : public QUICK_SELECT_I { protected: - bool next,dont_free,in_ror_merged_scan; /* true if we enabled key only reads */ bool doing_key_read; -public: - int error; -protected: handler *file; - /* - If true, this quick select has its "own" handler object which should be - closed no later then this quick select is deleted. - */ - bool free_file; - bool in_range; - uint multi_range_count; /* copy from thd->variables.multi_range_count */ - uint multi_range_length; /* the allocated length for the array */ - uint multi_range_bufsiz; /* copy from thd->variables.read_rnd_buff_size */ - KEY_MULTI_RANGE *multi_range; /* the multi-range array (allocated and - freed by QUICK_RANGE_SELECT) */ - HANDLER_BUFFER *multi_range_buff; /* the handler buffer (allocated and - freed by QUICK_RANGE_SELECT) */ - MY_BITMAP column_bitmap, *save_read_set, *save_write_set; - friend class TRP_ROR_INTERSECT; - friend - QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, - struct st_table_ref *ref, - ha_rows records); - friend bool get_quick_keys(PARAM *param, - QUICK_RANGE_SELECT *quick,KEY_PART *key, - SEL_ARG *key_tree, - uchar *min_key, uint min_key_flag, - uchar *max_key, uint max_key_flag); - friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx, - SEL_ARG *key_tree, - MEM_ROOT *alloc); - friend - int read_keys_and_merge_scans(THD *thd, TABLE *head, - List<QUICK_RANGE_SELECT> quick_selects, - QUICK_RANGE_SELECT *pk_quick_select, - READ_RECORD *read_record, - bool intersection, - key_map *filtered_scans, - Unique **unique_ptr); + /* Members to deal with case when this quick select is a ROR-merged scan */ + bool in_ror_merged_scan; + MY_BITMAP column_bitmap, *save_read_set, *save_write_set; + bool free_file; /* TRUE <=> this->file is "owned" by this quick select */ - friend class QUICK_SELECT_DESC; - friend class QUICK_INDEX_SORT_SELECT; - friend class QUICK_INDEX_MERGE_SELECT; - friend class QUICK_INDEX_INTERSECT_SELECT; - friend class QUICK_ROR_INTERSECT_SELECT; - friend class QUICK_GROUP_MIN_MAX_SELECT; + /* Range pointers to be used when not using MRR interface */ + /* Members needed to use the MRR interface */ + QUICK_RANGE_SEQ_CTX qr_traversal_ctx; +public: + uint mrr_flags; /* Flags to be used with MRR interface */ +protected: + uint mrr_buf_size; /* copy from thd->variables.mrr_buff_size */ + HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */ + /* Info about index we're scanning */ + DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */ QUICK_RANGE **cur_range; /* current element in ranges */ - + QUICK_RANGE *last_range; + KEY_PART *key_parts; KEY_PART_INFO *key_part_info; + + bool dont_free; /* Used by QUICK_SELECT_DESC */ + int cmp_next(QUICK_RANGE *range); int cmp_prev(QUICK_RANGE *range); bool row_in_ranges(); public: MEM_ROOT alloc; - QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0, - MEM_ROOT *parent_alloc=NULL); + QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc, + MEM_ROOT *parent_alloc, bool *create_err); ~QUICK_RANGE_SELECT(); - + + void need_sorted_output(); int init(); int reset(void); int get_next(); @@ -452,6 +451,38 @@ public: #endif private: /* Default copy ctor used by QUICK_SELECT_DESC */ + friend class TRP_ROR_INTERSECT; + friend + QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, + struct st_table_ref *ref, + ha_rows records); + friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick, + KEY_PART *key, SEL_ARG *key_tree, + uchar *min_key, uint min_key_flag, + uchar *max_key, uint max_key_flag); + friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx, + SEL_ARG *key_tree, + uint mrr_flags, + uint mrr_buf_size, + MEM_ROOT *alloc); + friend class QUICK_SELECT_DESC; + friend class QUICK_INDEX_SORT_SELECT; + friend class QUICK_INDEX_MERGE_SELECT; + friend class QUICK_ROR_INTERSECT_SELECT; + friend class QUICK_INDEX_INTERSECT_SELECT; + friend class QUICK_GROUP_MIN_MAX_SELECT; + friend bool quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range); + friend range_seq_t quick_range_seq_init(void *init_param, + uint n_ranges, uint flags); + friend + int read_keys_and_merge_scans(THD *thd, TABLE *head, + List<QUICK_RANGE_SELECT> quick_selects, + QUICK_RANGE_SELECT *pk_quick_select, + READ_RECORD *read_record, + bool intersection, + key_map *filtered_scans, + Unique **unique_ptr); + }; @@ -459,8 +490,10 @@ class QUICK_RANGE_SELECT_GEOM: public QUICK_RANGE_SELECT { public: QUICK_RANGE_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg, - bool no_alloc, MEM_ROOT *parent_alloc) - :QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc) + bool no_alloc, MEM_ROOT *parent_alloc, + bool *create_err) + :QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc, + create_err) {}; virtual int get_next(); }; @@ -540,6 +573,7 @@ public: ~QUICK_INDEX_SORT_SELECT(); int init(); + void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ } int reset(void); bool reverse_sorted() { return false; } bool unique_key_range() { return false; } @@ -628,6 +662,7 @@ public: ~QUICK_ROR_INTERSECT_SELECT(); int init(); + void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ } int reset(void); int get_next(); bool reverse_sorted() { return false; } @@ -690,6 +725,7 @@ public: ~QUICK_ROR_UNION_SELECT(); int init(); + void need_sorted_output() { DBUG_ASSERT(0); /* Can't do it */ } int reset(void); int get_next(); bool reverse_sorted() { return false; } @@ -811,6 +847,7 @@ public: void adjust_prefix_ranges(); bool alloc_buffers(); int init(); + void need_sorted_output() { /* always do it */ } int reset(); int get_next(); bool reverse_sorted() { return false; } @@ -826,7 +863,8 @@ public: class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT { public: - QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts); + QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts, + bool *create_err); int get_next(); bool reverse_sorted() { return 1; } int get_type() { return QS_TYPE_RANGE_DESC; } @@ -843,6 +881,13 @@ class SQL_SELECT :public Sql_alloc { public: QUICK_SELECT_I *quick; // If quick-select used COND *cond; // where condition + + /* + When using Index Condition Pushdown: condition that we've had before + extracting and pushing index condition. + In other cases, NULL. + */ + Item *pre_idx_push_select_cond; TABLE *head; IO_CACHE file; // Positions to used records ha_rows records; // Records in use if read from file @@ -859,7 +904,7 @@ class SQL_SELECT :public Sql_alloc { { key_map tmp; tmp.set_all(); - return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0; + return test_quick_select(thd, tmp, 0, limit, force_quick_range, FALSE) < 0; } /* RETURN @@ -875,21 +920,25 @@ class SQL_SELECT :public Sql_alloc { return rc; } int test_quick_select(THD *thd, key_map keys, table_map prev_tables, - ha_rows limit, bool force_quick_range); + ha_rows limit, bool force_quick_range, + bool ordered_output); }; -class FT_SELECT: public QUICK_RANGE_SELECT { +class FT_SELECT: public QUICK_RANGE_SELECT +{ public: - FT_SELECT(THD *thd, TABLE *table, uint key) : - QUICK_RANGE_SELECT (thd, table, key, 1) { VOID(init()); } + FT_SELECT(THD *thd, TABLE *table, uint key, bool *create_err) : + QUICK_RANGE_SELECT (thd, table, key, 1, NULL, create_err) + { (void) init(); } ~FT_SELECT() { file->ft_end(); } - int init() { return error=file->ft_init(); } + int init() { return file->ft_init(); } int reset() { return 0; } - int get_next() { return error= file->ha_ft_read(record); } + int get_next() { return file->ha_ft_read(record); } int get_type() { return QS_TYPE_FULLTEXT; } }; +FT_SELECT *get_ft_select(THD *thd, TABLE *table, uint key); QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, struct st_table_ref *ref, ha_rows records); |