~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.h

  • Committer: Stewart Smith
  • Date: 2009-06-16 00:45:15 UTC
  • mto: (1119.2.6 merge)
  • mto: This revision was merged to the branch mainline in revision 1124.
  • Revision ID: stewart@flamingspork.com-20090616004515-bgr8e62psvn2820l
make snowman test not leave tables behind after running

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
30
#include <bitset>
34
31
 
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 */
 
32
class JOIN :public Sql_alloc
 
33
{
 
34
  JOIN(const JOIN &rhs);                        /**< not implemented */
 
35
  JOIN& operator=(const JOIN &rhs);             /**< not implemented */
44
36
 
45
37
  /**
46
38
   * Contains a partial query execution plan which is extended during
47
39
   * cost-based optimization.
48
40
   */
49
 
  optimizer::Position positions[MAX_TABLES+1];
 
41
  Position positions[MAX_TABLES+1];
50
42
 
51
43
  /**
52
44
   * Contains the optimal query execution plan after cost-based optimization
53
45
   * has taken place. 
54
46
   */
55
 
  optimizer::Position best_positions[MAX_TABLES+1];
 
47
  Position best_positions[MAX_TABLES+1];
56
48
 
57
49
public:
58
50
  JoinTable *join_tab;
105
97
 
106
98
  /*
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.
110
102
  */
111
103
  bool simple_order;
112
104
  bool simple_group;
113
105
  /**
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'.
116
108
  */
117
109
  bool no_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 */
144
136
 
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;
154
147
 
155
148
  /**
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;
183
 
  DrizzleLock *lock;
 
176
  DRIZZLE_LOCK *lock;
184
177
 
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;
199
192
  int error;
200
193
 
201
 
  Order *order;
202
 
  Order *group_list; /**< hold parameters of select_query */
 
194
  order_st *order;
 
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.
224
217
  */
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 */
229
222
 
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)
 
228
    :
 
229
      join_tab(NULL),
 
230
      best_ref(NULL),
 
231
      map2table(NULL),
 
232
      join_tab_save(NULL),
 
233
      table(NULL),
 
234
      all_tables(NULL),
 
235
      sort_by_table(NULL),
 
236
      tables(0),
 
237
      outer_tables(0),
 
238
      const_tables(0),
 
239
      send_group_parts(0),
 
240
      sort_and_group(false),
 
241
      first_record(false),
 
242
      full_join(false),
 
243
      group(false),
 
244
      no_field_update(false),
 
245
      do_send_rows(true),
 
246
      resume_nested_loop(false),
 
247
      no_const_tables(false),
 
248
      select_distinct(false),
 
249
      group_optimized_away(false),
 
250
      simple_order(false),
 
251
      simple_group(false),
 
252
      no_order(false),
 
253
      skip_sort_order(false),
 
254
      union_part(false),
 
255
      optimized(false),
 
256
      need_tmp(false),
 
257
      hidden_group_fields(false),
 
258
      const_table_map(0),
 
259
      found_const_table_map(0),
 
260
      outer_join(0),
 
261
      send_records(0),
 
262
      found_records(0),
 
263
      examined_rows(0),
 
264
      row_limit(0),
 
265
      select_limit(0),
 
266
      fetch_limit(HA_POS_ERROR),
 
267
      session(session_arg),
 
268
      fields_list(fields_arg), 
 
269
      join_list(NULL),
 
270
      unit(NULL),
 
271
      select_lex(NULL),
 
272
      select(NULL),
 
273
      sj_subselects(session_arg->mem_root, 4),
 
274
      exec_tmp_table1(NULL),
 
275
      exec_tmp_table2(NULL),
 
276
      sum_funcs(NULL),
 
277
      sum_funcs2(NULL),
 
278
      having(NULL),
 
279
      tmp_having(NULL),
 
280
      having_history(NULL),
 
281
      select_options(select_options_arg),
 
282
      result(result_arg),
 
283
      lock(session_arg->lock),
 
284
      tmp_join(NULL),
 
285
      all_fields(fields_arg),
 
286
      error(0),
 
287
      cond_equal(NULL),
 
288
      return_tab(NULL),
 
289
      ref_pointer_array(NULL),
 
290
      items0(NULL),
 
291
      items1(NULL),
 
292
      items2(NULL),
 
293
      items3(NULL),
 
294
      ref_pointer_array_size(0),
 
295
      zero_result_cause(NULL),
 
296
      sortorder(NULL),
 
297
      table_reexec(NULL),
 
298
      join_tab_reexec(NULL)
 
299
  {
 
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;
 
307
  }
235
308
 
236
309
  /** 
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...
241
314
   */
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)
 
