110
class QuickSelectInterface
114
ha_rows records; /**< estimate of # of records to be retrieved */
115
double read_time; /**< time to perform this retrieval */
122
ha_rows records; /* estimate of # of records to be retrieved */
123
double read_time; /* time to perform this retrieval */
118
126
Index this quick select uses, or MAX_KEY for quick selects
119
127
that use several indexes
123
132
Total length of first used_key_parts parts of the key.
124
133
Applicable if index!= MAX_KEY.
126
uint32_t max_used_key_length;
128
Maximum number of (first) key parts this quick select uses for retrieval.
135
uint max_used_key_length;
138
Max. number of (first) key parts this quick select uses for retrieval.
129
139
eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
130
140
Applicable if index!= MAX_KEY.
132
142
For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
134
uint32_t used_key_parts;
136
* The rowid of last row retrieved by this quick select. This is used only when
137
* doing ROR-index_merge selects
139
unsigned char *last_rowid;
142
* Table record buffer used by this quick select.
144
unsigned char *record;
146
QuickSelectInterface();
147
virtual ~QuickSelectInterface(){};
150
* Do post-constructor initialization.
154
* Performs initializations that should have been in constructor if
155
* it was possible to return errors from constructors. The join optimizer may
156
* create and then delete quick selects without retrieving any rows so init()
157
* must not contain any IO or CPU intensive code.
159
* If init() call fails the only valid action is to delete this quick select,
160
* reset() and get_next() must not be called.
167
virtual int init() = 0;
170
* Initializes quick select for row retrieval.
174
* Should be called when it is certain that row retrieval will be
175
* necessary. This call may do heavyweight initialization like buffering first
176
* N records etc. If reset() call fails get_next() must not be called.
177
* Note that reset() may be called several times if
178
* - the quick select is executed in a subselect
179
* - a JOIN buffer is used
186
virtual int reset(void) = 0;
187
/** Gets next record to retrieve */
188
virtual int get_next() = 0;
190
/** Range end should be called when we have looped over the whole index */
147
virtual ~QUICK_SELECT_I(){};
150
Do post-constructor initialization.
154
init() performs initializations that should have been in constructor if
155
it was possible to return errors from constructors. The join optimizer may
156
create and then delete quick selects without retrieving any rows so init()
157
must not contain any IO or CPU intensive code.
159
If init() call fails the only valid action is to delete this quick select,
160
reset() and get_next() must not be called.
166
virtual int init() = 0;
169
Initialize quick select for row retrieval.
173
reset() should be called when it is certain that row retrieval will be
174
necessary. This call may do heavyweight initialization like buffering first
175
N records etc. If reset() call fails get_next() must not be called.
176
Note that reset() may be called several times if
177
* the quick select is executed in a subselect
178
* a JOIN buffer is used
184
virtual int reset(void) = 0;
186
virtual int get_next() = 0; /* get next record to retrieve */
188
/* Range end should be called when we have looped over the whole index */
191
189
virtual void range_end() {}
193
virtual bool reverse_sorted() const = 0;
195
virtual bool unique_key_range() const
203
QS_TYPE_INDEX_MERGE= 1,
204
QS_TYPE_RANGE_DESC= 2,
205
QS_TYPE_ROR_INTERSECT= 4,
206
QS_TYPE_ROR_UNION= 5,
207
QS_TYPE_GROUP_MIN_MAX= 6
191
virtual bool reverse_sorted() = 0;
192
virtual bool unique_key_range() { return false; }
196
QS_TYPE_INDEX_MERGE = 1,
197
QS_TYPE_RANGE_DESC = 2,
198
QS_TYPE_ROR_INTERSECT = 4,
199
QS_TYPE_ROR_UNION = 5,
200
QS_TYPE_GROUP_MIN_MAX = 6
210
/** Returns the type of this quick select - one of the QS_TYPE_* values */
211
virtual int get_type() const = 0;
214
* Initialize this quick select as a merged scan inside a ROR-union or a ROR-
215
* intersection scan. The caller must not additionally call init() if this
216
* function is called.
218
* @param If true, the quick select may use table->Cursor,
219
* otherwise it must create and use a separate Cursor
227
virtual int init_ror_merged_scan(bool)
234
* Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
203
/* Get type of this quick select - one of the QS_TYPE_* values */
204
virtual int get_type() = 0;
207
Initialize this quick select as a merged scan inside a ROR-union or a ROR-
208
intersection scan. The caller must not additionally call init() if this
211
init_ror_merged_scan()
212
reuse_handler If true, the quick select may use table->handler,
213
otherwise it must create and use a separate handler
219
virtual int init_ror_merged_scan(bool reuse_handler __attribute__((unused)))
220
{ assert(0); return 1; }
223
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
236
225
virtual void save_last_pos(){};
239
* Append comma-separated list of keys this quick select uses to key_names;
240
* append comma-separated list of corresponding used lengths to used_lengths.
242
* @note This is used by during explain plan.
244
virtual void add_keys_and_lengths(std::string *key_names,
245
std::string *used_lengths)=0;
248
* Append text representation of quick select structure (what and how is
249
* merged) to str. The result is added to "Extra" field in EXPLAIN output.
253
* This function is implemented only by quick selects that merge other quick
254
* selects output and/or can produce output suitable for merging.
256
virtual void add_info_string(std::string *)
260
* Returns true if any index used by this quick select
261
* uses field which is marked in passed bitmap.
263
virtual bool is_keys_used(const boost::dynamic_bitset<>& fields);
228
Append comma-separated list of keys this quick select uses to key_names;
229
append comma-separated list of corresponding used lengths to used_lengths.
230
This is used by select_describe.
232
virtual void add_keys_and_lengths(String *key_names,
233
String *used_lengths)=0;
236
Append text representation of quick select structure (what and how is
237
merged) to str. The result is added to "Extra" field in EXPLAIN output.
238
This function is implemented only by quick selects that merge other quick
239
selects output and/or can produce output suitable for merging.
241
virtual void add_info_string(String *str __attribute__((unused))) {};
243
Return 1 if any index used by this quick select
244
uses field which is marked in passed bitmap.
246
virtual bool is_keys_used(const MY_BITMAP *fields);
249
rowid of last row retrieved by this quick select. This is used only when
250
doing ROR-index_merge selects
255
Table record buffer used by this quick select.
266
261
struct st_qsel_param;
268
class QuickRangeSelect;
271
* MRR range sequence, array<QuickRange> implementation: sequence traversal
267
MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
274
270
typedef struct st_quick_range_seq_ctx
279
} QuickRangeSequenceContext;
281
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
283
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
286
* Executor class for SELECT statements.
290
* The QuickSelectInterface member variable is the implementor
291
* of the SELECT execution.
293
class SqlSelect : public memory::SqlAlloc
275
} QUICK_RANGE_SEQ_CTX;
277
range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags);
278
uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
282
Quick select that does a range scan on a single key. The records are
283
returned in key order.
285
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
289
DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
291
/* Members to deal with case when this quick select is a ROR-merged scan */
292
bool in_ror_merged_scan;
293
MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
294
bool free_file; /* TRUE <=> this->file is "owned" by this quick select */
296
/* Range pointers to be used when not using MRR interface */
297
QUICK_RANGE **cur_range; /* current element in ranges */
298
QUICK_RANGE *last_range;
300
/* Members needed to use the MRR interface */
301
QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
303
uint mrr_flags; /* Flags to be used with MRR interface */
305
uint mrr_buf_size; /* copy from thd->variables.read_rnd_buff_size */
306
HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
308
/* Info about index we're scanning */
310
KEY_PART_INFO *key_part_info;
312
bool dont_free; /* Used by QUICK_SELECT_DESC */
314
int cmp_next(QUICK_RANGE *range);
315
int cmp_prev(QUICK_RANGE *range);
316
bool row_in_ranges();
320
QUICK_RANGE_SELECT(THD *thd, Table *table,uint index_arg,bool no_alloc,
321
MEM_ROOT *parent_alloc, bool *create_err);
322
~QUICK_RANGE_SELECT();
328
int get_next_prefix(uint prefix_length, key_part_map keypart_map,
330
bool reverse_sorted() { return 0; }
331
bool unique_key_range();
332
int init_ror_merged_scan(bool reuse_handler);
334
{ file->position(record); }
335
int get_type() { return QS_TYPE_RANGE; }
336
void add_keys_and_lengths(String *key_names, String *used_lengths);
337
void add_info_string(String *str);
339
/* Used only by QUICK_SELECT_DESC */
340
QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
342
memmove(this, &org, sizeof(*this));
344
Use default MRR implementation for reverse scans. No table engine
345
currently can do an MRR scan with output in reverse index order.
348
mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
351
friend class TRP_ROR_INTERSECT;
353
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
354
struct st_table_ref *ref,
356
friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
357
KEY_PART *key, SEL_ARG *key_tree,
358
uchar *min_key, uint min_key_flag,
359
uchar *max_key, uint max_key_flag);
360
friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx,
365
friend class QUICK_SELECT_DESC;
366
friend class QUICK_INDEX_MERGE_SELECT;
367
friend class QUICK_ROR_INTERSECT_SELECT;
368
friend class QUICK_GROUP_MIN_MAX_SELECT;
369
friend uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
370
friend range_seq_t quick_range_seq_init(void *init_param,
371
uint n_ranges, uint flags);
372
friend void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
373
bool distinct,const char *message);
378
QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
380
QUICK_INDEX_MERGE_SELECT uses
381
* QUICK_RANGE_SELECTs to get rows
382
* Unique class to remove duplicate rows
384
INDEX MERGE OPTIMIZER
385
Current implementation doesn't detect all cases where index_merge could
386
be used, in particular:
387
* index_merge will never be used if range scan is possible (even if
388
range scan is more expensive)
390
* index_merge+'using index' is not supported (this the consequence of
391
the above restriction)
393
* If WHERE part contains complex nested AND and OR conditions, some ways
394
to retrieve rows using index_merge will not be considered. The choice
395
of read plan may depend on the order of conjuncts/disjuncts in WHERE
396
part of the query, see comments near imerge_list_or_list and
397
SEL_IMERGE::or_sel_tree_with_checks functions for details.
399
* There is no "index_merge_ref" method (but index_merge on non-first
400
table in join is possible with 'range checked for each record').
402
See comments around SEL_IMERGE class and test_quick_select for more
405
ROW RETRIEVAL ALGORITHM
407
index_merge uses Unique class for duplicates removal. index_merge takes
408
advantage of Clustered Primary Key (CPK) if the table has one.
409
The index_merge algorithm consists of two phases:
411
Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
414
activate 'index only';
415
while(retrieve next row for non-CPK scan)
417
if (there is a CPK scan and row will be retrieved by it)
420
put its rowid into Unique;
422
deactivate 'index only';
425
Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
430
retrieve all rows from row pointers stored in Unique;
432
retrieve all rows for CPK scan;
436
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
439
QUICK_INDEX_MERGE_SELECT(THD *thd, Table *table);
440
~QUICK_INDEX_MERGE_SELECT();
445
bool reverse_sorted() { return false; }
446
bool unique_key_range() { return false; }
447
int get_type() { return QS_TYPE_INDEX_MERGE; }
448
void add_keys_and_lengths(String *key_names, String *used_lengths);
449
void add_info_string(String *str);
450
bool is_keys_used(const MY_BITMAP *fields);
452
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
454
/* range quick selects this index_merge read consists of */
455
List<QUICK_RANGE_SELECT> quick_selects;
457
/* quick select that uses clustered primary key (NULL if none) */
458
QUICK_RANGE_SELECT* pk_quick_select;
460
/* true if this select is currently doing a clustered PK scan */
465
int read_keys_and_merge();
467
/* used to get rows collected in Unique */
468
READ_RECORD read_record;
473
Rowid-Ordered Retrieval (ROR) index intersection quick select.
474
This quick select produces intersection of row sequences returned
475
by several QUICK_RANGE_SELECTs it "merges".
477
All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
478
QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
480
All merged quick selects retrieve {rowid, covered_fields} tuples (not full
482
QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
483
by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
484
cover needed all fields.
486
If one of the merged quick selects is a Clustered PK range scan, it is
487
used only to filter rowid sequence produced by other merged quick selects.
490
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
493
QUICK_ROR_INTERSECT_SELECT(THD *thd, Table *table,
494
bool retrieve_full_rows,
495
MEM_ROOT *parent_alloc);
496
~QUICK_ROR_INTERSECT_SELECT();
501
bool reverse_sorted() { return false; }
502
bool unique_key_range() { return false; }
503
int get_type() { return QS_TYPE_ROR_INTERSECT; }
504
void add_keys_and_lengths(String *key_names, String *used_lengths);
505
void add_info_string(String *str);
506
bool is_keys_used(const MY_BITMAP *fields);
507
int init_ror_merged_scan(bool reuse_handler);
508
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
511
Range quick selects this intersection consists of, not including
514
List<QUICK_RANGE_SELECT> quick_selects;
517
Merged quick select that uses Clustered PK, if there is one. This quick
518
select is not used for row retrieval, it is used for row retrieval.
520
QUICK_RANGE_SELECT *cpk_quick;
522
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
523
THD *thd; /* current thread */
524
bool need_to_fetch_row; /* if true, do retrieve full table records. */
525
/* in top-level quick select, true if merged scans where initialized */
531
Rowid-Ordered Retrieval index union select.
532
This quick select produces union of row sequences returned by several
533
quick select it "merges".
535
All merged quick selects must return rowids in rowid order.
536
QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
538
All merged quick selects are set not to retrieve full table records.
539
ROR-union quick select always retrieves full records.
543
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
546
QUICK_ROR_UNION_SELECT(THD *thd, Table *table);
547
~QUICK_ROR_UNION_SELECT();
552
bool reverse_sorted() { return false; }
553
bool unique_key_range() { return false; }
554
int get_type() { return QS_TYPE_ROR_UNION; }
555
void add_keys_and_lengths(String *key_names, String *used_lengths);
556
void add_info_string(String *str);
557
bool is_keys_used(const MY_BITMAP *fields);
559
bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
561
List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
563
QUEUE queue; /* Priority queue for merge operation */
564
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
566
THD *thd; /* current thread */
567
uchar *cur_rowid; /* buffer used in get_next() */
568
uchar *prev_rowid; /* rowid of last row returned by get_next() */
569
bool have_prev_rowid; /* true if prev_rowid has valid data */
570
uint rowid_length; /* table rowid length */
572
static int queue_cmp(void *arg, uchar *val1, uchar *val2);
578
Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
580
This class provides a specialized index access method for GROUP-BY queries
583
SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
585
WHERE [RNG(A_1,...,A_p ; where p <= k)]
586
[AND EQ(B_1,...,B_m)]
588
[AND PA(A_i1,...,A_iq)]
589
GROUP BY A_1,...,A_k;
593
SELECT DISTINCT A_i1,...,A_ik
595
WHERE [RNG(A_1,...,A_p ; where p <= k)]
596
[AND PA(A_i1,...,A_iq)];
598
where all selected fields are parts of the same index.
599
The class of queries that can be processed by this quick select is fully
600
specified in the description of get_best_trp_group_min_max() in opt_range.cc.
602
The get_next() method directly produces result tuples, thus obviating the
603
need to call end_send_group() because all grouping is already done inside
606
Since one of the requirements is that all select fields are part of the same
607
index, this class produces only index keys, and not complete records.
610
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
613
handler *file; /* The handler used to get data. */
614
JOIN *join; /* Descriptor of the current query */
615
KEY *index_info; /* The index chosen for data access */
616
uchar *record; /* Buffer where the next record is returned. */
617
uchar *tmp_record; /* Temporary storage for next_min(), next_max(). */
618
uchar *group_prefix; /* Key prefix consisting of the GROUP fields. */
619
uint group_prefix_len; /* Length of the group prefix. */
620
uint group_key_parts; /* A number of keyparts in the group prefix */
621
uchar *last_prefix; /* Prefix of the last group for detecting EOF. */
622
bool have_min; /* Specify whether we are computing */
623
bool have_max; /* a MIN, a MAX, or both. */
624
bool seen_first_key; /* Denotes whether the first key was retrieved.*/
625
KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
626
/* of all MIN/MAX functions. */
627
uint min_max_arg_len; /* The length of the MIN/MAX argument field */
628
uchar *key_infix; /* Infix of constants from equality predicates. */
630
DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
631
uint real_prefix_len; /* Length of key prefix extended with key_infix. */
632
uint real_key_parts; /* A number of keyparts in the above value. */
633
List<Item_sum> *min_functions;
634
List<Item_sum> *max_functions;
635
List_iterator<Item_sum> *min_functions_it;
636
List_iterator<Item_sum> *max_functions_it;
639
The following two members are public to allow easy access from
640
TRP_GROUP_MIN_MAX::make_quick()
642
MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
643
QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
646
int next_min_in_range();
647
int next_max_in_range();
650
void update_min_result();
651
void update_max_result();
653
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join, bool have_min,
654
bool have_max, KEY_PART_INFO *min_max_arg_part,
655
uint group_prefix_len, uint group_key_parts,
656
uint used_key_parts, KEY *index_info, uint
657
use_index, double read_cost, ha_rows records, uint
658
key_infix_len, uchar *key_infix, MEM_ROOT
660
~QUICK_GROUP_MIN_MAX_SELECT();
661
bool add_range(SEL_ARG *sel_range);
662
void update_key_stat();
663
void adjust_prefix_ranges();
664
bool alloc_buffers();
668
bool reverse_sorted() { return false; }
669
bool unique_key_range() { return false; }
670
int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
671
void add_keys_and_lengths(String *key_names, String *used_lengths);
675
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
678
QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts,
681
bool reverse_sorted() { return 1; }
682
int get_type() { return QS_TYPE_RANGE_DESC; }
684
bool range_reads_after_key(QUICK_RANGE *range);
686
bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
688
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
689
List<QUICK_RANGE> rev_ranges;
690
List_iterator<QUICK_RANGE> rev_it;
694
class SQL_SELECT :public Sql_alloc {
296
QuickSelectInterface *quick; /**< If quick-select used */
297
COND *cond; /**< where condition */
696
QUICK_SELECT_I *quick; // If quick-select used
697
COND *cond; // where condition
299
internal::IO_CACHE *file; /**< Positions to used records */
300
ha_rows records; /**< Records in use if read from file */
301
double read_time; /**< Time to read rows */
302
key_map quick_keys; /**< Possible quick keys */
303
key_map needed_reg; /**< Possible quick keys after prev tables. */
304
table_map const_tables;
305
table_map read_tables;
699
IO_CACHE file; // Positions to used records
700
ha_rows records; // Records in use if read from file
701
double read_time; // Time to read rows
702
key_map quick_keys; // Possible quick keys
703
key_map needed_reg; // Possible quick keys after prev tables.
704
table_map const_tables,read_tables;
311
bool check_quick(Session *session, bool force_quick_range, ha_rows limit);
313
int test_quick_select(Session *session, key_map keys, table_map prev_tables,
314
ha_rows limit, bool force_quick_range,
710
bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
714
return test_quick_select(thd, tmp, 0, limit, force_quick_range, false) < 0;
716
inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; }
717
int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
718
ha_rows limit, bool force_quick_range,
315
719
bool ordered_output);
318
QuickRangeSelect *get_quick_select_for_ref(Session *session,
320
table_reference_st *ref,
324
Create a QuickRangeSelect from given key and SEL_ARG tree for that key.
329
idx Index of used key in param->key.
330
key_tree SEL_ARG tree for the used key
331
mrr_flags MRR parameter for quick select
332
mrr_buf_size MRR parameter for quick select
333
parent_alloc If not NULL, use it to allocate memory for
334
quick select data. Otherwise use quick->alloc.
336
The caller must call QUICK_SELECT::init for returned quick select.
338
CAUTION! This function may change session->mem_root to a memory::Root which will be
339
deallocated when the returned quick select is deleted.
343
otherwise created quick select
345
QuickRangeSelect *get_quick_select(Parameter *param,
349
uint32_t mrr_buf_size,
350
memory::Root *alloc);
352
uint32_t get_index_for_order(Table *table, Order *order, ha_rows limit);
354
SqlSelect *make_select(Table *head,
355
table_map const_tables,
356
table_map read_tables,
358
bool allow_null_cond,
361
bool get_quick_keys(Parameter *param,
362
QuickRangeSelect *quick,
365
unsigned char *min_key,
366
uint32_t min_key_flag,
367
unsigned char *max_key,
368
uint32_t max_key_flag);
370
} /* namespace optimizer */
372
} /* namespace drizzled */
374
#endif /* DRIZZLED_OPTIMIZER_RANGE_H */
722
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
723
struct st_table_ref *ref,
725
uint get_index_for_order(Table *table, order_st *order, ha_rows limit);