1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
4
* Copyright (C) 2008-2009 Sun Microsystems
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
24
* Defines the Join class
24
* Defines the JOIN class
27
27
#ifndef DRIZZLED_JOIN_H
28
28
#define DRIZZLED_JOIN_H
30
#include <drizzled/optimizer/position.h>
31
#include <drizzled/session.h>
32
#include <drizzled/sql_select.h>
40
class Join :public memory::SqlAlloc
42
Join(const Join &rhs); /**< not implemented */
43
Join& operator=(const Join &rhs); /**< not implemented */
32
class JOIN :public Sql_alloc
34
JOIN(const JOIN &rhs); /**< not implemented */
35
JOIN& operator=(const JOIN &rhs); /**< not implemented */
46
38
* Contains a partial query execution plan which is extended during
47
39
* cost-based optimization.
49
optimizer::Position positions[MAX_TABLES+1];
41
Position positions[MAX_TABLES+1];
52
44
* Contains the optimal query execution plan after cost-based optimization
55
optimizer::Position best_positions[MAX_TABLES+1];
47
Position best_positions[MAX_TABLES+1];
58
50
JoinTable *join_tab;
107
99
simple_xxxxx is set if order_st/GROUP BY doesn't include any references
108
to other tables than the first non-constant table in the Join.
100
to other tables than the first non-constant table in the JOIN.
109
101
It's also set if order_st/GROUP BY is empty.
111
103
bool simple_order;
112
104
bool simple_group;
114
106
Is set only in case if we have a GROUP BY clause
115
and no ORDER BY after constant elimination of 'order'.
107
and no order_st BY after constant elimination of 'order'.
118
/** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
110
/** Is set if we have a GROUP BY and we have order_st BY on a constant. */
119
111
bool skip_sort_order;
120
112
bool union_part; /**< this subselect is part of union */
121
113
bool optimized; /**< flag to avoid double optimization in EXPLAIN */
145
137
Session *session;
146
138
List<Item> *fields;
147
List<Item> &fields_list; /**< hold field list passed to select_query */
139
List<Item> &fields_list; /**< hold field list passed to mysql_select */
148
140
List<TableList> *join_list; /**< list of joined tables in reverse order */
149
141
/** unit structure (with global parameters) for this select */
150
142
Select_Lex_Unit *unit;
151
143
/** select that processed */
152
144
Select_Lex *select_lex;
153
optimizer::SqlSelect *select; /**< created in optimization phase */
145
SQL_SELECT *select; /**< created in optimisation phase */
146
Array<Item_in_subselect> sj_subselects;
156
149
Bitmap of nested joins embedding the position at the end of the current
180
173
uint64_t select_options;
181
174
select_result *result;
182
175
Tmp_Table_Param tmp_table_param;
185
Join *tmp_join; /**< copy of this Join to be used with temporary tables */
186
Rollup rollup; /**< Used with rollup */
178
JOIN *tmp_join; /**< copy of this JOIN to be used with temporary tables */
179
ROLLUP rollup; /**< Used with rollup */
187
180
DYNAMIC_ARRAY keyuse;
188
181
Item::cond_result cond_value;
189
182
Item::cond_result having_value;
198
191
List<Item> tmp_fields_list3;
202
Order *group_list; /**< hold parameters of select_query */
195
order_st *group_list; /**< hold parameters of mysql_select */
203
196
COND *conds; // ---"---
204
197
Item *conds_history; /**< store WHERE for explain */
205
TableList *tables_list; /**< hold 'tables' parameter of select_query */
198
TableList *tables_list; /**< hold 'tables' parameter of mysql_select */
206
199
COND_EQUAL *cond_equal;
207
200
JoinTable *return_tab; /**< used only for outer joins */
208
201
Item **ref_pointer_array; /**< used pointer reference for this select */
222
215
allocations that occur in repetition at execution time will result in
223
216
excessive memory usage.
225
SortField *sortorder; // make_unireg_sortorder()
218
SORT_FIELD *sortorder; // make_unireg_sortorder()
226
219
Table **table_reexec; // make_simple_join()
227
220
JoinTable *join_tab_reexec; // make_simple_join()
228
221
/* end of allocation caching storage */
230
223
/** Constructors */
231
Join(Session *session_arg,
224
JOIN(Session *session_arg,
232
225
List<Item> &fields_arg,
233
226
uint64_t select_options_arg,
234
select_result *result_arg);
227
select_result *result_arg)
240
sort_and_group(false),
244
no_field_update(false),
246
resume_nested_loop(false),
247
no_const_tables(false),
248
select_distinct(false),
249
group_optimized_away(false),
253
skip_sort_order(false),
257
hidden_group_fields(false),
259
found_const_table_map(0),
266
fetch_limit(HA_POS_ERROR),
267
session(session_arg),
268
fields_list(fields_arg),
273
sj_subselects(session_arg->mem_root, 4),
274
exec_tmp_table1(NULL),
275
exec_tmp_table2(NULL),
280
having_history(NULL),
281
select_options(select_options_arg),
283
lock(session_arg->lock),
285
all_fields(fields_arg),
289
ref_pointer_array(NULL),
294
ref_pointer_array_size(0),
295
zero_result_cause(NULL),
298
join_tab_reexec(NULL)
300
select_distinct= test(select_options & SELECT_DISTINCT);
301
if (&fields_list != &fields_arg) /* only copy if not same*/
302
fields_list= fields_arg;
303
memset(&keyuse, 0, sizeof(keyuse));
304
tmp_table_param.init();
305
tmp_table_param.end_write_records= HA_POS_ERROR;
306
rollup.state= ROLLUP::STATE_NONE;
237
310
* This method is currently only used when a subselect EXPLAIN is performed.
239
312
* was previously in the init() method. See the note about the hack in
240
313
* sql_union.cc...
242
void reset(Session *session_arg,
243
List<Item> &fields_arg,
244
uint64_t select_options_arg,
245
select_result *result_arg);
315
inline void reset(Session *session_arg,
316
List<Item> &fields_arg,
317
uint64_t select_options_arg,
318
select_result *result_arg)
331
sort_and_group= false;
335
no_field_update= false;
337
resume_nested_loop= false;
338
no_const_tables= false;
339
select_distinct= false;
340
group_optimized_away= false;
344
skip_sort_order= false;
348
hidden_group_fields= false;
350
found_const_table_map= 0;
357
fetch_limit= HA_POS_ERROR;
358
session= session_arg;
359
fields_list= fields_arg;
364
exec_tmp_table1= NULL;
365
exec_tmp_table2= NULL;
370
having_history= NULL;
371
select_options= select_options_arg;
373
lock= session_arg->lock;
375
all_fields= fields_arg;
379
ref_pointer_array= NULL;
384
ref_pointer_array_size= 0;
385
zero_result_cause= NULL;
388
join_tab_reexec= NULL;
389
select_distinct= test(select_options & SELECT_DISTINCT);
390
if (&fields_list != &fields_arg) /* only copy if not same*/
391
fields_list= fields_arg;
392
memset(&keyuse, 0, sizeof(keyuse));
393
tmp_table_param.init();
394
tmp_table_param.end_write_records= HA_POS_ERROR;
395
rollup.state= ROLLUP::STATE_NONE;
247
398
int prepare(Item ***rref_pointer_array,
248
399
TableList *tables,
249
400
uint32_t wind_num,
255
406
Select_Lex *select,
256
407
Select_Lex_Unit *unit);
306
456
bool change_result(select_result *result);
307
bool is_top_level_join() const;
457
bool is_top_level_join() const
459
return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
460
select_lex == unit->fake_select_lex));
310
464
* Copy the partial query plan into the optimal query plan.
314
468
void copyPartialPlanIntoOptimalPlan(uint32_t size)
316
470
memcpy(best_positions, positions,
317
sizeof(optimizer::Position) * size);
471
sizeof(Position) * size);
320
void cache_const_exprs();
323
475
* @param[in] index the index of the position to retrieve
324
476
* @return a reference to the specified position in the optimal
327
optimizer::Position &getPosFromOptimalPlan(uint32_t index)
479
Position &getPosFromOptimalPlan(uint32_t index)
329
481
return best_positions[index];
343
495
* @param[in] index the index of the position to set
344
496
* @param[in] in_pos the value to set the position to
346
void setPosInPartialPlan(uint32_t index, optimizer::Position &in_pos)
498
void setPosInPartialPlan(uint32_t index, Position &in_pos)
348
500
positions[index]= in_pos;
362
514
* @return a pointer to the position in the partial query plan
364
optimizer::Position *getSpecificPosInPartialPlan(int32_t index)
516
Position *getSpecificPosInPartialPlan(int32_t index)
366
518
return positions + index;
371
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error);
372
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab);
373
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last);
374
enum_nested_loop_state end_send(Join *join, JoinTable *join_tab, bool end_of_records);
375
enum_nested_loop_state end_write(Join *join, JoinTable *join_tab, bool end_of_records);
376
enum_nested_loop_state end_update(Join *join, JoinTable *join_tab, bool end_of_records);
377
enum_nested_loop_state end_unique_update(Join *join, JoinTable *join_tab, bool end_of_records);
379
} /* namespace drizzled */
523
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error);
524
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab);
525
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last);
526
enum_nested_loop_state end_send(JOIN *join, JoinTable *join_tab, bool end_of_records);
527
enum_nested_loop_state end_write(JOIN *join, JoinTable *join_tab, bool end_of_records);
528
enum_nested_loop_state end_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
529
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
381
531
#endif /* DRIZZLED_JOIN_H */