319
  {
 
320
    join_tab= NULL;
 
321
    best_ref= NULL;
 
322
    map2table= NULL;
 
323
    join_tab_save= NULL;
 
324
    table= NULL;
 
325
    all_tables= NULL;
 
326
    sort_by_table= NULL;
 
327
    tables= 0;
 
328
    outer_tables= 0;
 
329
    const_tables= 0;
 
330
    send_group_parts= 0;
 
331
    sort_and_group= false;
 
332
    first_record= false;
 
333
    full_join= false;
 
334
    group= false;
 
335
    no_field_update= false;
 
336
    do_send_rows= true;
 
337
    resume_nested_loop= false;
 
338
    no_const_tables= false;
 
339
    select_distinct= false;
 
340
    group_optimized_away= false;
 
341
    simple_order= false;
 
342
    simple_group= false;
 
343
    no_order= false;
 
344
    skip_sort_order= false;
 
345
    union_part= false;
 
346
    optimized= false;
 
347
    need_tmp= false;
 
348
    hidden_group_fields= false;
 
349
    const_table_map= 0;
 
350
    found_const_table_map= 0;
 
351
    outer_join= 0;
 
352
    send_records= 0;
 
353
    found_records= 0;
 
354
    examined_rows= 0;
 
355
    row_limit= 0;
 
356
    select_limit= 0;
 
357
    fetch_limit= HA_POS_ERROR;
 
358
    session= session_arg;
 
359
    fields_list= fields_arg; 
 
360
    join_list= NULL;
 
361
    unit= NULL;
 
362
    select_lex= NULL;
 
363
    select= NULL;
 
364
    exec_tmp_table1= NULL;
 
365
    exec_tmp_table2= NULL;
 
366
    sum_funcs= NULL;
 
367
    sum_funcs2= NULL;
 
368
    having= NULL;
 
369
    tmp_having= NULL;
 
370
    having_history= NULL;
 
371
    select_options= select_options_arg;
 
372
    result= result_arg;
 
373
    lock= session_arg->lock;
 
374
    tmp_join= NULL;
 
375
    all_fields= fields_arg;
 
376
    error= 0;
 
377
    cond_equal= NULL;
 
378
    return_tab= NULL;
 
379
    ref_pointer_array= NULL;
 
380
    items0= NULL;
 
381
    items1= NULL;
 
382
    items2= NULL;
 
383
    items3= NULL;
 
384
    ref_pointer_array_size= 0;
 
385
    zero_result_cause= NULL;
 
386
    sortorder= NULL;
 
387
    table_reexec= 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;
 
396
  }
246
397
 
247
398
  int prepare(Item ***rref_pointer_array, 
248
399
              TableList *tables,
249
400
              uint32_t wind_num,
250
401
              COND *conds,
251
402
              uint32_t og_num,
252
 
              Order *order,
253
 
              Order *group,
 
403
              order_st *order,
 
404
              order_st *group,
254
405
              Item *having,
255
406
              Select_Lex *select,
256
407
              Select_Lex_Unit *unit);
257
 
 
258
408
  int optimize();
259
409
  int reinit();
260
410
  void exec();
293
443
    memory consumption.
294
444
  */
295
445
  void join_free();
296
 
  /** Cleanup this Join, possibly for reuse */
 
446
  /** Cleanup this JOIN, possibly for reuse */
297
447
  void cleanup(bool full);
298
448
  void clear();
299
449
  bool save_join_tab();
304
454
            !group_list);
305
455
  }
306
456
  bool change_result(select_result *result);
307
 
  bool is_top_level_join() const;
 
457
  bool is_top_level_join() const
 
458
  {
 
459
    return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
 
460
                                        select_lex == unit->fake_select_lex));
 
461
  }
308
462
 
309
463
  /**
310
464
   * Copy the partial query plan into the optimal query plan.
314
468
  void copyPartialPlanIntoOptimalPlan(uint32_t size)
315
469
  {
316
470
    memcpy(best_positions, positions, 
317
 
           sizeof(optimizer::Position) * size);
 
471
           sizeof(Position) * size);
318
472
  }
319
473
 
320
 
  void cache_const_exprs();
321
 
 
322
474
  /**
323
475
   * @param[in] index the index of the position to retrieve
324
476
   * @return a reference to the specified position in the optimal
325
477
   *         query plan
326
478
   */
327
 
  optimizer::Position &getPosFromOptimalPlan(uint32_t index)
 
479
  Position &getPosFromOptimalPlan(uint32_t index)
328
480
  {
329
481
    return best_positions[index];
330
482
  }
334
486
   * @return a reference to the specified position in the partial
335
487
   *         query plan
336
488
   */
337
 
  optimizer::Position &getPosFromPartialPlan(uint32_t index)
 
489
  Position &getPosFromPartialPlan(uint32_t index)
338
490
  {
339
491
    return positions[index];
340
492
  }
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
345
497
   */
346
 
  void setPosInPartialPlan(uint32_t index, optimizer::Position &in_pos)
 
498
  void setPosInPartialPlan(uint32_t index, Position &in_pos)
347
499
  {
348
500
    positions[index]= in_pos;
349
501
  }
351
503
  /**
352
504
   * @return a pointer to the first position in the partial query plan
353
505
   */
354
 
  optimizer::Position *getFirstPosInPartialPlan()
 
506
  Position *getFirstPosInPartialPlan()
355
507
  {
356
508
    return positions;
357
509
  }
361
513
   *                  query plan
362
514
   * @return a pointer to the position in the partial query plan
363
515
   */
364
 
  optimizer::Position *getSpecificPosInPartialPlan(int32_t index)
 
516
  Position *getSpecificPosInPartialPlan(int32_t index)
365
517
  {
366
518
    return positions + index;
367
519
  }
368
520
 
369
521
};
370
522
 
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 */
 
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);
380
530
 
381
531
#endif /* DRIZZLED_JOIN_H */