~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.h

  • Committer: Mark Atwood
  • Date: 2011-12-28 02:50:31 UTC
  • Revision ID: me@mark.atwood.name-20111228025031-eh4h1zwv4ig88g0i
fix tests/r/basic.result

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