~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.h

pandora-build v0.100 - Fixes several bugs found by cb1kenobi. Add several thoughts from folks at LCA.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
 
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; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_SQL_SELECT_H
 
21
#define DRIZZLED_SQL_SELECT_H
 
22
 
 
23
#include "drizzled/cached_item.h"
 
24
#include "drizzled/session.h"
 
25
#include "drizzled/field/varstring.h"
 
26
#include "drizzled/item/null.h"
 
27
#include <drizzled/enum_nested_loop_state.h>
 
28
#include "drizzled/optimizer/position.h"
 
29
#include "drizzled/optimizer/sargable_param.h"
 
30
#include "drizzled/optimizer/key_use.h"
 
31
#include "drizzled/join_cache.h"
 
32
#include "drizzled/join_table.h"
 
33
 
 
34
#include <vector>
 
35
 
 
36
 
 
37
class select_result;
16
38
 
17
39
/**
18
 
  @file
19
 
 
20
 
  @brief
21
 
  classes to use when handling where clause
22
 
*/
23
 
 
24
 
#ifdef USE_PRAGMA_INTERFACE
25
 
#pragma interface                       /* gcc class implementation */
26
 
#endif
 
40
 * @file API and Classes to use when handling where clause
 
41
 */
27
42
 
28
43
/* PREV_BITS only used in sql_select.cc */
29
44
#define PREV_BITS(type,A)       ((type) (((type) 1 << (A)) -1))
30
45
 
31
 
#include <storage/myisam/myisam.h>
32
 
 
33
46
/* Values in optimize */
34
47
#define KEY_OPTIMIZE_EXISTS             1
35
48
#define KEY_OPTIMIZE_REF_OR_NULL        2
36
49
 
37
 
typedef struct keyuse_t {
38
 
  TABLE *table;
39
 
  Item  *val;                           /**< or value if no field */
40
 
  table_map used_tables;
41
 
  uint  key, keypart;
42
 
  uint optimize; // 0, or KEY_OPTIMIZE_*
43
 
  key_part_map keypart_map;
44
 
  ha_rows      ref_table_rows;
45
 
  /**
46
 
    If true, the comparison this value was created from will not be
47
 
    satisfied if val has NULL 'value'.
48
 
  */
49
 
  bool null_rejecting;
50
 
  /*
51
 
    !NULL - This KEYUSE was created from an equality that was wrapped into
52
 
            an Item_func_trig_cond. This means the equality (and validity of 
53
 
            this KEYUSE element) can be turned on and off. The on/off state 
54
 
            is indicted by the pointed value:
55
 
              *cond_guard == true <=> equality condition is on
56
 
              *cond_guard == false <=> equality condition is off
57
 
 
58
 
    NULL  - Otherwise (the source equality can't be turned off)
59
 
  */
60
 
  bool *cond_guard;
61
 
  /*
62
 
     0..64    <=> This was created from semi-join IN-equality # sj_pred_no.
63
 
     MAX_UINT  Otherwise
64
 
  */
65
 
  uint         sj_pred_no;
66
 
} KEYUSE;
67
 
 
68
 
class store_key;
69
 
 
70
 
typedef struct st_table_ref
71
 
{
72
 
  bool          key_err;
73
 
  uint          key_parts;                ///< num of ...
74
 
  uint          key_length;               ///< length of key_buff
75
 
  int           key;                      ///< key no
76
 
  uchar         *key_buff;                ///< value to look for with key
77
 
  uchar         *key_buff2;               ///< key_buff+key_length
78
 
  store_key     **key_copy;               //
79
 
  Item          **items;                  ///< val()'s for each keypart
80
 
  /*  
81
 
    Array of pointers to trigger variables. Some/all of the pointers may be
82
 
    NULL.  The ref access can be used iff
83
 
    
84
 
      for each used key part i, (!cond_guards[i] || *cond_guards[i]) 
85
 
 
86
 
    This array is used by subquery code. The subquery code may inject
87
 
    triggered conditions, i.e. conditions that can be 'switched off'. A ref 
88
 
    access created from such condition is not valid when at least one of the 
89
 
    underlying conditions is switched off (see subquery code for more details)
90
 
  */
91
 
  bool          **cond_guards;
92
 
  /**
93
 
    (null_rejecting & (1<<i)) means the condition is '=' and no matching
94
 
    rows will be produced if items[i] IS NULL (see add_not_null_conds())
95
 
  */
96
 
  key_part_map  null_rejecting;
97
 
  table_map     depend_map;               ///< Table depends on these tables.
98
 
  /* null byte position in the key_buf. Used for REF_OR_NULL optimization */
99
 
  uchar          *null_ref_key;
100
 
 
101
 
  /*
102
 
    true <=> disable the "cache" as doing lookup with the same key value may
103
 
    produce different results (because of Index Condition Pushdown)
104
 
  */
105
 
  bool          disable_cache;
106
 
} TABLE_REF;
107
 
 
108
 
 
109
 
/**
110
 
  CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
111
 
  table
112
 
*/
113
 
 
114
 
typedef struct st_cache_field {
115
 
  /* 
116
 
    Where source data is located (i.e. this points to somewhere in 
117
 
    tableX->record[0])
118
 
  */
119
 
  uchar *str;
120
 
  uint length; /* Length of data at *str, in bytes */
121
 
  uint blob_length; /* Valid IFF blob_field != 0 */
122
 
  Field_blob *blob_field;
123
 
  bool strip; /* true <=> Strip endspaces ?? */
124
 
 
125
 
  TABLE *get_rowid; /* _ != NULL <=> */
126
 
} CACHE_FIELD;
127
 
 
128
 
 
129
 
