~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.h

  • Committer: Lee
  • Date: 2009-01-01 03:07:33 UTC
  • mto: (758.1.3 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: lbieber@lbieber-desktop-20090101030733-fb411b55f07vij8q
more header file cleanup

Show diffs side-by-side

added added

removed removed

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