~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.h

  • Committer: Monty Taylor
  • Date: 2008-11-16 06:29:53 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116062953-ivdltjmfe009b5fr
Moved stuff into item/

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