2002-05-12 22:46:42 +02:00
|
|
|
/* 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
|
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
class st_select_lex;
|
|
|
|
class st_select_lex_unit;
|
2002-05-12 22:46:42 +02:00
|
|
|
class JOIN;
|
|
|
|
class select_subselect;
|
2002-09-03 08:50:36 +02:00
|
|
|
class subselect_engine;
|
2002-11-07 22:45:19 +01:00
|
|
|
class Item_bool_func2;
|
|
|
|
|
|
|
|
typedef Item_bool_func2* (*compare_func_creator)(Item*, Item*);
|
2002-05-12 22:46:42 +02:00
|
|
|
|
2002-06-19 16:52:44 +02:00
|
|
|
/* base class for subselects */
|
2002-05-12 22:46:42 +02:00
|
|
|
|
2002-11-13 00:14:39 +01:00
|
|
|
class Item_subselect :public Item_result_field
|
2002-05-12 22:46:42 +02:00
|
|
|
{
|
2002-09-03 08:50:36 +02:00
|
|
|
my_bool engine_owner; /* Is this item owner of engine */
|
|
|
|
my_bool value_assigned; /* value already assigned to subselect */
|
2002-05-12 22:46:42 +02:00
|
|
|
protected:
|
2002-11-28 18:29:26 +01:00
|
|
|
/* substitution instead of subselect in case of optimization */
|
|
|
|
Item *substitution;
|
2002-09-03 08:50:36 +02:00
|
|
|
/* engine that perform execution of subselect (single select or union) */
|
|
|
|
subselect_engine *engine;
|
|
|
|
/* allowed number of columns (1 for single value subqueries) */
|
2002-06-19 16:52:44 +02:00
|
|
|
uint max_columns;
|
2002-12-06 20:55:53 +01:00
|
|
|
/* work with 'substitution' */
|
|
|
|
bool have_to_be_excluded;
|
2002-05-12 22:46:42 +02:00
|
|
|
|
|
|
|
public:
|
2002-10-08 22:49:59 +02:00
|
|
|
Item_subselect();
|
2002-05-12 22:46:42 +02:00
|
|
|
Item_subselect(Item_subselect *item)
|
|
|
|
{
|
2002-11-28 18:29:26 +01:00
|
|
|
substitution= item->substitution;
|
2002-05-12 22:46:42 +02:00
|
|
|
null_value= item->null_value;
|
|
|
|
decimals= item->decimals;
|
2002-06-19 16:52:44 +02:00
|
|
|
max_columns= item->max_columns;
|
2002-09-03 08:50:36 +02:00
|
|
|
engine= item->engine;
|
|
|
|
engine_owner= 0;
|
2002-05-12 22:46:42 +02:00
|
|
|
name= item->name;
|
|
|
|
}
|
2002-10-08 22:49:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2002-10-27 22:27:00 +01:00
|
|
|
virtual void init (THD *thd, st_select_lex *select_lex,
|
2002-11-07 22:45:19 +01:00
|
|
|
select_subselect *result);
|
2002-10-08 22:49:59 +02:00
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
~Item_subselect();
|
2002-12-06 20:55:53 +01:00
|
|
|
virtual void reset()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
null_value= 1;
|
|
|
|
}
|
2002-12-28 00:01:05 +01:00
|
|
|
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
2002-09-03 08:50:36 +02:00
|
|
|
bool assigned() { return value_assigned; }
|
|
|
|
void assigned(bool a) { value_assigned= a; }
|
2002-05-12 22:46:42 +02:00
|
|
|
enum Type type() const;
|
2002-12-15 10:14:53 +01:00
|
|
|
bool is_null()
|
|
|
|
{
|
|
|
|
val_int();
|
|
|
|
return null_value;
|
|
|
|
}
|
2002-07-01 13:14:51 +02:00
|
|
|
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
2002-09-28 17:34:56 +02:00
|
|
|
virtual void fix_length_and_dec();
|
2002-06-19 16:52:44 +02:00
|
|
|
table_map used_tables() const;
|
2002-11-13 23:26:18 +01:00
|
|
|
bool check_loop(uint id);
|
2002-05-12 22:46:42 +02:00
|
|
|
|
|
|
|
friend class select_subselect;
|
2002-12-19 20:15:09 +01:00
|
|
|
friend class Item_in_optimizer;
|
2002-05-12 22:46:42 +02:00
|
|
|
};
|
|
|
|
|
2002-06-19 16:52:44 +02:00
|
|
|
/* single value subselect */
|
|
|
|
|
2002-12-19 06:38:32 +01:00
|
|
|
class Item_cache;
|
2002-12-19 20:15:09 +01:00
|
|
|
class Item_singlerow_subselect :public Item_subselect
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
|
|
|
protected:
|
2002-12-19 06:38:33 +01:00
|
|
|
Item_cache *value, **row;
|
2002-06-19 16:52:44 +02:00
|
|
|
public:
|
2002-12-19 20:15:09 +01:00
|
|
|
Item_singlerow_subselect(THD *thd, st_select_lex *select_lex);
|
|
|
|
Item_singlerow_subselect(Item_singlerow_subselect *item):
|
2002-06-19 16:52:44 +02:00
|
|
|
Item_subselect(item)
|
|
|
|
{
|
2002-12-19 06:38:32 +01:00
|
|
|
value= item->value;
|
2002-06-19 16:52:44 +02:00
|
|
|
max_length= item->max_length;
|
|
|
|
decimals= item->decimals;
|
|
|
|
}
|
2002-12-19 06:38:32 +01:00
|
|
|
void reset();
|
2002-12-28 00:01:05 +01:00
|
|
|
void select_transformer(THD *thd, st_select_lex_unit *unit);
|
2002-12-19 06:38:33 +01:00
|
|
|
void store(uint i, Item* item);
|
2002-12-19 06:38:32 +01:00
|
|
|
double val();
|
2002-06-19 16:52:44 +02:00
|
|
|
longlong val_int ();
|
|
|
|
String *val_str (String *);
|
2002-12-19 20:15:09 +01:00
|
|
|
Item *new_item() { return new Item_singlerow_subselect(this); }
|
2002-12-19 06:38:32 +01:00
|
|
|
enum Item_result result_type() const;
|
2002-09-28 17:34:56 +02:00
|
|
|
void fix_length_and_dec();
|
2002-11-13 00:14:39 +01:00
|
|
|
|
2002-12-19 06:38:33 +01:00
|
|
|
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();
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
friend class select_singlerow_subselect;
|
2002-06-19 16:52:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* exists subselect */
|
|
|
|
|
|
|
|
class Item_exists_subselect :public Item_subselect
|
|
|
|
{
|
|
|
|
protected:
|
2002-09-03 08:50:36 +02:00
|
|
|
longlong value; /* value of this item (boolean: exists/not-exists) */
|
2002-06-19 16:52:44 +02:00
|
|
|
|
|
|
|
public:
|
2002-11-07 22:45:19 +01:00
|
|
|
Item_exists_subselect(THD *thd, st_select_lex *select_lex);
|
2002-06-19 16:52:44 +02:00
|
|
|
Item_exists_subselect(Item_exists_subselect *item):
|
|
|
|
Item_subselect(item)
|
|
|
|
{
|
|
|
|
value= item->value;
|
|
|
|
}
|
2002-10-27 22:27:00 +01:00
|
|
|
Item_exists_subselect(): Item_subselect() {}
|
|
|
|
|
2002-12-19 06:38:32 +01:00
|
|
|
void reset()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
value= 0;
|
|
|
|
}
|
|
|
|
|
2002-06-19 16:52:44 +02:00
|
|
|
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*);
|
2002-09-28 17:34:56 +02:00
|
|
|
void fix_length_and_dec();
|
2002-12-06 20:55:53 +01:00
|
|
|
|
2002-06-19 16:52:44 +02:00
|
|
|
friend class select_exists_subselect;
|
|
|
|
};
|
2002-09-03 08:50:36 +02:00
|
|
|
|
2002-10-27 22:27:00 +01:00
|
|
|
/* IN subselect */
|
|
|
|
|
|
|
|
class Item_in_subselect :public Item_exists_subselect
|
|
|
|
{
|
2002-11-07 22:45:19 +01:00
|
|
|
protected:
|
|
|
|
Item * left_expr;
|
2002-12-06 20:55:53 +01:00
|
|
|
bool was_null;
|
2002-10-27 22:27:00 +01:00
|
|
|
public:
|
|
|
|
Item_in_subselect(THD *thd, Item * left_expr, st_select_lex *select_lex);
|
|
|
|
Item_in_subselect(Item_in_subselect *item);
|
2002-11-07 22:45:19 +01:00
|
|
|
Item_in_subselect(): Item_exists_subselect() {}
|
2002-12-06 20:55:53 +01:00
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
value= 0;
|
|
|
|
null_value= 0;
|
|
|
|
was_null= 0;
|
|
|
|
}
|
2002-12-28 00:01:05 +01:00
|
|
|
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
|
|
|
void single_value_transformer(THD *thd, st_select_lex_unit *unit,
|
2002-11-07 22:45:19 +01:00
|
|
|
Item *left_expr, compare_func_creator func);
|
2002-12-28 00:01:05 +01:00
|
|
|
void row_value_transformer(THD *thd, st_select_lex_unit *unit,
|
|
|
|
Item *left_expr);
|
2002-12-06 20:55:53 +01:00
|
|
|
longlong val_int();
|
|
|
|
double val();
|
|
|
|
String *val_str(String*);
|
|
|
|
|
|
|
|
friend class Item_asterisk_remover;
|
|
|
|
friend class Item_ref_null_helper;
|
2002-11-07 22:45:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* 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);
|
2002-12-28 00:01:05 +01:00
|
|
|
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
2002-10-27 22:27:00 +01:00
|
|
|
};
|
|
|
|
|
2002-12-27 20:19:25 +01:00
|
|
|
class subselect_engine: public Sql_alloc
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
select_subselect *result; /* results storage class */
|
|
|
|
THD *thd; /* pointer to current THD */
|
|
|
|
Item_subselect *item; /* item, that use this engine */
|
2002-09-28 17:34:56 +02:00
|
|
|
enum Item_result res_type; /* type of results */
|
2002-12-27 20:19:25 +01:00
|
|
|
bool maybe_null; /* may be null (first item in select) */
|
2002-09-03 08:50:36 +02:00
|
|
|
public:
|
|
|
|
|
|
|
|
subselect_engine(THD *thd, Item_subselect *si, select_subselect *res)
|
|
|
|
{
|
|
|
|
result= res;
|
|
|
|
item= si;
|
|
|
|
this->thd= thd;
|
2002-09-28 17:34:56 +02:00
|
|
|
res_type= STRING_RESULT;
|
2002-12-27 20:19:25 +01:00
|
|
|
maybe_null= 0;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2002-12-27 20:19:25 +01:00
|
|
|
virtual ~subselect_engine() {}; // to satisfy compiler
|
2002-09-28 17:34:56 +02:00
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
virtual int prepare()= 0;
|
2002-12-19 06:38:33 +01:00
|
|
|
virtual void fix_length_and_dec(Item_cache** row)= 0;
|
2002-09-03 08:50:36 +02:00
|
|
|
virtual int exec()= 0;
|
|
|
|
virtual uint cols()= 0; /* return number of columnss in select */
|
|
|
|
virtual bool depended()= 0; /* depended from outer select */
|
2002-09-28 17:34:56 +02:00
|
|
|
enum Item_result type() { return res_type; }
|
2002-11-13 23:26:18 +01:00
|
|
|
virtual bool check_loop(uint id)= 0;
|
2002-11-28 18:29:26 +01:00
|
|
|
virtual void exclude()= 0;
|
2002-12-27 20:19:25 +01:00
|
|
|
bool may_be_null() { return maybe_null; };
|
2002-09-03 08:50:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class subselect_single_select_engine: public subselect_engine
|
|
|
|
{
|
2002-10-13 13:25:16 +02:00
|
|
|
my_bool prepared; /* simple subselect is prepared */
|
2002-09-03 08:50:36 +02:00
|
|
|
my_bool optimized; /* simple subselect is optimized */
|
2002-10-13 13:25:16 +02:00
|
|
|
my_bool executed; /* simple subselect is executed */
|
2002-09-03 08:50:36 +02:00
|
|
|
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);
|
2002-11-13 23:26:18 +01:00
|
|
|
int prepare();
|
2002-12-19 06:38:33 +01:00
|
|
|
void fix_length_and_dec(Item_cache** row);
|
2002-11-13 23:26:18 +01:00
|
|
|
int exec();
|
|
|
|
uint cols();
|
|
|
|
bool depended();
|
|
|
|
bool check_loop(uint id);
|
2002-11-28 18:29:26 +01:00
|
|
|
void exclude();
|
2002-09-03 08:50:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
2002-11-13 23:26:18 +01:00
|
|
|
int prepare();
|
2002-12-19 06:38:33 +01:00
|
|
|
void fix_length_and_dec(Item_cache** row);
|
2002-11-13 23:26:18 +01:00
|
|
|
int exec();
|
|
|
|
uint cols();
|
|
|
|
bool depended();
|
|
|
|
bool check_loop(uint id);
|
2002-11-28 18:29:26 +01:00
|
|
|
void exclude();
|
2002-09-03 08:50:36 +02:00
|
|
|
};
|