109
class QuickSelectInterface
113
ha_rows records; /**< estimate of # of records to be retrieved */
114
double read_time; /**< time to perform this retrieval */
120
ha_rows records; /* estimate of # of records to be retrieved */
121
double read_time; /* time to perform this retrieval */
117
124
Index this quick select uses, or MAX_KEY for quick selects
118
125
that use several indexes
122
130
Total length of first used_key_parts parts of the key.
123
131
Applicable if index!= MAX_KEY.
125
133
uint32_t max_used_key_length;
127
Maximum number of (first) key parts this quick select uses for retrieval.
136
Max. number of (first) key parts this quick select uses for retrieval.
128
137
eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
129
138
Applicable if index!= MAX_KEY.
131
140
For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
133
142
uint32_t used_key_parts;
135
* The rowid of last row retrieved by this quick select. This is used only when
136
* doing ROR-index_merge selects
138
unsigned char *last_rowid;
141
* Table record buffer used by this quick select.
143
unsigned char *record;
145
QuickSelectInterface();
146
virtual ~QuickSelectInterface(){};
149
* Do post-constructor initialization.
153
* Performs initializations that should have been in constructor if
154
* it was possible to return errors from constructors. The join optimizer may
155
* create and then delete quick selects without retrieving any rows so init()
156
* must not contain any IO or CPU intensive code.
158
* If init() call fails the only valid action is to delete this quick select,
159
* reset() and get_next() must not be called.
166
virtual int init() = 0;
169
* Initializes quick select for row retrieval.
173
* 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
185
virtual int reset(void) = 0;
186
/** Gets next record to retrieve */
187
virtual int get_next() = 0;
189
/** Range end should be called when we have looped over the whole index */
145
virtual ~QUICK_SELECT_I(){};
148
Do post-constructor initialization.
152
init() performs initializations that should have been in constructor if
153
it was possible to return errors from constructors. The join optimizer may
154
create and then delete quick selects without retrieving any rows so init()
155
must not contain any IO or CPU intensive code.
157
If init() call fails the only valid action is to delete this quick select,
158
reset() and get_next() must not be called.
164
virtual int init() = 0;
167
Initialize quick select for row retrieval.
171
reset() should be called when it is certain that row retrieval will be
172
necessary. This call may do heavyweight initialization like buffering first
173
N records etc. If reset() call fails get_next() must not be called.
174
Note that reset() may be called several times if
175
* the quick select is executed in a subselect
176
* a JOIN buffer is used
182
virtual int reset(void) = 0;
184
virtual int get_next() = 0; /* get next record to retrieve */
186
/* Range end should be called when we have looped over the whole index */
190
187
virtual void range_end() {}
192
virtual bool reverse_sorted() const = 0;
194
virtual bool unique_key_range() const
202
QS_TYPE_INDEX_MERGE= 1,
203
QS_TYPE_RANGE_DESC= 2,
204
QS_TYPE_ROR_INTERSECT= 4,
205
QS_TYPE_ROR_UNION= 5,
206
QS_TYPE_GROUP_MIN_MAX= 6
189
virtual bool reverse_sorted() = 0;
190
virtual bool unique_key_range() { return false; }
194
QS_TYPE_INDEX_MERGE = 1,
195
QS_TYPE_RANGE_DESC = 2,
196
QS_TYPE_ROR_INTERSECT = 4,
197
QS_TYPE_ROR_UNION = 5,
198
QS_TYPE_GROUP_MIN_MAX = 6
209
/** Returns the type of this quick select - one of the QS_TYPE_* values */
210
virtual int get_type() const = 0;
201
/* Get type of this quick select - one of the QS_TYPE_* values */
202
virtual int get_type() = 0;
213
* Initialize this quick select as a merged scan inside a ROR-union or a ROR-
214
* intersection scan. The caller must not additionally call init() if this
215
* function is called.
217
* @param If true, the quick select may use table->Cursor,
218
* otherwise it must create and use a separate Cursor
205
Initialize this quick select as a merged scan inside a ROR-union or a ROR-
206
intersection scan. The caller must not additionally call init() if this
209
init_ror_merged_scan()
210
reuse_handler If true, the quick select may use table->handler,
211
otherwise it must create and use a separate handler
226
217
virtual int init_ror_merged_scan(bool)
218
{ assert(0); return 1; }
233
* Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
221
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
235
223
virtual void save_last_pos(){};
238
* Append comma-separated list of keys this quick select uses to key_names;
239
* append comma-separated list of corresponding used lengths to used_lengths.
241
* @note This is used by during explain plan.
243
virtual void add_keys_and_lengths(String *key_names, String *used_lengths)=0;
246
* Append text representation of quick select structure (what and how is
247
* merged) to str. The result is added to "Extra" field in EXPLAIN output.
251
* This function is implemented only by quick selects that merge other quick
252
* selects output and/or can produce output suitable for merging.
254
virtual void add_info_string(String *)
258
* Returns true if any index used by this quick select
259
* uses field which is marked in passed bitmap.
261
virtual bool is_keys_used(const MyBitmap *fields);
226
Append comma-separated list of keys this quick select uses to key_names;
227
append comma-separated list of corresponding used lengths to used_lengths.
228
This is used by select_describe.
230
virtual void add_keys_and_lengths(String *key_names,
231
String *used_lengths)=0;
234
Append text representation of quick select structure (what and how is
235
merged) to str. The result is added to "Extra" field in EXPLAIN output.
236
This function is implemented only by quick selects that merge other quick
237
selects output and/or can produce output suitable for merging.
239
virtual void add_info_string(String *) {};
241
Return 1 if any index used by this quick select
242
uses field which is marked in passed bitmap.
244
virtual bool is_keys_used(const MY_BITMAP *fields);
247
rowid of last row retrieved by this quick select. This is used only when
248
doing ROR-index_merge selects
250
unsigned char *last_rowid;
253
Table record buffer used by this quick select.
255
unsigned char *record;
264
259
struct st_qsel_param;
266
class QuickRangeSelect;
269
* MRR range sequence, array<QuickRange> implementation: sequence traversal
265
MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
272
268
typedef struct st_quick_range_seq_ctx
277
} QuickRangeSequenceContext;
273
} QUICK_RANGE_SEQ_CTX;
279
275
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
281
276
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
284
* Executor class for SELECT statements.
288
* The QuickSelectInterface member variable is the implementor
289
* of the SELECT execution.
291
class SqlSelect : public memory::SqlAlloc
280
Quick select that does a range scan on a single key. The records are
281
returned in key order.
283
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
287
DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
289
/* Members to deal with case when this quick select is a ROR-merged scan */
290
bool in_ror_merged_scan;
291
MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
292
bool free_file; /* TRUE <=> this->file is "owned" by this quick select */
294
/* Range pointers to be used when not using MRR interface */
295
QUICK_RANGE **cur_range; /* current element in ranges */
296
QUICK_RANGE *last_range;
298
/* Members needed to use the MRR interface */
299
QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
301
uint32_t mrr_flags; /* Flags to be used with MRR interface */
303
uint32_t mrr_buf_size; /* copy from session->variables.read_rnd_buff_size */
304
HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
306
/* Info about index we're scanning */
308
KEY_PART_INFO *key_part_info;
310
bool dont_free; /* Used by QUICK_SELECT_DESC */
312
int cmp_next(QUICK_RANGE *range);
313
int cmp_prev(QUICK_RANGE *range);
314
bool row_in_ranges();
318
QUICK_RANGE_SELECT(Session *session, Table *table,uint32_t index_arg,bool no_alloc,
319
MEM_ROOT *parent_alloc, bool *create_err);
320
~QUICK_RANGE_SELECT();
326
int get_next_prefix(uint32_t prefix_length, key_part_map keypart_map,
327
unsigned char *cur_prefix);
328
bool reverse_sorted() { return 0; }
329
bool unique_key_range();
330
int init_ror_merged_scan(bool reuse_handler);
332
{ file->position(record); }
333
int get_type() { return QS_TYPE_RANGE; }
334
void add_keys_and_lengths(String *key_names, String *used_lengths);
335
void add_info_string(String *str);
337
/* Used only by QUICK_SELECT_DESC */
338
QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
340
memmove(this, &org, sizeof(*this));
342
Use default MRR implementation for reverse scans. No table engine
343
currently can do an MRR scan with output in reverse index order.
346
mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
349
friend class TRP_ROR_INTERSECT;
351
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
352
struct st_table_ref *ref,
354
friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
355
KEY_PART *key, SEL_ARG *key_tree,
356
unsigned char *min_key, uint32_t min_key_flag,
357
unsigned char *max_key, uint32_t max_key_flag);
358
friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint32_t idx,
361
uint32_t mrr_buf_size,
363
friend class QUICK_SELECT_DESC;
364
friend class QUICK_INDEX_MERGE_SELECT;
365
friend class QUICK_ROR_INTERSECT_SELECT;
366
friend class QUICK_GROUP_MIN_MAX_SELECT;
367
friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
368
friend range_seq_t quick_range_seq_init(void *init_param,
369
uint32_t n_ranges, uint32_t flags);
370
friend void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
371
bool distinct,const char *message);
376
QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
378
QUICK_INDEX_MERGE_SELECT uses
379
* QUICK_RANGE_SELECTs to get rows
380
* Unique class to remove duplicate rows
382
INDEX MERGE OPTIMIZER
383
Current implementation doesn't detect all cases where index_merge could
384
be used, in particular:
385
* index_merge will never be used if range scan is possible (even if
386
range scan is more expensive)
388
* index_merge+'using index' is not supported (this the consequence of
389
the above restriction)
391
* If WHERE part contains complex nested AND and OR conditions, some ways
392
to retrieve rows using index_merge will not be considered. The choice
393
of read plan may depend on the order of conjuncts/disjuncts in WHERE
394
part of the query, see comments near imerge_list_or_list and
395
SEL_IMERGE::or_sel_tree_with_checks functions for details.
397
* There is no "index_merge_ref" method (but index_merge on non-first
398
table in join is possible with 'range checked for each record').
400
See comments around SEL_IMERGE class and test_quick_select for more
403
ROW RETRIEVAL ALGORITHM
405
index_merge uses Unique class for duplicates removal. index_merge takes
406
advantage of Clustered Primary Key (CPK) if the table has one.
407
The index_merge algorithm consists of two phases:
409
Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
412
activate 'index only';
413
while(retrieve next row for non-CPK scan)
415
if (there is a CPK scan and row will be retrieved by it)
418
put its rowid into Unique;
420
deactivate 'index only';
423
Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
428
retrieve all rows from row pointers stored in Unique;
430
retrieve all rows for CPK scan;
434
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
437
QUICK_INDEX_MERGE_SELECT(Session *session, Table *table);
438
~QUICK_INDEX_MERGE_SELECT();
443
bool reverse_sorted() { return false; }
444
bool unique_key_range() { return false; }
445
int get_type() { return QS_TYPE_INDEX_MERGE; }
446
void add_keys_and_lengths(String *key_names, String *used_lengths);
447
void add_info_string(String *str);
448
bool is_keys_used(const MY_BITMAP *fields);
450
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
452
/* range quick selects this index_merge read consists of */
453
List<QUICK_RANGE_SELECT> quick_selects;
455
/* quick select that uses clustered primary key (NULL if none) */
456
QUICK_RANGE_SELECT* pk_quick_select;
458
/* true if this select is currently doing a clustered PK scan */
463
int read_keys_and_merge();
465
/* used to get rows collected in Unique */
466
READ_RECORD read_record;
471
Rowid-Ordered Retrieval (ROR) index intersection quick select.
472
This quick select produces intersection of row sequences returned
473
by several QUICK_RANGE_SELECTs it "merges".
475
All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
476
QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
478
All merged quick selects retrieve {rowid, covered_fields} tuples (not full
480
QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
481
by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
482
cover needed all fields.
484
If one of the merged quick selects is a Clustered PK range scan, it is
485
used only to filter rowid sequence produced by other merged quick selects.
488
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
491
QUICK_ROR_INTERSECT_SELECT(Session *session, Table *table,
492
bool retrieve_full_rows,
493
MEM_ROOT *parent_alloc);
494
~QUICK_ROR_INTERSECT_SELECT();
499
bool reverse_sorted() { return false; }
500
bool unique_key_range() { return false; }
501
int get_type() { return QS_TYPE_ROR_INTERSECT; }
502
void add_keys_and_lengths(String *key_names, String *used_lengths);
503
void add_info_string(String *str);
504
bool is_keys_used(const MY_BITMAP *fields);
505
int init_ror_merged_scan(bool reuse_handler);
506
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
509
Range quick selects this intersection consists of, not including
512
List<QUICK_RANGE_SELECT> quick_selects;
515
Merged quick select that uses Clustered PK, if there is one. This quick
516
select is not used for row retrieval, it is used for row retrieval.
518
QUICK_RANGE_SELECT *cpk_quick;
520
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
521
Session *session; /* current thread */
522
bool need_to_fetch_row; /* if true, do retrieve full table records. */
523
/* in top-level quick select, true if merged scans where initialized */
529
Rowid-Ordered Retrieval index union select.
530
This quick select produces union of row sequences returned by several
531
quick select it "merges".
533
All merged quick selects must return rowids in rowid order.
534
QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
536
All merged quick selects are set not to retrieve full table records.
537
ROR-union quick select always retrieves full records.
541
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
544
QUICK_ROR_UNION_SELECT(Session *session, Table *table);
545
~QUICK_ROR_UNION_SELECT();
550
bool reverse_sorted() { return false; }
551
bool unique_key_range() { return false; }
552
int get_type() { return QS_TYPE_ROR_UNION; }
553
void add_keys_and_lengths(String *key_names, String *used_lengths);
554
void add_info_string(String *str);
555
bool is_keys_used(const MY_BITMAP *fields);
557
bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
559
List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
561
QUEUE queue; /* Priority queue for merge operation */
562
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
564
Session *session; /* current thread */
565
unsigned char *cur_rowid; /* buffer used in get_next() */
566
unsigned char *prev_rowid; /* rowid of last row returned by get_next() */
567
bool have_prev_rowid; /* true if prev_rowid has valid data */
568
uint32_t rowid_length; /* table rowid length */
570
static int queue_cmp(void *arg, unsigned char *val1, unsigned char *val2);
576
Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
578
This class provides a specialized index access method for GROUP-BY queries
581
SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
583
WHERE [RNG(A_1,...,A_p ; where p <= k)]
584
[AND EQ(B_1,...,B_m)]
586
[AND PA(A_i1,...,A_iq)]
587
GROUP BY A_1,...,A_k;
591
SELECT DISTINCT A_i1,...,A_ik
593
WHERE [RNG(A_1,...,A_p ; where p <= k)]
594
[AND PA(A_i1,...,A_iq)];
596
where all selected fields are parts of the same index.
597
The class of queries that can be processed by this quick select is fully
598
specified in the description of get_best_trp_group_min_max() in opt_range.cc.
600
The get_next() method directly produces result tuples, thus obviating the
601
need to call end_send_group() because all grouping is already done inside
604
Since one of the requirements is that all select fields are part of the same
605
index, this class produces only index keys, and not complete records.
608
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
611
handler *file; /* The handler used to get data. */
612
JOIN *join; /* Descriptor of the current query */
613
KEY *index_info; /* The index chosen for data access */
614
unsigned char *record; /* Buffer where the next record is returned. */
615
unsigned char *tmp_record; /* Temporary storage for next_min(), next_max(). */
616
unsigned char *group_prefix; /* Key prefix consisting of the GROUP fields. */
617
uint32_t group_prefix_len; /* Length of the group prefix. */
618
uint32_t group_key_parts; /* A number of keyparts in the group prefix */
619
unsigned char *last_prefix; /* Prefix of the last group for detecting EOF. */
620
bool have_min; /* Specify whether we are computing */
621
bool have_max; /* a MIN, a MAX, or both. */
622
bool seen_first_key; /* Denotes whether the first key was retrieved.*/
623
KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
624
/* of all MIN/MAX functions. */
625
uint32_t min_max_arg_len; /* The length of the MIN/MAX argument field */
626
unsigned char *key_infix; /* Infix of constants from equality predicates. */
627
uint32_t key_infix_len;
628
DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
629
uint32_t real_prefix_len; /* Length of key prefix extended with key_infix. */
630
uint32_t real_key_parts; /* A number of keyparts in the above value. */
631
List<Item_sum> *min_functions;
632
List<Item_sum> *max_functions;
633
List_iterator<Item_sum> *min_functions_it;
634
List_iterator<Item_sum> *max_functions_it;
637
The following two members are public to allow easy access from
638
TRP_GROUP_MIN_MAX::make_quick()
640
MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
641
QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
644
int next_min_in_range();
645
int next_max_in_range();
648
void update_min_result();
649
void update_max_result();
651
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join, bool have_min,
652
bool have_max, KEY_PART_INFO *min_max_arg_part,
653
uint32_t group_prefix_len, uint32_t group_key_parts,
654
uint32_t used_key_parts, KEY *index_info, uint
655
use_index, double read_cost, ha_rows records, uint
656
key_infix_len, unsigned char *key_infix, MEM_ROOT
658
~QUICK_GROUP_MIN_MAX_SELECT();
659
bool add_range(SEL_ARG *sel_range);
660
void update_key_stat();
661
void adjust_prefix_ranges();
662
bool alloc_buffers();
666
bool reverse_sorted() { return false; }
667
bool unique_key_range() { return false; }
668
int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
669
void add_keys_and_lengths(String *key_names, String *used_lengths);
673
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
676
QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts,
679
bool reverse_sorted() { return 1; }
680
int get_type() { return QS_TYPE_RANGE_DESC; }
682
bool range_reads_after_key(QUICK_RANGE *range);
684
bool test_if_null_range(QUICK_RANGE *range, uint32_t used_key_parts);
686
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
687
List<QUICK_RANGE> rev_ranges;
688
List_iterator<QUICK_RANGE> rev_it;
692
class SQL_SELECT :public Sql_alloc {
294
QuickSelectInterface *quick; /**< If quick-select used */
295
COND *cond; /**< where condition */
694
QUICK_SELECT_I *quick; // If quick-select used
695
COND *cond; // where condition
297
internal::IO_CACHE *file; /**< Positions to used records */
298
ha_rows records; /**< Records in use if read from file */
299
double read_time; /**< Time to read rows */
300
key_map quick_keys; /**< Possible quick keys */
301
key_map needed_reg; /**< Possible quick keys after prev tables. */
302
table_map const_tables;
303
table_map read_tables;
697
IO_CACHE file; // Positions to used records
698
ha_rows records; // Records in use if read from file
699
double read_time; // Time to read rows
700
key_map quick_keys; // Possible quick keys
701
key_map needed_reg; // Possible quick keys after prev tables.
702
table_map const_tables,read_tables;
309
bool check_quick(Session *session, bool force_quick_range, ha_rows limit);
708
bool check_quick(Session *session, bool force_quick_range, ha_rows limit)
712
return test_quick_select(session, tmp, 0, limit, force_quick_range, false) < 0;
714
inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; }
311
715
int test_quick_select(Session *session, key_map keys, table_map prev_tables,
312
ha_rows limit, bool force_quick_range,
716
ha_rows limit, bool force_quick_range,
313
717
bool ordered_output);
316
QuickRangeSelect *get_quick_select_for_ref(Session *session,
318
struct table_reference_st *ref,
720
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
721
struct st_table_ref *ref,
319
722
ha_rows records);
322
Create a QuickRangeSelect from given key and SEL_ARG tree for that key.
327
idx Index of used key in param->key.
328
key_tree SEL_ARG tree for the used key
329
mrr_flags MRR parameter for quick select
330
mrr_buf_size MRR parameter for quick select
331
parent_alloc If not NULL, use it to allocate memory for
332
quick select data. Otherwise use quick->alloc.
334
The caller must call QUICK_SELECT::init for returned quick select.
336
CAUTION! This function may change session->mem_root to a memory::Root which will be
337
deallocated when the returned quick select is deleted.
341
otherwise created quick select
343
QuickRangeSelect *get_quick_select(Parameter *param,
347
uint32_t mrr_buf_size,
348
memory::Root *alloc);
350
723
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit);
352
SqlSelect *make_select(Table *head,
353
table_map const_tables,
354
table_map read_tables,
356
bool allow_null_cond,
359
bool get_quick_keys(Parameter *param,
360
QuickRangeSelect *quick,
363
unsigned char *min_key,
364
uint32_t min_key_flag,
365
unsigned char *max_key,
366
uint32_t max_key_flag);
368
} /* namespace optimizer */
370
} /* namespace drizzled */
372
#endif /* DRIZZLED_OPTIMIZER_RANGE_H */