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_result_interceptor;
26
class subselect_engine;
27
class subselect_hash_sj_engine;
28
class Item_bool_func2;
31
/* base class for subselects */
33
class Item_subselect :public Item_result_field
35
my_bool value_assigned; /* value already assigned to subselect */
37
/* thread handler, will be assigned in fix_fields only */
39
/* substitution instead of subselect in case of optimization */
41
/* unit of subquery */
43
st_select_lex_unit *unit;
45
/* engine that perform execution of subselect (single select or union) */
46
subselect_engine *engine;
47
/* old engine if engine was changed */
48
subselect_engine *old_engine;
49
/* cache of used external tables */
50
table_map used_tables_cache;
51
/* allowed number of columns (1 for single value subqueries) */
53
/* where subquery is placed */
54
enum_parsing_place parsing_place;
55
/* work with 'substitution' */
56
bool have_to_be_excluded;
57
/* cache of constant state */
58
bool const_item_cache;
61
/* changed engine indicator */
63
/* subquery is transformed */
66
/* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
69
enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
70
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
71
EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
75
virtual subs_type substype() { return UNKNOWN_SUBS; }
78
We need this method, because some compilers do not allow 'this'
79
pointer in constructor initialization list, but we need to pass a pointer
80
to subselect Item class to select_result_interceptor's constructor.
82
virtual void init (st_select_lex *select_lex,
83
select_result_interceptor *result);
91
virtual trans_res select_transformer(JOIN *join);
92
bool assigned() { return value_assigned; }
93
void assigned(bool a) { value_assigned= a; }
94
enum Type type() const;
100
bool fix_fields(THD *thd, Item **ref);
102
virtual void fix_length_and_dec();
103
table_map used_tables() const;
104
table_map not_null_tables() const { return 0; }
105
bool const_item() const;
106
inline table_map get_used_tables_cache() { return used_tables_cache; }
107
inline bool get_const_item_cache() { return const_item_cache; }
108
Item *get_tmp_table_item(THD *thd);
109
void update_used_tables();
110
virtual void print(String *str, enum_query_type query_type);
111
virtual bool have_guarded_conds() { return FALSE; }
112
bool change_engine(subselect_engine *eng)
120
True if this subquery has been already evaluated. Implemented only for
121
single select and union subqueries only.
123
bool is_evaluated() const;
124
bool is_uncacheable() const;
127
Used by max/min subquery to initialize value presence registration
128
mechanism. Engine call this method before rexecution query.
130
virtual void reset_value_registration() {}
131
enum_parsing_place place() { return parsing_place; }
132
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
135
Get the SELECT_LEX structure associated with this Item.
136
@return the SELECT_LEX structure associated with this Item
138
st_select_lex* get_select_lex();
140
friend class select_result_interceptor;
141
friend class Item_in_optimizer;
142
friend bool Item_field::fix_fields(THD *, Item **);
143
friend int Item_field::fix_outer_field(THD *, Field **, Item **);
144
friend bool Item_ref::fix_fields(THD *, Item **);
145
friend void mark_select_range_as_dependent(THD*,
146
st_select_lex*, st_select_lex*,
147
Field*, Item*, Item_ident*);
150
/* single value subselect */
153
class Item_singlerow_subselect :public Item_subselect
156
Item_cache *value, **row;
158
Item_singlerow_subselect(st_select_lex *select_lex);
159
Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
162
subs_type substype() { return SINGLEROW_SUBS; }
165
trans_res select_transformer(JOIN *join);
166
void store(uint i, Item* item);
169
String *val_str (String *);
170
my_decimal *val_decimal(my_decimal *);
172
enum Item_result result_type() const;
173
enum_field_types field_type() const;
174
void fix_length_and_dec();
177
Item* element_index(uint i) { return my_reinterpret_cast(Item*)(row[i]); }
178
Item** addr(uint i) { return (Item**)row + i; }
179
bool check_cols(uint c);
184
This method is used to implement a special case of semantic tree
185
rewriting, mandated by a SQL:2003 exception in the specification.
186
The only caller of this method is handle_sql2003_note184_exception(),
187
see the code there for more details.
188
Note that this method breaks the object internal integrity, by
189
removing it's association with the corresponding SELECT_LEX,
190
making this object orphan from the parse tree.
191
No other method, beside the destructor, should be called on this
192
object, as it is now invalid.
193
@return the SELECT_LEX structure that was given in the constructor.
195
st_select_lex* invalidate_and_restore_select_lex();
197
friend class select_singlerow_subselect;
200
/* used in static ALL/ANY optimization */
201
class select_max_min_finder_subselect;
202
class Item_maxmin_subselect :public Item_singlerow_subselect
206
bool was_values; // Set if we have found at least one row
208
Item_maxmin_subselect(THD *thd, Item_subselect *parent,
209
st_select_lex *select_lex, bool max);
210
virtual void print(String *str, enum_query_type query_type);
212
bool any_value() { return was_values; }
213
void register_value() { was_values= TRUE; }
214
void reset_value_registration() { was_values= FALSE; }
217
/* exists subselect */
219
class Item_exists_subselect :public Item_subselect
222
bool value; /* value of this item (boolean: exists/not-exists) */
225
Item_exists_subselect(st_select_lex *select_lex);
226
Item_exists_subselect(): Item_subselect() {}
228
subs_type substype() { return EXISTS_SUBS; }
234
enum Item_result result_type() const { return INT_RESULT;}
237
String *val_str(String*);
238
my_decimal *val_decimal(my_decimal *);
240
void fix_length_and_dec();
241
virtual void print(String *str, enum_query_type query_type);
243
friend class select_exists_subselect;
244
friend class subselect_uniquesubquery_engine;
245
friend class subselect_indexsubquery_engine;
250
Representation of IN subquery predicates of the form
251
"left_expr IN (SELECT ...)".
255
- A "subquery execution engine" (as a subclass of Item_subselect) that allows
256
it to evaluate subqueries. (and this class participates in execution by
257
having was_null variable where part of execution result is stored.
258
- Transformation methods (todo: more on this).
260
This class is not used directly, it is "wrapped" into Item_in_optimizer
261
which provides some small bits of subquery evaluation.
264
class Item_in_subselect :public Item_exists_subselect
270
Cache of the left operand of the subquery predicate. Allocated in the
271
runtime memory root, for each execution, thus need not be freed.
273
List<Cached_item> *left_expr_cache;
274
bool first_execution;
277
expr & optimizer used in subselect rewriting to store Item for
281
Item_in_optimizer *optimizer;
286
/* Used to trigger on/off conditions that were pushed down to subselect */
287
bool *pushed_cond_guards;
289
/* Priority of this predicate in the convert-to-semi-join-nest process. */
290
int sj_convert_priority;
293
Location of the subquery predicate. It is either
294
- pointer to join nest if the subquery predicate is in the ON expression
295
- (TABLE_LIST*)1 if the predicate is in the WHERE.
297
TABLE_LIST *expr_join_nest;
299
/* The method chosen to execute the IN predicate. */
300
enum enum_exec_method {
301
NOT_TRANSFORMED, /* No execution method was chosen for this IN. */
302
SEMI_JOIN, /* IN was converted to semi-join nest and should be removed. */
303
IN_TO_EXISTS, /* IN was converted to correlated EXISTS. */
304
MATERIALIZATION /* IN will be executed via subquery materialization. */
306
enum_exec_method exec_method;
308
bool *get_cond_guard(int i)
310
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
312
void set_cond_guard_var(int i, bool v)
314
if ( pushed_cond_guards)
315
pushed_cond_guards[i]= v;
317
bool have_guarded_conds() { return test(pushed_cond_guards); }
319
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
321
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
323
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
324
optimizer(0), abort_on_null(0), pushed_cond_guards(NULL),
325
exec_method(NOT_TRANSFORMED), upper_item(0)
328
subs_type substype() { return IN_SUBS; }
335
trans_res select_transformer(JOIN *join);
336
trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
337
trans_res single_value_transformer(JOIN *join, Comp_creator *func);
338
trans_res row_value_transformer(JOIN * join);
339
trans_res single_value_in_to_exists_transformer(JOIN * join,
341
trans_res row_value_in_to_exists_transformer(JOIN * join);
345
String *val_str(String*);
346
my_decimal *val_decimal(my_decimal *);
347
void update_null_value () { (void) val_bool(); }
349
void top_level_item() { abort_on_null=1; }
350
inline bool is_top_level_item() { return abort_on_null; }
351
bool test_limit(st_select_lex_unit *unit);
352
virtual void print(String *str, enum_query_type query_type);
353
bool fix_fields(THD *thd, Item **ref);
355
bool init_left_expr_cache();
356
bool is_expensive_processor(uchar *arg);
358
friend class Item_ref_null_helper;
359
friend class Item_is_not_null_test;
360
friend class Item_in_optimizer;
361
friend class subselect_indexsubquery_engine;
362
friend class subselect_hash_sj_engine;
366
/* ALL/ANY/SOME subselect */
367
class Item_allany_subselect :public Item_in_subselect
370
chooser_compare_func_creator func_creator;
374
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
375
st_select_lex *select_lex, bool all);
377
// only ALL subquery has upper not
378
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
379
trans_res select_transformer(JOIN *join);
380
virtual void print(String *str, enum_query_type query_type);
384
class subselect_engine: public Sql_alloc
387
select_result_interceptor *result; /* results storage class */
388
THD *thd; /* pointer to current THD */
389
Item_subselect *item; /* item, that use this engine */
390
enum Item_result res_type; /* type of results */
391
enum_field_types res_field_type; /* column type of the results */
392
bool maybe_null; /* may be null (first item in select) */
395
enum enum_engine_type {ABSTRACT_ENGINE, SINGLE_SELECT_ENGINE,
396
UNION_ENGINE, UNIQUESUBQUERY_ENGINE,
397
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE};
399
subselect_engine(Item_subselect *si, select_result_interceptor *res)
404
res_type= STRING_RESULT;
405
res_field_type= MYSQL_TYPE_VAR_STRING;
408
virtual ~subselect_engine() {}; // to satisfy compiler
409
virtual void cleanup()= 0;
412
Also sets "thd" for subselect_engine::result.
413
Should be called before prepare().
415
void set_thd(THD *thd_arg);
416
THD * get_thd() { return thd; }
417
virtual int prepare()= 0;
418
virtual void fix_length_and_dec(Item_cache** row)= 0;
426
Execute the engine. The result of execution is subquery value that is
427
either captured by previously set up select_result-based 'sink' or
428
stored somewhere by the exec() method itself.
430
A required side effect: If at least one pushed-down predicate is
431
disabled, subselect_engine->no_rows() must return correct result after
436
1 - Either an execution error, or the engine was "changed", and the
437
caller should call exec() again for the new engine.
439
virtual int exec()= 0;
440
virtual uint cols()= 0; /* return number of columns in select */
441
virtual uint8 uncacheable()= 0; /* query is uncacheable */
442
enum Item_result type() { return res_type; }
443
enum_field_types field_type() { return res_field_type; }
444
virtual void exclude()= 0;
445
virtual bool may_be_null() { return maybe_null; };
446
virtual table_map upper_select_const_tables()= 0;
447
static table_map calc_const_tables(TABLE_LIST *);
448
virtual void print(String *str, enum_query_type query_type)= 0;
449
virtual bool change_result(Item_subselect *si,
450
select_result_interceptor *result)= 0;
451
virtual bool no_tables()= 0;
452
virtual bool is_executed() const { return FALSE; }
453
/* Check if subquery produced any rows during last query execution */
454
virtual bool no_rows() = 0;
455
virtual enum_engine_type engine_type() { return ABSTRACT_ENGINE; }
458
void set_row(List<Item> &item_list, Item_cache **row);
462
class subselect_single_select_engine: public subselect_engine
464
my_bool prepared; /* simple subselect is prepared */
465
my_bool optimized; /* simple subselect is optimized */
466
my_bool executed; /* simple subselect is executed */
467
st_select_lex *select_lex; /* corresponding select_lex */
468
JOIN * join; /* corresponding JOIN structure */
470
subselect_single_select_engine(st_select_lex *select,
471
select_result_interceptor *result,
472
Item_subselect *item);
475
void fix_length_and_dec(Item_cache** row);
480
table_map upper_select_const_tables();
481
virtual void print (String *str, enum_query_type query_type);
482
bool change_result(Item_subselect *si, select_result_interceptor *result);
485
bool is_executed() const { return executed; }
487
virtual enum_engine_type engine_type() { return SINGLE_SELECT_ENGINE; }
489
friend class subselect_hash_sj_engine;
490
friend class Item_in_subselect;
494
class subselect_union_engine: public subselect_engine
496
st_select_lex_unit *unit; /* corresponding unit structure */
498
subselect_union_engine(st_select_lex_unit *u,
499
select_result_interceptor *result,
500
Item_subselect *item);
503
void fix_length_and_dec(Item_cache** row);
508
table_map upper_select_const_tables();
509
virtual void print (String *str, enum_query_type query_type);
510
bool change_result(Item_subselect *si, select_result_interceptor *result);
512
bool is_executed() const;
514
virtual enum_engine_type engine_type() { return UNION_ENGINE; }
518
struct st_join_table;
522
A subquery execution engine that evaluates the subquery by doing one index
523
lookup in a unique index.
525
This engine is used to resolve subqueries in forms
527
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
531
(oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
532
FROM tbl WHERE subqwhere)
534
i.e. the subquery is a single table SELECT without GROUP BY, aggregate
538
class subselect_uniquesubquery_engine: public subselect_engine
542
Item *cond; /* The WHERE condition of subselect */
544
TRUE<=> last execution produced empty set. Valid only when left
547
bool empty_result_set;
548
bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */
551
// constructor can assign THD because it will be called after JOIN::prepare
552
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
553
Item_subselect *subs, Item *where)
554
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
560
void fix_length_and_dec(Item_cache** row);
562
uint cols() { return 1; }
563
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
565
table_map upper_select_const_tables() { return 0; }
566
virtual void print (String *str, enum_query_type query_type);
567
bool change_result(Item_subselect *si, select_result_interceptor *result);
571
bool no_rows() { return empty_result_set; }
572
virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; }
576
class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
578
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
581
The "having" clause. This clause (further reffered to as "artificial
582
having") was inserted by subquery transformation code. It contains
583
Item(s) that have a side-effect: they record whether the subquery has
584
produced a row with NULL certain components. We need to use it for cases
586
(oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
587
where we do index lookup on t.key=oe1 but need also to check if there
588
was a row such that t.no_key IS NULL.
590
NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
591
it should have been in uniquesubquery_engine in order to allow execution of
594
(oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
596
We could use uniquesubquery_engine for the first component and let
597
Item_is_not_null_test( non_key_maybe_null_field) to handle the second.
599
However, subqueries like the above are currently not handled by index
600
lookup-based subquery engines, the engine applicability check misses
601
them: it doesn't switch the engine for case of artificial having and
602
[eq_]ref access (only for artifical having + ref_or_null or no having).
603
The above example subquery is handled as a full-blown SELECT with eq_ref
606
Due to this limitation, the "artificial having" currently needs to be
607
checked by only in indexsubquery_engine.
612
// constructor can assign THD because it will be called after JOIN::prepare
613
subselect_indexsubquery_engine(THD *thd_arg, st_join_table *tab_arg,
614
Item_subselect *subs, Item *where,
615
Item *having_arg, bool chk_null)
616
:subselect_uniquesubquery_engine(thd_arg, tab_arg, subs, where),
617
check_null(chk_null),
621
virtual void print (String *str, enum_query_type query_type);
622
virtual enum_engine_type engine_type() { return INDEXSUBQUERY_ENGINE; }
626
inline bool Item_subselect::is_evaluated() const
628
return engine->is_executed();
632
inline bool Item_subselect::is_uncacheable() const
634
return engine->uncacheable();
639
Compute an IN predicate via a hash semi-join. The subquery is materialized
640
during the first evaluation of the IN predicate. The IN predicate is executed
641
via the functionality inherited from subselect_uniquesubquery_engine.
644
class subselect_hash_sj_engine: public subselect_uniquesubquery_engine
647
/* TRUE if the subquery was materialized into a temp table. */
648
bool is_materialized;
650
The old engine already chosen at parse time and stored in permanent memory.
651
Through this member we can re-create and re-prepare materialize_join for
652
each execution of a prepared statement. We akso resuse the functionality
653
of subselect_single_select_engine::[prepare | cols].
655
subselect_single_select_engine *materialize_engine;
657
QEP to execute the subquery and materialize its result into a
658
temporary table. Created during the first call to exec().
660
JOIN *materialize_join;
661
/* Temp table context of the outer select's JOIN. */
662
TMP_TABLE_PARAM *tmp_param;
665
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
666
subselect_single_select_engine *old_engine)
667
:subselect_uniquesubquery_engine(thd, NULL, in_predicate, NULL),
668
is_materialized(FALSE), materialize_engine(old_engine),
669
materialize_join(NULL), tmp_param(NULL)
671
~subselect_hash_sj_engine();
673
bool init_permanent(List<Item> *tmp_columns);
676
int prepare() { return 0; }
678
virtual void print (String *str, enum_query_type query_type);
681
return materialize_engine->cols();
683
virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; }