item_subselect.h 7.42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/* Copyright (C) 2000 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* subselect Item */

#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

unknown's avatar
unknown committed
23 24
class st_select_lex;
class st_select_lex_unit;
25 26
class JOIN;
class select_subselect;
unknown's avatar
unknown committed
27
class subselect_engine;
unknown's avatar
unknown committed
28 29 30
class Item_bool_func2;

typedef Item_bool_func2* (*compare_func_creator)(Item*, Item*);
31

unknown's avatar
unknown committed
32
/* base class for subselects */
33

unknown's avatar
unknown committed
34
class Item_subselect :public Item_result_field
35
{
unknown's avatar
unknown committed
36 37
  my_bool engine_owner; /* Is this item owner of engine */
  my_bool value_assigned; /* value already assigned to subselect */
38
protected:
unknown's avatar
unknown committed
39 40
  /* substitution instead of subselect in case of optimization */
  Item *substitution;
unknown's avatar
unknown committed
41 42 43
  /* engine that perform execution of subselect (single select or union) */
  subselect_engine *engine; 
  /* allowed number of columns (1 for single value subqueries) */
unknown's avatar
unknown committed
44
  uint max_columns;
45 46
  /* work with 'substitution' */
  bool have_to_be_excluded;
47 48

public:
49
  Item_subselect();
50 51
  Item_subselect(Item_subselect *item)
  {
unknown's avatar
unknown committed
52
    substitution= item->substitution;
53 54
    null_value= item->null_value;
    decimals= item->decimals;
unknown's avatar
unknown committed
55
    max_columns= item->max_columns;
unknown's avatar
unknown committed
56 57
    engine= item->engine;
    engine_owner= 0;
58 59
    name= item->name;
  }
60 61 62 63 64 65

  /* 
     We need this method, because some compilers do not allow 'this'
     pointer in constructor initialization list, but we need pass pointer
     to subselect Item class to select_subselect classes constructor.
  */
unknown's avatar
unknown committed
66
  virtual void init (THD *thd, st_select_lex *select_lex, 
unknown's avatar
unknown committed
67
		     select_subselect *result);
68

unknown's avatar
unknown committed
69
  ~Item_subselect();
70
  virtual void reset() 
unknown's avatar
unknown committed
71 72 73
  {
    null_value= 1;
  }
unknown's avatar
unknown committed
74
  virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
unknown's avatar
unknown committed
75 76
  bool assigned() { return value_assigned; }
  void assigned(bool a) { value_assigned= a; }
77
  enum Type type() const;
unknown's avatar
unknown committed
78 79 80 81 82
  bool is_null()
  {
    val_int();
    return null_value;
  }
unknown's avatar
unknown committed
83
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
84
  virtual void fix_length_and_dec();
unknown's avatar
unknown committed
85
  table_map used_tables() const;
86 87

  friend class select_subselect;
unknown's avatar
unknown committed
88
  friend class Item_in_optimizer;
89 90
};

unknown's avatar
unknown committed
91 92
/* single value subselect */

93
class Item_cache;
unknown's avatar
unknown committed
94
class Item_singlerow_subselect :public Item_subselect
unknown's avatar
unknown committed
95 96
{
protected:
97
  Item_cache *value, **row;
unknown's avatar
unknown committed
98
public:
unknown's avatar
unknown committed
99 100
  Item_singlerow_subselect(THD *thd, st_select_lex *select_lex);
  Item_singlerow_subselect(Item_singlerow_subselect *item):
unknown's avatar
unknown committed
101 102
    Item_subselect(item)
  {
103
    value= item->value;
unknown's avatar
unknown committed
104 105 106
    max_length= item->max_length;
    decimals= item->decimals;
  }
107
  void reset();
unknown's avatar
unknown committed
108
  void select_transformer(THD *thd, st_select_lex_unit *unit);
109
  void store(uint i, Item* item);
110
  double val();
unknown's avatar
unknown committed
111 112
  longlong val_int ();
  String *val_str (String *);
unknown's avatar
unknown committed
113
  Item *new_item() { return new Item_singlerow_subselect(this); }
114
  enum Item_result result_type() const;
115
  void fix_length_and_dec();
unknown's avatar
unknown committed
116

117 118 119 120 121 122 123
  uint cols();
  Item* el(uint i) { return (Item*)row[i]; }
  Item** addr(uint i) { return (Item**)row + i; }
  bool check_cols(uint c);
  bool null_inside();
  void bring_value();

unknown's avatar
unknown committed
124
  friend class select_singlerow_subselect;
unknown's avatar
unknown committed
125 126 127 128 129 130 131
};

/* exists subselect */

class Item_exists_subselect :public Item_subselect
{
protected:
unknown's avatar
unknown committed
132
  longlong value; /* value of this item (boolean: exists/not-exists) */
unknown's avatar
unknown committed
133 134

public:
unknown's avatar
unknown committed
135
  Item_exists_subselect(THD *thd, st_select_lex *select_lex);
unknown's avatar
unknown committed
136 137 138 139 140
  Item_exists_subselect(Item_exists_subselect *item):
    Item_subselect(item)
  {
    value= item->value;
  }
unknown's avatar
unknown committed
141 142
  Item_exists_subselect(): Item_subselect() {}

143
  void reset() 
unknown's avatar
unknown committed
144 145 146 147
  {
    value= 0;
  }

unknown's avatar
unknown committed
148 149 150 151 152
  Item *new_item() { return new Item_exists_subselect(this); }
  enum Item_result result_type() const { return INT_RESULT;}
  longlong val_int();
  double val();
  String *val_str(String*);
153
  void fix_length_and_dec();
154

unknown's avatar
unknown committed
155 156
  friend class select_exists_subselect;
};
unknown's avatar
unknown committed
157