typedef struct st_join_cache 
130
 
{
131
 
  uchar *buff;
132
 
  uchar *pos;    /* Start of free space in the buffer */
133
 
  uchar *end;
134
 
  uint records;  /* # of row cominations currently stored in the cache */
135
 
  uint record_nr;
136
 
  uint ptr_record; 
137
 
  /* 
138
 
    Number of fields (i.e. cache_field objects). Those correspond to table
139
 
    columns, and there are also special fields for
140
 
     - table's column null bits
141
 
     - table's null-complementation byte
142
 
     - [new] table's rowid.
143
 
  */
144
 
  uint fields; 
145
 
  uint length; 
146
 
  uint blobs;
147
 
  CACHE_FIELD *field;
148
 
  CACHE_FIELD **blob_ptr;
149
 
  SQL_SELECT *select;
150
 
} JOIN_CACHE;
151
 
 
152
 
 
153
 
/*
154
 
  The structs which holds the join connections and join states
155
 
*/
156
 
enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
157
 
                 JT_ALL, JT_RANGE, JT_NEXT, JT_REF_OR_NULL,
158
 
                 JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE};
159
 
 
160
50
class JOIN;
161
51
 
162
 
enum enum_nested_loop_state
163
 
{
164
 
  NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1,
165
 
  NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1,
166
 
  NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4
167
 
};
168
 
 
169
 
 
170
 
/* Values for JOIN_TAB::packed_info */
171
 
#define TAB_INFO_HAVE_VALUE 1
172
 
#define TAB_INFO_USING_INDEX 2
173
 
#define TAB_INFO_USING_WHERE 4
174
 
#define TAB_INFO_FULL_SCAN_ON_NULL 8
175
 
 
176
 
class SJ_TMP_TABLE;
177
 
 
178
 
typedef enum_nested_loop_state
179
 
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
180
 
typedef int (*Read_record_func)(struct st_join_table *tab);
181
 
Next_select_func setup_end_select_func(JOIN *join);
182
 
 
183
 
 
184
 
typedef struct st_join_table {
185
 
  st_join_table() {}                          /* Remove gcc warning */
186
 
  TABLE         *table;
187
 
  KEYUSE        *keyuse;                        /**< pointer to first used key */
188
 
  SQL_SELECT    *select;
189
 
  COND          *select_cond;
190
 
  QUICK_SELECT_I *quick;
191
 
  /* 
192
 
    The value of select_cond before we've attempted to do Index Condition
193
 
    Pushdown. We may need to restore everything back if we first choose one
194
 
    index but then reconsider (see test_if_skip_sort_order() for such
195
 
    scenarios).
196
 
    NULL means no index condition pushdown was performed.
197
 
  */
198
 
  Item          *pre_idx_push_select_cond;
199
 
  Item         **on_expr_ref;   /**< pointer to the associated on expression   */
200
 
  COND_EQUAL    *cond_equal;    /**< multiple equalities for the on expression */
201
 
  st_join_table *first_inner;   /**< first inner table for including outerjoin */
202
 
  bool           found;         /**< true after all matches or null complement */
203
 
  bool           not_null_compl;/**< true before null complement is added      */
204
 
  st_join_table *last_inner;    /**< last table table for embedding outer join */
205
 
  st_join_table *first_upper;  /**< first inner table for embedding outer join */
206
 
  st_join_table *first_unmatched; /**< used for optimization purposes only     */
207
 
  
208
 
  /* Special content for EXPLAIN 'Extra' column or NULL if none */
209
 
  const char    *info;
210
 
  /* 
211
 
    Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
212
 
    column, or 0 if there is no info.
213
 
  */
214
 
  uint          packed_info;
215
 
 
216
 
  Read_record_func read_first_record;
217
 
  Next_select_func next_select;
218
 
  READ_RECORD   read_record;
219
 
  /* 
220
 
    Currently the following two fields are used only for a [NOT] IN subquery
221
 
    if it is executed by an alternative full table scan when the left operand of
222
 
    the subquery predicate is evaluated to NULL.
223
 
  */  
224
 
  Read_record_func save_read_first_record;/* to save read_first_record */ 
225
 
  int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
226
 
  double        worst_seeks;
227
 
  key_map       const_keys;                     /**< Keys with constant part */
228
 
  key_map       checked_keys;                   /**< Keys checked in find_best */
229
 
  key_map       needed_reg;
230
 
  key_map       keys;                           /**< all keys with can be used */
231
 
 
232
 
  /* Either #rows in the table or 1 for const table.  */
233
 
  ha_rows       records;
234
 
  /*
235
 
    Number of records that will be scanned (yes scanned, not returned) by the
236
 
    best 'independent' access method, i.e. table scan or QUICK_*_SELECT)
237
 
  */
238
 
  ha_rows       found_records;
239
 
  /*
240
 
    Cost of accessing the table using "ALL" or range/index_merge access
241
 
    method (but not 'index' for some reason), i.e. this matches method which
242
 
    E(#records) is in found_records.
243
 
  */
244
 
  ha_rows       read_time;
245
 
  
246
 
  table_map     dependent,key_dependent;
247
 
  uint          use_quick,index;
248
 
  uint          status;                         ///< Save status for cache
249
 
  uint          used_fields,used_fieldlength,used_blobs;
250
 
  enum join_type type;
251
 
  bool          cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
252
 
  /* true <=> index-based access method must return records in order */
253
 
  bool          sorted;
254
 
  /* 
255
 
    If it's not 0 the number stored this field indicates that the index
256
 
    scan has been chosen to access the table data and we expect to scan 
257
 
    this number of rows for the table.
258
 
  */ 
259
 
  ha_rows       limit; 
260
 
  TABLE_REF     ref;
261
 
  JOIN_CACHE    cache;
262
 
  JOIN          *join;
263
 
  /** Bitmap of nested joins this table is part of */
264
 
 
265
 
  /* SemiJoinDuplicateElimination variables: */
266
 
  /*
267
 
    Embedding SJ-nest (may be not the direct parent), or NULL if none.
268
 
    This variable holds the result of table pullout.
269
 
  */
270
 
  TABLE_LIST    *emb_sj_nest;
271
 
 
272
 
  /* Variables for semi-join duplicate elimination */
273
 
  SJ_TMP_TABLE  *flush_weedout_table;
274
 
  SJ_TMP_TABLE  *check_weed_out_table;
275
 
  struct st_join_table  *do_firstmatch;
276
 
 
277
 
  /* 
278
 
     ptr  - this join tab should do an InsideOut scan. Points 
279
 
            to the tab for which we'll need to check tab->found_match.
280
 
 
281
 
     NULL - Not an insideout scan.
282
 
  */
283
 
  struct st_join_table *insideout_match_tab;
284
 
  uchar *insideout_buf; // Buffer to save index tuple to be able to skip dups
285
 
 
286
 
  /* Used by InsideOut scan. Just set to true when have found a row. */
287
 
  bool found_match;
288
 
 
289
 
  enum { 
290
 
    /* If set, the rowid of this table must be put into the temptable. */
291
 
    KEEP_ROWID=1, 
292
 
    /* 
293
 
      If set, one should call h->position() to obtain the rowid,
294
 
      otherwise, the rowid is assumed to already be in h->ref
295
 
      (this is because join caching and filesort() save the rowid and then
296
 
      put it back into h->ref)
297
 
    */
298
 
    CALL_POSITION=2
299
 
  };
300
 
  /* A set of flags from the above enum */
301
 
  int  rowid_keep_flags;
302
 
 
303
 
 
304
 
  /* NestedOuterJoins: Bitmap of nested joins this table is part of */
305
 
  nested_join_map embedding_map;
306
 
 
307
 
  void cleanup();
308
 
  inline bool is_using_loose_index_scan()
309
 
  {
310
 
    return (select && select->quick &&
311
 
            (select->quick->get_type() ==
312
 
             QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
313
 
  }
314
 
} JOIN_TAB;
315
 
 
316
 
enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
317
 
                                        end_of_records);
318
 
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
319
 
                                  end_of_records);
