MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_subselect.h
1 #ifndef ITEM_SUBSELECT_INCLUDED
2 #define ITEM_SUBSELECT_INCLUDED
3 
4 /* Copyright (c) 2002, 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 Foundation,
17  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
18 
19 /* subselect Item */
20 
21 class st_select_lex;
22 class st_select_lex_unit;
23 class JOIN;
24 class select_result_interceptor;
25 class subselect_engine;
27 class Item_bool_func2;
28 class Cached_item;
29 class Comp_creator;
30 
31 typedef class st_select_lex SELECT_LEX;
32 
37 typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
38 
39 /* base class for subselects */
40 
42 {
43 private:
44  bool value_assigned; /* value already assigned to subselect */
51  bool traced_before;
52 public:
53  /*
54  Used inside Item_subselect::fix_fields() according to this scenario:
55  > Item_subselect::fix_fields
56  > engine->prepare
57  > child_join->prepare
58  (Here we realize we need to do the rewrite and set
59  substitution= some new Item, eg. Item_in_optimizer )
60  < child_join->prepare
61  < engine->prepare
62  *ref= substitution;
63  < Item_subselect::fix_fields
64  */
65  Item *substitution;
66 public:
67  /* unit of subquery */
68  st_select_lex_unit *unit;
74 
76  const subselect_engine *get_engine_for_explain() const { return engine; }
77 
78 protected:
79  /* engine that perform execution of subselect (single select or union) */
80  subselect_engine *engine;
81  /* old engine if engine was changed */
82  subselect_engine *old_engine;
83  /* cache of used external tables */
84  table_map used_tables_cache;
85  /* allowed number of columns (1 for single value subqueries) */
86  uint max_columns;
87  /* where subquery is placed */
88  enum_parsing_place parsing_place;
89  /* work with 'substitution' */
90  bool have_to_be_excluded;
91  /* cache of constant state */
92  bool const_item_cache;
93 
94 public:
95  /* changed engine indicator */
96  bool engine_changed;
97  /* subquery is transformed */
98  bool changed;
99 
100  enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
101  enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
102  EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
103 
104  Item_subselect();
105 
106  virtual subs_type substype() { return UNKNOWN_SUBS; }
107 
108  /*
109  We need this method, because some compilers do not allow 'this'
110  pointer in constructor initialization list, but we need to pass a pointer
111  to subselect Item class to select_result_interceptor's constructor.
112  */
113  virtual void init (st_select_lex *select_lex,
114  select_result_interceptor *result);
115 
116  ~Item_subselect();
117  virtual void cleanup();
118  virtual void reset()
119  {
120  null_value= 1;
121  }
122  virtual trans_res select_transformer(JOIN *join);
123  bool assigned() const { return value_assigned; }
124  void assigned(bool a) { value_assigned= a; }
125  enum Type type() const;
126  bool is_null()
127  {
128  update_null_value();
129  return null_value;
130  }
131  bool fix_fields(THD *thd, Item **ref);
132  void fix_after_pullout(st_select_lex *parent_select,
133  st_select_lex *removed_select);
134  virtual bool exec();
135  virtual void fix_length_and_dec();
136  table_map used_tables() const;
137  table_map not_null_tables() const { return 0; }
138  bool const_item() const;
139  inline table_map get_used_tables_cache() { return used_tables_cache; }
140  inline bool get_const_item_cache() { return const_item_cache; }
141  Item *get_tmp_table_item(THD *thd);
142  void update_used_tables();
143  virtual void print(String *str, enum_query_type query_type);
144  virtual bool have_guarded_conds() { return FALSE; }
145  bool change_engine(subselect_engine *eng)
146  {
147  old_engine= engine;
148  engine= eng;
149  engine_changed= 1;
150  return eng == 0;
151  }
152 
153  /*
154  True if this subquery has been already evaluated. Implemented only for
155  single select and union subqueries only.
156  */
157  bool is_evaluated() const;
158  bool is_uncacheable() const;
159 
160  /*
161  Used by max/min subquery to initialize value presence registration
162  mechanism. Engine call this method before rexecution query.
163  */
164  virtual void reset_value_registration() {}
165  enum_parsing_place place() { return parsing_place; }
166  bool walk_join_condition(List<TABLE_LIST> *tables, Item_processor processor,
167  bool walk_subquery, uchar *argument);
168  bool walk_body(Item_processor processor, bool walk_subquery, uchar *arg);
169  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
170  virtual bool explain_subquery_checker(uchar **arg);
171  bool inform_item_in_cond_of_tab(uchar *join_tab_index);
172  virtual bool clean_up_after_removal(uchar *arg);
173 
174  const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
175 
176  friend class select_result_interceptor;
177  friend class Item_in_optimizer;
178  friend bool Item_field::fix_fields(THD *, Item **);
179  friend int Item_field::fix_outer_field(THD *, Field **, Item **);
180  friend bool Item_ref::fix_fields(THD *, Item **);
181  friend void Item_ident::fix_after_pullout(st_select_lex *parent_select,
182  st_select_lex *removed_selec);
183  friend void mark_select_range_as_dependent(THD*,
184  st_select_lex*, st_select_lex*,
185  Field*, Item*, Item_ident*);
186 };
187 
188 /* single value subselect */
189 
190 class Item_cache;
192 {
193 protected:
194  Item_cache *value, **row;
195  bool no_rows;
196 public:
197  Item_singlerow_subselect(st_select_lex *select_lex);
199  Item_subselect(), value(0), row (0), no_rows(false) {}
200 
201  virtual void cleanup();
202  subs_type substype() { return SINGLEROW_SUBS; }
203 
204  virtual void reset();
205  trans_res select_transformer(JOIN *join);
206  void store(uint i, Item* item);
207  double val_real();
208  longlong val_int ();
209  String *val_str (String *);
210  my_decimal *val_decimal(my_decimal *);
211  bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
212  bool get_time(MYSQL_TIME *ltime);
213  bool val_bool();
214  enum Item_result result_type() const;
215  enum_field_types field_type() const;
216  void fix_length_and_dec();
217 
218  /*
219  Mark the subquery as having no rows.
220  If there are aggregate functions (in the outer query),
221  we need to generate a NULL row. @c return_zero_rows().
222  */
223  virtual void no_rows_in_result();
224 
225  uint cols();
226  Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); }
227  Item** addr(uint i) { return (Item**)row + i; }
228  bool check_cols(uint c);
229  bool null_inside();
230  void bring_value();
231 
244  st_select_lex* invalidate_and_restore_select_lex();
245 
246  friend class select_singlerow_subselect;
247 };
248 
249 /* used in static ALL/ANY optimization */
250 class select_max_min_finder_subselect;
252 {
253 protected:
254  bool max;
255  bool was_values; // Set if we have found at least one row
256 public:
257  Item_maxmin_subselect(THD *thd, Item_subselect *parent,
258  st_select_lex *select_lex, bool max, bool ignore_nulls);
259  virtual void print(String *str, enum_query_type query_type);
260  virtual void cleanup();
261  bool any_value() { return was_values; }
262  void register_value() { was_values= TRUE; }
263  void reset_value_registration() { was_values= FALSE; }
264 };
265 
266 /* exists subselect */
267 
269 {
270 protected:
271  bool value; /* value of this item (boolean: exists/not-exists) */
272 
273 public:
281 
292  };
293  enum_exec_method exec_method;
297  bool sj_chosen;
309 
310  Item_exists_subselect(st_select_lex *select_lex);
312  :Item_subselect(), value(false), exec_method(EXEC_UNSPECIFIED),
314  {}
315  virtual trans_res select_transformer(JOIN *join)
316  {
317  exec_method= EXEC_EXISTS;
318  return RES_OK;
319  }
320  subs_type substype() { return EXISTS_SUBS; }
321  virtual void reset()
322  {
323  value= 0;
324  }
325 
326  enum Item_result result_type() const { return INT_RESULT;}
327  longlong val_int();
328  double val_real();
329  String *val_str(String*);
331  bool val_bool();
332  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
333  {
334  return get_date_from_int(ltime, fuzzydate);
335  }
336  bool get_time(MYSQL_TIME *ltime)
337  {
338  return get_time_from_int(ltime);
339  }
340  void fix_length_and_dec();
341  virtual void print(String *str, enum_query_type query_type);
342 
343  friend class select_exists_subselect;
344  friend class subselect_indexsubquery_engine;
345 };
346 
347 
364 {
365 public:
366  Item *left_expr;
367 protected:
368  /*
369  Cache of the left operand of the subquery predicate. Allocated in the
370  runtime memory root, for each execution, thus need not be freed.
371  */
372  List<Cached_item> *left_expr_cache;
374 
376 
377  /*
378  expr & optimizer used in subselect rewriting to store Item for
379  all JOIN in UNION
380  */
381  Item *expr;
382  Item_in_optimizer *optimizer;
383  bool was_null;
384  bool abort_on_null;
385 private:
391  struct In2exists_info: public Sql_alloc
392  {
397  bool added_to_where;
403  } *in2exists_info;
404 
405  Item *remove_in2exists_conds(Item* conds);
406 
407 public:
408  /* Used to trigger on/off conditions that were pushed down to subselect */
409  bool *pushed_cond_guards;
410 
411  Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
412 
413  /*
414  Location of the subquery predicate. It is either
415  - pointer to join nest if the subquery predicate is in the ON expression
416  - (TABLE_LIST*)1 if the predicate is in the WHERE.
417  */
418  TABLE_LIST *expr_join_nest;
419 
420  bool in2exists_added_to_where() const
421  { return in2exists_info && in2exists_info->added_to_where; }
422 
424  bool originally_dependent() const
425  { return in2exists_info->originally_dependent; }
426 
427  bool *get_cond_guard(int i)
428  {
429  return pushed_cond_guards ? pushed_cond_guards + i : NULL;
430  }
431  void set_cond_guard_var(int i, bool v)
432  {
433  if ( pushed_cond_guards)
434  pushed_cond_guards[i]= v;
435  }
436  bool have_guarded_conds() { return test(pushed_cond_guards); }
437 
438  Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
440  :Item_exists_subselect(), left_expr(NULL), left_expr_cache(NULL),
441  left_expr_cache_filled(false), need_expr_cache(TRUE), expr(NULL),
442  optimizer(NULL), was_null(FALSE), abort_on_null(FALSE),
443  in2exists_info(NULL), pushed_cond_guards(NULL), upper_item(NULL)
444  {}
445  virtual void cleanup();
446  subs_type substype() { return IN_SUBS; }
447  virtual void reset()
448  {
449  value= 0;
450  null_value= 0;
451  was_null= 0;
452  }
453  trans_res select_transformer(JOIN *join);
454  trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
455  trans_res single_value_transformer(JOIN *join, Comp_creator *func);
456  trans_res row_value_transformer(JOIN * join);
458  Comp_creator *func);
459  trans_res row_value_in_to_exists_transformer(JOIN * join);
460  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
461  virtual bool exec();
462  longlong val_int();
463  double val_real();
464  String *val_str(String*);
466  void update_null_value () { (void) val_bool(); }
467  bool val_bool();
468  void top_level_item() { abort_on_null=1; }
469  inline bool is_top_level_item() { return abort_on_null; }
470  bool test_limit(st_select_lex_unit *unit);
471  virtual void print(String *str, enum_query_type query_type);
472  bool fix_fields(THD *thd, Item **ref);
473  void fix_after_pullout(st_select_lex *parent_select,
474  st_select_lex *removed_select);
475  bool init_left_expr_cache();
476 
481  bool finalize_exists_transform(SELECT_LEX *select_lex);
487 
488  friend class Item_ref_null_helper;
489  friend class Item_is_not_null_test;
490  friend class Item_in_optimizer;
491  friend class subselect_indexsubquery_engine;
492  friend class subselect_hash_sj_engine;
493 };
494 
495 
496 /* ALL/ANY/SOME subselect */
498 {
499 public:
500  chooser_compare_func_creator func_creator;
501  Comp_creator *func;
502  bool all;
503 
504  Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
505  st_select_lex *select_lex, bool all);
506 
507  // only ALL subquery has upper not
508  subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
509  trans_res select_transformer(JOIN *join);
510  virtual void print(String *str, enum_query_type query_type);
511 };
512 
513 
515 {
516 protected:
517  select_result_interceptor *result; /* results storage class */
518  Item_subselect *item; /* item, that use this engine */
519  enum Item_result res_type; /* type of results */
520  enum_field_types res_field_type; /* column type of the results */
521  bool maybe_null; /* may be null (first item in select) */
522 public:
523 
524  enum enum_engine_type {ABSTRACT_ENGINE, SINGLE_SELECT_ENGINE,
525  UNION_ENGINE, UNIQUESUBQUERY_ENGINE,
526  INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE};
527 
528  subselect_engine(Item_subselect *si, select_result_interceptor *res)
529  :result(res), item(si), res_type(STRING_RESULT),
530  res_field_type(MYSQL_TYPE_VAR_STRING), maybe_null(false)
531  {}
532  virtual ~subselect_engine() {}; // to satisfy compiler
536  virtual void cleanup()= 0;
537 
539  void set_thd_for_result();
540  virtual bool prepare()= 0;
541  virtual void fix_length_and_dec(Item_cache** row)= 0;
542  /*
543  Execute the engine
544 
545  SYNOPSIS
546  exec()
547 
548  DESCRIPTION
549  Execute the engine. The result of execution is subquery value that is
550  either captured by previously set up select_result-based 'sink' or
551  stored somewhere by the exec() method itself.
552 
553  RETURN
554  0 - OK
555  1 - Either an execution error, or the engine was "changed", and the
556  caller should call exec() again for the new engine.
557  */
558  virtual bool exec()= 0;
559  virtual uint cols() const = 0; /* return number of columns in select */
560  virtual uint8 uncacheable() const = 0; /* query is uncacheable */
561  virtual enum Item_result type() const { return res_type; }
562  virtual enum_field_types field_type() const { return res_field_type; }
563  virtual void exclude()= 0;
564  virtual bool may_be_null() const { return maybe_null; };
565  virtual table_map upper_select_const_tables() const = 0;
566  static table_map calc_const_tables(TABLE_LIST *);
567  virtual void print(String *str, enum_query_type query_type)= 0;
568  virtual bool change_result(Item_subselect *si,
569  select_result_interceptor *result)= 0;
570  virtual bool no_tables() const = 0;
571  virtual bool is_executed() const { return FALSE; }
572  virtual enum_engine_type engine_type() const { return ABSTRACT_ENGINE; }
573 #ifndef DBUG_OFF
574 
578  const Item_subselect *get_item() const { return item; }
579 #endif
580 
581 protected:
582  void set_row(List<Item> &item_list, Item_cache **row);
583 };
584 
585 
587 {
588 private:
589  bool prepared; /* simple subselect is prepared */
590  bool executed; /* simple subselect is executed */
591  bool optimize_error;
592  st_select_lex *select_lex; /* corresponding select_lex */
593  JOIN * join; /* corresponding JOIN structure */
594 public:
595  subselect_single_select_engine(st_select_lex *select,
596  select_result_interceptor *result,
597  Item_subselect *item);
598  virtual void cleanup();
599  virtual bool prepare();
600  virtual void fix_length_and_dec(Item_cache** row);
601  virtual bool exec();
602  virtual uint cols() const;
603  virtual uint8 uncacheable() const;
604  virtual void exclude();
605  virtual table_map upper_select_const_tables() const;
606  virtual void print (String *str, enum_query_type query_type);
607  virtual bool change_result(Item_subselect *si,
608  select_result_interceptor *result);
609  virtual bool no_tables() const;
610  virtual bool may_be_null() const;
611  virtual bool is_executed() const { return executed; }
612  virtual enum_engine_type engine_type() const { return SINGLE_SELECT_ENGINE; }
613 
614  friend class subselect_hash_sj_engine;
615  friend class Item_in_subselect;
616 };
617 
618 
620 {
621 public:
622  subselect_union_engine(st_select_lex_unit *u,
623  select_result_interceptor *result,
624  Item_subselect *item);
625  virtual void cleanup();
626  virtual bool prepare();
627  virtual void fix_length_and_dec(Item_cache** row);
628  virtual bool exec();
629  virtual uint cols() const;
630  virtual uint8 uncacheable() const;
631  virtual void exclude();
632  virtual table_map upper_select_const_tables() const;
633  virtual void print (String *str, enum_query_type query_type);
634  virtual bool change_result(Item_subselect *si,
635  select_result_interceptor *result);
636  virtual bool no_tables() const;
637  virtual bool is_executed() const;
638  virtual enum_engine_type engine_type() const { return UNION_ENGINE; }
639 
640 private:
641  st_select_lex_unit *unit; /* corresponding unit structure */
642 };
643 
644 
645 struct st_join_table;
646 
647 
665 {
666 protected:
667  st_join_table *tab;
668  Item *cond; /* The WHERE condition of subselect */
669 private:
670  /* FALSE for 'ref', TRUE for 'ref-or-null'. */
671  bool check_null;
672  /*
673  The "having" clause. This clause (further referred to as "artificial
674  having") was inserted by subquery transformation code. It contains
675  Item(s) that have a side-effect: they record whether the subquery has
676  produced a row with NULL certain components. We need to use it for cases
677  like
678  (oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
679  where we do index lookup on t.key=oe1 but need also to check if there
680  was a row such that t.no_key IS NULL.
681  */
682  Item *having;
687  bool unique;
688 public:
689 
690  // constructor can assign THD because it will be called after JOIN::prepare
691  subselect_indexsubquery_engine(THD *thd_arg, st_join_table *tab_arg,
692  Item_subselect *subs, Item *where,
693  Item *having_arg, bool chk_null,
694  bool unique_arg)
695  :subselect_engine(subs, 0), tab(tab_arg), cond(where),
696  check_null(chk_null), having(having_arg), unique(unique_arg)
697  {};
698  virtual bool exec();
699  virtual void print (String *str, enum_query_type query_type);
700  virtual enum_engine_type engine_type() const
701  { return unique ? UNIQUESUBQUERY_ENGINE : INDEXSUBQUERY_ENGINE; }
702  virtual void cleanup() {}
703  virtual bool prepare();
704  virtual void fix_length_and_dec(Item_cache** row);
705  virtual uint cols() const { return 1; }
706  virtual uint8 uncacheable() const { return UNCACHEABLE_DEPENDENT; }
707  virtual void exclude();
708  virtual table_map upper_select_const_tables() const { return 0; }
709  virtual bool change_result(Item_subselect *si,
710  select_result_interceptor *result);
711  virtual bool no_tables() const;
712  bool scan_table();
713  void copy_ref_key(bool *require_scan, bool *convert_error);
714 };
715 
716 /*
717  This function is actually defined in sql_parse.cc, but it depends on
718  chooser_compare_func_creator defined in this file.
719  */
720 Item * all_any_subquery_creator(Item *left_expr,
721  chooser_compare_func_creator cmp,
722  bool all,
723  SELECT_LEX *select_lex);
724 
725 
726 inline bool Item_subselect::is_evaluated() const
727 {
728  return engine->is_executed();
729 }
730 
731 
732 inline bool Item_subselect::is_uncacheable() const
733 {
734  return engine->uncacheable();
735 }
736 
737 
745 {
746 private:
747  /* TRUE if the subquery was materialized into a temp table. */
748  bool is_materialized;
754  enum nulls_exist
755  {
757  NEX_IRRELEVANT_OR_FALSE= 0,
759  NEX_UNKNOWN= 1,
761  NEX_TRUE= 2
762  };
763  enum nulls_exist mat_table_has_nulls;
764  /*
765  The old engine already chosen at parse time and stored in permanent memory.
766  Through this member we can re-create and re-prepare the join object
767  used to materialize the subquery for each execution of a prepared
768  statement. We also reuse the functionality of
769  subselect_single_select_engine::[prepare | cols].
770  */
771  subselect_single_select_engine *materialize_engine;
772  /* Temp table context of the outer select's JOIN. */
773  TMP_TABLE_PARAM *tmp_param;
774 
775 public:
776  subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
777  subselect_single_select_engine *old_engine)
778  :subselect_indexsubquery_engine(thd, NULL, in_predicate, NULL,
779  NULL, false, true),
780  is_materialized(false), materialize_engine(old_engine), tmp_param(NULL)
781  {}
783 
784  bool setup(List<Item> *tmp_columns);
785  virtual void cleanup();
786  virtual bool prepare()
787  {
788  return materialize_engine->prepare();
789  }
790  virtual bool exec();
791  virtual void print (String *str, enum_query_type query_type);
792  virtual uint cols() const
793  {
794  return materialize_engine->cols();
795  }
796  virtual enum_engine_type engine_type() const { return HASH_SJ_ENGINE; }
797 
798  const st_join_table *get_join_tab() const { return tab; }
799  Item *get_cond_for_explain() const { return cond; }
800 };
801 #endif /* ITEM_SUBSELECT_INCLUDED */