~drizzle-trunk/drizzle/development

1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008-2009 Sun Microsystems
5
 *
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.
10
 *
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.
15
 *
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
19
 */
20
21
/**
22
 * @file
23
 *
24
 * Defines the JOIN class
25
 */
26
27
#ifndef DRIZZLED_JOIN_H
28
#define DRIZZLED_JOIN_H
29
1100.4.2 by Padraig O'Sullivan
Removed the typedef for nested_join_map and instead just declare these
30
#include <bitset>
31
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
32
class JOIN :public Sql_alloc
33
{
34
  JOIN(const JOIN &rhs);                        /**< not implemented */
35
  JOIN& operator=(const JOIN &rhs);             /**< not implemented */
36
public:
1089.1.1 by Brian Aker
Remove of JOIN_TAB to JoinTable
37
  JoinTable *join_tab;
38
  JoinTable **best_ref;
39
  JoinTable **map2table;    /**< mapping between table indexes and JoinTables */
40
  JoinTable *join_tab_save; /**< saved join_tab for subquery reexecution */
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
41
42
  Table **table;
43
  Table **all_tables;
44
  /**
45
    The table which has an index that allows to produce the requried ordering.
46
    A special value of 0x1 means that the ordering will be produced by
47
    passing 1st non-const table to filesort(). NULL means no such table exists.
48
  */
49
  Table *sort_by_table;
50
51
  uint32_t tables;        /**< Number of tables in the join */
52
  uint32_t outer_tables;  /**< Number of tables that are not inside semijoin */
53
  uint32_t const_tables;
54
  uint32_t send_group_parts;
55
56
  bool sort_and_group;
57
  bool first_record;
58
  bool full_join;
59
  bool group;
60
  bool no_field_update;
61
  bool do_send_rows;
62
  /**
63
    true when we want to resume nested loop iterations when
64
    fetching data from a cursor
65
  */
66
  bool resume_nested_loop;
67
  /**
68
    true <=> optimizer must not mark any table as a constant table.
69
    This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
70
    when we optimize the select that reads the results of the union from a
71
    temporary table, we must not mark the temp. table as constant because
72
    the number of rows in it may vary from one subquery execution to another.
73
  */
74
  bool no_const_tables;
75
  bool select_distinct;				/**< Set if SELECT DISTINCT */
76
  /**
77
    If we have the GROUP BY statement in the query,
78
    but the group_list was emptied by optimizer, this
79
    flag is true.
80
    It happens when fields in the GROUP BY are from
81
    constant table
82
  */
83
  bool group_optimized_away;
84
85
  /*
86
    simple_xxxxx is set if order_st/GROUP BY doesn't include any references
87
    to other tables than the first non-constant table in the JOIN.
88
    It's also set if order_st/GROUP BY is empty.
89
  */
90
  bool simple_order;
91
  bool simple_group;
92
  /**
93
    Is set only in case if we have a GROUP BY clause
94
    and no order_st BY after constant elimination of 'order'.
95
  */
96
  bool no_order;
97
  /** Is set if we have a GROUP BY and we have order_st BY on a constant. */
98
  bool skip_sort_order;
99
  bool union_part; /**< this subselect is part of union */
100
  bool optimized; /**< flag to avoid double optimization in EXPLAIN */
101
  bool need_tmp;
102
  bool hidden_group_fields;
103
104
  table_map const_table_map;
105
  table_map found_const_table_map;
106
  table_map outer_join;
107
108
  ha_rows send_records;
109
  ha_rows found_records;
110
  ha_rows examined_rows;
111
  ha_rows row_limit;
112
  ha_rows select_limit;
113
  /**
114
    Used to fetch no more than given amount of rows per one
115
    fetch operation of server side cursor.
116
    The value is checked in end_send and end_send_group in fashion, similar
117
    to offset_limit_cnt:
118
      - fetch_limit= HA_POS_ERROR if there is no cursor.
119
      - when we open a cursor, we set fetch_limit to 0,
120
      - on each fetch iteration we add num_rows to fetch to fetch_limit
121
  */
122
  ha_rows fetch_limit;
123
124
  Session	*session;
125
  List<Item> *fields;
126
  List<Item> &fields_list; /**< hold field list passed to mysql_select */
127
  List<TableList> *join_list; /**< list of joined tables in reverse order */
128
  /** unit structure (with global parameters) for this select */
129
  Select_Lex_Unit *unit;
130
  /** select that processed */
131
  Select_Lex *select_lex;
132
  SQL_SELECT *select; /**< created in optimisation phase */
133
  Array<Item_in_subselect> sj_subselects;
134
135
  POSITION positions[MAX_TABLES+1];
136
  POSITION best_positions[MAX_TABLES+1];
137
138
  /**
139
    Bitmap of nested joins embedding the position at the end of the current
140
    partial join (valid only during join optimizer run).
141
  */
1100.4.2 by Padraig O'Sullivan
Removed the typedef for nested_join_map and instead just declare these
142
  std::bitset<64> cur_embedding_map;
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
143
144
  double best_read;
1101.1.16 by Monty Taylor
Reverted 1103
145
  List<Cached_item> group_fields;
146
  List<Cached_item> group_fields_cache;
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
147
  Table *tmp_table;
148
  /** used to store 2 possible tmp table of SELECT */
149
  Table *exec_tmp_table1;
150
  Table *exec_tmp_table2;
151
  Item_sum **sum_funcs;
152
  Item_sum ***sum_funcs_end;
153
  /** second copy of sumfuncs (for queries with 2 temporary tables */
154
  Item_sum **sum_funcs2;
155
  Item_sum ***sum_funcs_end2;
156
  Item *having;
157
  Item *tmp_having; /**< To store having when processed temporary table */
158
  Item *having_history; /**< Store having for explain */
159
  uint64_t select_options;
160
  select_result *result;
161
  Tmp_Table_Param tmp_table_param;
162
  DRIZZLE_LOCK *lock;
163
164
  JOIN *tmp_join; /**< copy of this JOIN to be used with temporary tables */
165
  ROLLUP rollup;				/**< Used with rollup */
166
  DYNAMIC_ARRAY keyuse;
167
  Item::cond_result cond_value;
168
  Item::cond_result having_value;
169
  List<Item> all_fields; /**< to store all fields that used in query */
170
  /** Above list changed to use temporary table */
171
  List<Item> tmp_all_fields1;
172
  List<Item> tmp_all_fields2;
173
  List<Item> tmp_all_fields3;
174
  /** Part, shared with list above, emulate following list */
175
  List<Item> tmp_fields_list1;
176
  List<Item> tmp_fields_list2;
177
  List<Item> tmp_fields_list3;
178
  int error;
179
180
  order_st *order;
181
  order_st *group_list; /**< hold parameters of mysql_select */
182
  COND *conds;                            // ---"---
183
  Item *conds_history; /**< store WHERE for explain */
184
  TableList *tables_list; /**< hold 'tables' parameter of mysql_select */
185
  COND_EQUAL *cond_equal;
1089.1.1 by Brian Aker
Remove of JOIN_TAB to JoinTable
186
  JoinTable *return_tab; /**< used only for outer joins */
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
187
  Item **ref_pointer_array; /**< used pointer reference for this select */
188
  /** Copy of above to be used with different lists */
189
  Item **items0;
190
  Item **items1;
191
  Item **items2;
192
  Item **items3;
193
  Item **current_ref_pointer_array;
194
  uint32_t ref_pointer_array_size; ///< size of above in bytes
195
  const char *zero_result_cause; ///< not 0 if exec must return zero result
196
197
  /*
198
    storage for caching buffers allocated during query execution.
199
    These buffers allocations need to be cached as the thread memory pool is
200
    cleared only at the end of the execution of the whole query and not caching
201
    allocations that occur in repetition at execution time will result in
202
    excessive memory usage.
203
  */
204
  SORT_FIELD *sortorder;                        // make_unireg_sortorder()
205
  Table **table_reexec;                         // make_simple_join()
1089.1.1 by Brian Aker
Remove of JOIN_TAB to JoinTable
206
  JoinTable *join_tab_reexec;                    // make_simple_join()
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
207
  /* end of allocation caching storage */
208
209
  /** Constructors */
210
  JOIN(Session *session_arg, 
211
       List<Item> &fields_arg, 
212
       uint64_t select_options_arg,
213
       select_result *result_arg)
214
    :
215
      join_tab(NULL),
216
      best_ref(NULL),
217
      map2table(NULL),
218
      join_tab_save(NULL),
219
      table(NULL),
220
      all_tables(NULL),
221
      sort_by_table(NULL),
222
      tables(0),
223
      outer_tables(0),
224
      const_tables(0),
225
      send_group_parts(0),
226
      sort_and_group(false),
227
      first_record(false),
228
      full_join(false),
229
      group(false),
230
      no_field_update(false),
231
      do_send_rows(true),
232
      resume_nested_loop(false),
233
      no_const_tables(false),
234
      select_distinct(false),
235
      group_optimized_away(false),
236
      simple_order(false),
237
      simple_group(false),
238
      no_order(false),
239
      skip_sort_order(false),
240
      union_part(false),
241
      optimized(false),
242
      need_tmp(false),
243
      hidden_group_fields(false),
1055.3.1 by Jay Pipes
table_map defined as uint64_t, not pointer type, so change initialization to 0 from NULL.
244
      const_table_map(0),
245
      found_const_table_map(0),
246
      outer_join(0),
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
247
      send_records(0),
248
      found_records(0),
249
      examined_rows(0),
250
      row_limit(0),
251
      select_limit(0),
252
      fetch_limit(HA_POS_ERROR),
253
      session(session_arg),
254
      fields_list(fields_arg), 
255
      join_list(NULL),
256
      unit(NULL),
257
      select_lex(NULL),
258
      select(NULL),
259
      sj_subselects(session_arg->mem_root, 4),
260
      exec_tmp_table1(NULL),
261
      exec_tmp_table2(NULL),
262
      sum_funcs(NULL),
263
      sum_funcs2(NULL),
264
      having(NULL),
265
      tmp_having(NULL),
266
      having_history(NULL),
267
      select_options(select_options_arg),
268
      result(result_arg),
269
      lock(session_arg->lock),
270
      tmp_join(NULL),
271
      all_fields(fields_arg),
272
      error(0),
273
      cond_equal(NULL),
274
      return_tab(NULL),
275
      ref_pointer_array(NULL),
276
      items0(NULL),
277
      items1(NULL),
278
      items2(NULL),
279
      items3(NULL),
280
      ref_pointer_array_size(0),
281
      zero_result_cause(NULL),
282
      sortorder(NULL),
283
      table_reexec(NULL),
284
      join_tab_reexec(NULL)
285
  {
286
    select_distinct= test(select_options & SELECT_DISTINCT);
287
    if (&fields_list != &fields_arg) /* only copy if not same*/
288
      fields_list= fields_arg;
289
    memset(&keyuse, 0, sizeof(keyuse));
1101.1.16 by Monty Taylor
Reverted 1103
290
    tmp_table_param.init();
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
291
    tmp_table_param.end_write_records= HA_POS_ERROR;
292
    rollup.state= ROLLUP::STATE_NONE;
293
  }
294
295
  /** 
296
   * This method is currently only used when a subselect EXPLAIN is performed.
297
   * I pulled out the init() method and have simply reset the values to what
298
   * was previously in the init() method.  See the note about the hack in 
299
   * sql_union.cc...
300
   */
301
  inline void reset(Session *session_arg, 
302
       List<Item> &fields_arg, 
303
       uint64_t select_options_arg,
304
       select_result *result_arg)
305
  {
306
    join_tab= NULL;
307
    best_ref= NULL;
308
    map2table= NULL;
309
    join_tab_save= NULL;
310
    table= NULL;
311
    all_tables= NULL;
312
    sort_by_table= NULL;
313
    tables= 0;
314
    outer_tables= 0;
315
    const_tables= 0;
316
    send_group_parts= 0;
317
    sort_and_group= false;
318
    first_record= false;
319
    full_join= false;
320
    group= false;
321
    no_field_update= false;
322
    do_send_rows= true;
323
    resume_nested_loop= false;
324
    no_const_tables= false;
325
    select_distinct= false;
326
    group_optimized_away= false;
327
    simple_order= false;
328
    simple_group= false;
329
    no_order= false;
330
    skip_sort_order= false;
331
    union_part= false;
332
    optimized= false;
333
    need_tmp= false;
334
    hidden_group_fields= false;
1055.3.1 by Jay Pipes
table_map defined as uint64_t, not pointer type, so change initialization to 0 from NULL.
335
    const_table_map= 0;
336
    found_const_table_map= 0;
337
    outer_join= 0;
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
338
    send_records= 0;
339
    found_records= 0;
340
    examined_rows= 0;
341
    row_limit= 0;
342
    select_limit= 0;
343
    fetch_limit= HA_POS_ERROR;
344
    session= session_arg;
345
    fields_list= fields_arg; 
346
    join_list= NULL;
347
    unit= NULL;
348
    select_lex= NULL;
349
    select= NULL;
350
    exec_tmp_table1= NULL;
351
    exec_tmp_table2= NULL;
352
    sum_funcs= NULL;
353
    sum_funcs2= NULL;
354
    having= NULL;
355
    tmp_having= NULL;
356
    having_history= NULL;
357
    select_options= select_options_arg;
358
    result= result_arg;
359
    lock= session_arg->lock;
360
    tmp_join= NULL;
361
    all_fields= fields_arg;
362
    error= 0;
363
    cond_equal= NULL;
364
    return_tab= NULL;
365
    ref_pointer_array= NULL;
366
    items0= NULL;
367
    items1= NULL;
368
    items2= NULL;
369
    items3= NULL;
370
    ref_pointer_array_size= 0;
371
    zero_result_cause= NULL;
372
    sortorder= NULL;
373
    table_reexec= NULL;
374
    join_tab_reexec= NULL;
375
    select_distinct= test(select_options & SELECT_DISTINCT);
376
    if (&fields_list != &fields_arg) /* only copy if not same*/
377
      fields_list= fields_arg;
378
    memset(&keyuse, 0, sizeof(keyuse));
1101.1.16 by Monty Taylor
Reverted 1103
379
    tmp_table_param.init();
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
380
    tmp_table_param.end_write_records= HA_POS_ERROR;
381
    rollup.state= ROLLUP::STATE_NONE;
382
  }
383
384
  int prepare(Item ***rref_pointer_array, 
385
              TableList *tables,
386
              uint32_t wind_num,
387
              COND *conds,
388
              uint32_t og_num,
389
              order_st *order,
390
              order_st *group,
391
              Item *having,
392
              Select_Lex *select,
393
              Select_Lex_Unit *unit);
394
  int optimize();
395
  int reinit();
396
  void exec();
397
  int destroy();
398
  void restore_tmp();
399
  bool alloc_func_list();
400
  bool setup_subquery_materialization();
401
  bool make_sum_func_list(List<Item> &all_fields, 
402
                          List<Item> &send_fields,
403
                  			  bool before_group_by,
404
                          bool recompute= false);
405
406
  inline void set_items_ref_array(Item **ptr)
407
  {
408
    memcpy(ref_pointer_array, ptr, ref_pointer_array_size);
409
    current_ref_pointer_array= ptr;
410
  }
411
  inline void init_items_ref_array()
412
  {
413
    items0= ref_pointer_array + all_fields.elements;
414
    memcpy(items0, ref_pointer_array, ref_pointer_array_size);
415
    current_ref_pointer_array= items0;
416
  }
417
418
  bool rollup_init();
419
  bool rollup_make_fields(List<Item> &all_fields, 
420
                          List<Item> &fields,
421
                  			  Item_sum ***func);
422
  int rollup_send_data(uint32_t idx);
423
  int rollup_write_data(uint32_t idx, Table *table);
424
  void remove_subq_pushed_predicates(Item **where);
425
  /**
426
    Release memory and, if possible, the open tables held by this execution
427
    plan (and nested plans). It's used to release some tables before
428
    the end of execution in order to increase concurrency and reduce
429
    memory consumption.
430
  */
431
  void join_free();
432
  /** Cleanup this JOIN, possibly for reuse */
433
  void cleanup(bool full);
434
  void clear();
435
  bool save_join_tab();
436
  bool init_save_join_tab();
437
  bool send_row_on_empty_set()
438
  {
439
    return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
440
	    !group_list);
441
  }
442
  bool change_result(select_result *result);
443
  bool is_top_level_join() const
444
  {
445
    return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
446
                                        select_lex == unit->fake_select_lex));
447
  }
448
};
449
1089.1.1 by Brian Aker
Remove of JOIN_TAB to JoinTable
450
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error);
451
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab);
452
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last);
453
enum_nested_loop_state end_send(JOIN *join, JoinTable *join_tab, bool end_of_records);
454
enum_nested_loop_state end_write(JOIN *join, JoinTable *join_tab, bool end_of_records);
455
enum_nested_loop_state end_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
456
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *join_tab, bool end_of_records);
1039.2.2 by Jay Pipes
Phase 2 of JOIN refactoring.
457
1039.2.1 by Jay Pipes
First phase refactoring the JOIN class:
458
#endif /* DRIZZLED_JOIN_H */