320
 
enum_nested_loop_state end_send_group(JOIN *join, JOIN_TAB *join_tab,
321
 
                                      bool end_of_records);
322
 
enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab,
323
 
                                       bool end_of_records);
324
 
 
325
 
/**
326
 
  Information about a position of table within a join order. Used in join
327
 
  optimization.
328
 
*/
329
 
typedef struct st_position
330
 
{
331
 
  /*
332
 
    The "fanout": number of output rows that will be produced (after
333
 
    pushed down selection condition is applied) per each row combination of
334
 
    previous tables.
335
 
  */
336
 
  double records_read;
337
 
 
338
 
  /* 
339
 
    Cost accessing the table in course of the entire complete join execution,
340
 
    i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times 
341
 
    number the access method will be invoked.
342
 
  */
343
 
  double read_time;
344
 
  JOIN_TAB *table;
345
 
 
346
 
  /*
347
 
    NULL  -  'index' or 'range' or 'index_merge' or 'ALL' access is used.
348
 
    Other - [eq_]ref[_or_null] access is used. Pointer to {t.keypart1 = expr}
349
 
  */
350
 
  KEYUSE *key;
351
 
 
352
 
  /* If ref-based access is used: bitmap of tables this table depends on  */
353
 
  table_map ref_depend_map;
354
 
 
355
 
  bool use_insideout_scan;
356
 
} POSITION;
357
 
 
 
52
enum_nested_loop_state sub_select_cache(JOIN *join, JoinTable *join_tab, bool end_of_records);
 
53
enum_nested_loop_state sub_select(JOIN *join,JoinTable *join_tab, bool end_of_records);
 
54
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *join_tab, bool end_of_records);
 
55
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *join_tab, bool end_of_records);
358
56
 
359
57
typedef struct st_rollup
360
58
{
365
63
  List<Item> *fields;
366
64
} ROLLUP;
367
65
 
368
 
 
369
 
/*
370
 
  Describes use of one temporary table to weed out join duplicates.
371
 
  The temporar
372
 
 
373
 
  Used to
374
 
    - create a temp table
375
 
    - when we reach the weed-out tab, walk through rowid-ed tabs and
376
 
      and copy rowids.
377
 
      For each table we need
378
 
       - rowid offset
379
 
       - null bit address.
380
 
*/
381
 
 
382
 
class SJ_TMP_TABLE : public Sql_alloc
383
 
{
384
 
public:
385
 
  /* Array of pointers to tables that should be "used" */
386
 
  class TAB
387
 
  {
388
 
  public:
389
 
    JOIN_TAB *join_tab;
390
 
    uint rowid_offset;
391
 
    ushort null_byte;
392
 
    uchar null_bit;
393
 
  };
394
 
  TAB *tabs;
395
 
  TAB *tabs_end;
396
 
 
397
 
  uint null_bits;
398
 
  uint null_bytes;
399
 
  uint rowid_len;
400
 
 
401
 
  TABLE *tmp_table;
402
 
 
403
 
  MI_COLUMNDEF *start_recinfo;
404
 
  MI_COLUMNDEF *recinfo;
405
 
 
406
 
  /* Pointer to next table (next->start_idx > this->end_idx) */
407
 
  SJ_TMP_TABLE *next; 
408
 
};
409
 
 
410
 
 
411
 
