1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
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; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
* Defines the Join class
27
#ifndef DRIZZLED_JOIN_H
28
#define DRIZZLED_JOIN_H
30
#include <drizzled/optimizer/position.h>
31
#include <drizzled/sql_select.h>
32
#include <drizzled/tmp_table_param.h>
42
class Join :public memory::SqlAlloc
44
Join(const Join &rhs); /**< not implemented */
45
Join& operator=(const Join &rhs); /**< not implemented */
48
* Contains a partial query execution plan which is extended during
49
* cost-based optimization.
51
optimizer::Position positions[MAX_TABLES+1];
54
* Contains the optimal query execution plan after cost-based optimization
57
optimizer::Position best_positions[MAX_TABLES+1];
62
JoinTable **map2table; /**< mapping between table indexes and JoinTables */
63
JoinTable *join_tab_save; /**< saved join_tab for subquery reexecution */
68
The table which has an index that allows to produce the requried ordering.
69
A special value of 0x1 means that the ordering will be produced by
70
passing 1st non-const table to filesort(). NULL means no such table exists.
74
uint32_t tables; /**< Number of tables in the join */
75
uint32_t outer_tables; /**< Number of tables that are not inside semijoin */
76
uint32_t const_tables;
77
uint32_t send_group_parts;
86
true when we want to resume nested loop iterations when
87
fetching data from a cursor
89
bool resume_nested_loop;
91
true <=> optimizer must not mark any table as a constant table.
92
This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
93
when we optimize the select that reads the results of the union from a
94
temporary table, we must not mark the temp. table as constant because
95
the number of rows in it may vary from one subquery execution to another.
98
bool select_distinct; /**< Set if SELECT DISTINCT */
100
If we have the GROUP BY statement in the query,
101
but the group_list was emptied by optimizer, this
103
It happens when fields in the GROUP BY are from
106
bool group_optimized_away;
109
simple_xxxxx is set if order_st/GROUP BY doesn't include any references
110
to other tables than the first non-constant table in the Join.
111
It's also set if order_st/GROUP BY is empty.
116
Is set only in case if we have a GROUP BY clause
117
and no ORDER BY after constant elimination of 'order'.
120
/** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
121
bool skip_sort_order;
122
bool union_part; /**< this subselect is part of union */
123
bool optimized; /**< flag to avoid double optimization in EXPLAIN */
125
bool hidden_group_fields;
127
table_map const_table_map;
128
table_map found_const_table_map;
129
table_map outer_join;
131
ha_rows send_records;
132
ha_rows found_records;
133
ha_rows examined_rows;
135
ha_rows select_limit;
137
Used to fetch no more than given amount of rows per one
138
fetch operation of server side cursor.
139
The value is checked in end_send and end_send_group in fashion, similar
141
- fetch_limit= HA_POS_ERROR if there is no cursor.
142
- when we open a cursor, we set fetch_limit to 0,
143
- on each fetch iteration we add num_rows to fetch to fetch_limit
149
List<Item> &fields_list; /**< hold field list passed to select_query */
150
List<TableList> *join_list; /**< list of joined tables in reverse order */
151
/** unit structure (with global parameters) for this select */
152
Select_Lex_Unit *unit;
153
/** select that processed */
154
Select_Lex *select_lex;
155
optimizer::SqlSelect *select; /**< created in optimization phase */
158
Bitmap of nested joins embedding the position at the end of the current
159
partial join (valid only during join optimizer run).
161
std::bitset<64> cur_embedding_map;
164
* The cost for the final query execution plan chosen after optimization
165
* has completed. The QEP is stored in the best_positions variable.
168
List<Cached_item> group_fields;
169
List<Cached_item> group_fields_cache;
171
/** used to store 2 possible tmp table of SELECT */
172
Table *exec_tmp_table1;
173
Table *exec_tmp_table2;
174
Item_sum **sum_funcs;
175
Item_sum ***sum_funcs_end;
176
/** second copy of sumfuncs (for queries with 2 temporary tables */
177
Item_sum **sum_funcs2;
178
Item_sum ***sum_funcs_end2;
180
Item *tmp_having; /**< To store having when processed temporary table */
181
Item *having_history; /**< Store having for explain */
182
uint64_t select_options;
183
select_result *result;
184
Tmp_Table_Param tmp_table_param;
187
Join *tmp_join; /**< copy of this Join to be used with temporary tables */
188
Rollup rollup; /**< Used with rollup */
189
DYNAMIC_ARRAY keyuse;
190
Item::cond_result cond_value;
191
Item::cond_result having_value;
192
List<Item> all_fields; /**< to store all fields that used in query */
193
/** Above list changed to use temporary table */
194
List<Item> tmp_all_fields1;
195
List<Item> tmp_all_fields2;
196
List<Item> tmp_all_fields3;
197
/** Part, shared with list above, emulate following list */
198
List<Item> tmp_fields_list1;
199
List<Item> tmp_fields_list2;
200
List<Item> tmp_fields_list3;
204
Order *group_list; /**< hold parameters of select_query */
205
COND *conds; // ---"---
206
Item *conds_history; /**< store WHERE for explain */
207
TableList *tables_list; /**< hold 'tables' parameter of select_query */
208
COND_EQUAL *cond_equal;
209
JoinTable *return_tab; /**< used only for outer joins */
210
Item **ref_pointer_array; /**< used pointer reference for this select */
211
/** Copy of above to be used with different lists */
216
Item **current_ref_pointer_array;
217
uint32_t ref_pointer_array_size; ///< size of above in bytes
218
const char *zero_result_cause; ///< not 0 if exec must return zero result
221
storage for caching buffers allocated during query execution.
222
These buffers allocations need to be cached as the thread memory pool is
223
cleared only at the end of the execution of the whole query and not caching
224
allocations that occur in repetition at execution time will result in
225
excessive memory usage.
227
SortField *sortorder; // make_unireg_sortorder()
228
Table **table_reexec; // make_simple_join()
229
JoinTable *join_tab_reexec; // make_simple_join()
230
/* end of allocation caching storage */
233
Join(Session *session_arg,
234
List<Item> &fields_arg,
235
uint64_t select_options_arg,
236
select_result *result_arg);
239
* This method is currently only used when a subselect EXPLAIN is performed.
240
* I pulled out the init() method and have simply reset the values to what
241
* was previously in the init() method. See the note about the hack in
244
void reset(Session *session_arg,
245
List<Item> &fields_arg,
246
uint64_t select_options_arg,
247
select_result *result_arg);
249
int prepare(Item ***rref_pointer_array,
258
Select_Lex_Unit *unit);
265
bool alloc_func_list();
266
bool setup_subquery_materialization();
267
bool make_sum_func_list(List<Item> &all_fields,
268
List<Item> &send_fields,
269
bool before_group_by,
270
bool recompute= false);
272
inline void set_items_ref_array(Item **ptr)
274
memcpy(ref_pointer_array, ptr, ref_pointer_array_size);
275
current_ref_pointer_array= ptr;
277
inline void init_items_ref_array()
279
items0= ref_pointer_array + all_fields.elements;
280
memcpy(items0, ref_pointer_array, ref_pointer_array_size);
281
current_ref_pointer_array= items0;
285
bool rollup_make_fields(List<Item> &all_fields,
288
int rollup_send_data(uint32_t idx);
289
int rollup_write_data(uint32_t idx, Table *table);
290
void remove_subq_pushed_predicates(Item **where);
292
Release memory and, if possible, the open tables held by this execution
293
plan (and nested plans). It's used to release some tables before
294
the end of execution in order to increase concurrency and reduce
298
/** Cleanup this Join, possibly for reuse */
299
void cleanup(bool full);
301
bool save_join_tab();
302
bool init_save_join_tab();
303
bool send_row_on_empty_set()
305
return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
308
bool change_result(select_result *result);
309
bool is_top_level_join() const;
312
* Copy the partial query plan into the optimal query plan.
314
* @param[in] size the size of the plan which is to be copied
316
void copyPartialPlanIntoOptimalPlan(uint32_t size)
318
memcpy(best_positions, positions,
319
sizeof(optimizer::Position) * size);
322
void cache_const_exprs();
325
* @param[in] index the index of the position to retrieve
326
* @return a reference to the specified position in the optimal
329
optimizer::Position &getPosFromOptimalPlan(uint32_t index)
331
return best_positions[index];
335
* @param[in] index the index of the position to retrieve
336
* @return a reference to the specified position in the partial
339
optimizer::Position &getPosFromPartialPlan(uint32_t index)
341
return positions[index];
345
* @param[in] index the index of the position to set
346
* @param[in] in_pos the value to set the position to
348
void setPosInPartialPlan(uint32_t index, optimizer::Position &in_pos)
350
positions[index]= in_pos;
354
* @return a pointer to the first position in the partial query plan
356
optimizer::Position *getFirstPosInPartialPlan()
362
* @param[in] index the index of the operator to retrieve from the partial
364
* @return a pointer to the position in the partial query plan
366
optimizer::Position *getSpecificPosInPartialPlan(int32_t index)
368
return positions + index;
373
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error);
374
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab);
375
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last);
376
enum_nested_loop_state end_send(Join *join, JoinTable *join_tab, bool end_of_records);
377
enum_nested_loop_state end_write(Join *join, JoinTable *join_tab, bool end_of_records);
378
enum_nested_loop_state end_update(Join *join, JoinTable *join_tab, bool end_of_records);
379
enum_nested_loop_state end_unique_update(Join *join, JoinTable *join_tab, bool end_of_records);
381
} /* namespace drizzled */
383
#endif /* DRIZZLED_JOIN_H */