My Project
|
00001 #ifndef SQL_EXECUTOR_INCLUDED 00002 #define SQL_EXECUTOR_INCLUDED 00003 00004 /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights 00005 reserved. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; version 2 of the License. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00019 00022 #include "records.h" /* READ_RECORD */ 00023 00024 class JOIN; 00025 typedef struct st_join_table JOIN_TAB; 00026 typedef struct st_table_ref TABLE_REF; 00027 typedef struct st_position POSITION; 00028 00034 enum enum_nested_loop_state 00035 { 00040 NESTED_LOOP_KILLED= -2, 00042 NESTED_LOOP_ERROR= -1, 00044 NESTED_LOOP_OK= 0, 00049 NESTED_LOOP_QUERY_LIMIT= 3, 00055 NESTED_LOOP_CURSOR_LIMIT= 4 00056 }; 00057 00058 00059 typedef enum_nested_loop_state 00060 (*Next_select_func)(JOIN *, struct st_join_table *, bool); 00061 00062 /* 00063 Temporary table used by semi-join DuplicateElimination strategy 00064 00065 This consists of the temptable itself and data needed to put records 00066 into it. The table's DDL is as follows: 00067 00068 CREATE TABLE tmptable (col VARCHAR(n) BINARY, PRIMARY KEY(col)); 00069 00070 where the primary key can be replaced with unique constraint if n exceeds 00071 the limit (as it is always done for query execution-time temptables). 00072 00073 The record value is a concatenation of rowids of tables from the join we're 00074 executing. If a join table is on the inner side of the outer join, we 00075 assume that its rowid can be NULL and provide means to store this rowid in 00076 the tuple. 00077 */ 00078 00079 class SJ_TMP_TABLE : public Sql_alloc 00080 { 00081 public: 00082 /* 00083 Array of pointers to tables whose rowids compose the temporary table 00084 record. 00085 */ 00086 class TAB 00087 { 00088 public: 00089 JOIN_TAB *join_tab; 00090 uint rowid_offset; 00091 ushort null_byte; 00092 uchar null_bit; 00093 }; 00094 TAB *tabs; 00095 TAB *tabs_end; 00096 00097 /* 00098 is_confluent==TRUE means this is a special case where the temptable record 00099 has zero length (and presence of a unique key means that the temptable can 00100 have either 0 or 1 records). 00101 In this case we don't create the physical temptable but instead record 00102 its state in SJ_TMP_TABLE::have_confluent_record. 00103 */ 00104 bool is_confluent; 00105 00106 /* 00107 When is_confluent==TRUE: the contents of the table (whether it has the 00108 record or not). 00109 */ 00110 bool have_confluent_row; 00111 00112 /* table record parameters */ 00113 uint null_bits; 00114 uint null_bytes; 00115 uint rowid_len; 00116 00117 /* The temporary table itself (NULL means not created yet) */ 00118 TABLE *tmp_table; 00119 00120 /* 00121 These are the members we got from temptable creation code. We'll need 00122 them if we'll need to convert table from HEAP to MyISAM/Maria. 00123 */ 00124 MI_COLUMNDEF *start_recinfo; 00125 MI_COLUMNDEF *recinfo; 00126 00127 /* Pointer to next table (next->start_idx > this->end_idx) */ 00128 SJ_TMP_TABLE *next; 00129 }; 00130 00131 00137 class Semijoin_mat_exec : public Sql_alloc 00138 { 00139 public: 00140 Semijoin_mat_exec(TABLE_LIST *sj_nest, bool is_scan, uint table_count, 00141 uint mat_table_index, uint inner_table_index) 00142 :sj_nest(sj_nest), is_scan(is_scan), table_count(table_count), 00143 mat_table_index(mat_table_index), inner_table_index(inner_table_index), 00144 table_param(), table(NULL) 00145 {} 00146 ~Semijoin_mat_exec() 00147 {} 00148 TABLE_LIST *const sj_nest; 00149 const bool is_scan; 00150 const uint table_count; 00151 const uint mat_table_index; 00152 const uint inner_table_index; 00153 TMP_TABLE_PARAM table_param; 00154 TABLE *table; 00155 }; 00156 00157 00158 00177 class QEP_operation :public Sql_alloc 00178 { 00179 public: 00180 // Type of the operation 00181 enum enum_op_type { OT_CACHE, OT_TMP_TABLE }; 00187 JOIN_TAB *join_tab; 00188 00189 QEP_operation(): join_tab(NULL) {}; 00190 QEP_operation(JOIN_TAB *tab): join_tab(tab) {}; 00191 virtual ~QEP_operation() {}; 00192 virtual enum_op_type type()= 0; 00196 virtual int init() { return 0; }; 00202 virtual enum_nested_loop_state put_record()= 0; 00206 virtual enum_nested_loop_state end_send()= 0; 00210 virtual void free() {}; 00211 }; 00212 00213 00235 class QEP_tmp_table :public QEP_operation 00236 { 00237 public: 00238 QEP_tmp_table(JOIN_TAB *tab) : QEP_operation(tab), 00239 write_func(NULL) 00240 {}; 00241 enum_op_type type() { return OT_TMP_TABLE; } 00242 enum_nested_loop_state put_record() { return put_record(false); }; 00243 /* 00244 Send the result of operation further (to a next operation/client) 00245 This function is called after all records were put into the buffer 00246 (determined by the caller). 00247 00248 @return return one of enum_nested_loop_state values. 00249 */ 00250 enum_nested_loop_state end_send(); 00252 void set_write_func(Next_select_func new_write_func) 00253 { 00254 write_func= new_write_func; 00255 } 00256 00257 private: 00259 Next_select_func write_func; 00260 enum_nested_loop_state put_record(bool end_of_records); 00261 __attribute__((warn_unused_result)) 00262 bool prepare_tmp_table(); 00263 }; 00264 00265 void setup_tmptable_write_func(JOIN_TAB *tab); 00266 Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab); 00267 enum_nested_loop_state sub_select_op(JOIN *join, JOIN_TAB *join_tab, bool 00268 end_of_records); 00269 enum_nested_loop_state end_send_group(JOIN *join, JOIN_TAB *join_tab, 00270 bool end_of_records); 00271 enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab, 00272 bool end_of_records); 00273 enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool 00274 end_of_records); 00275 enum_nested_loop_state 00276 evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, int error); 00277 00278 00279 00280 void copy_fields(TMP_TABLE_PARAM *param); 00281 bool copy_funcs(Item **func_ptr, const THD *thd); 00282 bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref); 00283 00285 int report_handler_error(TABLE *table, int error); 00286 00287 int safe_index_read(JOIN_TAB *tab); 00288 SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length, 00289 SORT_FIELD *sortorder); 00290 void pick_table_access_method(JOIN_TAB *tab); 00291 00292 int join_read_const_table(JOIN_TAB *tab, POSITION *pos); 00293 void join_read_key_unlock_row(st_join_table *tab); 00294 int join_init_quick_read_record(JOIN_TAB *tab); 00295 int join_init_read_record(JOIN_TAB *tab); 00296 int join_read_first(JOIN_TAB *tab); 00297 int join_read_last(JOIN_TAB *tab); 00298 int join_read_last_key(JOIN_TAB *tab); 00299 int join_materialize_derived(JOIN_TAB *tab); 00300 int join_materialize_semijoin(JOIN_TAB *tab); 00301 int join_read_prev_same(READ_RECORD *info); 00302 00303 int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl); 00304 int test_if_item_cache_changed(List<Cached_item> &list); 00305 00306 // Create list for using with tempory table 00307 bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, 00308 List<Item> &new_list1, 00309 List<Item> &new_list2, 00310 uint elements, List<Item> &items); 00311 // Create list for using with tempory table 00312 bool change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, 00313 List<Item> &new_list1, 00314 List<Item> &new_list2, 00315 uint elements, List<Item> &items); 00316 bool alloc_group_fields(JOIN *join, ORDER *group); 00317 bool prepare_sum_aggregators(Item_sum **func_ptr, bool need_distinct); 00318 bool setup_sum_funcs(THD *thd, Item_sum **func_ptr); 00319 bool make_group_fields(JOIN *main_join, JOIN *curr_join); 00320 bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, 00321 Ref_ptr_array ref_pointer_array, 00322 List<Item> &res_selected_fields, List<Item> &res_all_fields, 00323 uint elements, List<Item> &all_fields); 00324 #endif /* SQL_EXECUTOR_INCLUDED */