class JOIN :public Sql_alloc
412
 
{
413
 
  JOIN(const JOIN &rhs);                        /**< not implemented */
414
 
  JOIN& operator=(const JOIN &rhs);             /**< not implemented */
415
 
public:
416
 
  JOIN_TAB *join_tab,**best_ref;
417
 
  JOIN_TAB **map2table;    ///< mapping between table indexes and JOIN_TABs
418
 
  JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
419
 
  TABLE    **table,**all_tables;
420
 
  /**
421
 
    The table which has an index that allows to produce the requried ordering.
422
 
    A special value of 0x1 means that the ordering will be produced by
423
 
    passing 1st non-const table to filesort(). NULL means no such table exists.
424
 
  */
425
 
  TABLE    *sort_by_table;
426
 
  uint     tables;        /**< Number of tables in the join */
427
 
  uint     outer_tables;  /**< Number of tables that are not inside semijoin */
428
 
  uint     const_tables;
429
 
  uint     send_group_parts;
430
 
  bool     sort_and_group,first_record,full_join,group, no_field_update;
431
 
  bool     do_send_rows;
432
 
  /**
433
 
    true when we want to resume nested loop iterations when
434
 
    fetching data from a cursor
435
 
  */
436
 
  bool     resume_nested_loop;
437
 
  table_map const_table_map,found_const_table_map,outer_join;
438
 
  ha_rows  send_records,found_records,examined_rows,row_limit, select_limit;
439
 
  /**
440
 
    Used to fetch no more than given amount of rows per one
441
 
    fetch operation of server side cursor.
442
 
    The value is checked in end_send and end_send_group in fashion, similar
443
 
    to offset_limit_cnt:
444
 
      - fetch_limit= HA_POS_ERROR if there is no cursor.
445
 
      - when we open a cursor, we set fetch_limit to 0,
446
 
      - on each fetch iteration we add num_rows to fetch to fetch_limit
447
 
  */
448
 
  ha_rows  fetch_limit;
449
 
  POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
450
 
  
451
 
  /* *
452
 
    Bitmap of nested joins embedding the position at the end of the current 
453
 
    partial join (valid only during join optimizer run).
454
 
  */
455
 
  nested_join_map cur_embedding_map;
456
 
 
457
 
  double   best_read;
458
 
  List<Item> *fields;
459
 
  List<Cached_item> group_fields, group_fields_cache;
460
 
  TABLE    *tmp_table;
461
 
  /// used to store 2 possible tmp table of SELECT
462
 
  TABLE    *exec_tmp_table1, *exec_tmp_table2;
463
 
  THD      *thd;
464
 
  Item_sum  **sum_funcs, ***sum_funcs_end;
465
 
  /** second copy of sumfuncs (for queries with 2 temporary tables */
466
 
  Item_sum  **sum_funcs2, ***sum_funcs_end2;
467
 
  Item      *having;
468
 
  Item      *tmp_having; ///< To store having when processed temporary table
469
 
  Item      *having_history; ///< Store having for explain
470
 
  uint64_t  select_options;
471
 
  select_result *result;
472
 
  TMP_TABLE_PARAM tmp_table_param;
473
 
  DRIZZLE_LOCK *lock;
474
 
  /// unit structure (with global parameters) for this select
475
 
  SELECT_LEX_UNIT *unit;
476
 
  /// select that processed
477
 
  SELECT_LEX *select_lex;
478
 
  /** 
479
 
    true <=> optimizer must not mark any table as a constant table.
480
 
    This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
481
 
    when we optimize the select that reads the results of the union from a
482
 
    temporary table, we must not mark the temp. table as constant because
483
 
    the number of rows in it may vary from one subquery execution to another.
484
 
  */
485
 
  bool no_const_tables; 
486
 
  
487
 
  JOIN *tmp_join; ///< copy of this JOIN to be used with temporary tables
488
 
  ROLLUP rollup;                                ///< Used with rollup
489
 
 
490
 
  bool select_distinct;                         ///< Set if SELECT DISTINCT
491
 
  /**
492
 
    If we have the GROUP BY statement in the query,
493
 
    but the group_list was emptied by optimizer, this
494
 
    flag is true.
495
 
    It happens when fields in the GROUP BY are from
496
 
    constant table
497
 
  */
498
 
  bool group_optimized_away;
499
 
 
500
 
  /*
501
 
    simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
502
 
    to other tables than the first non-constant table in the JOIN.
503
 
    It's also set if ORDER/GROUP BY is empty.
504
 
  */
505
 
  bool simple_order, simple_group;
506
 
  /**
507
 
    Is set only in case if we have a GROUP BY clause
508
 
    and no ORDER BY after constant elimination of 'order'.
509
 
  */
510
 
  bool no_order;
511
 
  /** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
512
 
  bool          skip_sort_order;
513
 
 
514
 
  bool need_tmp, hidden_group_fields;
515
 
  DYNAMIC_ARRAY keyuse;
516
 
  Item::cond_result cond_value, having_value;
517
 
  List<Item> all_fields; ///< to store all fields that used in query
518
 
  ///Above list changed to use temporary table
519
 
  List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
520
 
  ///Part, shared with list above, emulate following list
521
 
  List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
522
 
  List<Item> &fields_list; ///< hold field list passed to mysql_select
523
 
  int error;
524
 
 
525
 
  ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
526
 
  COND *conds;                            // ---"---
527
 
  Item *conds_history;                    // store WHERE for explain
528
 
  TABLE_LIST *tables_list;           ///<hold 'tables' parameter of mysql_select
529
 
  List<TABLE_LIST> *join_list;       ///< list of joined tables in reverse order
530
 
  COND_EQUAL *cond_equal;
531
 
  SQL_SELECT *select;                ///<created in optimisation phase
532
 
  JOIN_TAB *return_tab;              ///<used only for outer joins
533
 
  Item **ref_pointer_array; ///<used pointer reference for this select
534
 
  // Copy of above to be used with different lists
535
 
  Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
536
 
  uint ref_pointer_array_size; ///< size of above in bytes
537
 
  const char *zero_result_cause; ///< not 0 if exec must return zero result
538
 
  
539
 
  bool union_part; ///< this subselect is part of union 
540
 
  bool optimized; ///< flag to avoid double optimization in EXPLAIN
541
 
  
542
 
  Array<Item_in_subselect> sj_subselects;
543
 
 
544
 
  /* Descriptions of temporary tables used to weed-out semi-join duplicates */
545
 
  SJ_TMP_TABLE  *sj_tmp_tables;
546
 
 
547
 
  table_map cur_emb_sj_nests;
548
 
 
549
 
  /* 
550
 
    storage for caching buffers allocated during query execution. 
551
 
    These buffers allocations need to be cached as the thread memory pool is
552
 
    cleared only at the end of the execution of the whole query and not caching
553
 
    allocations that occur in repetition at execution time will result in 
554
 
    excessive memory usage.
555
 
  */  
556
 
  SORT_FIELD *sortorder;                        // make_unireg_sortorder()
557
 
  TABLE **table_reexec;                         // make_simple_join()
558
 
  JOIN_TAB *join_tab_reexec;                    // make_simple_join()
559
 
  /* end of allocation caching storage */
560
 
 
561
 
  JOIN(THD *thd_arg, List<Item> &fields_arg, uint64_t select_options_arg,
562
 
       select_result *result_arg)
563
 
    :fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4)
