MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
opt_range.h
1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 
17 /* classes to use when handling where clause */
18 
19 #ifndef _opt_range_h
20 #define _opt_range_h
21 
22 #include "thr_malloc.h" /* sql_memdup */
23 #include "records.h" /* READ_RECORD */
24 #include "queues.h" /* QUEUE */
25 /*
26  It is necessary to include set_var.h instead of item.h because there
27  are dependencies on include order for set_var.h and item.h. This
28  will be resolved later.
29 */
30 #include "sql_class.h" // set_var.h: THD
31 #include "set_var.h" /* Item */
32 
33 #include <algorithm>
34 
35 class JOIN;
36 class Item_sum;
37 
38 typedef struct st_key_part {
39  uint16 key,part;
40  /* See KEY_PART_INFO for meaning of the next two: */
41  uint16 store_length, length;
42  uint8 null_bit;
43  /*
44  Keypart flags (0 when this structure is used by partition pruning code
45  for fake partitioning index description)
46  */
47  uint8 flag;
48  Field *field;
49  Field::imagetype image_type;
50 } KEY_PART;
51 
52 
53 class QUICK_RANGE :public Sql_alloc {
54  public:
55  uchar *min_key,*max_key;
56  uint16 min_length,max_length,flag;
57  key_part_map min_keypart_map, // bitmap of used keyparts in min_key
58  max_keypart_map; // bitmap of used keyparts in max_key
59 
60  QUICK_RANGE(); /* Full range */
61  QUICK_RANGE(const uchar *min_key_arg, uint min_length_arg,
62  key_part_map min_keypart_map_arg,
63  const uchar *max_key_arg, uint max_length_arg,
64  key_part_map max_keypart_map_arg,
65  uint flag_arg);
66 
81  void make_min_endpoint(key_range *kr, uint prefix_length,
82  key_part_map keypart_map) {
83  using std::min;
85  kr->length= min(kr->length, prefix_length);
86  kr->keypart_map&= keypart_map;
87  }
88 
99  kr->key= (const uchar*)min_key;
100  kr->length= min_length;
101  kr->keypart_map= min_keypart_map;
102  kr->flag= ((flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
103  (flag & EQ_RANGE) ? HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
104  }
105 
120  void make_max_endpoint(key_range *kr, uint prefix_length,
121  key_part_map keypart_map) {
122  using std::min;
123  make_max_endpoint(kr);
124  kr->length= min(kr->length, prefix_length);
125  kr->keypart_map&= keypart_map;
126  }
127 
138  kr->key= (const uchar*)max_key;
139  kr->length= max_length;
140  kr->keypart_map= max_keypart_map;
141  /*
142  We use READ_AFTER_KEY here because if we are reading on a key
143  prefix we want to find all keys with this prefix
144  */
145  kr->flag= (flag & NEAR_MAX ? HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
146  }
147 };
148 
149 
150 /*
151  Quick select interface.
152  This class is a parent for all QUICK_*_SELECT and FT_SELECT classes.
153 
154  The usage scenario is as follows:
155  1. Create quick select
156  quick= new QUICK_XXX_SELECT(...);
157 
158  2. Perform lightweight initialization. This can be done in 2 ways:
159  2.a: Regular initialization
160  if (quick->init())
161  {
162  //the only valid action after failed init() call is delete
163  delete quick;
164  }
165  2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT
166  if (quick->init_ror_merged_scan())
167  delete quick;
168 
169  3. Perform zero, one, or more scans.
170  while (...)
171  {
172  // initialize quick select for scan. This may allocate
173  // buffers and/or prefetch rows.
174  if (quick->reset())
175  {
176  //the only valid action after failed reset() call is delete
177  delete quick;
178  //abort query
179  }
180 
181  // perform the scan
182  do
183  {
184  res= quick->get_next();
185  } while (res && ...)
186  }
187 
188  4. Delete the select:
189  delete quick;
190 
191  NOTE
192  quick select doesn't use Sql_alloc/MEM_ROOT allocation because "range
193  checked for each record" functionality may create/destroy
194  O(#records_in_some_table) quick selects during query execution.
195 */
196 
198 {
199 public:
200  ha_rows records; /* estimate of # of records to be retrieved */
201  double read_time; /* time to perform this retrieval */
202  TABLE *head;
203  /*
204  Index this quick select uses, or MAX_KEY for quick selects
205  that use several indexes
206  */
207  uint index;
208 
209  /*
210  Total length of first used_key_parts parts of the key.
211  Applicable if index!= MAX_KEY.
212  */
213  uint max_used_key_length;
214 
215  /*
216  Max. number of (first) key parts this quick select uses for retrieval.
217  eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
218  Applicable if index!= MAX_KEY.
219 
220  For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
221  */
222  uint used_key_parts;
223 
224  QUICK_SELECT_I();
225  virtual ~QUICK_SELECT_I(){};
226 
227  /*
228  Do post-constructor initialization.
229  SYNOPSIS
230  init()
231 
232  init() performs initializations that should have been in constructor if
233  it was possible to return errors from constructors. The join optimizer may
234  create and then delete quick selects without retrieving any rows so init()
235  must not contain any IO or CPU intensive code.
236 
237  If init() call fails the only valid action is to delete this quick select,
238  reset() and get_next() must not be called.
239 
240  RETURN
241  0 OK
242  other Error code
243  */
244  virtual int init() = 0;
245 
246  /*
247  Initialize quick select for row retrieval.
248  SYNOPSIS
249  reset()
250 
251  reset() should be called when it is certain that row retrieval will be
252  necessary. This call may do heavyweight initialization like buffering first
253  N records etc. If reset() call fails get_next() must not be called.
254  Note that reset() may be called several times if
255  * the quick select is executed in a subselect
256  * a JOIN buffer is used
257 
258  RETURN
259  0 OK
260  other Error code
261  */
262  virtual int reset(void) = 0;
263 
264  virtual int get_next() = 0; /* get next record to retrieve */
265 
266  /* Range end should be called when we have looped over the whole index */
267  virtual void range_end() {}
268 
272  virtual bool reverse_sorted() const = 0;
277  virtual bool reverse_sort_possible() const = 0;
278  virtual bool unique_key_range() { return false; }
279  virtual bool clustered_pk_range() { return false; }
280 
281  /*
282  Request that this quick select produces sorted output.
283  Not all quick selects can provide sorted output, the caller is responsible
284  for calling this function only for those quick selects that can.
285  The implementation is also allowed to provide sorted output even if it
286  was not requested if benificial, or required by implementation
287  internals.
288  */
289  virtual void need_sorted_output() = 0;
290  enum {
291  QS_TYPE_RANGE = 0,
292  QS_TYPE_INDEX_MERGE = 1,
293  QS_TYPE_RANGE_DESC = 2,
294  QS_TYPE_FULLTEXT = 3,
295  QS_TYPE_ROR_INTERSECT = 4,
296  QS_TYPE_ROR_UNION = 5,
297  QS_TYPE_GROUP_MIN_MAX = 6
298  };
299 
300  /* Get type of this quick select - one of the QS_TYPE_* values */
301  virtual int get_type() = 0;
302 
303  /*
304  Initialize this quick select as a merged scan inside a ROR-union or a ROR-
305  intersection scan. The caller must not additionally call init() if this
306  function is called.
307  SYNOPSIS
308  init_ror_merged_scan()
309  reuse_handler If true, the quick select may use table->handler,
310  otherwise it must create and use a separate handler
311  object.
312  RETURN
313  0 Ok
314  other Error
315  */
316  virtual int init_ror_merged_scan(bool reuse_handler)
317  { DBUG_ASSERT(0); return 1; }
318 
319  /*
320  Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
321  */
322  virtual void save_last_pos(){};
323 
324  /*
325  Append comma-separated list of keys this quick select uses to key_names;
326  append comma-separated list of corresponding used lengths to used_lengths.
327  This is used by select_describe.
328  */
329  virtual void add_keys_and_lengths(String *key_names,
330  String *used_lengths)=0;
331 
332  /*
333  Append text representation of quick select structure (what and how is
334  merged) to str. The result is added to "Extra" field in EXPLAIN output.
335  This function is implemented only by quick selects that merge other quick
336  selects output and/or can produce output suitable for merging.
337  */
338  virtual void add_info_string(String *str) {};
339  /*
340  Return 1 if any index used by this quick select
341  uses field which is marked in passed bitmap.
342  */
343  virtual bool is_keys_used(const MY_BITMAP *fields);
344 
350  virtual bool is_valid() { return index != MAX_KEY; };
351 
352  /*
353  rowid of last row retrieved by this quick select. This is used only when
354  doing ROR-index_merge selects
355  */
356  uchar *last_rowid;
357 
358  /*
359  Table record buffer used by this quick select.
360  */
361  uchar *record;
362 #ifndef DBUG_OFF
363  /*
364  Print quick select information to DBUG_FILE. Caller is responsible
365  for locking DBUG_FILE before this call and unlocking it afterwards.
366  */
367  virtual void dbug_dump(int indent, bool verbose)= 0;
368 #endif
369 
370  /*
371  Returns a QUICK_SELECT with reverse order of to the index.
372  */
373  virtual QUICK_SELECT_I *make_reverse(uint used_key_parts_arg) { return NULL; }
374  virtual void set_handler(handler *file_arg) {}
375 };
376 
377 
378 struct st_qsel_param;
379 class PARAM;
380 class SEL_ARG;
381 
382 
383 /*
384  MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
385  context.
386 */
388 {
389  QUICK_RANGE **first;
390  QUICK_RANGE **cur;
391  QUICK_RANGE **last;
393 
394 range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags);
395 uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
396 
397 
398 /*
399  Quick select that does a range scan on a single key. The records are
400  returned in key order if ::need_sorted_output() has been called.
401 */
403 {
404 protected:
405  handler *file;
406  /* Members to deal with case when this quick select is a ROR-merged scan */
407  bool in_ror_merged_scan;
408  MY_BITMAP column_bitmap;
409 
410  friend class TRP_ROR_INTERSECT;
411  friend
412  QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
413  struct st_table_ref *ref,
414  ha_rows records);
415  friend bool get_quick_keys(PARAM *param,
416  QUICK_RANGE_SELECT *quick,KEY_PART *key,
417  SEL_ARG *key_tree,
418  uchar *min_key, uint min_key_flag,
419  uchar *max_key, uint max_key_flag);
420  friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx,
421  SEL_ARG *key_tree,
422  uint mrr_flags,
423  uint mrr_buf_size,
424  MEM_ROOT *alloc);
425  friend uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
426  friend range_seq_t quick_range_seq_init(void *init_param,
427  uint n_ranges, uint flags);
428  friend class QUICK_SELECT_DESC;
429  friend class QUICK_INDEX_MERGE_SELECT;
430  friend class QUICK_ROR_INTERSECT_SELECT;
431  friend class QUICK_GROUP_MIN_MAX_SELECT;
432 
433  DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
434  bool free_file; /* TRUE <=> this->file is "owned" by this quick select */
435 
436  /* Range pointers to be used when not using MRR interface */
437  QUICK_RANGE **cur_range; /* current element in ranges */
438  QUICK_RANGE *last_range;
439 
440  /* Members needed to use the MRR interface */
441  QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
442 public:
443  uint mrr_flags; /* Flags to be used with MRR interface */
444 protected:
445  uint mrr_buf_size; /* copy from thd->variables.read_rnd_buff_size */
446  HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
447 
448  /* Info about index we're scanning */
449  KEY_PART *key_parts;
450  KEY_PART_INFO *key_part_info;
451 
452  bool dont_free; /* Used by QUICK_SELECT_DESC */
453 
454  int cmp_next(QUICK_RANGE *range);
455  int cmp_prev(QUICK_RANGE *range);
456  bool row_in_ranges();
457 public:
458  MEM_ROOT alloc;
459 
460  QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc,
461  MEM_ROOT *parent_alloc, bool *create_error);
463 
464  void need_sorted_output();
465  int init();
466  int reset(void);
467  int get_next();
468  void range_end();
469  int get_next_prefix(uint prefix_length, uint group_key_parts,
470  uchar *cur_prefix);
471  bool reverse_sorted() const { return false; }
472  bool reverse_sort_possible() const { return true; }
473  bool unique_key_range();
474  int init_ror_merged_scan(bool reuse_handler);
475  void save_last_pos()
476  { file->position(record); }
477  int get_type() { return QS_TYPE_RANGE; }
478  void add_keys_and_lengths(String *key_names, String *used_lengths);
479  void add_info_string(String *str);
480 #ifndef DBUG_OFF
481  void dbug_dump(int indent, bool verbose);
482 #endif
483  QUICK_SELECT_I *make_reverse(uint used_key_parts_arg);
484  void set_handler(handler *file_arg) { file= file_arg; }
485 private:
486  /* Default copy ctor used by QUICK_SELECT_DESC */
487 };
488 
489 
491 {
492 public:
493  QUICK_RANGE_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg,
494  bool no_alloc, MEM_ROOT *parent_alloc,
495  bool *create_error)
496  :QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc,
497  create_error)
498  {};
499  virtual int get_next();
500 };
501 
502 
503 /*
504  QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
505 
506  QUICK_INDEX_MERGE_SELECT uses
507  * QUICK_RANGE_SELECTs to get rows
508  * Unique class to remove duplicate rows
509 
510  INDEX MERGE OPTIMIZER
511  Current implementation doesn't detect all cases where index_merge could
512  be used, in particular:
513  * index_merge will never be used if range scan is possible (even if
514  range scan is more expensive)
515 
516  * index_merge+'using index' is not supported (this the consequence of
517  the above restriction)
518 
519  * If WHERE part contains complex nested AND and OR conditions, some ways
520  to retrieve rows using index_merge will not be considered. The choice
521  of read plan may depend on the order of conjuncts/disjuncts in WHERE
522  part of the query, see comments near imerge_list_or_list and
523  SEL_IMERGE::or_sel_tree_with_checks functions for details.
524 
525  * There is no "index_merge_ref" method (but index_merge on non-first
526  table in join is possible with 'range checked for each record').
527 
528  See comments around SEL_IMERGE class and test_quick_select for more
529  details.
530 
531  ROW RETRIEVAL ALGORITHM
532 
533  index_merge uses Unique class for duplicates removal. index_merge takes
534  advantage of Clustered Primary Key (CPK) if the table has one.
535  The index_merge algorithm consists of two phases:
536 
537  Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
538  prepare()
539  {
540  activate 'index only';
541  while(retrieve next row for non-CPK scan)
542  {
543  if (there is a CPK scan and row will be retrieved by it)
544  skip this row;
545  else
546  put its rowid into Unique;
547  }
548  deactivate 'index only';
549  }
550 
551  Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
552  calls):
553 
554  fetch()
555  {
556  retrieve all rows from row pointers stored in Unique;
557  free Unique;
558  retrieve all rows for CPK scan;
559  }
560 */
561 
563 {
564  Unique *unique;
565 public:
566  QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table);
568 
569  int init();
570  void need_sorted_output() { DBUG_ASSERT(false); /* Can't do it */ }
571  int reset(void);
572  int get_next();
573  bool reverse_sorted() const { return false; }
574  bool reverse_sort_possible() const { return false; }
575  bool unique_key_range() { return false; }
576  int get_type() { return QS_TYPE_INDEX_MERGE; }
577  void add_keys_and_lengths(String *key_names, String *used_lengths);
578  void add_info_string(String *str);
579  bool is_keys_used(const MY_BITMAP *fields);
580 #ifndef DBUG_OFF
581  void dbug_dump(int indent, bool verbose);
582 #endif
583 
584  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
585 
586  /* range quick selects this index_merge read consists of */
587  List<QUICK_RANGE_SELECT> quick_selects;
588 
589  /* quick select that uses clustered primary key (NULL if none) */
590  QUICK_RANGE_SELECT* pk_quick_select;
591 
592  /* true if this select is currently doing a clustered PK scan */
593  bool doing_pk_scan;
594 
595  MEM_ROOT alloc;
596  THD *thd;
597  int read_keys_and_merge();
598 
599  bool clustered_pk_range() { return test(pk_quick_select); }
600 
601  virtual bool is_valid()
602  {
603  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
604  QUICK_RANGE_SELECT *quick;
605  bool valid= true;
606  while ((quick= it++))
607  {
608  if (!quick->is_valid())
609  {
610  valid= false;
611  break;
612  }
613  }
614  return valid;
615  }
616 
617  /* used to get rows collected in Unique */
618  READ_RECORD read_record;
619 };
620 
621 
622 /*
623  Rowid-Ordered Retrieval (ROR) index intersection quick select.
624  This quick select produces intersection of row sequences returned
625  by several QUICK_RANGE_SELECTs it "merges".
626 
627  All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
628  QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
629 
630  All merged quick selects retrieve {rowid, covered_fields} tuples (not full
631  table records).
632  QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
633  by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
634  cover needed all fields.
635 
636  If one of the merged quick selects is a Clustered PK range scan, it is
637  used only to filter rowid sequence produced by other merged quick selects.
638 */
639 
641 {
642 public:
643  QUICK_ROR_INTERSECT_SELECT(THD *thd, TABLE *table,
644  bool retrieve_full_rows,
645  MEM_ROOT *parent_alloc);
647 
648  int init();
649  void need_sorted_output() { DBUG_ASSERT(false); /* Can't do it */ }
650  int reset(void);
651  int get_next();
652  bool reverse_sorted() const { return false; }
653  bool reverse_sort_possible() const { return false; }
654  bool unique_key_range() { return false; }
655  int get_type() { return QS_TYPE_ROR_INTERSECT; }
656  void add_keys_and_lengths(String *key_names, String *used_lengths);
657  void add_info_string(String *str);
658  bool is_keys_used(const MY_BITMAP *fields);
659 #ifndef DBUG_OFF
660  void dbug_dump(int indent, bool verbose);
661 #endif
662  int init_ror_merged_scan(bool reuse_handler);
663  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
664 
665  /*
666  Range quick selects this intersection consists of, not including
667  cpk_quick.
668  */
669  List<QUICK_RANGE_SELECT> quick_selects;
670 
671  virtual bool is_valid()
672  {
673  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
674  QUICK_RANGE_SELECT *quick;
675  bool valid= true;
676  while ((quick= it++))
677  {
678  if (!quick->is_valid())
679  {
680  valid= false;
681  break;
682  }
683  }
684  return valid;
685  }
686 
687  /*
688  Merged quick select that uses Clustered PK, if there is one. This quick
689  select is not used for row retrieval, it is used for row retrieval.
690  */
691  QUICK_RANGE_SELECT *cpk_quick;
692 
693  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
694  THD *thd; /* current thread */
695  bool need_to_fetch_row; /* if true, do retrieve full table records. */
696  /* in top-level quick select, true if merged scans where initialized */
697  bool scans_inited;
698 };
699 
700 
701 /*
702  Rowid-Ordered Retrieval index union select.
703  This quick select produces union of row sequences returned by several
704  quick select it "merges".
705 
706  All merged quick selects must return rowids in rowid order.
707  QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
708 
709  All merged quick selects are set not to retrieve full table records.
710  ROR-union quick select always retrieves full records.
711 
712 */
713 
715 {
716 public:
717  QUICK_ROR_UNION_SELECT(THD *thd, TABLE *table);
719 
720  int init();
721  void need_sorted_output() { DBUG_ASSERT(false); /* Can't do it */ }
722  int reset(void);
723  int get_next();
724  bool reverse_sorted() const { return false; }
725  bool reverse_sort_possible() const { return false; }
726  bool unique_key_range() { return false; }
727  int get_type() { return QS_TYPE_ROR_UNION; }
728  void add_keys_and_lengths(String *key_names, String *used_lengths);
729  void add_info_string(String *str);
730  bool is_keys_used(const MY_BITMAP *fields);
731 #ifndef DBUG_OFF
732  void dbug_dump(int indent, bool verbose);
733 #endif
734 
735  bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
736 
737  List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
738 
739  virtual bool is_valid()
740  {
741  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
742  QUICK_SELECT_I *quick;
743  bool valid= true;
744  while ((quick= it++))
745  {
746  if (!quick->is_valid())
747  {
748  valid= false;
749  break;
750  }
751  }
752  return valid;
753  }
754 
755  QUEUE queue; /* Priority queue for merge operation */
756  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
757 
758  THD *thd; /* current thread */
759  uchar *cur_rowid; /* buffer used in get_next() */
760  uchar *prev_rowid; /* rowid of last row returned by get_next() */
761  bool have_prev_rowid; /* true if prev_rowid has valid data */
762  uint rowid_length; /* table rowid length */
763 private:
764  bool scans_inited;
765 };
766 
767 
768 /*
769  Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
770 
771  This class provides a specialized index access method for GROUP-BY queries
772  of the forms:
773 
774  SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
775  FROM T
776  WHERE [RNG(A_1,...,A_p ; where p <= k)]
777  [AND EQ(B_1,...,B_m)]
778  [AND PC(C)]
779  [AND PA(A_i1,...,A_iq)]
780  GROUP BY A_1,...,A_k;
781 
782  or
783 
784  SELECT DISTINCT A_i1,...,A_ik
785  FROM T
786  WHERE [RNG(A_1,...,A_p ; where p <= k)]
787  [AND PA(A_i1,...,A_iq)];
788 
789  where all selected fields are parts of the same index.
790  The class of queries that can be processed by this quick select is fully
791  specified in the description of get_best_trp_group_min_max() in opt_range.cc.
792 
793  The get_next() method directly produces result tuples, thus obviating the
794  need to call end_send_group() because all grouping is already done inside
795  get_next().
796 
797  Since one of the requirements is that all select fields are part of the same
798  index, this class produces only index keys, and not complete records.
799 */
800 
802 {
803 private:
804  JOIN *join; /* Descriptor of the current query */
805  KEY *index_info; /* The index chosen for data access */
806  uchar *record; /* Buffer where the next record is returned. */
807  uchar *tmp_record; /* Temporary storage for next_min(), next_max(). */
808  uchar *group_prefix; /* Key prefix consisting of the GROUP fields. */
809  const uint group_prefix_len; /* Length of the group prefix. */
810  uint group_key_parts; /* A number of keyparts in the group prefix */
811  uchar *last_prefix; /* Prefix of the last group for detecting EOF. */
812  bool have_min; /* Specify whether we are computing */
813  bool have_max; /* a MIN, a MAX, or both. */
814  bool have_agg_distinct;/* aggregate_function(DISTINCT ...). */
815  bool seen_first_key; /* Denotes whether the first key was retrieved.*/
816  KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
817  /* of all MIN/MAX functions. */
818  uint min_max_arg_len; /* The length of the MIN/MAX argument field */
819  uchar *key_infix; /* Infix of constants from equality predicates. */
820  uint key_infix_len;
821  DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
822  uint real_prefix_len; /* Length of key prefix extended with key_infix. */
823  uint real_key_parts; /* A number of keyparts in the above value. */
824  List<Item_sum> *min_functions;
825  List<Item_sum> *max_functions;
826  List_iterator<Item_sum> *min_functions_it;
827  List_iterator<Item_sum> *max_functions_it;
828  /*
829  Use index scan to get the next different key instead of jumping into it
830  through index read
831  */
832  bool is_index_scan;
833 public:
834  /*
835  The following two members are public to allow easy access from
836  TRP_GROUP_MIN_MAX::make_quick()
837  */
838  MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
839  QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
840 private:
841  int next_prefix();
842  int next_min_in_range();
843  int next_max_in_range();
844  int next_min();
845  int next_max();
846  void update_min_result();
847  void update_max_result();
848 public:
849  QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join, bool have_min,
850  bool have_max, bool have_agg_distinct,
851  KEY_PART_INFO *min_max_arg_part,
852  uint group_prefix_len, uint group_key_parts,
853  uint used_key_parts, KEY *index_info, uint
854  use_index, double read_cost, ha_rows records, uint
855  key_infix_len, uchar *key_infix, MEM_ROOT
856  *parent_alloc, bool is_index_scan);
858  bool add_range(SEL_ARG *sel_range);
859  void update_key_stat();
860  void adjust_prefix_ranges();
861  bool alloc_buffers();
862  int init();
863  void need_sorted_output() { /* always do it */ }
864  int reset();
865  int get_next();
866  bool reverse_sorted() const { return false; }
867  bool reverse_sort_possible() const { return false; }
868  bool unique_key_range() { return false; }
869  int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
870  void add_keys_and_lengths(String *key_names, String *used_lengths);
871 #ifndef DBUG_OFF
872  void dbug_dump(int indent, bool verbose);
873 #endif
874  bool is_agg_distinct() { return have_agg_distinct; }
875  virtual void append_loose_scan_type(String *str)
876  {
877  if (is_index_scan)
878  str->append(STRING_WITH_LEN("scanning"));
879  }
880 };
881 
882 
884 {
885 public:
886  QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint used_key_parts,
887  bool *create_err);
888  int get_next();
889  bool reverse_sorted() const { return true; }
890  bool reverse_sort_possible() const { return true; }
891  int get_type() { return QS_TYPE_RANGE_DESC; }
892  QUICK_SELECT_I *make_reverse(uint used_key_parts_arg)
893  {
894  return this; // is already reverse sorted
895  }
896 private:
897  bool range_reads_after_key(QUICK_RANGE *range);
898  int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
899  List<QUICK_RANGE> rev_ranges;
901  uint used_key_parts;
902 };
903 
904 
905 class SQL_SELECT :public Sql_alloc {
906  public:
907  QUICK_SELECT_I *quick; // If quick-select used
908  Item *cond; // where condition
909  Item *icp_cond; // conditions pushed to index
910  TABLE *head;
911  IO_CACHE file; // Positions to used records
912  ha_rows records; // Records in use if read from file
913  double read_time; // Time to read rows
914  key_map quick_keys; // Possible quick keys
915  key_map needed_reg; // Possible quick keys after prev tables.
916  table_map const_tables,read_tables;
917  bool free_cond;
918 
929 
930  SQL_SELECT();
931  ~SQL_SELECT();
932  void cleanup();
933  void set_quick(QUICK_SELECT_I *new_quick) { delete quick; quick= new_quick; }
934  bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
935  {
936  key_map tmp(key_map::ALL_BITS);
937  return test_quick_select(thd, tmp, 0, limit, force_quick_range,
938  ORDER::ORDER_NOT_RELEVANT) < 0;
939  }
940  inline bool skip_record(THD *thd, bool *skip_record)
941  {
942  *skip_record= cond ? cond->val_int() == FALSE : FALSE;
943  return thd->is_error();
944  }
945  int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
946  ha_rows limit, bool force_quick_range,
947  const ORDER::enum_order interesting_order);
948 };
949 
950 
952 {
953 public:
954  FT_SELECT(THD *thd, TABLE *table, uint key, bool *error) :
955  QUICK_RANGE_SELECT (thd, table, key, 1, NULL, error) { (void) init(); }
956  ~FT_SELECT() { file->ft_end(); }
957  int init() { return file->ft_init(); }
958  int reset() { return 0; }
959  int get_next() { return file->ft_read(record); }
960  int get_type() { return QS_TYPE_FULLTEXT; }
961 };
962 
963 FT_SELECT *get_ft_select(THD *thd, TABLE *table, uint key);
964 QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
965  struct st_table_ref *ref,
966  ha_rows records);
967 SQL_SELECT *make_select(TABLE *head, table_map const_tables,
968  table_map read_tables, Item *conds,
969  bool allow_null_cond, int *error);
970 
971 #ifdef WITH_PARTITION_STORAGE_ENGINE
972 bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond);
973 void store_key_image_to_rec(Field *field, uchar *ptr, uint len);
974 #endif
975 
976 extern String null_string;
977 
978 #endif