107
class QuickSelectInterface
111
ha_rows records; /**< estimate of # of records to be retrieved */
112
double read_time; /**< time to perform this retrieval */
127
ha_rows records; /* estimate of # of records to be retrieved */
128
double read_time; /* time to perform this retrieval */
115
131
Index this quick select uses, or MAX_KEY for quick selects
116
132
that use several indexes
120
137
Total length of first used_key_parts parts of the key.
121
138
Applicable if index!= MAX_KEY.
123
140
uint32_t max_used_key_length;
125
Maximum number of (first) key parts this quick select uses for retrieval.
143
Max. number of (first) key parts this quick select uses for retrieval.
126
144
eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
127
145
Applicable if index!= MAX_KEY.
129
147
For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
131
149
uint32_t used_key_parts;
133
* The rowid of last row retrieved by this quick select. This is used only when
134
* doing ROR-index_merge selects
136
unsigned char *last_rowid;
139
* Table record buffer used by this quick select.
141
unsigned char *record;
143
QuickSelectInterface();
144
virtual ~QuickSelectInterface(){};
147
* Do post-constructor initialization.
151
* Performs initializations that should have been in constructor if
152
* it was possible to return errors from constructors. The join optimizer may
153
* create and then delete quick selects without retrieving any rows so init()
154
* must not contain any IO or CPU intensive code.
156
* If init() call fails the only valid action is to delete this quick select,
157
* reset() and get_next() must not be called.
164
virtual int init() = 0;
167
* Initializes quick select for row retrieval.
171
* 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
183
virtual int reset(void) = 0;
184
/** Gets next record to retrieve */
185
virtual int get_next() = 0;
187
/** Range end should be called when we have looped over the whole index */
152
virtual ~QUICK_SELECT_I(){};
155
Do post-constructor initialization.
159
init() performs initializations that should have been in constructor if
160
it was possible to return errors from constructors. The join optimizer may
161
create and then delete quick selects without retrieving any rows so init()
162
must not contain any IO or CPU intensive code.
164
If init() call fails the only valid action is to delete this quick select,
165
reset() and get_next() must not be called.
171
virtual int init() = 0;
174
Initialize quick select for row retrieval.
178
reset() should be called when it is certain that row retrieval will be
179
necessary. This call may do heavyweight initialization like buffering first
180
N records etc. If reset() call fails get_next() must not be called.
181
Note that reset() may be called several times if
182
* the quick select is executed in a subselect
183
* a JOIN buffer is used
189
virtual int reset(void) = 0;
191
virtual int get_next() = 0; /* get next record to retrieve */
193
/* Range end should be called when we have looped over the whole index */
188
194
virtual void range_end() {}
190
virtual bool reverse_sorted() const = 0;
192
virtual bool unique_key_range() const
200
QS_TYPE_INDEX_MERGE= 1,
201
QS_TYPE_RANGE_DESC= 2,
202
QS_TYPE_ROR_INTERSECT= 4,
203
QS_TYPE_ROR_UNION= 5,
204
QS_TYPE_GROUP_MIN_MAX= 6
196
virtual bool reverse_sorted() = 0;
197
virtual bool unique_key_range() { return false; }
201
QS_TYPE_INDEX_MERGE = 1,
202
QS_TYPE_RANGE_DESC = 2,
203
QS_TYPE_ROR_INTERSECT = 4,
204
QS_TYPE_ROR_UNION = 5,
205
QS_TYPE_GROUP_MIN_MAX = 6
207
/** Returns the type of this quick select - one of the QS_TYPE_* values */
208
virtual int get_type() const = 0;
208
/* Get type of this quick select - one of the QS_TYPE_* values */
209
virtual int get_type() = 0;
211
* Initialize this quick select as a merged scan inside a ROR-union or a ROR-
212
* intersection scan. The caller must not additionally call init() if this
213
* function is called.
215
* @param If true, the quick select may use table->Cursor,
216
* otherwise it must create and use a separate Cursor
212
Initialize this quick select as a merged scan inside a ROR-union or a ROR-
213
intersection scan. The caller must not additionally call init() if this
216
init_ror_merged_scan()
217
reuse_handler If true, the quick select may use table->handler,
218
otherwise it must create and use a separate handler
224
224
virtual int init_ror_merged_scan(bool)
225
{ assert(0); return 1; }
231
* Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
228
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
233
230
virtual void save_last_pos(){};
236
* Append comma-separated list of keys this quick select uses to key_names;
237
* append comma-separated list of corresponding used lengths to used_lengths.
239
* @note This is used by during explain plan.
241
virtual void add_keys_and_lengths(String *key_names, String *used_lengths)=0;
244
* Append text representation of quick select structure (what and how is
245
* merged) to str. The result is added to "Extra" field in EXPLAIN output.
249
* This function is implemented only by quick selects that merge other quick
250
* selects output and/or can produce output suitable for merging.
252
virtual void add_info_string(String *)
256
* Returns true if any index used by this quick select
257
* uses field which is marked in passed bitmap.
259
virtual bool is_keys_used(const boost::dynamic_bitset<>& fields);
233
Append comma-separated list of keys this quick select uses to key_names;
234
append comma-separated list of corresponding used lengths to used_lengths.
235
This is used by select_describe.
237
virtual void add_keys_and_lengths(String *key_names,
238
String *used_lengths)=0;
241
Append text representation of quick select structure (what and how is
242
merged) to str. The result is added to "Extra" field in EXPLAIN output.
243
This function is implemented only by quick selects that merge other quick
244
selects output and/or can produce output suitable for merging.
246
virtual void add_info_string(String *) {};
248
Return 1 if any index used by this quick select
249
uses field which is marked in passed bitmap.
251
virtual bool is_keys_used(const MY_BITMAP *fields);
254
rowid of last row retrieved by this quick select. This is used only when
255
doing ROR-index_merge selects
257
unsigned char *last_rowid;
260
Table record buffer used by this quick select.
262
unsigned char *record;
262
266
struct st_qsel_param;
264
class QuickRangeSelect;
267
* MRR range sequence, array<QuickRange> implementation: sequence traversal
272
MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
270
275
typedef struct st_quick_range_seq_ctx
275
} QuickRangeSequenceContext;
280
} QUICK_RANGE_SEQ_CTX;
277
282
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
279
283
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
282
* Executor class for SELECT statements.
286
* The QuickSelectInterface member variable is the implementor
287
* of the SELECT execution.
287
Quick select that does a range scan on a single key. The records are
288
returned in key order.
290
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
294
DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
296
/* Members to deal with case when this quick select is a ROR-merged scan */
297
bool in_ror_merged_scan;
298
MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
299
bool free_file; /* TRUE <=> this->file is "owned" by this quick select */
301
/* Range pointers to be used when not using MRR interface */
302
QUICK_RANGE **cur_range; /* current element in ranges */
303
QUICK_RANGE *last_range;
305
/* Members needed to use the MRR interface */
306
QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
308
uint32_t mrr_flags; /* Flags to be used with MRR interface */
310
uint32_t mrr_buf_size; /* copy from session->variables.read_rnd_buff_size */
311
HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
313
/* Info about index we're scanning */
315
KEY_PART_INFO *key_part_info;
317
bool dont_free; /* Used by QUICK_SELECT_DESC */
319
int cmp_next(QUICK_RANGE *range);
320
int cmp_prev(QUICK_RANGE *range);
321
bool row_in_ranges();
325
QUICK_RANGE_SELECT(Session *session, Table *table,uint32_t index_arg,bool no_alloc,
326
MEM_ROOT *parent_alloc, bool *create_err);
327
~QUICK_RANGE_SELECT();
333
int get_next_prefix(uint32_t prefix_length, key_part_map keypart_map,
334
unsigned char *cur_prefix);
335
bool reverse_sorted() { return 0; }
336
bool unique_key_range();
337
int init_ror_merged_scan(bool reuse_handler);
338
void save_last_pos();
339
int get_type() { return QS_TYPE_RANGE; }
340
void add_keys_and_lengths(String *key_names, String *used_lengths);
341
void add_info_string(String *str);
343
/* Used only by QUICK_SELECT_DESC */
344
QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
346
memmove(this, &org, sizeof(*this));
348
Use default MRR implementation for reverse scans. No table engine
349
currently can do an MRR scan with output in reverse index order.
352
mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
355
friend class TRP_ROR_INTERSECT;
357
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
358
struct st_table_ref *ref,
360
friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
361
KEY_PART *key, SEL_ARG *key_tree,
362
unsigned char *min_key, uint32_t min_key_flag,
363
unsigned char *max_key, uint32_t max_key_flag);
364
friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint32_t idx,
367
uint32_t mrr_buf_size,
369
friend class QUICK_SELECT_DESC;
370
friend class QUICK_INDEX_MERGE_SELECT;
371
friend class QUICK_ROR_INTERSECT_SELECT;
372
friend class QUICK_GROUP_MIN_MAX_SELECT;
373
friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
374
friend range_seq_t quick_range_seq_init(void *init_param,
375
uint32_t n_ranges, uint32_t flags);
376
friend void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
377
bool distinct,const char *message);
382
QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
384
QUICK_INDEX_MERGE_SELECT uses
385
* QUICK_RANGE_SELECTs to get rows
386
* Unique class to remove duplicate rows
388
INDEX MERGE OPTIMIZER
389
Current implementation doesn't detect all cases where index_merge could
390
be used, in particular:
391
* index_merge will never be used if range scan is possible (even if
392
range scan is more expensive)
394
* index_merge+'using index' is not supported (this the consequence of
395
the above restriction)
397
* If WHERE part contains complex nested AND and OR conditions, some ways
398
to retrieve rows using index_merge will not be considered. The choice
399
of read plan may depend on the order of conjuncts/disjuncts in WHERE
400
part of the query, see comments near imerge_list_or_list and
401
SEL_IMERGE::or_sel_tree_with_checks functions for details.
403
* There is no "index_merge_ref" method (but index_merge on non-first
404
table in join is possible with 'range checked for each record').
406
See comments around SEL_IMERGE class and test_quick_select for more
409
ROW RETRIEVAL ALGORITHM
411
index_merge uses Unique class for duplicates removal. index_merge takes
412
advantage of Clustered Primary Key (CPK) if the table has one.
413
The index_merge algorithm consists of two phases:
415
Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
418
activate 'index only';
419
while(retrieve next row for non-CPK scan)
421
if (there is a CPK scan and row will be retrieved by it)
424
put its rowid into Unique;
426
deactivate 'index only';
429
Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
434
retrieve all rows from row pointers stored in Unique;
436
retrieve all rows for CPK scan;
440
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
443
QUICK_INDEX_MERGE_SELECT(Session *session, Table *table);
444
~QUICK_INDEX_MERGE_SELECT();
449
bool reverse_sorted() { return false; }
450
bool unique_key_range() { return false; }
451
int get_type() { return QS_TYPE_INDEX_MERGE; }
452
void add_keys_and_lengths(String *key_names, String *used_lengths);
453
void add_info_string(String *str);
454
bool is_keys_used(const MY_BITMAP *fields);
456
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
458
/* range quick selects this index_merge read consists of */
459
List<QUICK_RANGE_SELECT> quick_selects;
461
/* quick select that uses clustered primary key (NULL if none) */
462
QUICK_RANGE_SELECT* pk_quick_select;
464
/* true if this select is currently doing a clustered PK scan */
469
int read_keys_and_merge();
471
/* used to get rows collected in Unique */
472
READ_RECORD read_record;
477
Rowid-Ordered Retrieval (ROR) index intersection quick select.
478
This quick select produces intersection of row sequences returned
479
by several QUICK_RANGE_SELECTs it "merges".
481
All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
482
QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
484
All merged quick selects retrieve {rowid, covered_fields} tuples (not full
486
QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
487
by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
488
cover needed all fields.
490
If one of the merged quick selects is a Clustered PK range scan, it is
491
used only to filter rowid sequence produced by other merged quick selects.
494
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
497
QUICK_ROR_INTERSECT_SELECT(Session *session, Table *table,
498
bool retrieve_full_rows,
499
MEM_ROOT *parent_alloc);
500
~QUICK_ROR_INTERSECT_SELECT();
505
bool reverse_sorted() { return false; }
506
bool unique_key_range() { return false; }
507
int get_type() { return QS_TYPE_ROR_INTERSECT; }
508
void add_keys_and_lengths(String *key_names, String *used_lengths);
509
void add_info_string(String *str);
510
bool is_keys_used(const MY_BITMAP *fields);
511
int init_ror_merged_scan(bool reuse_handler);
512
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
515
Range quick selects this intersection consists of, not including
518
List<QUICK_RANGE_SELECT> quick_selects;
521
Merged quick select that uses Clustered PK, if there is one. This quick
522
select is not used for row retrieval, it is used for row retrieval.
524
QUICK_RANGE_SELECT *cpk_quick;
526
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
527
Session *session; /* current thread */
528
bool need_to_fetch_row; /* if true, do retrieve full table records. */
529
/* in top-level quick select, true if merged scans where initialized */
535
* This function object is defined in drizzled/opt_range.cc
536
* We need this here for the priority_queue definition in the
537
* QUICK_ROR_UNION_SELECT class.
289
class SqlSelect : public memory::SqlAlloc
539
class compare_functor;
543
Rowid-Ordered Retrieval index union select.
544
This quick select produces union of row sequences returned by several
545
quick select it "merges".
547
All merged quick selects must return rowids in rowid order.
548
QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
550
All merged quick selects are set not to retrieve full table records.
551
ROR-union quick select always retrieves full records.
555
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
558
QUICK_ROR_UNION_SELECT(Session *session, Table *table);
559
~QUICK_ROR_UNION_SELECT();
564
bool reverse_sorted() { return false; }
565
bool unique_key_range() { return false; }
566
int get_type() { return QS_TYPE_ROR_UNION; }
567
void add_keys_and_lengths(String *key_names, String *used_lengths);
568
void add_info_string(String *str);
569
bool is_keys_used(const MY_BITMAP *fields);
571
bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
573
List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
575
/* Priority queue for merge operation */
576
std::priority_queue<QUICK_SELECT_I *, std::vector<QUICK_SELECT_I *>, compare_functor >
578
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
580
Session *session; /* current thread */
581
unsigned char *cur_rowid; /* buffer used in get_next() */
582
unsigned char *prev_rowid; /* rowid of last row returned by get_next() */
583
bool have_prev_rowid; /* true if prev_rowid has valid data */
584
uint32_t rowid_length; /* table rowid length */
590
Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
592
This class provides a specialized index access method for GROUP-BY queries
595
SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
597
WHERE [RNG(A_1,...,A_p ; where p <= k)]
598
[AND EQ(B_1,...,B_m)]
600
[AND PA(A_i1,...,A_iq)]
601
GROUP BY A_1,...,A_k;
605
SELECT DISTINCT A_i1,...,A_ik
607
WHERE [RNG(A_1,...,A_p ; where p <= k)]
608
[AND PA(A_i1,...,A_iq)];
610
where all selected fields are parts of the same index.
611
The class of queries that can be processed by this quick select is fully
612
specified in the description of get_best_trp_group_min_max() in opt_range.cc.
614
The get_next() method directly produces result tuples, thus obviating the
615
need to call end_send_group() because all grouping is already done inside
618
Since one of the requirements is that all select fields are part of the same
619
index, this class produces only index keys, and not complete records.
622
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
625
handler *file; /* The handler used to get data. */
626
JOIN *join; /* Descriptor of the current query */
627
KEY *index_info; /* The index chosen for data access */
628
unsigned char *record; /* Buffer where the next record is returned. */
629
unsigned char *tmp_record; /* Temporary storage for next_min(), next_max(). */
630
unsigned char *group_prefix; /* Key prefix consisting of the GROUP fields. */
631
uint32_t group_prefix_len; /* Length of the group prefix. */
632
uint32_t group_key_parts; /* A number of keyparts in the group prefix */
633
unsigned char *last_prefix; /* Prefix of the last group for detecting EOF. */
634
bool have_min; /* Specify whether we are computing */
635
bool have_max; /* a MIN, a MAX, or both. */
636
bool seen_first_key; /* Denotes whether the first key was retrieved.*/
637
KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
638
/* of all MIN/MAX functions. */
639
uint32_t min_max_arg_len; /* The length of the MIN/MAX argument field */
640
unsigned char *key_infix; /* Infix of constants from equality predicates. */
641
uint32_t key_infix_len;
642
DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
643
uint32_t real_prefix_len; /* Length of key prefix extended with key_infix. */
644
uint32_t real_key_parts; /* A number of keyparts in the above value. */
645
List<Item_sum> *min_functions;
646
List<Item_sum> *max_functions;
647
List_iterator<Item_sum> *min_functions_it;
648
List_iterator<Item_sum> *max_functions_it;
651
The following two members are public to allow easy access from
652
TRP_GROUP_MIN_MAX::make_quick()
654
MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
655
QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
658
int next_min_in_range();
659
int next_max_in_range();
662
void update_min_result();
663
void update_max_result();
665
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join, bool have_min,
666
bool have_max, KEY_PART_INFO *min_max_arg_part,
667
uint32_t group_prefix_len, uint32_t group_key_parts,
668
uint32_t used_key_parts, KEY *index_info, uint
669
use_index, double read_cost, ha_rows records, uint
670
key_infix_len, unsigned char *key_infix, MEM_ROOT
672
~QUICK_GROUP_MIN_MAX_SELECT();
673
bool add_range(SEL_ARG *sel_range);
674
void update_key_stat();
675
void adjust_prefix_ranges();
676
bool alloc_buffers();
680
bool reverse_sorted() { return false; }
681
bool unique_key_range() { return false; }
682
int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
683
void add_keys_and_lengths(String *key_names, String *used_lengths);
687
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
690
QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts,
693
bool reverse_sorted() { return 1; }
694
int get_type() { return QS_TYPE_RANGE_DESC; }
696
bool range_reads_after_key(QUICK_RANGE *range);
697
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
698
List<QUICK_RANGE> rev_ranges;
699
List_iterator<QUICK_RANGE> rev_it;
703
class SQL_SELECT :public Sql_alloc {
292
QuickSelectInterface *quick; /**< If quick-select used */
293
COND *cond; /**< where condition */
705
QUICK_SELECT_I *quick; // If quick-select used
706
COND *cond; // where condition
295
internal::IO_CACHE *file; /**< Positions to used records */
296
ha_rows records; /**< Records in use if read from file */
297
double read_time; /**< Time to read rows */
298
key_map quick_keys; /**< Possible quick keys */
299
key_map needed_reg; /**< Possible quick keys after prev tables. */
300
table_map const_tables;
301
table_map read_tables;
708
IO_CACHE file; // Positions to used records
709
ha_rows records; // Records in use if read from file
710
double read_time; // Time to read rows
711
key_map quick_keys; // Possible quick keys
712
key_map needed_reg; // Possible quick keys after prev tables.
713
table_map const_tables,read_tables;
307
719
bool check_quick(Session *session, bool force_quick_range, ha_rows limit);
308
720
bool skip_record();