564
 
  {
565
 
    init(thd_arg, fields_arg, select_options_arg, result_arg);
566
 
  }
567
 
 
568
 
  void init(THD *thd_arg, List<Item> &fields_arg, uint64_t select_options_arg,
569
 
       select_result *result_arg)
570
 
  {
571
 
    join_tab= join_tab_save= 0;
572
 
    table= 0;
573
 
    tables= 0;
574
 
    const_tables= 0;
575
 
    join_list= 0;
576
 
    sort_and_group= 0;
577
 
    first_record= 0;
578
 
    do_send_rows= 1;
579
 
    resume_nested_loop= false;
580
 
    send_records= 0;
581
 
    found_records= 0;
582
 
    fetch_limit= HA_POS_ERROR;
583
 
    examined_rows= 0;
584
 
    exec_tmp_table1= 0;
585
 
    exec_tmp_table2= 0;
586
 
    sortorder= 0;
587
 
    table_reexec= 0;
588
 
    join_tab_reexec= 0;
589
 
    thd= thd_arg;
590
 
    sum_funcs= sum_funcs2= 0;
591
 
    having= tmp_having= having_history= 0;
592
 
    select_options= select_options_arg;
593
 
    result= result_arg;
594
 
    lock= thd_arg->lock;
595
 
    select_lex= 0; //for safety
596
 
    tmp_join= 0;
597
 
    select_distinct= test(select_options & SELECT_DISTINCT);
598
 
    no_order= 0;
599
 
    simple_order= 0;
600
 
    simple_group= 0;
601
 
    skip_sort_order= 0;
602
 
    need_tmp= 0;
603
 
    hidden_group_fields= 0; /*safety*/
604
 
    error= 0;
605
 
    select= 0;
606
 
    return_tab= 0;
607
 
    ref_pointer_array= items0= items1= items2= items3= 0;
608
 
    ref_pointer_array_size= 0;
609
 
    zero_result_cause= 0;
610
 
    optimized= 0;
611
 
    cond_equal= 0;
612
 
    group_optimized_away= 0;
613
 
 
614
 
    all_fields= fields_arg;
615
 
    fields_list= fields_arg;
616
 
    memset(&keyuse, 0, sizeof(keyuse));
617
 
    tmp_table_param.init();
618
 
    tmp_table_param.end_write_records= HA_POS_ERROR;
619
 
    rollup.state= ROLLUP::STATE_NONE;
620
 
    sj_tmp_tables= NULL;
621
 
 
622
 
    no_const_tables= false;
623
 
  }
624
 
 
625
 
  int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
626
 
              COND *conds, uint og_num, ORDER *order, ORDER *group,
627
 
              Item *having, ORDER *proc_param, SELECT_LEX *select,
628
 
              SELECT_LEX_UNIT *unit);
629
 
  int optimize();
630
 
  int reinit();
631
 
  void exec();
632
 
  int destroy();
633
 
  void restore_tmp();
634
 
  bool alloc_func_list();
635
 
  bool flatten_subqueries();
636
 
  bool setup_subquery_materialization();
637
 
  bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
638
 
                          bool before_group_by, bool recompute= false);
639
 
 
640
 
  inline void set_items_ref_array(Item **ptr)
641
 
  {
642
 
    memcpy(ref_pointer_array, ptr, ref_pointer_array_size);
643
 
    current_ref_pointer_array= ptr;
644
 
  }
645
 
  inline void init_items_ref_array()
646
 
  {
647
 
    items0= ref_pointer_array + all_fields.elements;
648
 
    memcpy(items0, ref_pointer_array, ref_pointer_array_size);
649
 
    current_ref_pointer_array= items0;
650
 
  }
