390.1.2
by Monty Taylor
Fixed copyright headers in drizzled/ |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2008 Sun Microsystems
|
|
5 |
*
|
|
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.
|
|
9 |
*
|
|
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.
|
|
14 |
*
|
|
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
|
|
18 |
*/
|
|
1
by brian
clean slate |
19 |
|
575.1.6
by Monty Taylor
Cleaned up some headers for PCH. |
20 |
#ifndef DRIZZLED_ITEM_SUBSELECT_H
|
21 |
#define DRIZZLED_ITEM_SUBSELECT_H
|
|
22 |
||
1
by brian
clean slate |
23 |
/* subselect Item */
|
24 |
||
25 |
||
1237.9.3
by Padraig O'Sullivan
Removed one the includes I put in server_includes.h for the last commit to get rid of the inclusion |
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" |
|
584.4.7
by Monty Taylor
Removed a big bank of includes from item.h. |
30 |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
31 |
namespace drizzled |
32 |
{
|
|
33 |
||
846
by Brian Aker
Removing on typedeffed class. |
34 |
class Select_Lex; |
848
by Brian Aker
typdef class removal (just... use the name of the class). |
35 |
class Select_Lex_Unit; |
1541.1.1
by Brian Aker
JOIN -> Join rename |
36 |
class Join; |
1
by brian
clean slate |
37 |
class select_result_interceptor; |
38 |
class subselect_engine; |
|
39 |
class subselect_hash_sj_engine; |
|
40 |
class Item_bool_func2; |
|
41 |
class Cached_item; |
|
584.4.7
by Monty Taylor
Removed a big bank of includes from item.h. |
42 |
class Item_in_optimizer; |
43 |
class Item_func_not_all; |
|
851
by Brian Aker
Class rewrite of Session (aka get all of the junk out) |
44 |
class Tmp_Table_Param; |
584.4.7
by Monty Taylor
Removed a big bank of includes from item.h. |
45 |
|
1
by brian
clean slate |
46 |
|
47 |
/* base class for subselects */
|
|
48 |
||
49 |
class Item_subselect :public Item_result_field |
|
50 |
{
|
|
275
by Brian Aker
Full removal of my_bool from central server. |
51 |
bool value_assigned; /* value already assigned to subselect */ |
1
by brian
clean slate |
52 |
public: |
53 |
/* thread handler, will be assigned in fix_fields only */
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
54 |
Session *session; |
1
by brian
clean slate |
55 |
/* substitution instead of subselect in case of optimization */
|
56 |
Item *substitution; |
|
57 |
/* unit of subquery */
|
|
848
by Brian Aker
typdef class removal (just... use the name of the class). |
58 |
Select_Lex_Unit *unit; |
1
by brian
clean slate |
59 |
protected: |
60 |
/* engine that perform execution of subselect (single select or union) */
|
|
61 |
subselect_engine *engine; |
|
62 |
/* old engine if engine was changed */
|
|
63 |
subselect_engine *old_engine; |
|
64 |
/* cache of used external tables */
|
|
65 |
table_map used_tables_cache; |
|
66 |
/* allowed number of columns (1 for single value subqueries) */
|
|
482
by Brian Aker
Remove uint. |
67 |
uint32_t max_columns; |
1
by brian
clean slate |
68 |
/* where subquery is placed */
|
69 |
enum_parsing_place parsing_place; |
|
70 |
/* work with 'substitution' */
|
|
71 |
bool have_to_be_excluded; |
|
72 |
/* cache of constant state */
|
|
73 |
bool const_item_cache; |
|
74 |
||
75 |
public: |
|
76 |
/* changed engine indicator */
|
|
77 |
bool engine_changed; |
|
78 |
/* subquery is transformed */
|
|
79 |
bool changed; |
|
80 |
||
81 |
/* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
82 |
bool is_correlated; |
1
by brian
clean slate |
83 |
|
84 |
enum trans_res {RES_OK, RES_REDUCE, RES_ERROR}; |
|
85 |
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS, |
|
86 |
EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS}; |
|
87 |
||
88 |
Item_subselect(); |
|
89 |
||
90 |
virtual subs_type substype() { return UNKNOWN_SUBS; } |
|
91 |
||
92 |
/*
|
|
93 |
We need this method, because some compilers do not allow 'this'
|
|
94 |
pointer in constructor initialization list, but we need to pass a pointer
|
|
95 |
to subselect Item class to select_result_interceptor's constructor.
|
|
96 |
*/
|
|
846
by Brian Aker
Removing on typedeffed class. |
97 |
virtual void init (Select_Lex *select_lex, |
1
by brian
clean slate |
98 |
select_result_interceptor *result); |
99 |
||
100 |
~Item_subselect(); |
|
101 |
void cleanup(); |
|
102 |
virtual void reset() |
|
103 |
{
|
|
104 |
null_value= 1; |
|
105 |
}
|
|
1541.1.1
by Brian Aker
JOIN -> Join rename |
106 |
virtual trans_res select_transformer(Join *join); |
1
by brian
clean slate |
107 |
bool assigned() { return value_assigned; } |
108 |
void assigned(bool a) { value_assigned= a; } |
|
109 |
enum Type type() const; |
|
110 |
bool is_null() |
|
111 |
{
|
|
112 |
update_null_value(); |
|
113 |
return null_value; |
|
114 |
}
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
115 |
bool fix_fields(Session *session, Item **ref); |
1
by brian
clean slate |
116 |
virtual bool exec(); |
117 |
virtual void fix_length_and_dec(); |
|
118 |
table_map used_tables() const; |
|
119 |
table_map not_null_tables() const { return 0; } |
|
120 |
bool const_item() const; |
|
121 |
inline table_map get_used_tables_cache() { return used_tables_cache; } |
|
122 |
inline bool get_const_item_cache() { return const_item_cache; } |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
123 |
Item *get_tmp_table_item(Session *session); |
1
by brian
clean slate |
124 |
void update_used_tables(); |
125 |
virtual void print(String *str, enum_query_type query_type); |
|
51.1.24
by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE |
126 |
virtual bool have_guarded_conds() { return false; } |
1
by brian
clean slate |
127 |
bool change_engine(subselect_engine *eng) |
128 |
{
|
|
129 |
old_engine= engine; |
|
130 |
engine= eng; |
|
131 |
engine_changed= 1; |
|
132 |
return eng == 0; |
|
133 |
}
|
|
134 |
/*
|
|
135 |
True if this subquery has been already evaluated. Implemented only for
|
|
136 |
single select and union subqueries only.
|
|
137 |
*/
|
|
138 |
bool is_evaluated() const; |
|
139 |
bool is_uncacheable() const; |
|
140 |
||
141 |
/*
|
|
142 |
Used by max/min subquery to initialize value presence registration
|
|
143 |
mechanism. Engine call this method before rexecution query.
|
|
144 |
*/
|
|
145 |
virtual void reset_value_registration() {} |
|
146 |
enum_parsing_place place() { return parsing_place; } |
|
481
by Brian Aker
Remove all of uchar. |
147 |
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg); |
1
by brian
clean slate |
148 |
|
149 |
/**
|
|
846
by Brian Aker
Removing on typedeffed class. |
150 |
Get the Select_Lex structure associated with this Item.
|
151 |
@return the Select_Lex structure associated with this Item
|
|
1
by brian
clean slate |
152 |
*/
|
846
by Brian Aker
Removing on typedeffed class. |
153 |
Select_Lex* get_select_lex(); |
1
by brian
clean slate |
154 |
|
155 |
friend class select_result_interceptor; |
|
156 |
friend class Item_in_optimizer; |
|
520.1.21
by Brian Aker
THD -> Session rename |
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*, |
|
846
by Brian Aker
Removing on typedeffed class. |
161 |
Select_Lex*, Select_Lex*, |
1
by brian
clean slate |
162 |
Field*, Item*, Item_ident*); |
163 |
};
|
|
164 |
||
165 |
/* single value subselect */
|
|
166 |
||
167 |
class Item_cache; |
|
168 |
class Item_singlerow_subselect :public Item_subselect |
|
169 |
{
|
|
170 |
protected: |
|
171 |
Item_cache *value, **row; |
|
172 |
public: |
|
846
by Brian Aker
Removing on typedeffed class. |
173 |
Item_singlerow_subselect(Select_Lex *select_lex); |
1
by brian
clean slate |
174 |
Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {} |
175 |
||
176 |
void cleanup(); |
|
177 |
subs_type substype() { return SINGLEROW_SUBS; } |
|
178 |
||
179 |
void reset(); |
|
1541.1.1
by Brian Aker
JOIN -> Join rename |
180 |
trans_res select_transformer(Join *join); |
482
by Brian Aker
Remove uint. |
181 |
void store(uint32_t i, Item* item); |
1
by brian
clean slate |
182 |
double val_real(); |
152
by Brian Aker
longlong replacement |
183 |
int64_t val_int (); |
1
by brian
clean slate |
184 |
String *val_str (String *); |
185 |
my_decimal *val_decimal(my_decimal *); |
|
186 |
bool val_bool(); |
|
187 |
enum Item_result result_type() const; |
|
188 |
enum_field_types field_type() const; |
|
189 |
void fix_length_and_dec(); |
|
190 |
||
482
by Brian Aker
Remove uint. |
191 |
uint32_t cols(); |
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); |
|
1
by brian
clean slate |
195 |
bool null_inside(); |
196 |
void bring_value(); |
|
197 |
||
198 |
/**
|
|
199 |
This method is used to implement a special case of semantic tree
|
|
200 |
rewriting, mandated by a SQL:2003 exception in the specification.
|
|
201 |
The only caller of this method is handle_sql2003_note184_exception(),
|
|
202 |
see the code there for more details.
|
|
203 |
Note that this method breaks the object internal integrity, by
|
|
846
by Brian Aker
Removing on typedeffed class. |
204 |
removing it's association with the corresponding Select_Lex,
|
1
by brian
clean slate |
205 |
making this object orphan from the parse tree.
|
206 |
No other method, beside the destructor, should be called on this
|
|
207 |
object, as it is now invalid.
|
|
846
by Brian Aker
Removing on typedeffed class. |
208 |
@return the Select_Lex structure that was given in the constructor.
|
1
by brian
clean slate |
209 |
*/
|
846
by Brian Aker
Removing on typedeffed class. |
210 |
Select_Lex* invalidate_and_restore_select_lex(); |
1
by brian
clean slate |
211 |
|
212 |
friend class select_singlerow_subselect; |
|
213 |
};
|
|
214 |
||
215 |
/* used in static ALL/ANY optimization */
|
|
216 |
class select_max_min_finder_subselect; |
|
217 |
class Item_maxmin_subselect :public Item_singlerow_subselect |
|
218 |
{
|
|
219 |
protected: |
|
220 |
bool max; |
|
221 |
bool was_values; // Set if we have found at least one row |
|
222 |
public: |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
223 |
Item_maxmin_subselect(Session *session, Item_subselect *parent, |
846
by Brian Aker
Removing on typedeffed class. |
224 |
Select_Lex *select_lex, bool max); |
1
by brian
clean slate |
225 |
virtual void print(String *str, enum_query_type query_type); |
226 |
void cleanup(); |
|
227 |
bool any_value() { return was_values; } |
|
51.1.24
by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE |
228 |
void register_value() { was_values= true; } |
229 |
void reset_value_registration() { was_values= false; } |
|
1
by brian
clean slate |
230 |
};
|
231 |
||
232 |
/* exists subselect */
|
|
233 |
||
234 |
class Item_exists_subselect :public Item_subselect |
|
235 |
{
|
|
236 |
protected: |
|
237 |
bool value; /* value of this item (boolean: exists/not-exists) */ |
|
238 |
||
239 |
public: |
|
846
by Brian Aker
Removing on typedeffed class. |
240 |
Item_exists_subselect(Select_Lex *select_lex); |
1
by brian
clean slate |
241 |
Item_exists_subselect(): Item_subselect() {} |
242 |
||
243 |
subs_type substype() { return EXISTS_SUBS; } |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
244 |
void reset() |
1
by brian
clean slate |
245 |
{
|
246 |
value= 0; |
|
247 |
}
|
|
248 |
||
249 |
enum Item_result result_type() const { return INT_RESULT;} |
|
152
by Brian Aker
longlong replacement |
250 |
int64_t val_int(); |
1
by brian
clean slate |
251 |
double val_real(); |
252 |
String *val_str(String*); |
|
253 |
my_decimal *val_decimal(my_decimal *); |
|
254 |
bool val_bool(); |
|
255 |
void fix_length_and_dec(); |
|
256 |
virtual void print(String *str, enum_query_type query_type); |
|
257 |
||
258 |
friend class select_exists_subselect; |
|
259 |
friend class subselect_uniquesubquery_engine; |
|
260 |
friend class subselect_indexsubquery_engine; |
|
261 |
};
|
|
262 |
||
263 |
||
264 |
/**
|
|
265 |
Representation of IN subquery predicates of the form
|
|
266 |
"left_expr IN (SELECT ...)".
|
|
267 |
||
268 |
@detail
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
269 |
This class has:
|
1
by brian
clean slate |
270 |
- A "subquery execution engine" (as a subclass of Item_subselect) that allows
|
271 |
it to evaluate subqueries. (and this class participates in execution by
|
|
272 |
having was_null variable where part of execution result is stored.
|
|
273 |
- Transformation methods (todo: more on this).
|
|
274 |
||
275 |
This class is not used directly, it is "wrapped" into Item_in_optimizer
|
|
276 |
which provides some small bits of subquery evaluation.
|
|
277 |
*/
|
|
278 |
||
279 |
class Item_in_subselect :public Item_exists_subselect |
|
280 |
{
|
|
281 |
public: |
|
282 |
Item *left_expr; |
|
283 |
protected: |
|
284 |
/*
|
|
285 |
Cache of the left operand of the subquery predicate. Allocated in the
|
|
286 |
runtime memory root, for each execution, thus need not be freed.
|
|
287 |
*/
|
|
1101.1.16
by Monty Taylor
Reverted 1103 |
288 |
List<Cached_item> *left_expr_cache; |
1
by brian
clean slate |
289 |
bool first_execution; |
290 |
||
291 |
/*
|
|
292 |
expr & optimizer used in subselect rewriting to store Item for
|
|
293 |
all JOIN in UNION
|
|
294 |
*/
|
|
295 |
Item *expr; |
|
296 |
Item_in_optimizer *optimizer; |
|
297 |
bool was_null; |
|
298 |
bool abort_on_null; |
|
299 |
||
300 |
public: |
|
301 |
/* Used to trigger on/off conditions that were pushed down to subselect */
|
|
302 |
bool *pushed_cond_guards; |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
303 |
|
1
by brian
clean slate |
304 |
/* Priority of this predicate in the convert-to-semi-join-nest process. */
|
305 |
int sj_convert_priority; |
|
306 |
||
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
307 |
/*
|
1
by brian
clean slate |
308 |
Location of the subquery predicate. It is either
|
309 |
- pointer to join nest if the subquery predicate is in the ON expression
|
|
327.2.4
by Brian Aker
Refactoring table.h |
310 |
- (TableList*)1 if the predicate is in the WHERE.
|
1
by brian
clean slate |
311 |
*/
|
327.2.4
by Brian Aker
Refactoring table.h |
312 |
TableList *expr_join_nest; |
1
by brian
clean slate |
313 |
|
314 |
/* The method chosen to execute the IN predicate. */
|
|
315 |
enum enum_exec_method { |
|
316 |
NOT_TRANSFORMED, /* No execution method was chosen for this IN. */ |
|
317 |
SEMI_JOIN, /* IN was converted to semi-join nest and should be removed. */ |
|
318 |
IN_TO_EXISTS, /* IN was converted to correlated EXISTS. */ |
|
319 |
MATERIALIZATION /* IN will be executed via subquery materialization. */ |
|
320 |
};
|
|
321 |
enum_exec_method exec_method; |
|
322 |
||
323 |
bool *get_cond_guard(int i) |
|
324 |
{
|
|
325 |
return pushed_cond_guards ? pushed_cond_guards + i : NULL; |
|
326 |
}
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
327 |
void set_cond_guard_var(int i, bool v) |
328 |
{
|
|
1
by brian
clean slate |
329 |
if ( pushed_cond_guards) |
330 |
pushed_cond_guards[i]= v; |
|
331 |
}
|
|
1637.5.4
by Prafulla Tekawade
Reverting some un-necessary changes. |
332 |
bool have_guarded_conds() { return test(pushed_cond_guards); } |
1
by brian
clean slate |
333 |
|
334 |
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery |
|
335 |
||
846
by Brian Aker
Removing on typedeffed class. |
336 |
Item_in_subselect(Item * left_expr, Select_Lex *select_lex); |
1
by brian
clean slate |
337 |
Item_in_subselect() |
1221.1.1
by Jay Pipes
Fixes some valgrind warnings regarding conditionals depending on unintialized variables. Use initializer lists properly, dang it. :) Also, removed the new_Cached_item() function's use_result_field, as this was only used for views and was producing a valgrind warning unnecessarily. |
338 |
:
|
339 |
Item_exists_subselect(), |
|
340 |
left_expr(NULL), |
|
341 |
left_expr_cache(NULL), |
|
342 |
first_execution(true), |
|
343 |
optimizer(NULL), |
|
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), |
|
349 |
upper_item(NULL) |
|
1
by brian
clean slate |
350 |
{}
|
351 |
void cleanup(); |
|
352 |
subs_type substype() { return IN_SUBS; } |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
353 |
void reset() |
1
by brian
clean slate |
354 |
{
|
355 |
value= 0; |
|
356 |
null_value= 0; |
|
357 |
was_null= 0; |
|
358 |
}
|
|
1541.1.1
by Brian Aker
JOIN -> Join rename |
359 |
trans_res select_transformer(Join *join); |
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); |
|
362 |
trans_res row_value_transformer(Join * join); |
|
363 |
trans_res single_value_in_to_exists_transformer(Join * join, |
|
584.4.7
by Monty Taylor
Removed a big bank of includes from item.h. |
364 |
const Comp_creator *func); |
1541.1.1
by Brian Aker
JOIN -> Join rename |
365 |
trans_res row_value_in_to_exists_transformer(Join * join); |
1
by brian
clean slate |
366 |
virtual bool exec(); |
152
by Brian Aker
longlong replacement |
367 |
int64_t val_int(); |
1
by brian
clean slate |
368 |
double val_real(); |
369 |
String *val_str(String*); |
|
370 |
my_decimal *val_decimal(my_decimal *); |
|
371 |
void update_null_value () { (void) val_bool(); } |
|
372 |
bool val_bool(); |
|
373 |
void top_level_item() { abort_on_null=1; } |
|
374 |
inline bool is_top_level_item() { return abort_on_null; } |
|
848
by Brian Aker
typdef class removal (just... use the name of the class). |
375 |
bool test_limit(Select_Lex_Unit *unit); |
1
by brian
clean slate |
376 |
virtual void print(String *str, enum_query_type query_type); |
520.1.22
by Brian Aker
Second pass of thd cleanup |
377 |
bool fix_fields(Session *session, Item **ref); |
1
by brian
clean slate |
378 |
bool setup_engine(); |
379 |
bool init_left_expr_cache(); |
|
481
by Brian Aker
Remove all of uchar. |
380 |
bool is_expensive_processor(unsigned char *arg); |
1
by brian
clean slate |
381 |
|
382 |
friend class Item_ref_null_helper; |
|
383 |
friend class Item_is_not_null_test; |
|
384 |
friend class Item_in_optimizer; |
|
385 |
friend class subselect_indexsubquery_engine; |
|
386 |
friend class subselect_hash_sj_engine; |
|
387 |
};
|
|
388 |
||
389 |
||
390 |
/* ALL/ANY/SOME subselect */
|
|
391 |
class Item_allany_subselect :public Item_in_subselect |
|
392 |
{
|
|
393 |
public: |
|
394 |
chooser_compare_func_creator func_creator; |
|
395 |
Comp_creator *func; |
|
396 |
bool all; |
|
397 |
||
398 |
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc, |
|
846
by Brian Aker
Removing on typedeffed class. |
399 |
Select_Lex *select_lex, bool all); |
1
by brian
clean slate |
400 |
|
401 |
// only ALL subquery has upper not
|
|
402 |
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; } |
|
1541.1.1
by Brian Aker
JOIN -> Join rename |
403 |
trans_res select_transformer(Join *join); |
1
by brian
clean slate |
404 |
virtual void print(String *str, enum_query_type query_type); |
405 |
};
|
|
406 |
||
407 |
||
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
408 |
class subselect_engine: public memory::SqlAlloc |
1
by brian
clean slate |
409 |
{
|
410 |
protected: |
|
411 |
select_result_interceptor *result; /* results storage class */ |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
412 |
Session *session; /* pointer to current Session */ |
1
by brian
clean slate |
413 |
Item_subselect *item; /* item, that use this engine */ |
414 |
enum Item_result res_type; /* type of results */ |
|
415 |
enum_field_types res_field_type; /* column type of the results */ |
|
416 |
bool maybe_null; /* may be null (first item in select) */ |
|
417 |
public: |
|
418 |
||
419 |
enum enum_engine_type {ABSTRACT_ENGINE, SINGLE_SELECT_ENGINE, |
|
420 |
UNION_ENGINE, UNIQUESUBQUERY_ENGINE, |
|
421 |
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE}; |
|
422 |
||
423 |
subselect_engine(Item_subselect *si, select_result_interceptor *res) |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
424 |
:session(NULL) |
1
by brian
clean slate |
425 |
{
|
426 |
result= res; |
|
427 |
item= si; |
|
428 |
res_type= STRING_RESULT; |
|
241
by Brian Aker
First pass of CHAR removal. |
429 |
res_field_type= DRIZZLE_TYPE_VARCHAR; |
1
by brian
clean slate |
430 |
maybe_null= 0; |
431 |
}
|
|
432 |
virtual ~subselect_engine() {}; // to satisfy compiler |
|
433 |
virtual void cleanup()= 0; |
|
434 |
||
435 |
/*
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
436 |
Also sets "session" for subselect_engine::result.
|
1
by brian
clean slate |
437 |
Should be called before prepare().
|
438 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
439 |
void set_session(Session *session_arg); |
440 |
Session * get_session() { return session; } |
|
1
by brian
clean slate |
441 |
virtual int prepare()= 0; |
442 |
virtual void fix_length_and_dec(Item_cache** row)= 0; |
|
443 |
/*
|
|
444 |
Execute the engine
|
|
445 |
||
446 |
SYNOPSIS
|
|
447 |
exec()
|
|
448 |
||
449 |
DESCRIPTION
|
|
450 |
Execute the engine. The result of execution is subquery value that is
|
|
451 |
either captured by previously set up select_result-based 'sink' or
|
|
452 |
stored somewhere by the exec() method itself.
|
|
453 |
||
454 |
A required side effect: If at least one pushed-down predicate is
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
455 |
disabled, subselect_engine->no_rows() must return correct result after
|
1
by brian
clean slate |
456 |
the exec() call.
|
457 |
||
458 |
RETURN
|
|
459 |
0 - OK
|
|
460 |
1 - Either an execution error, or the engine was "changed", and the
|
|
461 |
caller should call exec() again for the new engine.
|
|
462 |
*/
|
|
463 |
virtual int exec()= 0; |
|
482
by Brian Aker
Remove uint. |
464 |
virtual uint32_t cols()= 0; /* return number of columns in select */ |
206
by Brian Aker
Removed final uint dead types. |
465 |
virtual uint8_t uncacheable()= 0; /* query is uncacheable */ |
1
by brian
clean slate |
466 |
enum Item_result type() { return res_type; } |
467 |
enum_field_types field_type() { return res_field_type; } |
|
468 |
virtual void exclude()= 0; |
|
469 |
virtual bool may_be_null() { return maybe_null; }; |
|
470 |
virtual table_map upper_select_const_tables()= 0; |
|
327.2.4
by Brian Aker
Refactoring table.h |
471 |
static table_map calc_const_tables(TableList *); |
1
by brian
clean slate |
472 |
virtual void print(String *str, enum_query_type query_type)= 0; |
473 |
virtual bool change_result(Item_subselect *si, |
|
474 |
select_result_interceptor *result)= 0; |
|
475 |
virtual bool no_tables()= 0; |
|
51.1.24
by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE |
476 |
virtual bool is_executed() const { return false; } |
1
by brian
clean slate |
477 |
/* Check if subquery produced any rows during last query execution */
|
478 |
virtual bool no_rows() = 0; |
|
479 |
virtual enum_engine_type engine_type() { return ABSTRACT_ENGINE; } |
|
480 |
||
481 |
protected: |
|
482 |
void set_row(List<Item> &item_list, Item_cache **row); |
|
483 |
};
|
|
484 |
||
485 |
||
486 |
class subselect_single_select_engine: public subselect_engine |
|
487 |
{
|
|
275
by Brian Aker
Full removal of my_bool from central server. |
488 |
bool prepared; /* simple subselect is prepared */ |
489 |
bool optimized; /* simple subselect is optimized */ |
|
490 |
bool executed; /* simple subselect is executed */ |
|
846
by Brian Aker
Removing on typedeffed class. |
491 |
Select_Lex *select_lex; /* corresponding select_lex */ |
1541.1.1
by Brian Aker
JOIN -> Join rename |
492 |
Join * join; /* corresponding JOIN structure */ |
1
by brian
clean slate |
493 |
public: |
846
by Brian Aker
Removing on typedeffed class. |
494 |
subselect_single_select_engine(Select_Lex *select, |
1
by brian
clean slate |
495 |
select_result_interceptor *result, |
496 |
Item_subselect *item); |
|
497 |
void cleanup(); |
|
498 |
int prepare(); |
|
499 |
void fix_length_and_dec(Item_cache** row); |
|
500 |
int exec(); |
|
482
by Brian Aker
Remove uint. |
501 |
uint32_t cols(); |
206
by Brian Aker
Removed final uint dead types. |
502 |
uint8_t uncacheable(); |
1
by brian
clean slate |
503 |
void exclude(); |
504 |
table_map upper_select_const_tables(); |
|
505 |
virtual void print (String *str, enum_query_type query_type); |
|
506 |
bool change_result(Item_subselect *si, select_result_interceptor *result); |
|
507 |
bool no_tables(); |
|
508 |
bool may_be_null(); |
|
509 |
bool is_executed() const { return executed; } |
|
510 |
bool no_rows(); |
|
511 |
virtual enum_engine_type engine_type() { return SINGLE_SELECT_ENGINE; } |
|
512 |
||
513 |
friend class subselect_hash_sj_engine; |
|
514 |
friend class Item_in_subselect; |
|
515 |
};
|
|
516 |
||
517 |
||
518 |
class subselect_union_engine: public subselect_engine |
|
519 |
{
|
|
848
by Brian Aker
typdef class removal (just... use the name of the class). |
520 |
Select_Lex_Unit *unit; /* corresponding unit structure */ |
1
by brian
clean slate |
521 |
public: |
848
by Brian Aker
typdef class removal (just... use the name of the class). |
522 |
subselect_union_engine(Select_Lex_Unit *u, |
1
by brian
clean slate |
523 |
select_result_interceptor *result, |
524 |
Item_subselect *item); |
|
525 |
void cleanup(); |
|
526 |
int prepare(); |
|
527 |
void fix_length_and_dec(Item_cache** row); |
|
528 |
int exec(); |
|
482
by Brian Aker
Remove uint. |
529 |
uint32_t cols(); |
206
by Brian Aker
Removed final uint dead types. |
530 |
uint8_t uncacheable(); |
1
by brian
clean slate |
531 |
void exclude(); |
532 |
table_map upper_select_const_tables(); |
|
533 |
virtual void print (String *str, enum_query_type query_type); |
|
534 |
bool change_result(Item_subselect *si, select_result_interceptor *result); |
|
535 |
bool no_tables(); |
|
536 |
bool is_executed() const; |
|
537 |
bool no_rows(); |
|
538 |
virtual enum_engine_type engine_type() { return UNION_ENGINE; } |
|
539 |
};
|
|
540 |
||
541 |
||
1089.1.1
by Brian Aker
Remove of JOIN_TAB to JoinTable |
542 |
class JoinTable; |
1
by brian
clean slate |
543 |
|
544 |
||
545 |
/*
|
|
546 |
A subquery execution engine that evaluates the subquery by doing one index
|
|
547 |
lookup in a unique index.
|
|
548 |
||
549 |
This engine is used to resolve subqueries in forms
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
550 |
|
551 |
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
|
|
552 |
||
1
by brian
clean slate |
553 |
or, tuple-based:
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
554 |
|
1
by brian
clean slate |
555 |
(oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
556 |
FROM tbl WHERE subqwhere)
|
557 |
||
1
by brian
clean slate |
558 |
i.e. the subquery is a single table SELECT without GROUP BY, aggregate
|
559 |
functions, etc.
|
|
560 |
*/
|
|
561 |
||
562 |
class subselect_uniquesubquery_engine: public subselect_engine |
|
563 |
{
|
|
564 |
protected: |
|
1089.1.1
by Brian Aker
Remove of JOIN_TAB to JoinTable |
565 |
JoinTable *tab; |
1
by brian
clean slate |
566 |
Item *cond; /* The WHERE condition of subselect */ |
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
567 |
/*
|
1
by brian
clean slate |
568 |
TRUE<=> last execution produced empty set. Valid only when left
|
569 |
expression is NULL.
|
|
570 |
*/
|
|
571 |
bool empty_result_set; |
|
572 |
bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */ |
|
573 |
public: |
|
574 |
||
1541.1.1
by Brian Aker
JOIN -> Join rename |
575 |
// constructor can assign Session because it will be called after Join::prepare
|
1089.1.1
by Brian Aker
Remove of JOIN_TAB to JoinTable |
576 |
subselect_uniquesubquery_engine(Session *session_arg, JoinTable *tab_arg, |
1
by brian
clean slate |
577 |
Item_subselect *subs, Item *where) |
578 |
:subselect_engine(subs, 0), tab(tab_arg), cond(where) |
|
579 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
580 |
set_session(session_arg); |
1
by brian
clean slate |
581 |
}
|
582 |
void cleanup(); |
|
583 |
int prepare(); |
|
584 |
void fix_length_and_dec(Item_cache** row); |
|
585 |
int exec(); |
|
482
by Brian Aker
Remove uint. |
586 |
uint32_t cols() { return 1; } |
206
by Brian Aker
Removed final uint dead types. |
587 |
uint8_t uncacheable() { return UNCACHEABLE_DEPENDENT; } |
1
by brian
clean slate |
588 |
void exclude(); |
589 |
table_map upper_select_const_tables() { return 0; } |
|
590 |
virtual void print (String *str, enum_query_type query_type); |
|
591 |
bool change_result(Item_subselect *si, select_result_interceptor *result); |
|
592 |
bool no_tables(); |
|
593 |
int scan_table(); |
|
594 |
bool copy_ref_key(); |
|
595 |
bool no_rows() { return empty_result_set; } |
|
596 |
virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; } |
|
597 |
};
|
|
598 |
||
599 |
||
600 |
class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine |
|
601 |
{
|
|
602 |
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
|
|
603 |
bool check_null; |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
604 |
/*
|
1
by brian
clean slate |
605 |
The "having" clause. This clause (further reffered to as "artificial
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
606 |
having") was inserted by subquery transformation code. It contains
|
607 |
Item(s) that have a side-effect: they record whether the subquery has
|
|
1
by brian
clean slate |
608 |
produced a row with NULL certain components. We need to use it for cases
|
609 |
like
|
|
610 |
(oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
|
|
611 |
where we do index lookup on t.key=oe1 but need also to check if there
|
|
612 |
was a row such that t.no_key IS NULL.
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
613 |
|
1
by brian
clean slate |
614 |
NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
|
615 |
it should have been in uniquesubquery_engine in order to allow execution of
|
|
616 |
subqueries like
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
617 |
|
1
by brian
clean slate |
618 |
(oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
|
619 |
||
620 |
We could use uniquesubquery_engine for the first component and let
|
|
621 |
Item_is_not_null_test( non_key_maybe_null_field) to handle the second.
|
|
622 |
||
623 |
However, subqueries like the above are currently not handled by index
|
|
624 |
lookup-based subquery engines, the engine applicability check misses
|
|
625 |
them: it doesn't switch the engine for case of artificial having and
|
|
626 |
[eq_]ref access (only for artifical having + ref_or_null or no having).
|
|
627 |
The above example subquery is handled as a full-blown SELECT with eq_ref
|
|
628 |
access to one table.
|
|
629 |
||
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
630 |
Due to this limitation, the "artificial having" currently needs to be
|
1
by brian
clean slate |
631 |
checked by only in indexsubquery_engine.
|
632 |
*/
|
|
633 |
Item *having; |
|
634 |
public: |
|
635 |
||
1541.1.1
by Brian Aker
JOIN -> Join rename |
636 |
// constructor can assign Session because it will be called after Join::prepare
|
1089.1.1
by Brian Aker
Remove of JOIN_TAB to JoinTable |
637 |
subselect_indexsubquery_engine(Session *session_arg, JoinTable *tab_arg, |
1
by brian
clean slate |
638 |
Item_subselect *subs, Item *where, |
639 |
Item *having_arg, bool chk_null) |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
640 |
:subselect_uniquesubquery_engine(session_arg, tab_arg, subs, where), |
1
by brian
clean slate |
641 |
check_null(chk_null), |
642 |
having(having_arg) |
|
643 |
{}
|
|
644 |
int exec(); |
|
645 |
virtual void print (String *str, enum_query_type query_type); |
|
646 |
virtual enum_engine_type engine_type() { return INDEXSUBQUERY_ENGINE; } |
|
647 |
};
|
|
648 |
||
649 |
||
650 |
inline bool Item_subselect::is_evaluated() const |
|
651 |
{
|
|
652 |
return engine->is_executed(); |
|
653 |
}
|
|
654 |
||
655 |
||
656 |
inline bool Item_subselect::is_uncacheable() const |
|
657 |
{
|
|
658 |
return engine->uncacheable(); |
|
659 |
}
|
|
660 |
||
661 |
||
662 |
/**
|
|
663 |
Compute an IN predicate via a hash semi-join. The subquery is materialized
|
|
664 |
during the first evaluation of the IN predicate. The IN predicate is executed
|
|
665 |
via the functionality inherited from subselect_uniquesubquery_engine.
|
|
666 |
*/
|
|
667 |
||
668 |
class subselect_hash_sj_engine: public subselect_uniquesubquery_engine |
|
669 |
{
|
|
670 |
protected: |
|
671 |
/* TRUE if the subquery was materialized into a temp table. */
|
|
672 |
bool is_materialized; |
|
673 |
/*
|
|
674 |
The old engine already chosen at parse time and stored in permanent memory.
|
|
675 |
Through this member we can re-create and re-prepare materialize_join for
|
|
676 |
each execution of a prepared statement. We akso resuse the functionality
|
|
677 |
of subselect_single_select_engine::[prepare | cols].
|
|
678 |
*/
|
|
679 |
subselect_single_select_engine *materialize_engine; |
|
680 |
/*
|
|
681 |
QEP to execute the subquery and materialize its result into a
|
|
682 |
temporary table. Created during the first call to exec().
|
|
683 |
*/
|
|
1541.1.1
by Brian Aker
JOIN -> Join rename |
684 |
Join *materialize_join; |
1
by brian
clean slate |
685 |
/* Temp table context of the outer select's JOIN. */
|
851
by Brian Aker
Class rewrite of Session (aka get all of the junk out) |
686 |
Tmp_Table_Param *tmp_param; |
1
by brian
clean slate |
687 |
|
688 |
public: |
|
779.3.10
by Monty Taylor
Turned on -Wshadow. |
689 |
subselect_hash_sj_engine(Session *session_in, Item_subselect *in_predicate, |
1
by brian
clean slate |
690 |
subselect_single_select_engine *old_engine) |
779.3.10
by Monty Taylor
Turned on -Wshadow. |
691 |
:subselect_uniquesubquery_engine(session_in, NULL, in_predicate, NULL), |
51.1.24
by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE |
692 |
is_materialized(false), materialize_engine(old_engine), |
1
by brian
clean slate |
693 |
materialize_join(NULL), tmp_param(NULL) |
694 |
{}
|
|
695 |
~subselect_hash_sj_engine(); |
|
696 |
||
697 |
bool init_permanent(List<Item> *tmp_columns); |
|
698 |
bool init_runtime(); |
|
699 |
void cleanup(); |
|
700 |
int prepare() { return 0; } |
|
701 |
int exec(); |
|
702 |
virtual void print (String *str, enum_query_type query_type); |
|
482
by Brian Aker
Remove uint. |
703 |
uint32_t cols() |
1
by brian
clean slate |
704 |
{
|
705 |
return materialize_engine->cols(); |
|
706 |
}
|
|
707 |
virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; } |
|
708 |
};
|
|
575.1.6
by Monty Taylor
Cleaned up some headers for PCH. |
709 |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
710 |
} /* namespace drizzled */ |
711 |
||
575.1.6
by Monty Taylor
Cleaned up some headers for PCH. |
712 |
#endif /* DRIZZLED_ITEM_SUBSELECT_H */ |