1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
#ifdef USE_PRAGMA_INTERFACE
19
#pragma interface /* gcc class implementation */
23
class st_select_lex_unit;
25
class select_subselect;
26
class subselect_engine;
27
class Item_bool_func2;
29
/* base class for subselects */
31
class Item_subselect :public Item_result_field
33
my_bool value_assigned; /* value already assigned to subselect */
35
/* thread handler, will be assigned in fix_fields only */
37
/* substitution instead of subselect in case of optimization */
39
/* unit of subquery */
40
st_select_lex_unit *unit;
41
/* engine that perform execution of subselect (single select or union) */
42
subselect_engine *engine;
43
/* old engine if engine was changed */
44
subselect_engine *old_engine;
45
/* cache of used external tables */
46
table_map used_tables_cache;
47
/* allowed number of columns (1 for single value subqueries) */
49
/* where subquery is placed */
50
enum_parsing_place parsing_place;
51
/* work with 'substitution' */
52
bool have_to_be_excluded;
53
/* cache of constant state */
54
bool const_item_cache;
57
/* changed engine indicator */
59
/* subquery is transformed */
62
/* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
65
enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
66
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
67
EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
71
virtual subs_type substype() { return UNKNOWN_SUBS; }
74
We need this method, because some compilers do not allow 'this'
75
pointer in constructor initialization list, but we need pass pointer
76
to subselect Item class to select_subselect classes constructor.
78
virtual void init (st_select_lex *select_lex,
79
select_subselect *result);
87
virtual trans_res select_transformer(JOIN *join);
88
bool assigned() { return value_assigned; }
89
void assigned(bool a) { value_assigned= a; }
90
enum Type type() const;
96
bool fix_fields(THD *thd, Item **ref);
98
virtual void fix_length_and_dec();
99
table_map used_tables() const;
100
table_map not_null_tables() const { return 0; }
101
bool const_item() const;
102
inline table_map get_used_tables_cache() { return used_tables_cache; }
103
inline bool get_const_item_cache() { return const_item_cache; }
104
Item *get_tmp_table_item(THD *thd);
105
void update_used_tables();
106
virtual void print(String *str, enum_query_type query_type);
107
virtual bool have_guarded_conds() { return FALSE; }
108
bool change_engine(subselect_engine *eng)
116
True if this subquery has been already evaluated. Implemented only for
117
single select and union subqueries only.
119
bool is_evaluated() const;
120
bool is_uncacheable() const;
123
Used by max/min subquery to initialize value presence registration
124
mechanism. Engine call this method before rexecution query.
126
virtual void reset_value_registration() {}
127
enum_parsing_place place() { return parsing_place; }
128
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
131
Get the SELECT_LEX structure associated with this Item.
132
@return the SELECT_LEX structure associated with this Item
134
st_select_lex* get_select_lex();
135
const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
137
friend class select_subselect;
138
friend class Item_in_optimizer;
139
friend bool Item_field::fix_fields(THD *, Item **);
140
friend int Item_field::fix_outer_field(THD *, Field **, Item **);
141
friend bool Item_ref::fix_fields(THD *, Item **);
142
friend void mark_select_range_as_dependent(THD*,
143
st_select_lex*, st_select_lex*,
144
Field*, Item*, Item_ident*);
147
/* single value subselect */
150
class Item_singlerow_subselect :public Item_subselect
153
Item_cache *value, **row;
155
Item_singlerow_subselect(st_select_lex *select_lex);
156
Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
159
subs_type substype() { return SINGLEROW_SUBS; }
162
trans_res select_transformer(JOIN *join);
163
void store(uint i, Item* item);
166
String *val_str (String *);
167
my_decimal *val_decimal(my_decimal *);
169
enum Item_result result_type() const;
170
enum_field_types field_type() const;
171
void fix_length_and_dec();
174
Item* element_index(uint i) { return my_reinterpret_cast(Item*)(row[i]); }
175
Item** addr(uint i) { return (Item**)row + i; }
176
bool check_cols(uint c);
181
This method is used to implement a special case of semantic tree
182
rewriting, mandated by a SQL:2003 exception in the specification.
183
The only caller of this method is handle_sql2003_note184_exception(),
184
see the code there for more details.
185
Note that this method breaks the object internal integrity, by
186
removing it's association with the corresponding SELECT_LEX,
187
making this object orphan from the parse tree.
188
No other method, beside the destructor, should be called on this
189
object, as it is now invalid.
190
@return the SELECT_LEX structure that was given in the constructor.
192
st_select_lex* invalidate_and_restore_select_lex();
194
friend class select_singlerow_subselect;
197
/* used in static ALL/ANY optimization */
198
class select_max_min_finder_subselect;
199
class Item_maxmin_subselect :public Item_singlerow_subselect
203
bool was_values; // Set if we have found at least one row
205
Item_maxmin_subselect(THD *thd, Item_subselect *parent,
206
st_select_lex *select_lex, bool max);
207
virtual void print(String *str, enum_query_type query_type);
209
bool any_value() { return was_values; }
210
void register_value() { was_values= TRUE; }
211
void reset_value_registration() { was_values= FALSE; }
214
/* exists subselect */
216
class Item_exists_subselect :public Item_subselect
219
bool value; /* value of this item (boolean: exists/not-exists) */
222
Item_exists_subselect(st_select_lex *select_lex);
223
Item_exists_subselect(): Item_subselect() {}
225
subs_type substype() { return EXISTS_SUBS; }
231
enum Item_result result_type() const { return INT_RESULT;}
234
String *val_str(String*);
235
my_decimal *val_decimal(my_decimal *);
237
void fix_length_and_dec();
238
virtual void print(String *str, enum_query_type query_type);
240
friend class select_exists_subselect;
241
friend class subselect_uniquesubquery_engine;
242
friend class subselect_indexsubquery_engine;
247
IN subselect: this represents "left_exr IN (SELECT ...)"
250
- (as a descendant of Item_subselect) a "subquery execution engine" which
251
allows it to evaluate subqueries. (and this class participates in
252
execution by having was_null variable where part of execution result
254
- Transformation methods (todo: more on this).
256
This class is not used directly, it is "wrapped" into Item_in_optimizer
257
which provides some small bits of subquery evaluation.
260
class Item_in_subselect :public Item_exists_subselect
265
expr & optimizer used in subselect rewriting to store Item for
269
Item_in_optimizer *optimizer;
274
/* Used to trigger on/off conditions that were pushed down to subselect */
275
bool *pushed_cond_guards;
277
bool *get_cond_guard(int i)
279
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
281
void set_cond_guard_var(int i, bool v)
283
if ( pushed_cond_guards)
284
pushed_cond_guards[i]= v;
286
bool have_guarded_conds() { return test(pushed_cond_guards); }
288
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
290
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
292
:Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
293
pushed_cond_guards(NULL), upper_item(0)
296
subs_type substype() { return IN_SUBS; }
303
trans_res select_transformer(JOIN *join);
304
trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
305
trans_res single_value_transformer(JOIN *join, Comp_creator *func);
306
trans_res row_value_transformer(JOIN * join);
309
String *val_str(String*);
310
my_decimal *val_decimal(my_decimal *);
311
void update_null_value () { (void) val_bool(); }
313
void top_level_item() { abort_on_null=1; }
314
inline bool is_top_level_item() { return abort_on_null; }
315
bool test_limit(st_select_lex_unit *unit);
316
virtual void print(String *str, enum_query_type query_type);
317
bool fix_fields(THD *thd, Item **ref);
319
friend class Item_ref_null_helper;
320
friend class Item_is_not_null_test;
321
friend class subselect_indexsubquery_engine;
325
/* ALL/ANY/SOME subselect */
326
class Item_allany_subselect :public Item_in_subselect
329
chooser_compare_func_creator func_creator;
333
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
334
st_select_lex *select_lex, bool all);
336
// only ALL subquery has upper not
337
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
338
trans_res select_transformer(JOIN *join);
339
virtual void print(String *str, enum_query_type query_type);
343
class subselect_engine: public Sql_alloc
346
select_subselect *result; /* results storage class */
347
THD *thd; /* pointer to current THD */
348
Item_subselect *item; /* item, that use this engine */
349
enum Item_result res_type; /* type of results */
350
enum_field_types res_field_type; /* column type of the results */
351
bool maybe_null; /* may be null (first item in select) */
354
subselect_engine(Item_subselect *si, select_subselect *res)
359
res_type= STRING_RESULT;
360
res_field_type= MYSQL_TYPE_VAR_STRING;
363
virtual ~subselect_engine() {}; // to satisfy compiler
364
virtual void cleanup()= 0;
367
Also sets "thd" for subselect_engine::result.
368
Should be called before prepare().
370
void set_thd(THD *thd_arg);
371
THD * get_thd() { return thd; }
372
virtual int prepare()= 0;
373
virtual void fix_length_and_dec(Item_cache** row)= 0;
381
Execute the engine. The result of execution is subquery value that is
382
either captured by previously set up select_result-based 'sink' or
383
stored somewhere by the exec() method itself.
385
A required side effect: If at least one pushed-down predicate is
386
disabled, subselect_engine->no_rows() must return correct result after
391
1 - Either an execution error, or the engine was "changed", and the
392
caller should call exec() again for the new engine.
394
virtual int exec()= 0;
395
virtual uint cols()= 0; /* return number of columns in select */
396
virtual uint8 uncacheable()= 0; /* query is uncacheable */
397
enum Item_result type() { return res_type; }
398
enum_field_types field_type() { return res_field_type; }
399
virtual void exclude()= 0;
400
virtual bool may_be_null() { return maybe_null; };
401
virtual table_map upper_select_const_tables()= 0;
402
static table_map calc_const_tables(TABLE_LIST *);
403
virtual void print(String *str, enum_query_type query_type)= 0;
404
virtual bool change_result(Item_subselect *si, select_subselect *result)= 0;
405
virtual bool no_tables()= 0;
406
virtual bool is_executed() const { return FALSE; }
407
/* Check if subquery produced any rows during last query execution */
408
virtual bool no_rows() = 0;
411
void set_row(List<Item> &item_list, Item_cache **row);
415
class subselect_single_select_engine: public subselect_engine
417
my_bool prepared; /* simple subselect is prepared */
418
my_bool optimized; /* simple subselect is optimized */
419
my_bool executed; /* simple subselect is executed */
420
st_select_lex *select_lex; /* corresponding select_lex */
421
JOIN * join; /* corresponding JOIN structure */
423
subselect_single_select_engine(st_select_lex *select,
424
select_subselect *result,
425
Item_subselect *item);
428
void fix_length_and_dec(Item_cache** row);
433
table_map upper_select_const_tables();
434
virtual void print (String *str, enum_query_type query_type);
435
bool change_result(Item_subselect *si, select_subselect *result);
438
bool is_executed() const { return executed; }
443
class subselect_union_engine: public subselect_engine
445
st_select_lex_unit *unit; /* corresponding unit structure */
447
subselect_union_engine(st_select_lex_unit *u,
448
select_subselect *result,
449
Item_subselect *item);
452
void fix_length_and_dec(Item_cache** row);
457
table_map upper_select_const_tables();
458
virtual void print (String *str, enum_query_type query_type);
459
bool change_result(Item_subselect *si, select_subselect *result);
461
bool is_executed() const;
466
struct st_join_table;
470
A subquery execution engine that evaluates the subquery by doing one index
471
lookup in a unique index.
473
This engine is used to resolve subqueries in forms
475
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
479
(oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
480
FROM tbl WHERE subqwhere)
482
i.e. the subquery is a single table SELECT without GROUP BY, aggregate
486
class subselect_uniquesubquery_engine: public subselect_engine
490
Item *cond; /* The WHERE condition of subselect */
492
TRUE<=> last execution produced empty set. Valid only when left
495
bool empty_result_set;
496
bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */
499
// constructor can assign THD because it will be called after JOIN::prepare
500
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
501
Item_subselect *subs, Item *where)
502
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
506
~subselect_uniquesubquery_engine();
509
void fix_length_and_dec(Item_cache** row);
511
uint cols() { return 1; }
512
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
514
table_map upper_select_const_tables() { return 0; }
515
virtual void print (String *str, enum_query_type query_type);
516
bool change_result(Item_subselect *si, select_subselect *result);
520
bool no_rows() { return empty_result_set; }
524
class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
526
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
529
The "having" clause. This clause (further reffered to as "artificial
530
having") was inserted by subquery transformation code. It contains
531
Item(s) that have a side-effect: they record whether the subquery has
532
produced a row with NULL certain components. We need to use it for cases
534
(oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
535
where we do index lookup on t.key=oe1 but need also to check if there
536
was a row such that t.no_key IS NULL.
538
NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
539
it should have been in uniquesubquery_engine in order to allow execution of
542
(oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
544
We could use uniquesubquery_engine for the first component and let
545
Item_is_not_null_test( non_key_maybe_null_field) to handle the second.
547
However, subqueries like the above are currently not handled by index
548
lookup-based subquery engines, the engine applicability check misses
549
them: it doesn't switch the engine for case of artificial having and
550
[eq_]ref access (only for artifical having + ref_or_null or no having).
551
The above example subquery is handled as a full-blown SELECT with eq_ref
554
Due to this limitation, the "artificial having" currently needs to be
555
checked by only in indexsubquery_engine.
560
// constructor can assign THD because it will be called after JOIN::prepare
561
subselect_indexsubquery_engine(THD *thd_arg, st_join_table *tab_arg,
562
Item_subselect *subs, Item *where,
563
Item *having_arg, bool chk_null)
564
:subselect_uniquesubquery_engine(thd_arg, tab_arg, subs, where),
565
check_null(chk_null),
569
virtual void print (String *str, enum_query_type query_type);
573
inline bool Item_subselect::is_evaluated() const
575
return engine->is_executed();
578
inline bool Item_subselect::is_uncacheable() const
580
return engine->uncacheable();