The world's most popular open source database
00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* classes to use when handling where clause */ 00019 00020 #ifdef USE_PRAGMA_INTERFACE 00021 #pragma interface /* gcc class implementation */ 00022 #endif 00023 00024 #include "procedure.h" 00025 #include <myisam.h> 00026 00027 typedef struct keyuse_t { 00028 TABLE *table; 00029 Item *val; /* or value if no field */ 00030 table_map used_tables; 00031 uint key, keypart, optimize; 00032 key_part_map keypart_map; 00033 ha_rows ref_table_rows; 00034 /* 00035 If true, the comparison this value was created from will not be 00036 satisfied if val has NULL 'value'. 00037 */ 00038 bool null_rejecting; 00039 } KEYUSE; 00040 00041 class store_key; 00042 00043 typedef struct st_table_ref 00044 { 00045 bool key_err; 00046 uint key_parts; // num of ... 00047 uint key_length; // length of key_buff 00048 int key; // key no 00049 byte *key_buff; // value to look for with key 00050 byte *key_buff2; // key_buff+key_length 00051 store_key **key_copy; // 00052 Item **items; // val()'s for each keypart 00053 /* 00054 (null_rejecting & (1<<i)) means the condition is '=' and no matching 00055 rows will be produced if items[i] IS NULL (see add_not_null_conds()) 00056 */ 00057 key_part_map null_rejecting; 00058 table_map depend_map; // Table depends on these tables. 00059 /* null byte position in the key_buf. Used for REF_OR_NULL optimization */ 00060 byte *null_ref_key; 00061 } TABLE_REF; 00062 00063 00064 /* 00065 CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer 00066 table 00067 */ 00068 00069 typedef struct st_cache_field { 00070 char *str; 00071 uint length,blob_length; 00072 Field_blob *blob_field; 00073 bool strip; 00074 } CACHE_FIELD; 00075 00076 00077 typedef struct st_join_cache { 00078 uchar *buff,*pos,*end; 00079 uint records,record_nr,ptr_record,fields,length,blobs; 00080 CACHE_FIELD *field,**blob_ptr; 00081 SQL_SELECT *select; 00082 } JOIN_CACHE; 00083 00084 00085 /* 00086 The structs which holds the join connections and join states 00087 */ 00088 enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF, 00089 JT_ALL, JT_RANGE, JT_NEXT, JT_FT, JT_REF_OR_NULL, 00090 JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE}; 00091 00092 class JOIN; 00093 00094 enum enum_nested_loop_state 00095 { 00096 NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1, 00097 NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1, 00098 NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4 00099 }; 00100 00101 typedef enum_nested_loop_state 00102 (*Next_select_func)(JOIN *, struct st_join_table *, bool); 00103 typedef int (*Read_record_func)(struct st_join_table *tab); 00104 Next_select_func setup_end_select_func(JOIN *join); 00105 00106 00107 typedef struct st_join_table { 00108 st_join_table() {} /* Remove gcc warning */ 00109 TABLE *table; 00110 KEYUSE *keyuse; /* pointer to first used key */ 00111 SQL_SELECT *select; 00112 COND *select_cond; 00113 QUICK_SELECT_I *quick; 00114 Item **on_expr_ref; /* pointer to the associated on expression */ 00115 COND_EQUAL *cond_equal; /* multiple equalities for the on expression */ 00116 st_join_table *first_inner; /* first inner table for including outerjoin */ 00117 bool found; /* true after all matches or null complement */ 00118 bool not_null_compl;/* true before null complement is added */ 00119 st_join_table *last_inner; /* last table table for embedding outer join */ 00120 st_join_table *first_upper; /* first inner table for embedding outer join */ 00121 st_join_table *first_unmatched; /* used for optimization purposes only */ 00122 const char *info; 00123 Read_record_func read_first_record; 00124 Next_select_func next_select; 00125 READ_RECORD read_record; 00126 double worst_seeks; 00127 key_map const_keys; /* Keys with constant part */ 00128 key_map checked_keys; /* Keys checked in find_best */ 00129 key_map needed_reg; 00130 key_map keys; /* all keys with can be used */ 00131 00132 /* Either #rows in the table or 1 for const table. */ 00133 ha_rows records; 00134 /* 00135 Number of records that will be scanned (yes scanned, not returned) by the 00136 best 'independent' access method, i.e. table scan or QUICK_*_SELECT) 00137 */ 00138 ha_rows found_records; 00139 /* 00140 Cost of accessing the table using "ALL" or range/index_merge access 00141 method (but not 'index' for some reason), i.e. this matches method which 00142 E(#records) is in found_records. 00143 */ 00144 ha_rows read_time; 00145 00146 table_map dependent,key_dependent; 00147 uint use_quick,index; 00148 uint status; // Save status for cache 00149 uint used_fields,used_fieldlength,used_blobs; 00150 enum join_type type; 00151 bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; 00152 bool sorted; 00153 TABLE_REF ref; 00154 JOIN_CACHE cache; 00155 JOIN *join; 00156 /* Bitmap of nested joins this table is part of */ 00157 nested_join_map embedding_map; 00158 00159 void cleanup(); 00160 inline bool is_using_loose_index_scan() 00161 { 00162 return (select && select->quick && 00163 (select->quick->get_type() == 00164 QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)); 00165 } 00166 } JOIN_TAB; 00167 00168 enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool 00169 end_of_records); 00170 enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool 00171 end_of_records); 00172 00173 /* 00174 Information about a position of table within a join order. Used in join 00175 optimization. 00176 */ 00177 typedef struct st_position 00178 { 00179 double records_read; 00180 /* 00181 Cost accessing the table in course of the entire complete join execution, 00182 i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times 00183 number the access method will be invoked. 00184 */ 00185 double read_time; 00186 JOIN_TAB *table; 00187 KEYUSE *key; 00188 } POSITION; 00189 00190 00191 typedef struct st_rollup 00192 { 00193 enum State { STATE_NONE, STATE_INITED, STATE_READY }; 00194 State state; 00195 Item_null_result **null_items; 00196 Item ***ref_pointer_arrays; 00197 List<Item> *fields; 00198 } ROLLUP; 00199 00200 00201 class JOIN :public Sql_alloc 00202 { 00203 JOIN(const JOIN &rhs); /* not implemented */ 00204 JOIN& operator=(const JOIN &rhs); /* not implemented */ 00205 public: 00206 JOIN_TAB *join_tab,**best_ref; 00207 JOIN_TAB **map2table; // mapping between table indexes and JOIN_TABs 00208 JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution 00209 TABLE **table,**all_tables,*sort_by_table; 00210 uint tables,const_tables; 00211 uint send_group_parts; 00212 bool sort_and_group,first_record,full_join,group, no_field_update; 00213 bool do_send_rows; 00214 /* 00215 TRUE when we want to resume nested loop iterations when 00216 fetching data from a cursor 00217 */ 00218 bool resume_nested_loop; 00219 table_map const_table_map,found_const_table_map,outer_join; 00220 ha_rows send_records,found_records,examined_rows,row_limit, select_limit; 00221 /* 00222 Used to fetch no more than given amount of rows per one 00223 fetch operation of server side cursor. 00224 The value is checked in end_send and end_send_group in fashion, similar 00225 to offset_limit_cnt: 00226 - fetch_limit= HA_POS_ERROR if there is no cursor. 00227 - when we open a cursor, we set fetch_limit to 0, 00228 - on each fetch iteration we add num_rows to fetch to fetch_limit 00229 */ 00230 ha_rows fetch_limit; 00231 POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; 00232 00233 /* 00234 Bitmap of nested joins embedding the position at the end of the current 00235 partial join (valid only during join optimizer run). 00236 */ 00237 nested_join_map cur_embedding_map; 00238 00239 double best_read; 00240 List<Item> *fields; 00241 List<Cached_item> group_fields, group_fields_cache; 00242 TABLE *tmp_table; 00243 // used to store 2 possible tmp table of SELECT 00244 TABLE *exec_tmp_table1, *exec_tmp_table2; 00245 THD *thd; 00246 Item_sum **sum_funcs, ***sum_funcs_end; 00247 /* second copy of sumfuncs (for queries with 2 temporary tables */ 00248 Item_sum **sum_funcs2, ***sum_funcs_end2; 00249 Procedure *procedure; 00250 Item *having; 00251 Item *tmp_having; // To store having when processed temporary table 00252 Item *having_history; // Store having for explain 00253 ulonglong select_options; 00254 select_result *result; 00255 TMP_TABLE_PARAM tmp_table_param; 00256 MYSQL_LOCK *lock; 00257 // unit structure (with global parameters) for this select 00258 SELECT_LEX_UNIT *unit; 00259 // select that processed 00260 SELECT_LEX *select_lex; 00261 00262 JOIN *tmp_join; // copy of this JOIN to be used with temporary tables 00263 ROLLUP rollup; // Used with rollup 00264 00265 bool select_distinct; // Set if SELECT DISTINCT 00266 00267 /* 00268 simple_xxxxx is set if ORDER/GROUP BY doesn't include any references 00269 to other tables than the first non-constant table in the JOIN. 00270 It's also set if ORDER/GROUP BY is empty. 00271 */ 00272 bool simple_order, simple_group; 00273 /* 00274 Is set only in case if we have a GROUP BY clause 00275 and no ORDER BY after constant elimination of 'order'. 00276 */ 00277 bool no_order; 00278 /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ 00279 bool skip_sort_order; 00280 00281 bool need_tmp, hidden_group_fields; 00282 DYNAMIC_ARRAY keyuse; 00283 Item::cond_result cond_value; 00284 List<Item> all_fields; // to store all fields that used in query 00285 //Above list changed to use temporary table 00286 List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3; 00287 //Part, shared with list above, emulate following list 00288 List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3; 00289 List<Item> &fields_list; // hold field list passed to mysql_select 00290 List<Item> procedure_fields_list; 00291 int error; 00292 00293 ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select 00294 COND *conds; // ---"--- 00295 Item *conds_history; // store WHERE for explain 00296 TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select 00297 List<TABLE_LIST> *join_list; // list of joined tables in reverse order 00298 COND_EQUAL *cond_equal; 00299 SQL_SELECT *select; //created in optimisation phase 00300 JOIN_TAB *return_tab; //used only for outer joins 00301 Item **ref_pointer_array; //used pointer reference for this select 00302 // Copy of above to be used with different lists 00303 Item **items0, **items1, **items2, **items3, **current_ref_pointer_array; 00304 uint ref_pointer_array_size; // size of above in bytes 00305 const char *zero_result_cause; // not 0 if exec must return zero result 00306 00307 bool union_part; // this subselect is part of union 00308 bool optimized; // flag to avoid double optimization in EXPLAIN 00309 00310 JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg, 00311 select_result *result_arg) 00312 :fields_list(fields_arg) 00313 { 00314 init(thd_arg, fields_arg, select_options_arg, result_arg); 00315 } 00316 00317 void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg, 00318 select_result *result_arg) 00319 { 00320 join_tab= join_tab_save= 0; 00321 table= 0; 00322 tables= 0; 00323 const_tables= 0; 00324 join_list= 0; 00325 sort_and_group= 0; 00326 first_record= 0; 00327 do_send_rows= 1; 00328 resume_nested_loop= FALSE; 00329 send_records= 0; 00330 found_records= 0; 00331 fetch_limit= HA_POS_ERROR; 00332 examined_rows= 0; 00333 exec_tmp_table1= 0; 00334 exec_tmp_table2= 0; 00335 thd= thd_arg; 00336 sum_funcs= sum_funcs2= 0; 00337 procedure= 0; 00338 having= tmp_having= having_history= 0; 00339 select_options= select_options_arg; 00340 result= result_arg; 00341 lock= thd_arg->lock; 00342 select_lex= 0; //for safety 00343 tmp_join= 0; 00344 select_distinct= test(select_options & SELECT_DISTINCT); 00345 no_order= 0; 00346 simple_order= 0; 00347 simple_group= 0; 00348 skip_sort_order= 0; 00349 need_tmp= 0; 00350 hidden_group_fields= 0; /*safety*/ 00351 error= 0; 00352 select= 0; 00353 return_tab= 0; 00354 ref_pointer_array= items0= items1= items2= items3= 0; 00355 ref_pointer_array_size= 0; 00356 zero_result_cause= 0; 00357 optimized= 0; 00358 cond_equal= 0; 00359 00360 all_fields= fields_arg; 00361 fields_list= fields_arg; 00362 bzero((char*) &keyuse,sizeof(keyuse)); 00363 tmp_table_param.init(); 00364 tmp_table_param.end_write_records= HA_POS_ERROR; 00365 rollup.state= ROLLUP::STATE_NONE; 00366 } 00367 00368 int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, 00369 COND *conds, uint og_num, ORDER *order, ORDER *group, 00370 Item *having, ORDER *proc_param, SELECT_LEX *select, 00371 SELECT_LEX_UNIT *unit); 00372 int optimize(); 00373 int reinit(); 00374 void exec(); 00375 int destroy(); 00376 void restore_tmp(); 00377 bool alloc_func_list(); 00378 bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields, 00379 bool before_group_by, bool recompute= FALSE); 00380 00381 inline void set_items_ref_array(Item **ptr) 00382 { 00383 memcpy((char*) ref_pointer_array, (char*) ptr, ref_pointer_array_size); 00384 current_ref_pointer_array= ptr; 00385 } 00386 inline void init_items_ref_array() 00387 { 00388 items0= ref_pointer_array + all_fields.elements; 00389 memcpy(items0, ref_pointer_array, ref_pointer_array_size); 00390 current_ref_pointer_array= items0; 00391 } 00392 00393 bool rollup_init(); 00394 bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields, 00395 Item_sum ***func); 00396 int rollup_send_data(uint idx); 00397 int rollup_write_data(uint idx, TABLE *table); 00398 bool test_in_subselect(Item **where); 00399 /* 00400 Release memory and, if possible, the open tables held by this execution 00401 plan (and nested plans). It's used to release some tables before 00402 the end of execution in order to increase concurrency and reduce 00403 memory consumption. 00404 */ 00405 void join_free(); 00406 /* Cleanup this JOIN, possibly for reuse */ 00407 void cleanup(bool full); 00408 void clear(); 00409 bool save_join_tab(); 00410 bool send_row_on_empty_set() 00411 { 00412 return (do_send_rows && tmp_table_param.sum_func_count != 0 && 00413 !group_list); 00414 } 00415 bool change_result(select_result *result); 00416 bool is_top_level_join() const 00417 { 00418 return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 || 00419 select_lex == unit->fake_select_lex)); 00420 } 00421 }; 00422 00423 00424 typedef struct st_select_check { 00425 uint const_ref,reg_ref; 00426 } SELECT_CHECK; 00427 00428 extern const char *join_type_str[]; 00429 void TEST_join(JOIN *join); 00430 00431 /* Extern functions in sql_select.cc */ 00432 bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag); 00433 TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, 00434 ORDER *group, bool distinct, bool save_sum_fields, 00435 ulonglong select_options, ha_rows rows_limit, 00436 char* alias); 00437 void free_tmp_table(THD *thd, TABLE *entry); 00438 void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, 00439 bool reset_with_sum_func); 00440 bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, 00441 Item **ref_pointer_array, 00442 List<Item> &new_list1, List<Item> &new_list2, 00443 uint elements, List<Item> &fields); 00444 void copy_fields(TMP_TABLE_PARAM *param); 00445 void copy_funcs(Item **func_ptr); 00446 bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, 00447 int error, bool ignore_last_dupp_error); 00448 uint find_shortest_key(TABLE *table, const key_map *usable_keys); 00449 Field* create_tmp_field_from_field(THD *thd, Field* org_field, 00450 const char *name, TABLE *table, 00451 Item_field *item, uint convert_blob_length); 00452 00453 /* functions from opt_sum.cc */ 00454 bool simple_pred(Item_func *func_item, Item **args, bool *inv_order); 00455 int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds); 00456 00457 /* from sql_delete.cc, used by opt_range.cc */ 00458 extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b); 00459 00460 /* class to copying an field/item to a key struct */ 00461 00462 class store_key :public Sql_alloc 00463 { 00464 protected: 00465 Field *to_field; // Store data here 00466 char *null_ptr; 00467 char err; 00468 public: 00469 enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV }; 00470 store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length) 00471 :null_ptr(null),err(0) 00472 { 00473 if (field_arg->type() == FIELD_TYPE_BLOB) 00474 { 00475 /* Key segments are always packed with a 2 byte length prefix */ 00476 to_field= new Field_varstring(ptr, length, 2, (uchar*) null, 1, 00477 Field::NONE, field_arg->field_name, 00478 field_arg->table->s, field_arg->charset()); 00479 to_field->init(field_arg->table); 00480 } 00481 else 00482 to_field=field_arg->new_key_field(thd->mem_root, field_arg->table, 00483 ptr, (uchar*) null, 1); 00484 } 00485 virtual ~store_key() {} /* Not actually needed */ 00486 virtual enum store_key_result copy()=0; 00487 virtual const char *name() const=0; 00488 }; 00489 00490 00491 class store_key_field: public store_key 00492 { 00493 Copy_field copy_field; 00494 const char *field_name; 00495 public: 00496 store_key_field(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg, 00497 uint length, Field *from_field, const char *name_arg) 00498 :store_key(thd, to_field_arg,ptr, 00499 null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err 00500 : NullS,length), field_name(name_arg) 00501 { 00502 if (to_field) 00503 { 00504 copy_field.set(to_field,from_field,0); 00505 } 00506 } 00507 enum store_key_result copy() 00508 { 00509 TABLE *table= copy_field.to_field->table; 00510 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, 00511 table->write_set); 00512 copy_field.do_copy(©_field); 00513 dbug_tmp_restore_column_map(table->write_set, old_map); 00514 return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK; 00515 } 00516 const char *name() const { return field_name; } 00517 }; 00518 00519 00520 class store_key_item :public store_key 00521 { 00522 protected: 00523 Item *item; 00524 public: 00525 store_key_item(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg, 00526 uint length, Item *item_arg) 00527 :store_key(thd, to_field_arg,ptr, 00528 null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? 00529 &err : NullS, length), item(item_arg) 00530 {} 00531 enum store_key_result copy() 00532 { 00533 TABLE *table= to_field->table; 00534 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, 00535 table->write_set); 00536 int res= item->save_in_field(to_field, 1); 00537 dbug_tmp_restore_column_map(table->write_set, old_map); 00538 return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res); 00539 00540 } 00541 const char *name() const { return "func"; } 00542 }; 00543 00544 00545 class store_key_const_item :public store_key_item 00546 { 00547 bool inited; 00548 public: 00549 store_key_const_item(THD *thd, Field *to_field_arg, char *ptr, 00550 char *null_ptr_arg, uint length, 00551 Item *item_arg) 00552 :store_key_item(thd, to_field_arg,ptr, 00553 null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? 00554 &err : NullS, length, item_arg), inited(0) 00555 { 00556 } 00557 enum store_key_result copy() 00558 { 00559 int res; 00560 if (!inited) 00561 { 00562 inited=1; 00563 if ((res= item->save_in_field(to_field, 1))) 00564 { 00565 if (!err) 00566 err= res; 00567 } 00568 } 00569 return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); 00570 } 00571 const char *name() const { return "const"; } 00572 }; 00573 00574 bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref); 00575 bool error_if_full_join(JOIN *join); 00576 int report_error(TABLE *table, int error); 00577 int safe_index_read(JOIN_TAB *tab); 00578 COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
1.4.7

