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 */
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_ITEM_SUBSELECT_H
21
#define DRIZZLED_ITEM_SUBSELECT_H
16
23
/* subselect Item */
18
#ifdef USE_PRAGMA_INTERFACE
19
#pragma interface /* gcc class implementation */
23
class st_select_lex_unit;
26
#include "drizzled/comp_creator.h"
27
#include "drizzled/item/ref.h"
28
#include "drizzled/item/field.h"
29
#include "drizzled/item/bin_string.h"
35
class Select_Lex_Unit;
25
37
class select_result_interceptor;
26
38
class subselect_engine;
27
39
class subselect_hash_sj_engine;
28
40
class Item_bool_func2;
42
class Item_in_optimizer;
43
class Item_func_not_all;
44
class Tmp_Table_Param;
31
47
/* base class for subselects */
35
51
bool value_assigned; /* value already assigned to subselect */
37
53
/* thread handler, will be assigned in fix_fields only */
39
55
/* substitution instead of subselect in case of optimization */
40
56
Item *substitution;
41
57
/* unit of subquery */
43
st_select_lex_unit *unit;
58
Select_Lex_Unit *unit;
45
60
/* engine that perform execution of subselect (single select or union) */
46
61
subselect_engine *engine;
49
64
/* cache of used external tables */
50
65
table_map used_tables_cache;
51
66
/* allowed number of columns (1 for single value subqueries) */
53
68
/* where subquery is placed */
54
69
enum_parsing_place parsing_place;
55
70
/* work with 'substitution' */
79
94
pointer in constructor initialization list, but we need to pass a pointer
80
95
to subselect Item class to select_result_interceptor's constructor.
82
virtual void init (st_select_lex *select_lex,
97
virtual void init (Select_Lex *select_lex,
83
98
select_result_interceptor *result);
85
100
~Item_subselect();
105
120
bool const_item() const;
106
121
inline table_map get_used_tables_cache() { return used_tables_cache; }
107
122
inline bool get_const_item_cache() { return const_item_cache; }
108
Item *get_tmp_table_item(THD *thd);
123
Item *get_tmp_table_item(Session *session);
109
124
void update_used_tables();
110
125
virtual void print(String *str, enum_query_type query_type);
111
126
virtual bool have_guarded_conds() { return false; }
130
145
virtual void reset_value_registration() {}
131
146
enum_parsing_place place() { return parsing_place; }
132
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
147
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
135
Get the SELECT_LEX structure associated with this Item.
136
@return the SELECT_LEX structure associated with this Item
150
Get the Select_Lex structure associated with this Item.
151
@return the Select_Lex structure associated with this Item
138
st_select_lex* get_select_lex();
153
Select_Lex* get_select_lex();
140
155
friend class select_result_interceptor;
141
156
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*,
157
friend bool Item_field::fix_fields(Session *, Item **);
158
friend int Item_field::fix_outer_field(Session *, Field **, Item **);
159
friend bool Item_ref::fix_fields(Session *, Item **);
160
friend void mark_select_range_as_dependent(Session*,
161
Select_Lex*, Select_Lex*,
147
162
Field*, Item*, Item_ident*);
156
171
Item_cache *value, **row;
158
Item_singlerow_subselect(st_select_lex *select_lex);
173
Item_singlerow_subselect(Select_Lex *select_lex);
159
174
Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
173
188
enum_field_types field_type() const;
174
189
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);
192
Item* element_index(uint32_t i) { return reinterpret_cast<Item*>(row[i]); }
193
Item** addr(uint32_t i) { return (Item**)row + i; }
194
bool check_cols(uint32_t c);
180
195
bool null_inside();
181
196
void bring_value();
186
201
The only caller of this method is handle_sql2003_note184_exception(),
187
202
see the code there for more details.
188
203
Note that this method breaks the object internal integrity, by
189
removing it's association with the corresponding SELECT_LEX,
204
removing it's association with the corresponding Select_Lex,
190
205
making this object orphan from the parse tree.
191
206
No other method, beside the destructor, should be called on this
192
207
object, as it is now invalid.
193
@return the SELECT_LEX structure that was given in the constructor.
208
@return the Select_Lex structure that was given in the constructor.
195
st_select_lex* invalidate_and_restore_select_lex();
210
Select_Lex* invalidate_and_restore_select_lex();
197
212
friend class select_singlerow_subselect;
206
221
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);
223
Item_maxmin_subselect(Session *session, Item_subselect *parent,
224
Select_Lex *select_lex, bool max);
210
225
virtual void print(String *str, enum_query_type query_type);
212
227
bool any_value() { return was_values; }
286
301
/* Used to trigger on/off conditions that were pushed down to subselect */
287
302
bool *pushed_cond_guards;
289
304
/* Priority of this predicate in the convert-to-semi-join-nest process. */
290
305
int sj_convert_priority;
293
308
Location of the subquery predicate. It is either
294
309
- pointer to join nest if the subquery predicate is in the ON expression
295
- (TABLE_LIST*)1 if the predicate is in the WHERE.
310
- (TableList*)1 if the predicate is in the WHERE.
297
TABLE_LIST *expr_join_nest;
312
TableList *expr_join_nest;
299
314
/* The method chosen to execute the IN predicate. */
300
315
enum enum_exec_method {
319
334
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);
336
Item_in_subselect(Item * left_expr, Select_Lex *select_lex);
322
337
Item_in_subselect()
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)
339
Item_exists_subselect(),
341
left_expr_cache(NULL),
342
first_execution(true),
344
abort_on_null(false),
345
pushed_cond_guards(NULL),
346
sj_convert_priority(0),
347
expr_join_nest(NULL),
348
exec_method(NOT_TRANSFORMED),
328
352
subs_type substype() { return IN_SUBS; }
335
359
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);
360
trans_res select_in_like_transformer(JOIN *join, const Comp_creator *func);
361
trans_res single_value_transformer(JOIN *join, const Comp_creator *func);
338
362
trans_res row_value_transformer(JOIN * join);
339
363
trans_res single_value_in_to_exists_transformer(JOIN * join,
364
const Comp_creator *func);
341
365
trans_res row_value_in_to_exists_transformer(JOIN * join);
342
366
virtual bool exec();
343
367
int64_t val_int();
349
373
void top_level_item() { abort_on_null=1; }
350
374
inline bool is_top_level_item() { return abort_on_null; }
351
bool test_limit(st_select_lex_unit *unit);
375
bool test_limit(Select_Lex_Unit *unit);
352
376
virtual void print(String *str, enum_query_type query_type);
353
bool fix_fields(THD *thd, Item **ref);
377
bool fix_fields(Session *session, Item **ref);
354
378
bool setup_engine();
355
379
bool init_left_expr_cache();
356
bool is_expensive_processor(uchar *arg);
380
bool is_expensive_processor(unsigned char *arg);
358
382
friend class Item_ref_null_helper;
359
383
friend class Item_is_not_null_test;
374
398
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
375
st_select_lex *select_lex, bool all);
399
Select_Lex *select_lex, bool all);
377
401
// only ALL subquery has upper not
378
402
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
384
class subselect_engine: public Sql_alloc
408
class subselect_engine: public memory::SqlAlloc
387
411
select_result_interceptor *result; /* results storage class */
388
THD *thd; /* pointer to current THD */
412
Session *session; /* pointer to current Session */
389
413
Item_subselect *item; /* item, that use this engine */
390
414
enum Item_result res_type; /* type of results */
391
415
enum_field_types res_field_type; /* column type of the results */
409
433
virtual void cleanup()= 0;
412
Also sets "thd" for subselect_engine::result.
436
Also sets "session" for subselect_engine::result.
413
437
Should be called before prepare().
415
void set_thd(THD *thd_arg);
416
THD * get_thd() { return thd; }
439
void set_session(Session *session_arg);
440
Session * get_session() { return session; }
417
441
virtual int prepare()= 0;
418
442
virtual void fix_length_and_dec(Item_cache** row)= 0;
437
461
caller should call exec() again for the new engine.
439
463
virtual int exec()= 0;
440
virtual uint cols()= 0; /* return number of columns in select */
464
virtual uint32_t cols()= 0; /* return number of columns in select */
441
465
virtual uint8_t uncacheable()= 0; /* query is uncacheable */
442
466
enum Item_result type() { return res_type; }
443
467
enum_field_types field_type() { return res_field_type; }
444
468
virtual void exclude()= 0;
445
469
virtual bool may_be_null() { return maybe_null; };
446
470
virtual table_map upper_select_const_tables()= 0;
447
static table_map calc_const_tables(TABLE_LIST *);
471
static table_map calc_const_tables(TableList *);
448
472
virtual void print(String *str, enum_query_type query_type)= 0;
449
473
virtual bool change_result(Item_subselect *si,
450
474
select_result_interceptor *result)= 0;
464
488
bool prepared; /* simple subselect is prepared */
465
489
bool optimized; /* simple subselect is optimized */
466
490
bool executed; /* simple subselect is executed */
467
st_select_lex *select_lex; /* corresponding select_lex */
491
Select_Lex *select_lex; /* corresponding select_lex */
468
492
JOIN * join; /* corresponding JOIN structure */
470
subselect_single_select_engine(st_select_lex *select,
494
subselect_single_select_engine(Select_Lex *select,
471
495
select_result_interceptor *result,
472
496
Item_subselect *item);
475
499
void fix_length_and_dec(Item_cache** row);
478
502
uint8_t uncacheable();
480
504
table_map upper_select_const_tables();
494
518
class subselect_union_engine: public subselect_engine
496
st_select_lex_unit *unit; /* corresponding unit structure */
520
Select_Lex_Unit *unit; /* corresponding unit structure */
498
subselect_union_engine(st_select_lex_unit *u,
522
subselect_union_engine(Select_Lex_Unit *u,
499
523
select_result_interceptor *result,
500
524
Item_subselect *item);
503
527
void fix_length_and_dec(Item_cache** row);
506
530
uint8_t uncacheable();
508
532
table_map upper_select_const_tables();
523
547
lookup in a unique index.
525
549
This engine is used to resolve subqueries in forms
527
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
551
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
531
555
(oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
532
FROM tbl WHERE subqwhere)
556
FROM tbl WHERE subqwhere)
534
558
i.e. the subquery is a single table SELECT without GROUP BY, aggregate
548
572
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,
575
// constructor can assign Session because it will be called after JOIN::prepare
576
subselect_uniquesubquery_engine(Session *session_arg, JoinTable *tab_arg,
553
577
Item_subselect *subs, Item *where)
554
578
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
580
set_session(session_arg);
560
584
void fix_length_and_dec(Item_cache** row);
562
uint cols() { return 1; }
586
uint32_t cols() { return 1; }
563
587
uint8_t uncacheable() { return UNCACHEABLE_DEPENDENT; }
565
589
table_map upper_select_const_tables() { return 0; }
578
602
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
581
605
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
606
having") was inserted by subquery transformation code. It contains
607
Item(s) that have a side-effect: they record whether the subquery has
584
608
produced a row with NULL certain components. We need to use it for cases
586
610
(oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
587
611
where we do index lookup on t.key=oe1 but need also to check if there
588
612
was a row such that t.no_key IS NULL.
590
614
NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
591
615
it should have been in uniquesubquery_engine in order to allow execution of
594
618
(oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
596
620
We could use uniquesubquery_engine for the first component and let
603
627
The above example subquery is handled as a full-blown SELECT with eq_ref
604
628
access to one table.
606
Due to this limitation, the "artificial having" currently needs to be
630
Due to this limitation, the "artificial having" currently needs to be
607
631
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,
636
// constructor can assign Session because it will be called after JOIN::prepare
637
subselect_indexsubquery_engine(Session *session_arg, JoinTable *tab_arg,
614
638
Item_subselect *subs, Item *where,
615
639
Item *having_arg, bool chk_null)
616
:subselect_uniquesubquery_engine(thd_arg, tab_arg, subs, where),
640
:subselect_uniquesubquery_engine(session_arg, tab_arg, subs, where),
617
641
check_null(chk_null),
618
642
having(having_arg)
660
684
JOIN *materialize_join;
661
685
/* Temp table context of the outer select's JOIN. */
662
TMP_TABLE_PARAM *tmp_param;
686
Tmp_Table_Param *tmp_param;
665
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
689
subselect_hash_sj_engine(Session *session_in, Item_subselect *in_predicate,
666
690
subselect_single_select_engine *old_engine)
667
:subselect_uniquesubquery_engine(thd, NULL, in_predicate, NULL),
691
:subselect_uniquesubquery_engine(session_in, NULL, in_predicate, NULL),
668
692
is_materialized(false), materialize_engine(old_engine),
669
693
materialize_join(NULL), tmp_param(NULL)
676
700
int prepare() { return 0; }
678
702
virtual void print (String *str, enum_query_type query_type);
681
705
return materialize_engine->cols();
683
707
virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; }
710
} /* namespace drizzled */
712
#endif /* DRIZZLED_ITEM_SUBSELECT_H */