MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_optimizer.h
1 #ifndef SQL_OPTIMIZER_INCLUDED
2 #define SQL_OPTIMIZER_INCLUDED
3 
4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
19 
22 /*
23  This structure is used to collect info on potentially sargable
24  predicates in order to check whether they become sargable after
25  reading const tables.
26  We form a bitmap of indexes that can be used for sargable predicates.
27  Only such indexes are involved in range analysis.
28 */
29 
30 #include "opt_explain_format.h"
31 
32 typedef struct st_sargable_param
33 {
34  Field *field; /* field against which to check sargability */
35  Item **arg_value; /* values of potential keys for lookups */
36  uint num_values; /* number of values in the above array */
38 
39 typedef struct st_rollup
40 {
41  enum State { STATE_NONE, STATE_INITED, STATE_READY };
42  State state;
43  Item_null_array null_items;
44  Ref_ptr_array *ref_pointer_arrays;
45  List<Item> *fields;
46 } ROLLUP;
47 
48 class JOIN :public Sql_alloc
49 {
50  JOIN(const JOIN &rhs);
51  JOIN& operator=(const JOIN &rhs);
52 public:
53  JOIN_TAB *join_tab,**best_ref;
55  TABLE **table;
56  /*
57  The table which has an index that allows to produce the requried ordering.
58  A special value of 0x1 means that the ordering will be produced by
59  passing 1st non-const table to filesort(). NULL means no such table exists.
60  */
61  TABLE *sort_by_table;
85  uint tables;
87  uint const_tables;
88  uint tmp_tables;
89  uint send_group_parts;
97  bool first_record,full_join, no_field_update;
98  bool group;
99  bool do_send_rows;
100  table_map all_table_map;
101  table_map const_table_map;
102 
109  table_map outer_join;
110  /* Number of records produced after join + group operation */
111  ha_rows send_records;
112  ha_rows found_records,examined_rows,row_limit;
113  // m_select_limit is used to decide if we are likely to scan the whole table.
114  ha_rows m_select_limit;
124  ha_rows fetch_limit;
125 
130  ha_rows min_ft_matches;
131 
132  /* Finally picked QEP. This is result of join optimization */
133  POSITION *best_positions;
134 
135 /******* Join optimization state members start *******/
136 
137  /* Current join optimization state */
138  POSITION *positions;
139 
140  /* We also maintain a stack of join optimization states in * join->positions[] */
141 /******* Join optimization state members end *******/
142 
143 
144  Next_select_func first_select;
150  double best_read;
154  ha_rows best_rowcount;
155  List<Item> *fields;
156  List<Cached_item> group_fields, group_fields_cache;
157  THD *thd;
158  Item_sum **sum_funcs, ***sum_funcs_end;
160  Item_sum **sum_funcs2, ***sum_funcs_end2;
161  ulonglong select_options;
162  select_result *result;
163  TMP_TABLE_PARAM tmp_table_param;
164  MYSQL_LOCK *lock;
166  SELECT_LEX_UNIT *unit;
168  SELECT_LEX *select_lex;
177 
179 
181 
189 
190  /*
191  simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
192  to other tables than the first non-constant table in the JOIN.
193  It's also set if ORDER/GROUP BY is empty.
194  Used for deciding for or against using a temporary table to compute
195  GROUP/ORDER BY.
196  */
197  bool simple_order, simple_group;
198 
199  /*
200  ordered_index_usage is set if an ordered index access
201  should be used instead of a filesort when computing
202  ORDER/GROUP BY.
203  */
204  enum
205  {
206  ordered_index_void, // No ordered index avail.
207  ordered_index_group_by, // Use index for GROUP BY
208  ordered_index_order_by // Use index for ORDER BY
209  } ordered_index_usage;
210 
215  bool no_order;
218 
219  bool need_tmp;
220  int hidden_group_field_count;
221 
222  Key_use_array keyuse;
223 
225 
226  List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
228  List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
230  List<Item> procedure_fields_list;
231  int error;
232 
241  {
253  struct null {};
254 
255  public:
256  ORDER *order; //< ORDER expression that we are wrapping with this class
257  Explain_sort_clause src; //< origin of order list
258 
259  private:
260  int flags; //< bitmap of Explain_sort_property
261 
262  public:
263  ORDER_with_src() { clean(); }
264 
265  ORDER_with_src(ORDER *order_arg, Explain_sort_clause src_arg)
266  : order(order_arg), src(src_arg), flags(order_arg ? ESP_EXISTS : ESP_none)
267  {}
268 
274  ORDER_with_src &operator=(null *) { clean(); return *this; }
275 
281  ORDER_with_src(null *) { clean(); }
282 
295  operator ORDER *() { return order; }
296  operator const ORDER *() const { return order; }
297 
298  ORDER* operator->() const { return order; }
299 
300  void clean() { order= NULL; src= ESC_none; flags= ESP_none; }
301 
302  void set_flag(Explain_sort_property flag)
303  {
304  DBUG_ASSERT(order);
305  flags|= flag;
306  }
307  void reset_flag(Explain_sort_property flag) { flags&= ~flag; }
308  bool get_flag(Explain_sort_property flag) const {
309  DBUG_ASSERT(order);
310  return flags & flag;
311  }
312  int get_flags() const { DBUG_ASSERT(order); return flags; }
313  };
314 
318  ORDER_with_src order, group_list;
319 
324 
347  COND_EQUAL *cond_equal;
348  /*
349  Join tab to return to. Points to an element of join->join_tab array, or to
350  join->join_tab[-1].
351  This is used at execution stage to shortcut join enumeration. Currently
352  shortcutting is done to handle outer joins or handle semi-joins with
353  FirstMatch strategy.
354  */
355  JOIN_TAB *return_tab;
356 
357  /*
358  Used pointer reference for this select.
359  select_lex->ref_pointer_array contains five "slices" of the same length:
360  |========|========|========|========|========|
361  ref_ptrs items0 items1 items2 items3
362  */
363  Ref_ptr_array ref_ptrs;
364  // Copy of the initial slice above, to be used with different lists
365  Ref_ptr_array items0, items1, items2, items3;
366  // Used by rollup, to restore ref_ptrs after overwriting it.
367  Ref_ptr_array current_ref_ptrs;
368 
369  const char *zero_result_cause;
370 
371  bool union_part;
372  bool optimized;
373 
387 
388  // true: No need to run DTORs on pointers.
390 
391  /* Temporary tables used to weed-out semi-join duplicates */
392  List<TABLE> sj_tmp_tables;
393  List<Semijoin_mat_exec> sjm_exec_list;
394  /* end of allocation caching storage */
395 
400 
401  JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
402  select_result *result_arg)
403  : keyuse(thd_arg->mem_root),
404  fields_list(fields_arg),
405  sj_subselects(thd_arg->mem_root)
406  {
407  init(thd_arg, fields_arg, select_options_arg, result_arg);
408  }
409 
410  void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
411  select_result *result_arg)
412  {
413  join_tab= 0;
414  tables= 0;
415  primary_tables= 0;
416  const_tables= 0;
417  tmp_tables= 0;
418  const_table_map= 0;
419  join_list= 0;
420  implicit_grouping= FALSE;
421  sort_and_group= 0;
422  first_record= 0;
423  do_send_rows= 1;
424  send_records= 0;
425  found_records= 0;
426  fetch_limit= HA_POS_ERROR;
427  min_ft_matches= HA_POS_ERROR;
428  examined_rows= 0;
429  thd= thd_arg;
430  sum_funcs= sum_funcs2= 0;
432  select_options= select_options_arg;
433  result= result_arg;
434  lock= thd_arg->lock;
435  select_lex= 0; //for safety
436  select_distinct= test(select_options & SELECT_DISTINCT);
437  no_order= 0;
438  simple_order= 0;
439  simple_group= 0;
440  ordered_index_usage= ordered_index_void;
441  skip_sort_order= 0;
442  need_tmp= 0;
443  hidden_group_field_count= 0; /*safety*/
444  error= 0;
445  return_tab= 0;
446  ref_ptrs.reset();
447  items0.reset();
448  items1.reset();
449  items2.reset();
450  items3.reset();
453  cond_equal= 0;
455 
456  all_fields= fields_arg;
457  if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
458  fields_list= fields_arg;
459  keyuse.clear();
460  tmp_table_param.init();
461  tmp_table_param.end_write_records= HA_POS_ERROR;
462  rollup.state= ROLLUP::STATE_NONE;
463 
464  no_const_tables= FALSE;
465  /* can help debugging (makes smaller test cases): */
466  DBUG_EXECUTE_IF("no_const_tables",no_const_tables= TRUE;);
467  first_select= sub_select;
468  set_group_rpa= false;
469  group_sent= 0;
470  }
471 
473  bool plan_is_const() const { return const_tables == primary_tables; }
474 
480 
481  int prepare(TABLE_LIST *tables, uint wind_num,
482  Item *conds, uint og_num, ORDER *order, ORDER *group,
483  Item *having,
484  SELECT_LEX *select, SELECT_LEX_UNIT *unit);
485  int optimize();
486  void reset();
487  void exec();
488  bool prepare_result(List<Item> **columns_list);
489  bool explain();
490  bool destroy();
491  void restore_tmp();
492  bool alloc_func_list();
493  bool flatten_subqueries();
495  List<Item> &send_fields,
496  bool before_group_by, bool recompute= FALSE);
497 
500  {
501  size_t slice_sz= select_lex->ref_pointer_array.size() / 5U;
502  DBUG_ASSERT(select_lex->ref_pointer_array.size() % 5 == 0);
503  DBUG_ASSERT(slice_num < 5U);
504  return Ref_ptr_array(&select_lex->ref_pointer_array[slice_num * slice_sz],
505  slice_sz);
506  }
507 
514  {
515  DBUG_ASSERT(dst_arr.size() >= src_arr.size());
516  void *dest= dst_arr.array();
517  const void *src= src_arr.array();
518  memcpy(dest, src, src_arr.size() * src_arr.element_size());
519  }
520 
523  {
524  copy_ref_ptr_array(ref_ptrs, src_arr);
525  current_ref_ptrs= src_arr;
526  }
527 
530  {
531  items0= ref_ptr_array_slice(1);
532  copy_ref_ptr_array(items0, ref_ptrs);
533  current_ref_ptrs= items0;
534  }
535 
536  bool rollup_init();
539  Item_sum ***func);
540  int rollup_send_data(uint idx);
541  int rollup_write_data(uint idx, TABLE *table);
542  void remove_subq_pushed_predicates(Item **where);
549  void join_free();
551  void cleanup(bool full);
552  void clear();
553  bool save_join_tab();
554  void restore_join_tab();
555  bool init_save_join_tab();
567  {
568  return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
569  group_list == NULL && !group_optimized_away &&
570  select_lex->having_value != Item::COND_FALSE);
571  }
572  bool change_result(select_result *result);
573  bool is_top_level_join() const
574  {
575  return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
576  select_lex == unit->fake_select_lex));
577  }
578  bool cache_const_exprs();
579  bool generate_derived_keys();
581  bool get_best_combination();
583  bool add_sorting_to_table(JOIN_TAB *tab, ORDER_with_src *order);
585  void refine_best_rowcount();
586 
587 private:
593  void send_data();
594 
611  bool create_intermediate_table(JOIN_TAB *tab, List<Item> *tmp_table_fields,
612  ORDER_with_src &tmp_table_group,
613  bool save_sum_fields);
618  bool create_first_intermediate_table();
625  void optimize_distinct();
626 
638  void optimize_fts_query();
639 
640 
644  void optimize_fts_limit_query();
645 
657  void replace_item_field(const char* field_name, Item* new_item);
658 
659 #ifdef WITH_PARTITION_STORAGE_ENGINE
660  bool prune_table_partitions(THD *thd);
661 #endif
662 
666  bool implicit_grouping;
667 
668  void set_prefix_tables();
669  void cleanup_item_list(List<Item> &items) const;
670 public: // @todo: Make private
671  void set_semijoin_embedding();
672 private:
673  void set_semijoin_info();
674  bool set_access_methods();
675  bool setup_materialized_table(JOIN_TAB *tab, uint tableno,
676  const POSITION *inner_pos,
677  POSITION *sjm_pos);
678  bool make_tmp_tables_info();
679  bool compare_costs_of_subquery_strategies(
681 
683  class Prepare_error_tracker
684  {
685 public:
686  Prepare_error_tracker(THD *thd_arg) : thd(thd_arg) {}
687  ~Prepare_error_tracker()
688  {
689  if (unlikely(thd->is_error()))
690  thd->lex->mark_broken();
691  }
692 private:
693  THD *const thd;
694  };
695 
696 };
697 
698 
699 bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno,
700  bool other_tbls_ok);
701 void update_depend_map(JOIN *join);
702 void reset_nj_counters(List<TABLE_LIST> *join_list);
703 Item *remove_eq_conds(THD *thd, Item *cond, Item::cond_result *cond_value);
704 Item *optimize_cond(THD *thd, Item *conds, COND_EQUAL **cond_equal,
705  List<TABLE_LIST> *join_list,
706  bool build_equalities, Item::cond_result *cond_value);
708  COND_EQUAL *cond_equal,
709  void *table_join_idx);
710 Item *build_equal_items(THD *thd, Item *cond,
711  COND_EQUAL *inherited, bool do_inherit,
712  List<TABLE_LIST> *join_list,
713  COND_EQUAL **cond_equal_ref);
714 bool is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args);
715 Key_use_array *create_keyuse_for_table(THD *thd, TABLE *table, uint keyparts,
716  Item_field **fields,
717  List<Item> outer_exprs);
718 Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
719  bool *inherited_fl);
720 Item_field *get_best_field(Item_field *item_field, COND_EQUAL *cond_equal);
721 Item *
722 make_cond_for_table(Item *cond, table_map tables, table_map used_table,
723  bool exclude_expensive_cond);
724 
731 inline bool field_time_cmp_date(const Field *f, const Item *v)
732 {
733  return f->is_temporal() && !f->is_temporal_with_date() &&
734  v->is_temporal_with_date();
735 }
736 
737 #endif /* SQL_OPTIMIZER_INCLUDED */