651
 
 
652
 
  bool rollup_init();
653
 
  bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
654
 
                          Item_sum ***func);
655
 
  int rollup_send_data(uint idx);
656
 
  int rollup_write_data(uint idx, TABLE *table);
657
 
  void remove_subq_pushed_predicates(Item **where);
658
 
  /**
659
 
    Release memory and, if possible, the open tables held by this execution
660
 
    plan (and nested plans). It's used to release some tables before
661
 
    the end of execution in order to increase concurrency and reduce
662
 
    memory consumption.
663
 
  */
664
 
  void join_free();
665
 
  /** Cleanup this JOIN, possibly for reuse */
666
 
  void cleanup(bool full);
667
 
  void clear();
668
 
  bool save_join_tab();
669
 
  bool init_save_join_tab();
670
 
  bool send_row_on_empty_set()
671
 
  {
672
 
    return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
673
 
            !group_list);
674
 
  }
675
 
  bool change_result(select_result *result);
676
 
  bool is_top_level_join() const
677
 
  {
678
 
    return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
679
 
                                        select_lex == unit->fake_select_lex));
680
 
  }
681
 
};
682
 
 
683
 
 
684
 
typedef struct st_select_check {
685
 
  uint const_ref,reg_ref;
686
 
} SELECT_CHECK;
687
 
 
688
 
extern const char *join_type_str[];
 
66
#include "drizzled/join.h"
 
67
 
 
68
/*****************************************************************************
 
69
  Make som simple condition optimization:
 
70
  If there is a test 'field = const' change all refs to 'field' to 'const'
 
71
  Remove all dummy tests 'item = item', 'const op const'.
 
72
  Remove all 'item is NULL', when item can never be null!
 
73
  item->marker should be 0 for all items on entry
 
74
  Return in cond_value false if condition is impossible (1 = 2)
 
75
*****************************************************************************/
 
76
struct COND_CMP {
 
77
  Item *and_level;
 
78
  Item_func *cmp_func;
 
79
  COND_CMP(Item *a,Item_func *b) :and_level(a),cmp_func(b) {}
 
80
};
 
81
 
689
82
void TEST_join(JOIN *join);
690
83
 
691
84
/* Extern functions in sql_select.cc */
692
85
bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
693
 
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
694
 
                        ORDER *group, bool distinct, bool save_sum_fields,
 
86
Table *create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
 
87
                        order_st *group, bool distinct, bool save_sum_fields,
695
88
                        uint64_t select_options, ha_rows rows_limit,
696
 
                        char* alias);
697
 
void free_tmp_table(THD *thd, TABLE *entry);
698
 
void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, 
 
89
                        const char* alias);
 
90
void free_tmp_table(Session *session, Table *entry);
 
91
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param,
699
92
                       List<Item> &fields, bool reset_with_sum_func);
700
 
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
 
93
bool setup_copy_fields(Session *session, Tmp_Table_Param *param,
701
94
                       Item **ref_pointer_array,
702
95
                       List<Item> &new_list1, List<Item> &new_list2,
703
 
                       uint elements, List<Item> &fields);
704
 
void copy_fields(TMP_TABLE_PARAM *param);
 
96
                       uint32_t elements, List<Item> &fields);
 
97
void copy_fields(Tmp_Table_Param *param);
705
98
void copy_funcs(Item **func_ptr);
706
 
bool create_myisam_from_heap(THD *thd, TABLE *table,
707
 
                             MI_COLUMNDEF *start_recinfo,
708
 
                             MI_COLUMNDEF **recinfo, 
709
 
                             int error, bool ignore_last_dupp_key_error);
710
 
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
711
 
Field* create_tmp_field_from_field(THD *thd, Field* org_field,
712
 
                                   const char *name, TABLE *table,
713
 
                                   Item_field *item, uint convert_blob_length);
714
 
                                                                      
715
 
/* functions from opt_sum.cc */
716
 
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order);
717
 
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
718
 
 
719
 
/* from sql_delete.cc, used by opt_range.cc */
720
 
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
721
 
 
722
 
/** class to copying an field/item to a key struct */
723
 
 
724
 
class store_key :public Sql_alloc
725
 
{
726
 
public:
727
 
  bool null_key; /* true <=> the value of the key has a null part */
728
 
  enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
729
 
  store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
730
 
    :null_key(0), null_ptr(null), err(0)
731
 
  {
732
 
    if (field_arg->type() == DRIZZLE_TYPE_BLOB)
733
 
    {
734
 
      /* 
735
 
        Key segments are always packed with a 2 byte length prefix.
736
 
        See mi_rkey for details.
737
 
      */
738
 
      to_field= new Field_varstring(ptr, length, 2, null, 1, 
739
 
                                    Field::NONE, field_arg->field_name,
740
 
                                    field_arg->table->s, field_arg->charset());
741
 
      to_field->init(field_arg->table);
742
 
    }
743
 
    else
744
 
      to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
745
 
                                        ptr, null, 1);
746
 
  }
747
 
  virtual ~store_key() {}                       /** Not actually needed */
748
 
  virtual const char *name() const=0;
749
 
 
750
 
  /**
751
 
    @brief sets ignore truncation warnings mode and calls the real copy method
752
 
 
753
 
    @details this function makes sure truncation warnings when preparing the
754
 
    key buffers don't end up as errors (because of an enclosing INSERT/UPDATE).
755
 
  */
756
 
  enum store_key_result copy()
757
 
  {
758
 
    enum store_key_result result;
759
 
    THD *thd= to_field->table->in_use;
760
 
    enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields;
761
 
 
762
 
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
763
 
 
764
 
    result= copy_inner();
765
 
 
766
 
    thd->count_cuted_fields= saved_count_cuted_fields;
767
 
 
768
 
    return result;
769
 
  }
