~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.h

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

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