unknown's avatar
unknown committed
158 159 160 161
/* IN subselect */

class Item_in_subselect :public Item_exists_subselect
{
unknown's avatar
unknown committed
162 163
protected:
  Item * left_expr;
164
  bool was_null;
unknown's avatar
unknown committed
165 166 167
public:
  Item_in_subselect(THD *thd, Item * left_expr, st_select_lex *select_lex);
  Item_in_subselect(Item_in_subselect *item);
unknown's avatar
unknown committed
168
  Item_in_subselect(): Item_exists_subselect() {}
169 170 171 172 173 174
  void reset() 
  {
    value= 0;
    null_value= 0;
    was_null= 0;
  }
unknown's avatar
unknown committed
175 176
  virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
  void single_value_transformer(THD *thd, st_select_lex_unit *unit,
unknown's avatar
unknown committed
177
				Item *left_expr, compare_func_creator func);
unknown's avatar
unknown committed
178 179
  void row_value_transformer(THD *thd, st_select_lex_unit *unit,
			     Item *left_expr);
180 181 182 183 184 185
  longlong val_int();
  double val();
  String *val_str(String*);

  friend class Item_asterisk_remover;
  friend class Item_ref_null_helper;
186
  friend class Item_is_not_null_test;
unknown's avatar
unknown committed
187 188 189 190 191 192 193 194 195 196 197 198
};

/* ALL/ANY/SOME subselect */
class Item_allany_subselect :public Item_in_subselect
{
protected:
  compare_func_creator func;

public:
  Item_allany_subselect(THD *thd, Item * left_expr, compare_func_creator f,
		     st_select_lex *select_lex);
  Item_allany_subselect(Item_allany_subselect *item);
unknown's avatar
unknown committed
199
  virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
unknown's avatar
unknown committed
200 201
};

unknown's avatar
unknown committed
202
class subselect_engine: public Sql_alloc
unknown's avatar
unknown committed
203 204 205 206 207
{
protected:
  select_subselect *result; /* results storage class */
  THD *thd; /* pointer to current THD */
  Item_subselect *item; /* item, that use this engine */
208
  enum Item_result res_type; /* type of results */
unknown's avatar
unknown committed
209
  bool maybe_null; /* may be null (first item in select) */
unknown's avatar
unknown committed
210 211 212 213 214 215 216
public:

  subselect_engine(THD *thd, Item_subselect *si, select_subselect *res) 
  {
    result= res;
    item= si;
    this->thd= thd;
217
    res_type= STRING_RESULT;
unknown's avatar
unknown committed
218
    maybe_null= 0;
unknown's avatar
unknown committed
219
  }
unknown's avatar
unknown committed
220
  virtual ~subselect_engine() {}; // to satisfy compiler
221

unknown's avatar
unknown committed
222
  virtual int prepare()= 0;
223
  virtual void fix_length_and_dec(Item_cache** row)= 0;
unknown's avatar
unknown committed
224 225
  virtual int exec()= 0;
  virtual uint cols()= 0; /* return number of columnss in select */
226 227
  virtual bool dependent()= 0; /* depended from outer select */
  virtual bool uncacheable()= 0; /* query is uncacheable */
228
  enum Item_result type() { return res_type; }
unknown's avatar
unknown committed
229
  virtual void exclude()= 0;
unknown's avatar
unknown committed
230
  bool may_be_null() { return maybe_null; };
unknown's avatar
unknown committed
231 232 233 234
};

class subselect_single_select_engine: public subselect_engine
{
unknown's avatar
unknown committed
235
  my_bool prepared; /* simple subselect is prepared */
unknown's avatar
unknown committed
236
  my_bool optimized; /* simple subselect is optimized */
unknown's avatar
unknown committed
237
  my_bool executed; /* simple subselect is executed */
unknown's avatar
unknown committed
238 239 240 241 242 243
  st_select_lex *select_lex; /* corresponding select_lex */
  JOIN * join; /* corresponding JOIN structure */
public:
  subselect_single_select_engine(THD *thd, st_select_lex *select,
				 select_subselect *result,
				 Item_subselect *item);
unknown's avatar
unknown committed
244
  int prepare();
245
  void fix_length_and_dec(Item_cache** row);
unknown's avatar
unknown committed
246 247
  int exec();
  uint cols();
248 249
  bool dependent();
  bool uncacheable();
unknown's avatar
unknown committed
250
  void exclude();
unknown's avatar
unknown committed
251 252 253 254 255 256 257 258 259 260
};

class subselect_union_engine: public subselect_engine
{
  st_select_lex_unit *unit;  /* corresponding unit structure */
public:
  subselect_union_engine(THD *thd,
			 st_select_lex_unit *u,
			 select_subselect *result,
			 Item_subselect *item);
unknown's avatar
unknown committed
261
  int prepare();
262
  void fix_length_and_dec(Item_cache** row);
unknown's avatar
unknown committed
263 264
  int exec();
  uint cols();
265 266
  bool dependent();
  bool uncacheable();
unknown's avatar
unknown committed
267
  void exclude();
unknown's avatar
unknown committed
268
};