770
 
 
771
 
 protected:
772
 
  Field *to_field;                              // Store data here
773
 
  uchar *null_ptr;
774
 
  uchar err;
775
 
 
776
 
  virtual enum store_key_result copy_inner()=0;
777
 
};
778
 
 
779
 
 
780
 
class store_key_field: public store_key
781
 
{
782
 
  Copy_field copy_field;
783
 
  const char *field_name;
784
 
 public:
785
 
  store_key_field(THD *thd, Field *to_field_arg, uchar *ptr,
786
 
                  uchar *null_ptr_arg,
787
 
                  uint length, Field *from_field, const char *name_arg)
788
 
    :store_key(thd, to_field_arg,ptr,
789
 
               null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err
790
 
               : (uchar*) 0, length), field_name(name_arg)
791
 
  {
792
 
    if (to_field)
793
 
    {
794
 
      copy_field.set(to_field,from_field,0);
795
 
    }
796
 
  }
797
 
  const char *name() const { return field_name; }
798
 
 
799
 
 protected: 
800
 
  enum store_key_result copy_inner()
801
 
  {
802
 
    TABLE *table= copy_field.to_field->table;
803
 
    my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
804
 
                                                     table->write_set);
805
 
    copy_field.do_copy(&copy_field);
806
 
    dbug_tmp_restore_column_map(table->write_set, old_map);
807
 
    null_key= to_field->is_null();
808
 
    return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK;
809
 
  }
810
 
};
811
 
 
812
 
 
813
 
class store_key_item :public store_key
814
 
{
815
 
 protected:
816
 
  Item *item;
817
 
public:
818
 
  store_key_item(THD *thd, Field *to_field_arg, uchar *ptr,
819
 
                 uchar *null_ptr_arg, uint length, Item *item_arg)
820
 
    :store_key(thd, to_field_arg, ptr,
821
 
               null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
822
 
               &err : (uchar*) 0, length), item(item_arg)
823
 
  {}
824
 
  const char *name() const { return "func"; }
825
 
 
826
 
 protected:  
827
 
  enum store_key_result copy_inner()
828
 
  {
829
 
    TABLE *table= to_field->table;
830
 
    my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
831
 
                                                     table->write_set);
832
 
    int res= item->save_in_field(to_field, 1);
833
 
    dbug_tmp_restore_column_map(table->write_set, old_map);
834
 
    null_key= to_field->is_null() || item->null_value;
835
 
    return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res); 
836
 
  }
837
 
};
838
 
 
839
 
 
840
 
class store_key_const_item :public store_key_item
841
 
{
842
 
  bool inited;
843
 
public:
844
 
  store_key_const_item(THD *thd, Field *to_field_arg, uchar *ptr,
845
 
                       uchar *null_ptr_arg, uint length,
846
 
                       Item *item_arg)
847
 
    :store_key_item(thd, to_field_arg,ptr,
848
 
                    null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
849
 
                    &err : (uchar*) 0, length, item_arg), inited(0)
850
 
  {
851
 
  }
852
 
  const char *name() const { return "const"; }
853
 
 
854
 
protected:  
855
 
  enum store_key_result copy_inner()
856
 
  {
857
 
    int res;
858
 
    if (!inited)
859
 
    {
860
 
      inited=1;
861
 
      if ((res= item->save_in_field(to_field, 1)))
862
 
      {       
863
 
        if (!err)
864
 
          err= res;
865
 
      }
866
 
    }
867
 
    null_key= to_field->is_null() || item->null_value;
868
 
    return (err > 2 ?  STORE_KEY_FATAL : (store_key_result) err);
869
 
  }
870
 
};
871
 
 
872
 
bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref);
873
 
bool error_if_full_join(JOIN *join);
874
 
int report_error(TABLE *table, int error);
875
 
int safe_index_read(JOIN_TAB *tab);
876
 
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
 
99
Field* create_tmp_field_from_field(Session *session, Field* org_field,
 
100
                                   const char *name, Table *table,
 
101
                                   Item_field *item, uint32_t convert_blob_length);
 
102
bool test_if_ref(Item_field *left_item,Item *right_item);
 
103
COND *optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value);
 
104
COND *make_cond_for_table(COND *cond,table_map table, table_map used_table, bool exclude_expensive_cond);
 
105
COND* substitute_for_best_equal_field(COND *cond, COND_EQUAL *cond_equal, void *table_join_idx);
 
106
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data);
 
107
bool find_field_in_order_list (Field *field, void *data);
 
108
bool find_field_in_item_list (Field *field, void *data);
 
109
bool test_if_skip_sort_order(JoinTable *tab,order_st *order,ha_rows select_limit, bool no_changes, const key_map *map);
 
110
order_st *create_distinct_group(Session *session,
 
111
                                Item **ref_pointer_array,
 
112
                                order_st *order_list,
 
113
                                List<Item> &fields,
 
114
                                List<Item> &,
 
115
                                bool *all_order_by_fields_used);
 
116
// Create list for using with tempory table
 
117
bool change_to_use_tmp_fields(Session *session,
 
118
                              Item **ref_pointer_array,
 
119
                                                List<Item> &res_selected_fields,
 
120
                                                List<Item> &res_all_fields,
 
121
                                                uint32_t elements,
 
122
                              List<Item> &all_fields);
 
123
int do_select(JOIN *join, List<Item> *fields, Table *tmp_table);
 
124
bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
 
125
int create_sort_index(Session *session, JOIN *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by);
 
