~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.h

Reverted 1103

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems
5
5
 *
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
21
21
/**
22
22
 * @file
23
23
 *
24
 
 * Defines the Join class
 
24
 * Defines the JOIN class
25
25
 */
26
26
 
27
27
#ifndef DRIZZLED_JOIN_H
28
28
#define DRIZZLED_JOIN_H
29
29
 
30
 
#include <drizzled/optimizer/position.h>
31
 
#include <drizzled/session.h>
32
 
#include <drizzled/sql_select.h>
33
 
#include <bitset>
34
 
 
35
 
namespace drizzled
36
 
{
37
 
 
38
 
class Session;
39
 
 
40
 
class Join :public memory::SqlAlloc
41
 
{
42
 
  Join(const Join &rhs);                        /**< not implemented */
43
 
  Join& operator=(const Join &rhs);             /**< not implemented */
44
 
 
45
 
  /**
46
 
   * Contains a partial query execution plan which is extended during
47
 
   * cost-based optimization.
48
 
   */
49
 
  optimizer::Position positions[MAX_TABLES+1];
50
 
 
51
 
  /**
52
 
   * Contains the optimal query execution plan after cost-based optimization
53
 
   * has taken place. 
54
 
   */
55
 
  optimizer::Position best_positions[MAX_TABLES+1];
56
 
 
 
30
class JOIN :public Sql_alloc
 
31
{
 
32
  JOIN(const JOIN &rhs);                        /**< not implemented */
 
33
  JOIN& operator=(const JOIN &rhs);             /**< not implemented */
57
34
public:
58
35
  JoinTable *join_tab;
59
36
  JoinTable **best_ref;
105
82
 
106
83
  /*
107
84
    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.
 
85
    to other tables than the first non-constant table in the JOIN.
109
86
    It's also set if order_st/GROUP BY is empty.
110
87
  */
111
88
  bool simple_order;
112
89
  bool simple_group;
113
90
  /**
114
91
    Is set only in case if we have a GROUP BY clause
115
 
    and no ORDER BY after constant elimination of 'order'.
 
92
    and no order_st BY after constant elimination of 'order'.
116
93
  */
117
94
  bool no_order;
118
 
  /** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
 
95
  /** Is set if we have a GROUP BY and we have order_st BY on a constant. */
119
96
  bool skip_sort_order;
120
97
  bool union_part; /**< this subselect is part of union */
121
98
  bool optimized; /**< flag to avoid double optimization in EXPLAIN */
144
121
 
145
122
  Session       *session;
146
123
  List<Item> *fields;
147
 
  List<Item> &fields_list; /**< hold field list passed to select_query */
 
124
  List<Item> &fields_list; /**< hold field list passed to mysql_select */
148
125
  List<TableList> *join_list; /**< list of joined tables in reverse order */
149
126
  /** unit structure (with global parameters) for this select */
150
127
  Select_Lex_Unit *unit;
151
128
  /** select that processed */
152
129
  Select_Lex *select_lex;
153
 
  optimizer::SqlSelect *select; /**< created in optimization phase */
 
130
  SQL_SELECT *select; /**< created in optimisation phase */
 
131
  Array<Item_in_subselect> sj_subselects;
 
132
 
 
133
  POSITION positions[MAX_TABLES+1];
 
134
  POSITION best_positions[MAX_TABLES+1];
154
135
 
155
136
  /**
156
137
    Bitmap of nested joins embedding the position at the end of the current
157
138
    partial join (valid only during join optimizer run).
158
139
  */
159
 
  std::bitset<64> cur_embedding_map;
 
140
  nested_join_map cur_embedding_map;
160
141
 
161
 
  /**
162
 
   * The cost for the final query execution plan chosen after optimization
163
 
   * has completed. The QEP is stored in the best_positions variable.
164
 
   */
165
142
  double best_read;
166
143
  List<Cached_item> group_fields;
167
144
  List<Cached_item> group_fields_cache;
180
157
  uint64_t select_options;
181
158
  select_result *result;
182
159
  Tmp_Table_Param tmp_table_param;
183
 
  DrizzleLock *lock;
 
160
  DRIZZLE_LOCK *lock;
184
161
 
185
 
  Join *tmp_join; /**< copy of this Join to be used with temporary tables */
186
 
  Rollup rollup;                                /**< Used with rollup */
 
162
  JOIN *tmp_join; /**< copy of this JOIN to be used with temporary tables */
 
163
  ROLLUP rollup;                                /**< Used with rollup */
187
164
  DYNAMIC_ARRAY keyuse;
188
165
  Item::cond_result cond_value;
189
166
  Item::cond_result having_value;
198
175
  List<Item> tmp_fields_list3;
199
176
  int error;
200
177
 
201
 
  Order *order;
202
 
  Order *group_list; /**< hold parameters of select_query */
 
178
  order_st *order;
 
179
  order_st *group_list; /**< hold parameters of mysql_select */
203
180
  COND *conds;                            // ---"---
204
181
  Item *conds_history; /**< store WHERE for explain */
205
 
  TableList *tables_list; /**< hold 'tables' parameter of select_query */
 
182
  TableList *tables_list; /**< hold 'tables' parameter of mysql_select */
206
183
  COND_EQUAL *cond_equal;
207
184
  JoinTable *return_tab; /**< used only for outer joins */
208
185
  Item **ref_pointer_array; /**< used pointer reference for this select */
222
199
    allocations that occur in repetition at execution time will result in
223
200
    excessive memory usage.
224
201
  */
225
 
  SortField *sortorder;                        // make_unireg_sortorder()
 
202
  SORT_FIELD *sortorder;                        // make_unireg_sortorder()
226
203
  Table **table_reexec;                         // make_simple_join()
227
204
  JoinTable *join_tab_reexec;                    // make_simple_join()
228
205
  /* end of allocation caching storage */
229
206
 
230
207
  /** Constructors */
231
 
  Join(Session *session_arg, 
 
208
  JOIN(Session *session_arg, 
232
209
       List<Item> &fields_arg, 
233
210
       uint64_t select_options_arg,
234
 
       select_result *result_arg);
 
211
       select_result *result_arg)
 
212
    :
 
213
      join_tab(NULL),
 
214
      best_ref(NULL),
 
215
      map2table(NULL),
 
216
      join_tab_save(NULL),
 
217
      table(NULL),
 
218
      all_tables(NULL),
 
219
      sort_by_table(NULL),
 
220
      tables(0),
 
221
      outer_tables(0),
 
222
      const_tables(0),
 
223
      send_group_parts(0),
 
224
      sort_and_group(false),
 
225
      first_record(false),
 
226
      full_join(false),
 
227
      group(false),
 
228
      no_field_update(false),
 
229
      do_send_rows(true),
 
230
      resume_nested_loop(false),
 
231
      no_const_tables(false),
 
232
      select_distinct(false),
 
233
      group_optimized_away(false),
 
234
      simple_order(false),
 
235
      simple_group(false),
 
236
      no_order(false),
 
237
      skip_sort_order(false),
 
238
      union_part(false),
 
239
      optimized(false),
 
240
      need_tmp(false),
 
241
      hidden_group_fields(false),
 
242
      const_table_map(0),
 
243
      found_const_table_map(0),
 
244
      outer_join(0),
 
245
      send_records(0),
 
246
      found_records(0),
 
247
      examined_rows(0),
 
248
      row_limit(0),
 
249
      select_limit(0),
 
250
      fetch_limit(HA_POS_ERROR),
 
251
      session(session_arg),
 
252
      fields_list(fields_arg), 
 
253
      join_list(NULL),
 
254
      unit(NULL),
 
255
      select_lex(NULL),
 
256
      select(NULL),
 
257
      sj_subselects(session_arg->mem_root, 4),
 
258
      exec_tmp_table1(NULL),
 
259
      exec_tmp_table2(NULL),
 
260
      sum_funcs(NULL),
 
261
      sum_funcs2(NULL),
 
262
      having(NULL),
 
263
      tmp_having(NULL),
 
264
      having_history(NULL),
 
265
      select_options(select_options_arg),
 
266
      result(result_arg),
 
267
      lock(session_arg->lock),
 
268
      tmp_join(NULL),
 
269
      all_fields(fields_arg),
 
270
      error(0),
 
271
      cond_equal(NULL),
 
272
      return_tab(NULL),
 
273
      ref_pointer_array(NULL),
 
274
      items0(NULL),
 
275
      items1(NULL),
 
276
      items2(NULL),
 
277
      items3(NULL),
 
278
      ref_pointer_array_size(0),
 
279
      zero_result_cause(NULL),
 
280
      sortorder(NULL),
 
281
      table_reexec(NULL),
 
282
      join_tab_reexec(NULL)
 
283
  {
 
284
    select_distinct= test(select_options & SELECT_DISTINCT);
 
285
    if (&fields_list != &fields_arg) /* only copy if not same*/
 
286
      fields_list= fields_arg;
 
287
    memset(&keyuse, 0, sizeof(keyuse));
 
288
    tmp_table_param.init();
 
289
    tmp_table_param.end_write_records= HA_POS_ERROR;
 
290
    rollup.state= ROLLUP::STATE_NONE;
 
291
  }
235
292
 
236
293
  /** 
237
294
   * This method is currently only used when a subselect EXPLAIN is performed.
239
296
   * was previously in the init() method.  See the note about the hack in 
240
297
   * sql_union.cc...
241
298
   */
242
 
  void reset(Session *session_arg, 
243
 
             List<Item> &fields_arg, 
244
 
             uint64_t select_options_arg,
245
 
             select_result *result_arg);
 
299
  inline void reset(Session *session_arg, 
 
300
       List<Item> &fields_arg, 
 
301
       uint64_t select_options_arg,
 
302
       select_result *result_arg)
 
303
  {
 
304
    join_tab= NULL;
 
305
    best_ref= NULL;
 
306
    map2table= NULL;
 
307
    join_tab_save= NULL;
 
308
    table= NULL;
 
309
    all_tables= NULL;
 
310
    sort_by_table= NULL;
 
311
    tables= 0;
 
312
    outer_tables= 0;
 
313
    const_tables= 0;
 
314
    send_group_parts= 0;
 
315
    sort_and_group= false;
 
316
    first_record= false;
 
317
    full_join= false;
 
318
    group= false;
 
319
    no_field_update= false;
 
320
    do_send_rows= true;
 
321
    resume_nested_loop= false;
 
322
    no_const_tables= false;
 
323
    select_distinct= false;
 
324
    group_optimized_away= false;
 
325
    simple_order= false;
 
326
    simple_group= false;
 
327
    no_order= false;
 
328
    skip_sort_order= false;
 
329
    union_part= false;
 
330
    optimized= false;
 
331
    need_tmp= false;
 
332
    hidden_group_fields= false;
 
333
    const_table_map= 0;
 
334
    found_const_table_map= 0;
 
335
    outer_join= 0;
 
336
    send_records= 0;
 
337
    found_records= 0;
 
338
    examined_rows= 0;
 
339
    row_limit= 0;
 
340
    select_limit= 0;
 
341
    fetch_limit= HA_POS_ERROR;
 
342
    session= session_arg;
 
343
    fields_list= fields_arg; 
 
344
    join_list= NULL;
 
345
    unit= NULL;
 
346
    select_lex= NULL;
 
347
    select= NULL;
 
348
    exec_tmp_table1= NULL;
 
349
    exec_tmp_table2= NULL;
 
350
    sum_funcs= NULL;
 
351
    sum_funcs2= NULL;
 
352
    having= NULL;
 
353
    tmp_having= NULL;
 
354
    having_history= NULL;
 
355
    select_options= select_options_arg;
 
356
    result= result_arg;
 
357
    lock= session_arg->lock;
 
358
    tmp_join= NULL;
 
359
    all_fields= fields_arg;
 
360
    error= 0;
 
361
    cond_equal= NULL;
 
362
    return_tab= NULL;
 
363
    ref_pointer_array= NULL;
 
364
    items0= NULL;
 
365
    items1= NULL;
 
366
    items2= NULL;
 
367
    items3= NULL;
 
368
    ref_pointer_array_size= 0;
 
369
    zero_result_cause= NULL;
 
370
    sortorder= NULL;
 
371
    table_reexec= NULL;
 
372
    join_tab_reexec= NULL;
 
373
    select_distinct= test(select_options & SELECT_DISTINCT);
 
374
    if (&fields_list != &fields_arg) /* only copy if not same*/
 
375
      fields_list= fields_arg;
 
376
    memset(&keyuse, 0, sizeof(keyuse));
 
377
    tmp_table_param.init();
 
378
    tmp_table_param.end_write_records= HA_POS_ERROR;
 
379
    rollup.state= ROLLUP::STATE_NONE;
 
380
  }
246
381
 
247
382
  int prepare(Item ***rref_pointer_array, 
248
383
              TableList *tables,
249
384
              uint32_t wind_num,
250
385
              COND *conds,
251
386
              uint32_t og_num,
252
 
              Order *order,
253
 
              Order *group,
 
387
              order_st *order,
 
388
              order_st *group,
254
389
              Item *having,
255
390
              Select_Lex *select,
256
391
              Select_Lex_Unit *unit);
257
 
 
258
392
  int optimize();
259
393
  int reinit();
260
394
  void exec();
293
427
    memory consumption.
294
428
  */
295
429
  void join_free();
296
 
  /** Cleanup this Join, possibly for reuse */
 
430
  /** Cleanup this JOIN, possibly for reuse */
297
431
  void cleanup(bool full);
298
432
  void clear();
299
433
  bool save_join_tab();
304
438
            !group_list);
305
439
  }
306
440
  bool change_result(select_result *result);
307
 
  bool is_top_level_join() const;
308
 
 
309
 
  /**
310
 
   * Copy the partial query plan into the optimal query plan.
311
 
   *
312
 
   * @param[in] size the size of the plan which is to be copied
313
 
   */
314
 
  void copyPartialPlanIntoOptimalPlan(uint32_t size)
315
 
  {
316
 
    memcpy(best_positions, positions, 
317
 
           sizeof(optimizer::Position) * size);
318
 
  }
319
 
 
320
 
  void cache_const_exprs();
321
 
 
322
 
  /**
323
 
   * @param[in] index the index of the position to retrieve
324
 
   * @return a reference to the specified position in the optimal
325
 
   *         query plan
326
 
   */
327
 
  optimizer::Position &getPosFromOptimalPlan(uint32_t index)
328
 
  {
329
 
    return best_positions[index];
330
 
  }
331
 
 
332
 
  /**
333
 
   * @param[in] index the index of the position to retrieve
334
 
   * @return a reference to the specified position in the partial
335
 
   *         query plan
336
 
   */
337
 
  optimizer::Position &getPosFromPartialPlan(uint32_t index)
338
 
  {
339
 
    return positions[index];
340
 
  }
341
 
 
342
 
  /**
343
 
   * @param[in] index the index of the position to set
344
 
   * @param[in] in_pos the value to set the position to
345
 
   */
346
 
  void setPosInPartialPlan(uint32_t index, optimizer::Position &in_pos)
347
 
  {
348
 
    positions[index]= in_pos;
349
 
  }
350
 
 
351
 
  /**
352
 
   * @return a pointer to the first position in the partial query plan
353
 
   */
354
 
  optimizer::Position *getFirstPosInPartialPlan()
355
 
  {
356
 
    return positions;
357
 
  }
358
 
 
359
 
  /**
360
 
   * @param[in] index the index of the operator to retrieve from the partial
361
 
   *                  query plan
362
 
   * @return a pointer to the position in the partial query plan
363
 
   */
364
 
  optimizer::Position *getSpecificPosInPartialPlan(int32_t index)
365
 
  {
366
 
    return positions + index;
367
 
  }
368
 
 
 
441
  bool is_top_level_join() const
 
442
  {
 
443
    return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
 
444
                                        select_lex == unit->fake_select_lex));
 
445
  }
369
446
};
370
447
 
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);
378
 
 
379
 
} /* namespace drizzled */
 
448
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error);
 
449
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab);
 
450
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last);
 
451
enum_nested_loop_state end_send(JOIN *join, JoinTable *join_tab, bool end_of_records);
 
452
enum_nested_loop_state end_write(JOIN *join, JoinTable *join_tab, bool end_of_records);
 
453
enum_nested_loop_state end_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
 
454
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
380
455
 
381
456
#endif /* DRIZZLED_JOIN_H */