MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_executor.h
1 #ifndef SQL_EXECUTOR_INCLUDED
2 #define SQL_EXECUTOR_INCLUDED
3 
4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
21 #include "records.h" /* READ_RECORD */
22 
23 class JOIN;
24 typedef struct st_join_table JOIN_TAB;
25 typedef struct st_table_ref TABLE_REF;
26 typedef struct st_position POSITION;
27 
33 enum enum_nested_loop_state
34 {
39  NESTED_LOOP_KILLED= -2,
41  NESTED_LOOP_ERROR= -1,
43  NESTED_LOOP_OK= 0,
48  NESTED_LOOP_QUERY_LIMIT= 3,
54  NESTED_LOOP_CURSOR_LIMIT= 4
55 };
56 
57 
58 typedef enum_nested_loop_state
59 (*Next_select_func)(JOIN *, struct st_join_table *, bool);
60 
61 /*
62  Temporary table used by semi-join DuplicateElimination strategy
63 
64  This consists of the temptable itself and data needed to put records
65  into it. The table's DDL is as follows:
66 
67  CREATE TABLE tmptable (col VARCHAR(n) BINARY, PRIMARY KEY(col));
68 
69  where the primary key can be replaced with unique constraint if n exceeds
70  the limit (as it is always done for query execution-time temptables).
71 
72  The record value is a concatenation of rowids of tables from the join we're
73  executing. If a join table is on the inner side of the outer join, we
74  assume that its rowid can be NULL and provide means to store this rowid in
75  the tuple.
76 */
77 
78 class SJ_TMP_TABLE : public Sql_alloc
79 {
80 public:
81  /*
82  Array of pointers to tables whose rowids compose the temporary table
83  record.
84  */
85  class TAB
86  {
87  public:
88  JOIN_TAB *join_tab;
89  uint rowid_offset;
90  ushort null_byte;
91  uchar null_bit;
92  };
93  TAB *tabs;
94  TAB *tabs_end;
95 
96  /*
97  is_confluent==TRUE means this is a special case where the temptable record
98  has zero length (and presence of a unique key means that the temptable can
99  have either 0 or 1 records).
100  In this case we don't create the physical temptable but instead record
101  its state in SJ_TMP_TABLE::have_confluent_record.
102  */
103  bool is_confluent;
104 
105  /*
106  When is_confluent==TRUE: the contents of the table (whether it has the
107  record or not).
108  */
109  bool have_confluent_row;
110 
111  /* table record parameters */
112  uint null_bits;
113  uint null_bytes;
114  uint rowid_len;
115 
116  /* The temporary table itself (NULL means not created yet) */
117  TABLE *tmp_table;
118 
119  /*
120  These are the members we got from temptable creation code. We'll need
121  them if we'll need to convert table from HEAP to MyISAM/Maria.
122  */
123  MI_COLUMNDEF *start_recinfo;
124  MI_COLUMNDEF *recinfo;
125 
126  /* Pointer to next table (next->start_idx > this->end_idx) */
127  SJ_TMP_TABLE *next;
128 };
129 
130 
137 {
138 public:
141  :sj_nest(sj_nest), is_scan(is_scan), table_count(table_count),
142  mat_table_index(mat_table_index), inner_table_index(inner_table_index),
143  table_param(), table(NULL)
144  {}
146  {}
148  const bool is_scan;
149  const uint table_count;
150  const uint mat_table_index;
151  const uint inner_table_index;
152  TMP_TABLE_PARAM table_param;
154 };
155 
156 
157 
177 {
178 public:
179  // Type of the operation
180  enum enum_op_type { OT_CACHE, OT_TMP_TABLE };
187 
188  QEP_operation(): join_tab(NULL) {};
189  QEP_operation(JOIN_TAB *tab): join_tab(tab) {};
190  virtual ~QEP_operation() {};
191  virtual enum_op_type type()= 0;
195  virtual int init() { return 0; };
201  virtual enum_nested_loop_state put_record()= 0;
205  virtual enum_nested_loop_state end_send()= 0;
209  virtual void free() {};
210 };
211 
212 
235 {
236 public:
237  QEP_tmp_table(JOIN_TAB *tab) : QEP_operation(tab),
238  write_func(NULL)
239  {};
240  enum_op_type type() { return OT_TMP_TABLE; }
241  enum_nested_loop_state put_record() { return put_record(false); };
242  /*
243  Send the result of operation further (to a next operation/client)
244  This function is called after all records were put into the buffer
245  (determined by the caller).
246 
247  @return return one of enum_nested_loop_state values.
248  */
249  enum_nested_loop_state end_send();
251  void set_write_func(Next_select_func new_write_func)
252  {
253  write_func= new_write_func;
254  }
255 
256 private:
258  Next_select_func write_func;
259  enum_nested_loop_state put_record(bool end_of_records);
260  bool prepare_tmp_table();
261 };
262 
264 Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab);
265 enum_nested_loop_state sub_select_op(JOIN *join, JOIN_TAB *join_tab, bool
266  end_of_records);
267 enum_nested_loop_state end_send_group(JOIN *join, JOIN_TAB *join_tab,
268  bool end_of_records);
269 enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab,
270  bool end_of_records);
271 enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
272  end_of_records);
273 enum_nested_loop_state
274 evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, int error);
275 
276 
277 
278 void copy_fields(TMP_TABLE_PARAM *param);
279 bool copy_funcs(Item **func_ptr, const THD *thd);
280 bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref);
281 
283 int report_handler_error(TABLE *table, int error);
284 
285 int safe_index_read(JOIN_TAB *tab);
286 SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length,
287  SORT_FIELD *sortorder);
289 
290 int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
292 int join_init_quick_read_record(JOIN_TAB *tab);
294 int join_read_first(JOIN_TAB *tab);
295 int join_read_last(JOIN_TAB *tab);
296 int join_read_last_key(JOIN_TAB *tab);
297 int join_materialize_derived(JOIN_TAB *tab);
298 int join_materialize_semijoin(JOIN_TAB *tab);
299 int join_read_prev_same(READ_RECORD *info);
300 
301 int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl);
302 int test_if_item_cache_changed(List<Cached_item> &list);
303 
304 // Create list for using with tempory table
305 bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
306  List<Item> &new_list1,
307  List<Item> &new_list2,
308  uint elements, List<Item> &items);
309 // Create list for using with tempory table
310 bool change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
311  List<Item> &new_list1,
312  List<Item> &new_list2,
313  uint elements, List<Item> &items);
314 bool alloc_group_fields(JOIN *join, ORDER *group);
315 bool prepare_sum_aggregators(Item_sum **func_ptr, bool need_distinct);
316 bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
317 bool make_group_fields(JOIN *main_join, JOIN *curr_join);
318 bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
319  Ref_ptr_array ref_pointer_array,
320  List<Item> &res_selected_fields, List<Item> &res_all_fields,
321  uint elements, List<Item> &all_fields);
322 #endif /* SQL_EXECUTOR_INCLUDED */