item_subselect.h
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:11k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* subselect Item */
  14. #ifdef USE_PRAGMA_INTERFACE
  15. #pragma interface /* gcc class implementation */
  16. #endif
  17. class st_select_lex;
  18. class st_select_lex_unit;
  19. class JOIN;
  20. class select_subselect;
  21. class subselect_engine;
  22. class Item_bool_func2;
  23. class Statement;
  24. /* base class for subselects */
  25. class Item_subselect :public Item_result_field
  26. {
  27.   my_bool value_assigned; /* value already assigned to subselect */
  28. protected:
  29.   /* thread handler, will be assigned in fix_fields only */
  30.   THD *thd;
  31.   /* substitution instead of subselect in case of optimization */
  32.   Item *substitution;
  33.   /* unit of subquery */
  34.   st_select_lex_unit *unit;
  35.   /* engine that perform execution of subselect (single select or union) */
  36.   subselect_engine *engine;
  37.   /* old engine if engine was changed */
  38.   subselect_engine *old_engine;
  39.   /* cache of used external tables */
  40.   table_map used_tables_cache;
  41.   /* allowed number of columns (1 for single value subqueries) */
  42.   uint max_columns;
  43.   /* where subquery is placed */
  44.   enum_parsing_place parsing_place;
  45.   /* work with 'substitution' */
  46.   bool have_to_be_excluded;
  47.   /* cache of constant state */
  48.   bool const_item_cache;
  49. public:
  50.   /* changed engine indicator */
  51.   bool engine_changed;
  52.   /* subquery is transformed */
  53.   bool changed;
  54.   enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
  55.   enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
  56.   EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
  57.   Item_subselect();
  58.   virtual subs_type substype() { return UNKNOWN_SUBS; }
  59.   /*
  60.      We need this method, because some compilers do not allow 'this'
  61.      pointer in constructor initialization list, but we need pass pointer
  62.      to subselect Item class to select_subselect classes constructor.
  63.   */
  64.   virtual void init (st_select_lex *select_lex,
  65.      select_subselect *result);
  66.   ~Item_subselect();
  67.   void cleanup();
  68.   virtual void reset()
  69.   {
  70.     null_value= 1;
  71.   }
  72.   virtual trans_res select_transformer(JOIN *join);
  73.   bool assigned() { return value_assigned; }
  74.   void assigned(bool a) { value_assigned= a; }
  75.   enum Type type() const;
  76.   bool is_null()
  77.   {
  78.     val_int();
  79.     return null_value;
  80.   }
  81.   bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
  82.   virtual bool exec();
  83.   virtual void fix_length_and_dec();
  84.   table_map used_tables() const;
  85.   bool const_item() const;
  86.   inline table_map get_used_tables_cache() { return used_tables_cache; }
  87.   inline bool get_const_item_cache() { return const_item_cache; }
  88.   Item *get_tmp_table_item(THD *thd);
  89.   void update_used_tables();
  90.   void print(String *str);
  91.   bool change_engine(subselect_engine *eng)
  92.   {
  93.     old_engine= engine;
  94.     engine= eng;
  95.     engine_changed= 1;
  96.     return eng == 0;
  97.   }
  98.   /*
  99.     Used by max/min subquery to initialize value presence registration
  100.     mechanism. Engine call this method before rexecution query.
  101.   */
  102.   virtual void reset_value_registration() {}
  103.   friend class select_subselect;
  104.   friend class Item_in_optimizer;
  105.   friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **);
  106.   friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **);
  107. };
  108. /* single value subselect */
  109. class Item_cache;
  110. class Item_singlerow_subselect :public Item_subselect
  111. {
  112. protected:
  113.   Item_cache *value, **row;
  114. public:
  115.   Item_singlerow_subselect(st_select_lex *select_lex);
  116.   Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
  117.   void cleanup();
  118.   subs_type substype() { return SINGLEROW_SUBS; }
  119.   void reset();
  120.   trans_res select_transformer(JOIN *join);
  121.   void store(uint i, Item* item);
  122.   double val();
  123.   longlong val_int ();
  124.   String *val_str (String *);
  125.   enum Item_result result_type() const;
  126.   void fix_length_and_dec();
  127.   uint cols();
  128.   Item* el(uint i) { return my_reinterpret_cast(Item*)(row[i]); }
  129.   Item** addr(uint i) { return (Item**)row + i; }
  130.   bool check_cols(uint c);
  131.   bool null_inside();
  132.   void bring_value();
  133.   friend class select_singlerow_subselect;
  134. };
  135. /* used in static ALL/ANY optimisation */
  136. class select_max_min_finder_subselect;
  137. class Item_maxmin_subselect :public Item_singlerow_subselect
  138. {
  139. protected:
  140.   bool max;
  141.   bool was_values;  // Set if we have found at least one row
  142. public:
  143.   Item_maxmin_subselect(Item_subselect *parent,
  144. st_select_lex *select_lex, bool max);
  145.   void print(String *str);
  146.   void cleanup();
  147.   bool any_value() { return was_values; }
  148.   void register_value() { was_values= TRUE; }
  149.   void reset_value_registration() { was_values= FALSE; }
  150. };
  151. /* exists subselect */
  152. class Item_exists_subselect :public Item_subselect
  153. {
  154. protected:
  155.   longlong value; /* value of this item (boolean: exists/not-exists) */
  156. public:
  157.   Item_exists_subselect(st_select_lex *select_lex);
  158.   Item_exists_subselect(): Item_subselect() {}
  159.   subs_type substype() { return EXISTS_SUBS; }
  160.   void reset() 
  161.   {
  162.     value= 0;
  163.   }
  164.   enum Item_result result_type() const { return INT_RESULT;}
  165.   longlong val_int();
  166.   double val();
  167.   String *val_str(String*);
  168.   void fix_length_and_dec();
  169.   void print(String *str);
  170.   friend class select_exists_subselect;
  171.   friend class subselect_uniquesubquery_engine;
  172.   friend class subselect_indexsubquery_engine;
  173. };
  174. /* IN subselect */
  175. class Item_in_subselect :public Item_exists_subselect
  176. {
  177. protected:
  178.   Item *left_expr;
  179.   /*
  180.     expr & optimizer used in subselect rewriting to store Item for
  181.     all JOIN in UNION
  182.   */
  183.   Item *expr;
  184.   Item_in_optimizer *optimizer;
  185.   bool was_null;
  186.   bool abort_on_null;
  187.   bool transformed;
  188. public:
  189.   Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
  190.   Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
  191.   Item_in_subselect()
  192.     :Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
  193.      upper_item(0)
  194.   {}
  195.   subs_type substype() { return IN_SUBS; }
  196.   void reset() 
  197.   {
  198.     value= 0;
  199.     null_value= 0;
  200.     was_null= 0;
  201.   }
  202.   trans_res select_transformer(JOIN *join);
  203.   trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
  204.   trans_res single_value_transformer(JOIN *join, Comp_creator *func);
  205.   trans_res row_value_transformer(JOIN * join);
  206.   longlong val_int();
  207.   double val();
  208.   String *val_str(String*);
  209.   void top_level_item() { abort_on_null=1; }
  210.   bool test_limit(st_select_lex_unit *unit);
  211.   void print(String *str);
  212.   friend class Item_ref_null_helper;
  213.   friend class Item_is_not_null_test;
  214.   friend class subselect_indexsubquery_engine;
  215. };
  216. /* ALL/ANY/SOME subselect */
  217. class Item_allany_subselect :public Item_in_subselect
  218. {
  219. protected:
  220.   Comp_creator *func;
  221. public:
  222.   bool all;
  223.   Item_allany_subselect(Item * left_expr, Comp_creator *f,
  224.      st_select_lex *select_lex, bool all);
  225.   // only ALL subquery has upper not
  226.   subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
  227.   trans_res select_transformer(JOIN *join);
  228.   void print(String *str);
  229. };
  230. class subselect_engine: public Sql_alloc
  231. {
  232. protected:
  233.   select_subselect *result; /* results storage class */
  234.   THD *thd; /* pointer to current THD */
  235.   Item_subselect *item; /* item, that use this engine */
  236.   enum Item_result res_type; /* type of results */
  237.   bool maybe_null; /* may be null (first item in select) */
  238. public:
  239.   subselect_engine(Item_subselect *si, select_subselect *res)
  240.     :thd(0)
  241.   {
  242.     result= res;
  243.     item= si;
  244.     res_type= STRING_RESULT;
  245.     maybe_null= 0;
  246.   }
  247.   virtual ~subselect_engine() {}; // to satisfy compiler
  248.   virtual void cleanup()= 0;
  249.   // set_thd should be called before prepare()
  250.   void set_thd(THD *thd_arg) { thd= thd_arg; }
  251.   THD * get_thd() { return thd; }
  252.   virtual int prepare()= 0;
  253.   virtual void fix_length_and_dec(Item_cache** row)= 0;
  254.   virtual int exec()= 0;
  255.   virtual uint cols()= 0; /* return number of columnss in select */
  256.   virtual uint8 uncacheable()= 0; /* query is uncacheable */
  257.   enum Item_result type() { return res_type; }
  258.   virtual void exclude()= 0;
  259.   bool may_be_null() { return maybe_null; };
  260.   virtual table_map upper_select_const_tables()= 0;
  261.   static table_map calc_const_tables(TABLE_LIST *);
  262.   virtual void print(String *str)= 0;
  263.   virtual int change_item(Item_subselect *si, select_subselect *result)= 0;
  264.   virtual bool no_tables()= 0;
  265. };
  266. class subselect_single_select_engine: public subselect_engine
  267. {
  268.   my_bool prepared; /* simple subselect is prepared */
  269.   my_bool optimized; /* simple subselect is optimized */
  270.   my_bool executed; /* simple subselect is executed */
  271.   st_select_lex *select_lex; /* corresponding select_lex */
  272.   JOIN * join; /* corresponding JOIN structure */
  273. public:
  274.   subselect_single_select_engine(st_select_lex *select,
  275.  select_subselect *result,
  276.  Item_subselect *item);
  277.   void cleanup();
  278.   int prepare();
  279.   void fix_length_and_dec(Item_cache** row);
  280.   int exec();
  281.   uint cols();
  282.   uint8 uncacheable();
  283.   void exclude();
  284.   table_map upper_select_const_tables();
  285.   void print (String *str);
  286.   int change_item(Item_subselect *si, select_subselect *result);
  287.   bool no_tables();
  288. };
  289. class subselect_union_engine: public subselect_engine
  290. {
  291.   st_select_lex_unit *unit;  /* corresponding unit structure */
  292. public:
  293.   subselect_union_engine(st_select_lex_unit *u,
  294.  select_subselect *result,
  295.  Item_subselect *item);
  296.   void cleanup();
  297.   int prepare();
  298.   void fix_length_and_dec(Item_cache** row);
  299.   int exec();
  300.   uint cols();
  301.   uint8 uncacheable();
  302.   void exclude();
  303.   table_map upper_select_const_tables();
  304.   void print (String *str);
  305.   int change_item(Item_subselect *si, select_subselect *result);
  306.   bool no_tables();
  307. };
  308. struct st_join_table;
  309. class subselect_uniquesubquery_engine: public subselect_engine
  310. {
  311. protected:
  312.   st_join_table *tab;
  313.   Item *cond;
  314. public:
  315.   // constructor can assign THD because it will be called after JOIN::prepare
  316.   subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
  317.   Item_subselect *subs, Item *where)
  318.     :subselect_engine(subs, 0), tab(tab_arg), cond(where)
  319.   {
  320.     set_thd(thd_arg);
  321.   }
  322.   ~subselect_uniquesubquery_engine();
  323.   void cleanup();
  324.   int prepare();
  325.   void fix_length_and_dec(Item_cache** row);
  326.   int exec();
  327.   uint cols() { return 1; }
  328.   uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
  329.   void exclude();
  330.   table_map upper_select_const_tables() { return 0; }
  331.   void print (String *str);
  332.   int change_item(Item_subselect *si, select_subselect *result);
  333.   bool no_tables();
  334. };
  335. class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
  336. {
  337.   bool check_null;
  338. public:
  339.   // constructor can assign THD because it will be called after JOIN::prepare
  340.   subselect_indexsubquery_engine(THD *thd, st_join_table *tab_arg,
  341.  Item_subselect *subs, Item *where,
  342.  bool chk_null)
  343.     :subselect_uniquesubquery_engine(thd, tab_arg, subs, where),
  344.      check_null(chk_null)
  345.   {}
  346.   int exec();
  347.   void print (String *str);
  348. };