126
void save_index_subquery_explain_info(JoinTable *join_tab, Item* where);
 
127
Item *remove_additional_cond(Item* conds);
 
128
bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
 
129
bool init_sum_functions(Item_sum **func, Item_sum **end);
 
130
bool update_sum_func(Item_sum **func);
 
131
void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
 
132
bool change_refs_to_tmp_fields(Session *session,
 
133
                               Item **ref_pointer_array,
 
134
                               List<Item> &res_selected_fields,
 
135
                               List<Item> &res_all_fields,
 
136
                               uint32_t elements,
 
137
                                                 List<Item> &all_fields);
 
138
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed);
 
139
bool check_interleaving_with_nj(JoinTable *last, JoinTable *next);
 
140
 
 
141
int join_read_const_table(JoinTable *tab, drizzled::optimizer::Position *pos);
 
142
int join_read_system(JoinTable *tab);
 
143
int join_read_const(JoinTable *tab);
 
144
int join_read_key(JoinTable *tab);
 
145
int join_read_always_key(JoinTable *tab);
 
146
int join_read_last_key(JoinTable *tab);
 
147
int join_no_more_records(READ_RECORD *info);
 
148
int join_read_next(READ_RECORD *info);
 
149
int join_read_next_different(READ_RECORD *info);
 
150
int join_init_quick_read_record(JoinTable *tab);
 
151
int init_read_record_seq(JoinTable *tab);
 
152
int test_if_quick_select(JoinTable *tab);
 
153
int join_init_read_record(JoinTable *tab);
 
154
int join_read_first(JoinTable *tab);
 
155
int join_read_next_same(READ_RECORD *info);
 
156
int join_read_next_same_diff(READ_RECORD *info);
 
157
int join_read_last(JoinTable *tab);
 
158
int join_read_prev_same(READ_RECORD *info);
 
159
int join_read_prev(READ_RECORD *info);
 
160
int join_read_always_key_or_null(JoinTable *tab);
 
161
int join_read_next_same_or_null(READ_RECORD *info);
 
162
 
 
163
void calc_used_field_length(Session *, JoinTable *join_tab);
 
164
StoredKey *get_store_key(Session *session, 
 
165
                         drizzled::optimizer::KeyUse *keyuse,
 
166
                         table_map used_tables,
 
167
                         KEY_PART_INFO *key_part,
 
168
                         unsigned char *key_buff,
 
169
                         uint32_t maybe_null);
 
170
extern "C" int join_tab_cmp(const void* ptr1, const void* ptr2);
 
171
extern "C" int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
 
172
void push_index_cond(JoinTable *tab, uint32_t keyno, bool other_tbls_ok);
 
173
void add_not_null_conds(JOIN *join);
 
174
uint32_t max_part_bit(key_part_map bits);
 
175
COND *add_found_match_trig_cond(JoinTable *tab, COND *cond, JoinTable *root_tab);
 
176
order_st *create_distinct_group(Session *session,
 
177
                                Item **ref_pointer_array,
 
178
                                order_st *order,
 
179
                                List<Item> &fields,
 
180
                                List<Item> &all_fields,
 
181
                                bool *all_order_by_fields_used);
 
182
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab);
 
183
int join_tab_cmp(const void* ptr1, const void* ptr2);
 
184
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having);
 
185
int remove_dup_with_hash_index(Session *session, 
 
186
                               Table *table,
 
187
                               uint32_t field_count,
 
188
                               Field **first_field,
 
189
                               uint32_t key_length,
 
190
                               Item *having);
 
191
bool update_ref_and_keys(Session *session,
 
192
                         DYNAMIC_ARRAY *keyuse,
 
193
                         JoinTable *join_tab,
 
194
                         uint32_t tables,
 
195
                         COND *cond, 
 
196
                         COND_EQUAL *,
 
197
                         table_map normal_tables,
 
198
                         Select_Lex *select_lex,
 
199
                         std::vector<drizzled::optimizer::SargableParam> &sargables);
 
200
ha_rows get_quick_record_count(Session *session, drizzled::optimizer::SqlSelect *select, Table *table, const key_map *keys,ha_rows limit);
 
201
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
 
202
void add_group_and_distinct_keys(JOIN *join, JoinTable *join_tab);
 
203
void read_cached_record(JoinTable *tab);
 
204
bool mysql_select(Session *session, Item ***rref_pointer_array,
 
205
                  TableList *tables, uint32_t wild_num,  List<Item> &list,
 
206
                  COND *conds, uint32_t og_num, order_st *order, order_st *group,
 
207
                  Item *having, uint64_t select_type,
 
208
                  select_result *result, Select_Lex_Unit *unit,
 
209
                  Select_Lex *select_lex);
 
210
// Create list for using with tempory table
 
211
void init_tmptable_sum_functions(Item_sum **func);
 
212
void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
 
213
bool only_eq_ref_tables(JOIN *join, order_st *order, table_map tables);
 
214
bool create_ref_for_key(JOIN *join, JoinTable *j, 
 
215
                        drizzled::optimizer::KeyUse *org_keyuse, 
 
216
                        table_map used_tables);
 
217
 
 
218
#include "drizzled/stored_key.h"
 
219
 
 
220
bool cp_buffer_from_ref(Session *session, table_reference_st *ref);
 
221
int safe_index_read(JoinTable *tab);
 
222
COND *remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value);
877
223
int test_if_item_cache_changed(List<Cached_item> &list);
 
224
 
 
225
void print_join(Session *session, String *str,
 
226
                List<TableList> *tables, enum_query_type);
 
227
 
 
228
#endif /* DRIZZLED_SQL_SELECT_H */