My Project
sql_executor.h
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines