1
by brian
clean slate |
1 |
/* Copyright (C) 2000-2006 MySQL AB
|
2 |
||
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.
|
|
6 |
||
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.
|
|
11 |
||
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 */
|
|
15 |
||
16 |
||
17 |
/**
|
|
18 |
@file
|
|
19 |
||
20 |
@brief
|
|
21 |
classes to use when handling where clause
|
|
22 |
*/
|
|
23 |
||
24 |
#ifdef USE_PRAGMA_INTERFACE
|
|
25 |
#pragma interface /* gcc class implementation */ |
|
26 |
#endif
|
|
27 |
||
243.1.13
by Jay Pipes
More comments in mysql_priv.h to mark stuff TODO. Move sql_locale.h and object_creation_ctx.h up in the file since no more dependencies above them. |
28 |
/* PREV_BITS only used in sql_select.cc */
|
29 |
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
|
|
30 |
||
212.4.2
by Monty Taylor
Fixed the includes in places to make the myisam header file move work. |
31 |
#include <storage/myisam/myisam.h> |
1
by brian
clean slate |
32 |
|
33 |
/* Values in optimize */
|
|
34 |
#define KEY_OPTIMIZE_EXISTS 1
|
|
35 |
#define KEY_OPTIMIZE_REF_OR_NULL 2
|
|
36 |
||
37 |
typedef struct keyuse_t { |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
38 |
Table *table; |
1
by brian
clean slate |
39 |
Item *val; /**< or value if no field */ |
40 |
table_map used_tables; |
|
41 |
uint key, keypart; |
|
42 |
uint optimize; // 0, or KEY_OPTIMIZE_* |
|
43 |
key_part_map keypart_map; |
|
44 |
ha_rows ref_table_rows; |
|
45 |
/**
|
|
46 |
If true, the comparison this value was created from will not be
|
|
47 |
satisfied if val has NULL 'value'.
|
|
48 |
*/
|
|
49 |
bool null_rejecting; |
|
50 |
/*
|
|
51 |
!NULL - This KEYUSE was created from an equality that was wrapped into
|
|
52 |
an Item_func_trig_cond. This means the equality (and validity of
|
|
53 |
this KEYUSE element) can be turned on and off. The on/off state
|
|
54 |
is indicted by the pointed value:
|
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
55 |
*cond_guard == true <=> equality condition is on
|
56 |
*cond_guard == false <=> equality condition is off
|
|
1
by brian
clean slate |
57 |
|
58 |
NULL - Otherwise (the source equality can't be turned off)
|
|
59 |
*/
|
|
60 |
bool *cond_guard; |
|
61 |
/*
|
|
62 |
0..64 <=> This was created from semi-join IN-equality # sj_pred_no.
|
|
63 |
MAX_UINT Otherwise
|
|
64 |
*/
|
|
65 |
uint sj_pred_no; |
|
66 |
} KEYUSE; |
|
67 |
||
68 |
class store_key; |
|
69 |
||
70 |
typedef struct st_table_ref |
|
71 |
{
|
|
72 |
bool key_err; |
|
365.2.6
by Monty Taylor
Undid some stupid int->int16_t conversions. |
73 |
uint32_t key_parts; ///< num of ... |
74 |
uint32_t key_length; ///< length of key_buff |
|
75 |
int32_t key; ///< key no |
|
365.2.5
by Monty Taylor
More ~0 removal. |
76 |
unsigned char *key_buff; ///< value to look for with key |
77 |
unsigned char *key_buff2; ///< key_buff+key_length |
|
1
by brian
clean slate |
78 |
store_key **key_copy; // |
79 |
Item **items; ///< val()'s for each keypart |
|
80 |
/*
|
|
81 |
Array of pointers to trigger variables. Some/all of the pointers may be
|
|
82 |
NULL. The ref access can be used iff
|
|
83 |
|
|
84 |
for each used key part i, (!cond_guards[i] || *cond_guards[i])
|
|
85 |
||
86 |
This array is used by subquery code. The subquery code may inject
|
|
87 |
triggered conditions, i.e. conditions that can be 'switched off'. A ref
|
|
88 |
access created from such condition is not valid when at least one of the
|
|
89 |
underlying conditions is switched off (see subquery code for more details)
|
|
90 |
*/
|
|
91 |
bool **cond_guards; |
|
92 |
/**
|
|
93 |
(null_rejecting & (1<<i)) means the condition is '=' and no matching
|
|
94 |
rows will be produced if items[i] IS NULL (see add_not_null_conds())
|
|
95 |
*/
|
|
96 |
key_part_map null_rejecting; |
|
97 |
table_map depend_map; ///< Table depends on these tables. |
|
98 |
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
|
|
365.2.5
by Monty Taylor
More ~0 removal. |
99 |
unsigned char *null_ref_key; |
1
by brian
clean slate |
100 |
|
101 |
/*
|
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
102 |
true <=> disable the "cache" as doing lookup with the same key value may
|
1
by brian
clean slate |
103 |
produce different results (because of Index Condition Pushdown)
|
104 |
*/
|
|
105 |
bool disable_cache; |
|
106 |
} TABLE_REF; |
|
107 |
||
108 |
||
109 |
/**
|
|
110 |
CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
|
|
111 |
table
|
|
112 |
*/
|
|
113 |
||
114 |
typedef struct st_cache_field { |
|
115 |
/*
|
|
116 |
Where source data is located (i.e. this points to somewhere in
|
|
117 |
tableX->record[0])
|
|
118 |
*/
|
|
365.2.5
by Monty Taylor
More ~0 removal. |
119 |
unsigned char *str; |
365.2.6
by Monty Taylor
Undid some stupid int->int16_t conversions. |
120 |
uint32_t length; /* Length of data at *str, in bytes */ |
121 |
uint32_t blob_length; /* Valid IFF blob_field != 0 */ |
|
1
by brian
clean slate |
122 |
Field_blob *blob_field; |
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
123 |
bool strip; /* true <=> Strip endspaces ?? */ |
1
by brian
clean slate |
124 |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
125 |
Table *get_rowid; /* _ != NULL <=> */ |
1
by brian
clean slate |
126 |
} CACHE_FIELD; |
127 |
||
128 |
||
129 |
typedef struct st_join_cache |
|
130 |
{
|
|
365.2.5
by Monty Taylor
More ~0 removal. |
131 |
unsigned char *buff; |
132 |
unsigned char *pos; /* Start of free space in the buffer */ |
|
133 |
unsigned char *end; |
|
365.2.6
by Monty Taylor
Undid some stupid int->int16_t conversions. |
134 |
uint32_t records; /* # of row cominations currently stored in the cache */ |
135 |
uint32_t record_nr; |
|
136 |
uint32_t ptr_record; |
|
1
by brian
clean slate |
137 |
/*
|
138 |
Number of fields (i.e. cache_field objects). Those correspond to table
|
|
139 |
columns, and there are also special fields for
|
|
140 |
- table's column null bits
|
|
141 |
- table's null-complementation byte
|
|
142 |
- [new] table's rowid.
|
|
143 |
*/
|
|
365.2.6
by Monty Taylor
Undid some stupid int->int16_t conversions. |
144 |
uint32_t fields; |
145 |
uint32_t length; |
|
146 |
uint32_t blobs; |
|
1
by brian
clean slate |
147 |
CACHE_FIELD *field; |
148 |
CACHE_FIELD **blob_ptr; |
|
149 |
SQL_SELECT *select; |
|
150 |
} JOIN_CACHE; |
|
151 |
||
152 |
||
153 |
/*
|
|
154 |
The structs which holds the join connections and join states
|
|
155 |
*/
|
|
156 |
enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF, |
|
157 |
JT_ALL, JT_RANGE, JT_NEXT, JT_REF_OR_NULL, |
|
158 |
JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE}; |
|
159 |
||
160 |
class JOIN; |
|
161 |
||
162 |
enum enum_nested_loop_state |
|
163 |
{
|
|
164 |
NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1, |
|
165 |
NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1, |
|
166 |
NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4 |
|
167 |
};
|
|
168 |
||
169 |
||
170 |
/* Values for JOIN_TAB::packed_info */
|
|
171 |
#define TAB_INFO_HAVE_VALUE 1
|
|
172 |
#define TAB_INFO_USING_INDEX 2
|
|
173 |
#define TAB_INFO_USING_WHERE 4
|
|
174 |
#define TAB_INFO_FULL_SCAN_ON_NULL 8
|
|
175 |
||
176 |
class SJ_TMP_TABLE; |
|
177 |
||
178 |
typedef enum_nested_loop_state |
|
179 |
(*Next_select_func)(JOIN *, struct st_join_table *, bool); |
|
180 |
typedef int (*Read_record_func)(struct st_join_table *tab); |
|
181 |
Next_select_func setup_end_select_func(JOIN *join); |
|
182 |
||
183 |
||
184 |
typedef struct st_join_table { |
|
185 |
st_join_table() {} /* Remove gcc warning */ |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
186 |
Table *table; |
1
by brian
clean slate |
187 |
KEYUSE *keyuse; /**< pointer to first used key */ |
188 |
SQL_SELECT *select; |
|
189 |
COND *select_cond; |
|
190 |
QUICK_SELECT_I *quick; |
|
191 |
/*
|
|
192 |
The value of select_cond before we've attempted to do Index Condition
|
|
193 |
Pushdown. We may need to restore everything back if we first choose one
|
|
194 |
index but then reconsider (see test_if_skip_sort_order() for such
|
|
195 |
scenarios).
|
|
196 |
NULL means no index condition pushdown was performed.
|
|
197 |
*/
|
|
198 |
Item *pre_idx_push_select_cond; |
|
199 |
Item **on_expr_ref; /**< pointer to the associated on expression */ |
|
200 |
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */ |
|
201 |
st_join_table *first_inner; /**< first inner table for including outerjoin */ |
|
202 |
bool found; /**< true after all matches or null complement */ |
|
203 |
bool not_null_compl;/**< true before null complement is added */ |
|
204 |
st_join_table *last_inner; /**< last table table for embedding outer join */ |
|
205 |
st_join_table *first_upper; /**< first inner table for embedding outer join */ |
|
206 |
st_join_table *first_unmatched; /**< used for optimization purposes only */ |
|
207 |
||
208 |
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
|
209 |
const char *info; |
|
210 |
/*
|
|
211 |
Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
|
|
212 |
column, or 0 if there is no info.
|
|
213 |
*/
|
|
214 |
uint packed_info; |
|
215 |
||
216 |
Read_record_func read_first_record; |
|
217 |
Next_select_func next_select; |
|
218 |
READ_RECORD read_record; |
|
219 |
/*
|
|
220 |
Currently the following two fields are used only for a [NOT] IN subquery
|
|
221 |
if it is executed by an alternative full table scan when the left operand of
|
|
222 |
the subquery predicate is evaluated to NULL.
|
|
223 |
*/
|
|
224 |
Read_record_func save_read_first_record;/* to save read_first_record */ |
|
225 |
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */ |
|
226 |
double worst_seeks; |
|
227 |
key_map const_keys; /**< Keys with constant part */ |
|
228 |
key_map checked_keys; /**< Keys checked in find_best */ |
|
229 |
key_map needed_reg; |
|
230 |
key_map keys; /**< all keys with can be used */ |
|
231 |
||
232 |
/* Either #rows in the table or 1 for const table. */
|
|
233 |
ha_rows records; |
|
234 |
/*
|
|
235 |
Number of records that will be scanned (yes scanned, not returned) by the
|
|
236 |
best 'independent' access method, i.e. table scan or QUICK_*_SELECT)
|
|
237 |
*/
|
|
238 |
ha_rows found_records; |
|
239 |
/*
|
|
240 |
Cost of accessing the table using "ALL" or range/index_merge access
|
|
241 |
method (but not 'index' for some reason), i.e. this matches method which
|
|
242 |
E(#records) is in found_records.
|
|
243 |
*/
|
|
244 |
ha_rows read_time; |
|
245 |
||
246 |
table_map dependent,key_dependent; |
|
247 |
uint use_quick,index; |
|
248 |
uint status; ///< Save status for cache |
|
249 |
uint used_fields,used_fieldlength,used_blobs; |
|
250 |
enum join_type type; |
|
251 |
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; |
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
252 |
/* true <=> index-based access method must return records in order */
|
1
by brian
clean slate |
253 |
bool sorted; |
254 |
/*
|
|
255 |
If it's not 0 the number stored this field indicates that the index
|
|
256 |
scan has been chosen to access the table data and we expect to scan
|
|
257 |
this number of rows for the table.
|
|
258 |
*/
|
|
259 |
ha_rows limit; |
|
260 |
TABLE_REF ref; |
|
261 |
JOIN_CACHE cache; |
|
262 |
JOIN *join; |
|
263 |
/** Bitmap of nested joins this table is part of */
|
|
264 |
||
265 |
/* SemiJoinDuplicateElimination variables: */
|
|
266 |
/*
|
|
267 |
Embedding SJ-nest (may be not the direct parent), or NULL if none.
|
|
268 |
This variable holds the result of table pullout.
|
|
269 |
*/
|
|
327.2.4
by Brian Aker
Refactoring table.h |
270 |
TableList *emb_sj_nest; |
1
by brian
clean slate |
271 |
|
272 |
/* Variables for semi-join duplicate elimination */
|
|
273 |
SJ_TMP_TABLE *flush_weedout_table; |
|
274 |
SJ_TMP_TABLE *check_weed_out_table; |
|
275 |
struct st_join_table *do_firstmatch; |
|
276 |
||
277 |
/*
|
|
278 |
ptr - this join tab should do an InsideOut scan. Points
|
|
279 |
to the tab for which we'll need to check tab->found_match.
|
|
280 |
||
281 |
NULL - Not an insideout scan.
|
|
282 |
*/
|
|
283 |
struct st_join_table *insideout_match_tab; |
|
284 |
uchar *insideout_buf; // Buffer to save index tuple to be able to skip dups |
|
285 |
||
286 |
/* Used by InsideOut scan. Just set to true when have found a row. */
|
|
287 |
bool found_match; |
|
288 |
||
289 |
enum { |
|
290 |
/* If set, the rowid of this table must be put into the temptable. */
|
|
291 |
KEEP_ROWID=1, |
|
292 |
/*
|
|
293 |
If set, one should call h->position() to obtain the rowid,
|
|
294 |
otherwise, the rowid is assumed to already be in h->ref
|
|
295 |
(this is because join caching and filesort() save the rowid and then
|
|
296 |
put it back into h->ref)
|
|
297 |
*/
|
|
298 |
CALL_POSITION=2 |
|
299 |
};
|
|
300 |
/* A set of flags from the above enum */
|
|
301 |
int rowid_keep_flags; |
|
302 |
||
303 |
||
304 |
/* NestedOuterJoins: Bitmap of nested joins this table is part of */
|
|
305 |
nested_join_map embedding_map; |
|
306 |
||
307 |
void cleanup(); |
|
308 |
inline bool is_using_loose_index_scan() |
|
309 |
{
|
|
310 |
return (select && select->quick && |
|
311 |
(select->quick->get_type() == |
|
312 |
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)); |
|
313 |
}
|
|
314 |
} JOIN_TAB; |
|
315 |
||
316 |
enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool |
|
317 |
end_of_records); |
|
318 |
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool |
|
319 |
end_of_records); |
|
320 |
enum_nested_loop_state end_send_group(JOIN *join, JOIN_TAB *join_tab, |
|
321 |
bool end_of_records); |
|
322 |
enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab, |
|
323 |
bool end_of_records); |
|
324 |
||
325 |
/**
|
|
326 |
Information about a position of table within a join order. Used in join
|
|
327 |
optimization.
|
|
328 |
*/
|
|
329 |
typedef struct st_position |
|
330 |
{
|
|
331 |
/*
|
|
332 |
The "fanout": number of output rows that will be produced (after
|
|
333 |
pushed down selection condition is applied) per each row combination of
|
|
334 |
previous tables.
|
|
335 |
*/
|
|
336 |
double records_read; |
|
337 |
||
338 |
/*
|
|
339 |
Cost accessing the table in course of the entire complete join execution,
|
|
340 |
i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times
|
|
341 |
number the access method will be invoked.
|
|
342 |
*/
|
|
343 |
double read_time; |
|
344 |
JOIN_TAB *table; |
|
345 |
||
346 |
/*
|
|
347 |
NULL - 'index' or 'range' or 'index_merge' or 'ALL' access is used.
|
|
348 |
Other - [eq_]ref[_or_null] access is used. Pointer to {t.keypart1 = expr}
|
|
349 |
*/
|
|
350 |
KEYUSE *key; |
|
351 |
||
352 |
/* If ref-based access is used: bitmap of tables this table depends on */
|
|
353 |
table_map ref_depend_map; |
|
354 |
||
355 |
bool use_insideout_scan; |
|
356 |
} POSITION; |
|
357 |
||
358 |
||
359 |
typedef struct st_rollup |
|
360 |
{
|
|
361 |
enum State { STATE_NONE, STATE_INITED, STATE_READY }; |
|
362 |
State state; |
|
363 |
Item_null_result **null_items; |
|
364 |
Item ***ref_pointer_arrays; |
|
365 |
List<Item> *fields; |
|
366 |
} ROLLUP; |
|
367 |
||
368 |
||
369 |
class JOIN :public Sql_alloc |
|
370 |
{
|
|
371 |
JOIN(const JOIN &rhs); /**< not implemented */ |
|
372 |
JOIN& operator=(const JOIN &rhs); /**< not implemented */ |
|
373 |
public: |
|
374 |
JOIN_TAB *join_tab,**best_ref; |
|
375 |
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs |
|
376 |
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
377 |
Table **table,**all_tables; |
1
by brian
clean slate |
378 |
/**
|
379 |
The table which has an index that allows to produce the requried ordering.
|
|
380 |
A special value of 0x1 means that the ordering will be produced by
|
|
381 |
passing 1st non-const table to filesort(). NULL means no such table exists.
|
|
382 |
*/
|
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
383 |
Table *sort_by_table; |
1
by brian
clean slate |
384 |
uint tables; /**< Number of tables in the join */ |
385 |
uint outer_tables; /**< Number of tables that are not inside semijoin */ |
|
386 |
uint const_tables; |
|
387 |
uint send_group_parts; |
|
388 |
bool sort_and_group,first_record,full_join,group, no_field_update; |
|
389 |
bool do_send_rows; |
|
390 |
/**
|
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
391 |
true when we want to resume nested loop iterations when
|
1
by brian
clean slate |
392 |
fetching data from a cursor
|
393 |
*/
|
|
394 |
bool resume_nested_loop; |
|
395 |
table_map const_table_map,found_const_table_map,outer_join; |
|
396 |
ha_rows send_records,found_records,examined_rows,row_limit, select_limit; |
|
397 |
/**
|
|
398 |
Used to fetch no more than given amount of rows per one
|
|
399 |
fetch operation of server side cursor.
|
|
400 |
The value is checked in end_send and end_send_group in fashion, similar
|
|
401 |
to offset_limit_cnt:
|
|
402 |
- fetch_limit= HA_POS_ERROR if there is no cursor.
|
|
403 |
- when we open a cursor, we set fetch_limit to 0,
|
|
404 |
- on each fetch iteration we add num_rows to fetch to fetch_limit
|
|
405 |
*/
|
|
406 |
ha_rows fetch_limit; |
|
407 |
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; |
|
408 |
||
409 |
/* *
|
|
410 |
Bitmap of nested joins embedding the position at the end of the current
|
|
411 |
partial join (valid only during join optimizer run).
|
|
412 |
*/
|
|
413 |
nested_join_map cur_embedding_map; |
|
414 |
||
415 |
double best_read; |
|
416 |
List<Item> *fields; |
|
417 |
List<Cached_item> group_fields, group_fields_cache; |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
418 |
Table *tmp_table; |
1
by brian
clean slate |
419 |
/// used to store 2 possible tmp table of SELECT
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
420 |
Table *exec_tmp_table1, *exec_tmp_table2; |
1
by brian
clean slate |
421 |
THD *thd; |
422 |
Item_sum **sum_funcs, ***sum_funcs_end; |
|
423 |
/** second copy of sumfuncs (for queries with 2 temporary tables */
|
|
424 |
Item_sum **sum_funcs2, ***sum_funcs_end2; |
|
425 |
Item *having; |
|
426 |
Item *tmp_having; ///< To store having when processed temporary table |
|
427 |
Item *having_history; ///< Store having for explain |
|
151
by Brian Aker
Ulonglong to uint64_t |
428 |
uint64_t select_options; |
1
by brian
clean slate |
429 |
select_result *result; |
430 |
TMP_TABLE_PARAM tmp_table_param; |
|
319.1.1
by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_ |
431 |
DRIZZLE_LOCK *lock; |
1
by brian
clean slate |
432 |
/// unit structure (with global parameters) for this select
|
433 |
SELECT_LEX_UNIT *unit; |
|
434 |
/// select that processed
|
|
435 |
SELECT_LEX *select_lex; |
|
436 |
/**
|
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
437 |
true <=> optimizer must not mark any table as a constant table.
|
1
by brian
clean slate |
438 |
This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
|
439 |
when we optimize the select that reads the results of the union from a
|
|
440 |
temporary table, we must not mark the temp. table as constant because
|
|
441 |
the number of rows in it may vary from one subquery execution to another.
|
|
442 |
*/
|
|
443 |
bool no_const_tables; |
|
444 |
||
445 |
JOIN *tmp_join; ///< copy of this JOIN to be used with temporary tables |
|
446 |
ROLLUP rollup; ///< Used with rollup |
|
447 |
||
448 |
bool select_distinct; ///< Set if SELECT DISTINCT |
|
449 |
/**
|
|
450 |
If we have the GROUP BY statement in the query,
|
|
451 |
but the group_list was emptied by optimizer, this
|
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
452 |
flag is true.
|
1
by brian
clean slate |
453 |
It happens when fields in the GROUP BY are from
|
454 |
constant table
|
|
455 |
*/
|
|
456 |
bool group_optimized_away; |
|
457 |
||
458 |
/*
|
|
327.2.3
by Brian Aker
Refactoring of class Table |
459 |
simple_xxxxx is set if order_st/GROUP BY doesn't include any references
|
1
by brian
clean slate |
460 |
to other tables than the first non-constant table in the JOIN.
|
327.2.3
by Brian Aker
Refactoring of class Table |
461 |
It's also set if order_st/GROUP BY is empty.
|
1
by brian
clean slate |
462 |
*/
|
463 |
bool simple_order, simple_group; |
|
464 |
/**
|
|
465 |
Is set only in case if we have a GROUP BY clause
|
|
327.2.3
by Brian Aker
Refactoring of class Table |
466 |
and no order_st BY after constant elimination of 'order'.
|
1
by brian
clean slate |
467 |
*/
|
468 |
bool no_order; |
|
327.2.3
by Brian Aker
Refactoring of class Table |
469 |
/** Is set if we have a GROUP BY and we have order_st BY on a constant. */
|
1
by brian
clean slate |
470 |
bool skip_sort_order; |
471 |
||
472 |
bool need_tmp, hidden_group_fields; |
|
473 |
DYNAMIC_ARRAY keyuse; |
|
474 |
Item::cond_result cond_value, having_value; |
|
475 |
List<Item> all_fields; ///< to store all fields that used in query |
|
476 |
///Above list changed to use temporary table
|
|
477 |
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3; |
|
478 |
///Part, shared with list above, emulate following list
|
|
479 |
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3; |
|
480 |
List<Item> &fields_list; ///< hold field list passed to mysql_select |
|
481 |
int error; |
|
482 |
||
327.2.3
by Brian Aker
Refactoring of class Table |
483 |
order_st *order, *group_list, *proc_param; //hold parameters of mysql_select |
1
by brian
clean slate |
484 |
COND *conds; // ---"--- |
485 |
Item *conds_history; // store WHERE for explain |
|
327.2.4
by Brian Aker
Refactoring table.h |
486 |
TableList *tables_list; ///<hold 'tables' parameter of mysql_select |
487 |
List<TableList> *join_list; ///< list of joined tables in reverse order |
|
1
by brian
clean slate |
488 |
COND_EQUAL *cond_equal; |
489 |
SQL_SELECT *select; ///<created in optimisation phase |
|
490 |
JOIN_TAB *return_tab; ///<used only for outer joins |
|
491 |
Item **ref_pointer_array; ///<used pointer reference for this select |
|
492 |
// Copy of above to be used with different lists
|
|
493 |
Item **items0, **items1, **items2, **items3, **current_ref_pointer_array; |
|
494 |
uint ref_pointer_array_size; ///< size of above in bytes |
|
495 |
const char *zero_result_cause; ///< not 0 if exec must return zero result |
|
496 |
||
497 |
bool union_part; ///< this subselect is part of union |
|
498 |
bool optimized; ///< flag to avoid double optimization in EXPLAIN |
|
499 |
||
500 |
Array<Item_in_subselect> sj_subselects; |
|
501 |
||
502 |
/* Descriptions of temporary tables used to weed-out semi-join duplicates */
|
|
503 |
SJ_TMP_TABLE *sj_tmp_tables; |
|
504 |
||
505 |
table_map cur_emb_sj_nests; |
|
506 |
||
507 |
/*
|
|
508 |
storage for caching buffers allocated during query execution.
|
|
509 |
These buffers allocations need to be cached as the thread memory pool is
|
|
510 |
cleared only at the end of the execution of the whole query and not caching
|
|
511 |
allocations that occur in repetition at execution time will result in
|
|
512 |
excessive memory usage.
|
|
513 |
*/
|
|
514 |
SORT_FIELD *sortorder; // make_unireg_sortorder() |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
515 |
Table **table_reexec; // make_simple_join() |
1
by brian
clean slate |
516 |
JOIN_TAB *join_tab_reexec; // make_simple_join() |
517 |
/* end of allocation caching storage */
|
|
518 |
||
151
by Brian Aker
Ulonglong to uint64_t |
519 |
JOIN(THD *thd_arg, List<Item> &fields_arg, uint64_t select_options_arg, |
1
by brian
clean slate |
520 |
select_result *result_arg) |
521 |
:fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4) |
|
522 |
{
|
|
523 |
init(thd_arg, fields_arg, select_options_arg, result_arg); |
|
524 |
}
|
|
525 |
||
151
by Brian Aker
Ulonglong to uint64_t |
526 |
void init(THD *thd_arg, List<Item> &fields_arg, uint64_t select_options_arg, |
1
by brian
clean slate |
527 |
select_result *result_arg) |
528 |
{
|
|
529 |
join_tab= join_tab_save= 0; |
|
530 |
table= 0; |
|
531 |
tables= 0; |
|
532 |
const_tables= 0; |
|
533 |
join_list= 0; |
|
534 |
sort_and_group= 0; |
|
535 |
first_record= 0; |
|
536 |
do_send_rows= 1; |
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
537 |
resume_nested_loop= false; |
1
by brian
clean slate |
538 |
send_records= 0; |
539 |
found_records= 0; |
|
540 |
fetch_limit= HA_POS_ERROR; |
|
541 |
examined_rows= 0; |
|
542 |
exec_tmp_table1= 0; |
|
543 |
exec_tmp_table2= 0; |
|
544 |
sortorder= 0; |
|
545 |
table_reexec= 0; |
|
546 |
join_tab_reexec= 0; |
|
547 |
thd= thd_arg; |
|
548 |
sum_funcs= sum_funcs2= 0; |
|
549 |
having= tmp_having= having_history= 0; |
|
550 |
select_options= select_options_arg; |
|
551 |
result= result_arg; |
|
552 |
lock= thd_arg->lock; |
|
553 |
select_lex= 0; //for safety |
|
554 |
tmp_join= 0; |
|
555 |
select_distinct= test(select_options & SELECT_DISTINCT); |
|
556 |
no_order= 0; |
|
557 |
simple_order= 0; |
|
558 |
simple_group= 0; |
|
559 |
skip_sort_order= 0; |
|
560 |
need_tmp= 0; |
|
561 |
hidden_group_fields= 0; /*safety*/ |
|
562 |
error= 0; |
|
563 |
select= 0; |
|
564 |
return_tab= 0; |
|
565 |
ref_pointer_array= items0= items1= items2= items3= 0; |
|
566 |
ref_pointer_array_size= 0; |
|
567 |
zero_result_cause= 0; |
|
568 |
optimized= 0; |
|
569 |
cond_equal= 0; |
|
570 |
group_optimized_away= 0; |
|
571 |
||
572 |
all_fields= fields_arg; |
|
573 |
fields_list= fields_arg; |
|
212.6.6
by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove(). |
574 |
memset(&keyuse, 0, sizeof(keyuse)); |
1
by brian
clean slate |
575 |
tmp_table_param.init(); |
576 |
tmp_table_param.end_write_records= HA_POS_ERROR; |
|
577 |
rollup.state= ROLLUP::STATE_NONE; |
|
578 |
sj_tmp_tables= NULL; |
|
579 |
||
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
580 |
no_const_tables= false; |
1
by brian
clean slate |
581 |
}
|
582 |
||
327.2.4
by Brian Aker
Refactoring table.h |
583 |
int prepare(Item ***rref_pointer_array, TableList *tables, uint wind_num, |
327.2.3
by Brian Aker
Refactoring of class Table |
584 |
COND *conds, uint og_num, order_st *order, order_st *group, |
585 |
Item *having, order_st *proc_param, SELECT_LEX *select, |
|
1
by brian
clean slate |
586 |
SELECT_LEX_UNIT *unit); |
587 |
int optimize(); |
|
588 |
int reinit(); |
|
589 |
void exec(); |
|
590 |
int destroy(); |
|
591 |
void restore_tmp(); |
|
592 |
bool alloc_func_list(); |
|
593 |
bool flatten_subqueries(); |
|
594 |
bool setup_subquery_materialization(); |
|
595 |
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields, |
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
596 |
bool before_group_by, bool recompute= false); |
1
by brian
clean slate |
597 |
|
598 |
inline void set_items_ref_array(Item **ptr) |
|
599 |
{
|
|
212.6.6
by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove(). |
600 |
memcpy(ref_pointer_array, ptr, ref_pointer_array_size); |
1
by brian
clean slate |
601 |
current_ref_pointer_array= ptr; |
602 |
}
|
|
603 |
inline void init_items_ref_array() |
|
604 |
{
|
|
605 |
items0= ref_pointer_array + all_fields.elements; |
|
606 |
memcpy(items0, ref_pointer_array, ref_pointer_array_size); |
|
607 |
current_ref_pointer_array= items0; |
|
608 |
}
|
|
609 |
||
610 |
bool rollup_init(); |
|
611 |
bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields, |
|
612 |
Item_sum ***func); |
|
613 |
int rollup_send_data(uint idx); |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
614 |
int rollup_write_data(uint idx, Table *table); |
1
by brian
clean slate |
615 |
void remove_subq_pushed_predicates(Item **where); |
616 |
/**
|
|
617 |
Release memory and, if possible, the open tables held by this execution
|
|
618 |
plan (and nested plans). It's used to release some tables before
|
|
619 |
the end of execution in order to increase concurrency and reduce
|
|
620 |
memory consumption.
|
|
621 |
*/
|
|
622 |
void join_free(); |
|
623 |
/** Cleanup this JOIN, possibly for reuse */
|
|
624 |
void cleanup(bool full); |
|
625 |
void clear(); |
|
626 |
bool save_join_tab(); |
|
627 |
bool init_save_join_tab(); |
|
628 |
bool send_row_on_empty_set() |
|
629 |
{
|
|
630 |
return (do_send_rows && tmp_table_param.sum_func_count != 0 && |
|
631 |
!group_list); |
|
632 |
}
|
|
633 |
bool change_result(select_result *result); |
|
634 |
bool is_top_level_join() const |
|
635 |
{
|
|
636 |
return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 || |
|
637 |
select_lex == unit->fake_select_lex)); |
|
638 |
}
|
|
639 |
};
|
|
640 |
||
641 |
||
642 |
typedef struct st_select_check { |
|
643 |
uint const_ref,reg_ref; |
|
644 |
} SELECT_CHECK; |
|
645 |
||
646 |
extern const char *join_type_str[]; |
|
647 |
void TEST_join(JOIN *join); |
|
648 |
||
649 |
/* Extern functions in sql_select.cc */
|
|
650 |
bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag); |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
651 |
Table *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, |
327.2.3
by Brian Aker
Refactoring of class Table |
652 |
order_st *group, bool distinct, bool save_sum_fields, |
151
by Brian Aker
Ulonglong to uint64_t |
653 |
uint64_t select_options, ha_rows rows_limit, |
1
by brian
clean slate |
654 |
char* alias); |
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
655 |
void free_tmp_table(THD *thd, Table *entry); |
1
by brian
clean slate |
656 |
void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, |
657 |
List<Item> &fields, bool reset_with_sum_func); |
|
658 |
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, |
|
659 |
Item **ref_pointer_array, |
|
660 |
List<Item> &new_list1, List<Item> &new_list2, |
|
661 |
uint elements, List<Item> &fields); |
|
662 |
void copy_fields(TMP_TABLE_PARAM *param); |
|
663 |
void copy_funcs(Item **func_ptr); |
|
664 |
Field* create_tmp_field_from_field(THD *thd, Field* org_field, |
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
665 |
const char *name, Table *table, |
1
by brian
clean slate |
666 |
Item_field *item, uint convert_blob_length); |
667 |
||
668 |
/* functions from opt_sum.cc */
|
|
669 |
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order); |
|
327.2.4
by Brian Aker
Refactoring table.h |
670 |
int opt_sum_query(TableList *tables, List<Item> &all_fields,COND *conds); |
1
by brian
clean slate |
671 |
|
672 |
/* from sql_delete.cc, used by opt_range.cc */
|
|
673 |
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b); |
|
674 |
||
675 |
/** class to copying an field/item to a key struct */
|
|
676 |
||
677 |
class store_key :public Sql_alloc |
|
678 |
{
|
|
679 |
public: |
|
51.1.67
by Jay Pipes
standardized TRUE/FALSE |
680 |
bool null_key; /* true <=> the value of the key has a null part */ |
1
by brian
clean slate |
681 |
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV }; |
682 |
store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length) |
|
683 |
:null_key(0), null_ptr(null), err(0) |
|
684 |
{
|
|
212.2.2
by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE |
685 |
if (field_arg->type() == DRIZZLE_TYPE_BLOB) |
1
by brian
clean slate |
686 |
{
|
687 |
/*
|
|
688 |
Key segments are always packed with a 2 byte length prefix.
|
|
689 |
See mi_rkey for details.
|
|
690 |
*/
|
|
691 |
to_field= new Field_varstring(ptr, length, 2, null, 1, |
|
692 |
Field::NONE, field_arg->field_name, |
|
693 |
field_arg->table->s, field_arg->charset()); |
|
694 |
to_field->init(field_arg->table); |
|
695 |
}
|
|
696 |
else
|
|
697 |
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table, |
|
698 |
ptr, null, 1); |
|
699 |
}
|
|
700 |
virtual ~store_key() {} /** Not actually needed */ |
|
701 |
virtual const char *name() const=0; |
|
702 |
||
703 |
/**
|
|
704 |
@brief sets ignore truncation warnings mode and calls the real copy method
|
|
705 |
||
706 |
@details this function makes sure truncation warnings when preparing the
|
|
707 |
key buffers don't end up as errors (because of an enclosing INSERT/UPDATE).
|
|
708 |
*/
|
|
709 |
enum store_key_result copy() |
|
710 |
{
|
|
711 |
enum store_key_result result; |
|
712 |
THD *thd= to_field->table->in_use; |
|
713 |
enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields; |
|
714 |
||
715 |
thd->count_cuted_fields= CHECK_FIELD_IGNORE; |
|
716 |
||
717 |
result= copy_inner(); |
|
718 |
||
719 |
thd->count_cuted_fields= saved_count_cuted_fields; |
|
720 |
||
721 |
return result; |
|
722 |
}
|
|
723 |
||
724 |
protected: |
|
725 |
Field *to_field; // Store data here |
|
726 |
uchar *null_ptr; |
|
727 |
uchar err; |
|
728 |
||
729 |
virtual enum store_key_result copy_inner()=0; |
|
730 |
};
|
|
731 |
||
732 |
||
733 |
class store_key_field: public store_key |
|
734 |
{
|
|
735 |
Copy_field copy_field; |
|
736 |
const char *field_name; |
|
737 |
public: |
|
738 |
store_key_field(THD *thd, Field *to_field_arg, uchar *ptr, |
|
739 |
uchar *null_ptr_arg, |
|
740 |
uint length, Field *from_field, const char *name_arg) |
|
741 |
:store_key(thd, to_field_arg,ptr, |
|
742 |
null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err |
|
743 |
: (uchar*) 0, length), field_name(name_arg) |
|
744 |
{
|
|
745 |
if (to_field) |
|
746 |
{
|
|
747 |
copy_field.set(to_field,from_field,0); |
|
748 |
}
|
|
749 |
}
|
|
750 |
const char *name() const { return field_name; } |
|
751 |
||
752 |
protected: |
|
753 |
enum store_key_result copy_inner() |
|
754 |
{
|
|
755 |
copy_field.do_copy(©_field); |
|
756 |
null_key= to_field->is_null(); |
|
757 |
return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK; |
|
758 |
}
|
|
759 |
};
|
|
760 |
||
761 |
||
762 |
class store_key_item :public store_key |
|
763 |
{
|
|
764 |
protected: |
|
765 |
Item *item; |
|
766 |
public: |
|
767 |
store_key_item(THD *thd, Field *to_field_arg, uchar *ptr, |
|
768 |
uchar *null_ptr_arg, uint length, Item *item_arg) |
|
769 |
:store_key(thd, to_field_arg, ptr, |
|
770 |
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? |
|
771 |
&err : (uchar*) 0, length), item(item_arg) |
|
772 |
{}
|
|
773 |
const char *name() const { return "func"; } |
|
774 |
||
775 |
protected: |
|
776 |
enum store_key_result copy_inner() |
|
777 |
{
|
|
778 |
int res= item->save_in_field(to_field, 1); |
|
779 |
null_key= to_field->is_null() || item->null_value; |
|
780 |
return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res); |
|
781 |
}
|
|
782 |
};
|
|
783 |
||
784 |
||
785 |
class store_key_const_item :public store_key_item |
|
786 |
{
|
|
787 |
bool inited; |
|
788 |
public: |
|
789 |
store_key_const_item(THD *thd, Field *to_field_arg, uchar *ptr, |
|
790 |
uchar *null_ptr_arg, uint length, |
|
791 |
Item *item_arg) |
|
792 |
:store_key_item(thd, to_field_arg,ptr, |
|
793 |
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? |
|
794 |
&err : (uchar*) 0, length, item_arg), inited(0) |
|
795 |
{
|
|
796 |
}
|
|
797 |
const char *name() const { return "const"; } |
|
798 |
||
799 |
protected: |
|
800 |
enum store_key_result copy_inner() |
|
801 |
{
|
|
802 |
int res; |
|
803 |
if (!inited) |
|
804 |
{
|
|
805 |
inited=1; |
|
806 |
if ((res= item->save_in_field(to_field, 1))) |
|
807 |
{
|
|
808 |
if (!err) |
|
809 |
err= res; |
|
810 |
}
|
|
811 |
}
|
|
812 |
null_key= to_field->is_null() || item->null_value; |
|
813 |
return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); |
|
814 |
}
|
|
815 |
};
|
|
816 |
||
354
by Brian Aker
Refactor of Table methods. |
817 |
bool cp_buffer_from_ref(THD *thd, TABLE_REF *ref); |
1
by brian
clean slate |
818 |
bool error_if_full_join(JOIN *join); |
819 |
int safe_index_read(JOIN_TAB *tab); |
|
820 |
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value); |
|
821 |
int test_if_item_cache_changed(List<Cached_item> &list); |