00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00030 #include <config.h>
00031
00032 #include <float.h>
00033 #include <math.h>
00034
00035 #include <drizzled/item/cache.h>
00036 #include <drizzled/item/cmpfunc.h>
00037 #include <drizzled/item/copy_string.h>
00038 #include <drizzled/item/uint.h>
00039 #include <drizzled/cached_item.h>
00040 #include <drizzled/sql_base.h>
00041 #include <drizzled/sql_select.h>
00042 #include <drizzled/lock.h>
00043 #include <drizzled/nested_join.h>
00044 #include <drizzled/join.h>
00045 #include <drizzled/join_cache.h>
00046 #include <drizzled/show.h>
00047 #include <drizzled/field/blob.h>
00048 #include <drizzled/open_tables_state.h>
00049 #include <drizzled/optimizer/position.h>
00050 #include <drizzled/optimizer/sargable_param.h>
00051 #include <drizzled/optimizer/key_use.h>
00052 #include <drizzled/optimizer/range.h>
00053 #include <drizzled/optimizer/sum.h>
00054 #include <drizzled/optimizer/explain_plan.h>
00055 #include <drizzled/optimizer/access_method_factory.h>
00056 #include <drizzled/optimizer/access_method.h>
00057 #include <drizzled/records.h>
00058 #include <drizzled/probes.h>
00059 #include <drizzled/internal/my_bit.h>
00060 #include <drizzled/internal/my_sys.h>
00061 #include <drizzled/internal/iocache.h>
00062 #include <drizzled/plugin/storage_engine.h>
00063 #include <drizzled/session.h>
00064 #include <drizzled/select_result.h>
00065 #include <drizzled/debug.h>
00066 #include <drizzled/item/subselect.h>
00067 #include <drizzled/my_hash.h>
00068 #include <drizzled/sql_lex.h>
00069 #include <drizzled/statistics_variables.h>
00070 #include <drizzled/system_variables.h>
00071 #include <algorithm>
00072
00073 using namespace std;
00074
00075 namespace drizzled {
00076
00077 extern plugin::StorageEngine *heap_engine;
00078
00080 static bool make_group_fields(Join *main_join, Join *curr_join);
00081 static void calc_group_buffer(Join *join, Order *group);
00082 static bool alloc_group_fields(Join *join, Order *group);
00083 static uint32_t cache_record_length(Join *join, uint32_t index);
00084 static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
00085 static bool get_best_combination(Join *join);
00086 static void set_position(Join *join,
00087 uint32_t index,
00088 JoinTable *table,
00089 optimizer::KeyUse *key);
00090 static bool choose_plan(Join *join,table_map join_tables);
00091 static void best_access_path(Join *join, JoinTable *s,
00092 Session *session,
00093 table_map remaining_tables,
00094 uint32_t idx,
00095 double record_count,
00096 double read_time);
00097 static void optimize_straight_join(Join *join, table_map join_tables);
00098 static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
00099 static bool best_extension_by_limited_search(Join *join,
00100 table_map remaining_tables,
00101 uint32_t idx,
00102 double record_count,
00103 double read_time,
00104 uint32_t depth,
00105 uint32_t prune_level);
00106 static uint32_t determine_search_depth(Join* join);
00107 static void make_simple_join(Join*, Table*);
00108 static void make_outerjoin_info(Join *join);
00109 static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
00110 static void make_join_readinfo(Join&);
00111 static void update_depend_map(Join *join);
00112 static void update_depend_map(Join *join, Order *order);
00113 static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
00114 static void return_zero_rows(Join *join,
00115 select_result *res,
00116 TableList *tables,
00117 List<Item> &fields,
00118 bool send_row,
00119 uint64_t select_options,
00120 const char *info,
00121 Item *having);
00122 static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top);
00123 static int remove_duplicates(Join *join,Table *entry,List<Item> &fields, Item *having);
00124 static int setup_without_group(Session *session,
00125 Item **ref_pointer_array,
00126 TableList *tables,
00127 TableList *,
00128 List<Item> &fields,
00129 List<Item> &all_fields,
00130 COND **conds,
00131 Order *order,
00132 Order *group,
00133 bool *hidden_group_fields);
00134 static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
00135 static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
00136 static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
00137 static void reset_nj_counters(List<TableList> *join_list);
00138 static bool test_if_subpart(Order *a,Order *b);
00139 static void restore_prev_nj_state(JoinTable *last);
00140 static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
00141 static void free_blobs(Field **ptr);
00142
00143 Join::Join(Session *session_arg,
00144 List<Item> &fields_arg,
00145 uint64_t select_options_arg,
00146 select_result *result_arg) :
00147 join_tab(NULL),
00148 best_ref(NULL),
00149 map2table(NULL),
00150 join_tab_save(NULL),
00151 table(NULL),
00152 all_tables(NULL),
00153 sort_by_table(NULL),
00154 tables(0),
00155 outer_tables(0),
00156 const_tables(0),
00157 send_group_parts(0),
00158 sort_and_group(false),
00159 first_record(false),
00160 full_join(false),
00161 group(false),
00162 no_field_update(false),
00163 do_send_rows(true),
00164 resume_nested_loop(false),
00165 no_const_tables(false),
00166 select_distinct(false),
00167 group_optimized_away(false),
00168 simple_order(false),
00169 simple_group(false),
00170 no_order(false),
00171 skip_sort_order(false),
00172 union_part(false),
00173 optimized(false),
00174 need_tmp(false),
00175 hidden_group_fields(false),
00176 const_table_map(0),
00177 found_const_table_map(0),
00178 outer_join(0),
00179 send_records(0),
00180 found_records(0),
00181 examined_rows(0),
00182 row_limit(0),
00183 select_limit(0),
00184 fetch_limit(HA_POS_ERROR),
00185 session(session_arg),
00186 fields_list(fields_arg),
00187 join_list(NULL),
00188 unit(NULL),
00189 select_lex(NULL),
00190 select(NULL),
00191 exec_tmp_table1(NULL),
00192 exec_tmp_table2(NULL),
00193 sum_funcs(NULL),
00194 sum_funcs2(NULL),
00195 having(NULL),
00196 tmp_having(NULL),
00197 having_history(NULL),
00198 select_options(select_options_arg),
00199 result(result_arg),
00200 lock(session_arg->open_tables.lock),
00201 tmp_join(NULL),
00202 all_fields(fields_arg),
00203 error(0),
00204 cond_equal(NULL),
00205 return_tab(NULL),
00206 ref_pointer_array(NULL),
00207 items0(NULL),
00208 items1(NULL),
00209 items2(NULL),
00210 items3(NULL),
00211 ref_pointer_array_size(0),
00212 zero_result_cause(NULL),
00213 sortorder(NULL),
00214 table_reexec(NULL),
00215 join_tab_reexec(NULL)
00216 {
00217 select_distinct= test(select_options & SELECT_DISTINCT);
00218 if (&fields_list != &fields_arg)
00219 fields_list= fields_arg;
00220 memset(&keyuse, 0, sizeof(keyuse));
00221 tmp_table_param.init();
00222 tmp_table_param.end_write_records= HA_POS_ERROR;
00223 rollup.setState(Rollup::STATE_NONE);
00224 }
00225
00232 void Join::reset(Session *session_arg,
00233 List<Item> &fields_arg,
00234 uint64_t select_options_arg,
00235 select_result *result_arg)
00236 {
00237 join_tab= NULL;
00238 best_ref= NULL;
00239 map2table= NULL;
00240 join_tab_save= NULL;
00241 table= NULL;
00242 all_tables= NULL;
00243 sort_by_table= NULL;
00244 tables= 0;
00245 outer_tables= 0;
00246 const_tables= 0;
00247 send_group_parts= 0;
00248 sort_and_group= false;
00249 first_record= false;
00250 full_join= false;
00251 group= false;
00252 no_field_update= false;
00253 do_send_rows= true;
00254 resume_nested_loop= false;
00255 no_const_tables= false;
00256 select_distinct= false;
00257 group_optimized_away= false;
00258 simple_order= false;
00259 simple_group= false;
00260 no_order= false;
00261 skip_sort_order= false;
00262 union_part= false;
00263 optimized= false;
00264 need_tmp= false;
00265 hidden_group_fields= false;
00266 const_table_map= 0;
00267 found_const_table_map= 0;
00268 outer_join= 0;
00269 send_records= 0;
00270 found_records= 0;
00271 examined_rows= 0;
00272 row_limit= 0;
00273 select_limit= 0;
00274 fetch_limit= HA_POS_ERROR;
00275 session= session_arg;
00276 fields_list= fields_arg;
00277 join_list= NULL;
00278 unit= NULL;
00279 select_lex= NULL;
00280 select= NULL;
00281 exec_tmp_table1= NULL;
00282 exec_tmp_table2= NULL;
00283 sum_funcs= NULL;
00284 sum_funcs2= NULL;
00285 having= NULL;
00286 tmp_having= NULL;
00287 having_history= NULL;
00288 select_options= select_options_arg;
00289 result= result_arg;
00290 lock= session_arg->open_tables.lock;
00291 tmp_join= NULL;
00292 all_fields= fields_arg;
00293 error= 0;
00294 cond_equal= NULL;
00295 return_tab= NULL;
00296 ref_pointer_array= NULL;
00297 items0= NULL;
00298 items1= NULL;
00299 items2= NULL;
00300 items3= NULL;
00301 ref_pointer_array_size= 0;
00302 zero_result_cause= NULL;
00303 sortorder= NULL;
00304 table_reexec= NULL;
00305 join_tab_reexec= NULL;
00306 select_distinct= test(select_options & SELECT_DISTINCT);
00307 if (&fields_list != &fields_arg)
00308 fields_list= fields_arg;
00309 memset(&keyuse, 0, sizeof(keyuse));
00310 tmp_table_param.init();
00311 tmp_table_param.end_write_records= HA_POS_ERROR;
00312 rollup.setState(Rollup::STATE_NONE);
00313 }
00314
00315 bool Join::is_top_level_join() const
00316 {
00317 return unit == &session->lex().unit && (unit->fake_select_lex == 0 || select_lex == unit->fake_select_lex);
00318 }
00319
00332 int Join::prepare(Item ***rref_pointer_array,
00333 TableList *tables_init,
00334 uint32_t wild_num,
00335 COND *conds_init,
00336 uint32_t og_num,
00337 Order *order_init,
00338 Order *group_init,
00339 Item *having_init,
00340 Select_Lex *select_lex_arg,
00341 Select_Lex_Unit *unit_arg)
00342 {
00343
00344 if (optimized)
00345 return 0;
00346
00347 conds= conds_init;
00348 order= order_init;
00349 group_list= group_init;
00350 having= having_init;
00351 tables_list= tables_init;
00352 select_lex= select_lex_arg;
00353 select_lex->join= this;
00354 join_list= &select_lex->top_join_list;
00355 union_part= unit_arg->is_union();
00356
00357 session->lex().current_select->is_item_list_lookup= 1;
00358
00359
00360
00361
00362 if (session->derived_tables_processing)
00363 select_lex->exclude_from_table_unique_test= true;
00364
00365
00366
00367 if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
00368 setup_tables_and_check_access(session, &select_lex->context, join_list, tables_list, &select_lex->leaf_tables, false))
00369 {
00370 return(-1);
00371 }
00372
00373 TableList *table_ptr;
00374 for (table_ptr= select_lex->leaf_tables; table_ptr; table_ptr= table_ptr->next_leaf)
00375 {
00376 tables++;
00377 }
00378
00379
00380 if (setup_wild(session, fields_list, &all_fields, wild_num))
00381 return -1;
00382 select_lex->setup_ref_array(session, og_num);
00383 if (setup_fields(session, *rref_pointer_array, fields_list, MARK_COLUMNS_READ, &all_fields, 1) ||
00384 setup_without_group(session, *rref_pointer_array, tables_list, select_lex->leaf_tables, fields_list,
00385 all_fields, &conds, order, group_list, &hidden_group_fields))
00386 return -1;
00387
00388 ref_pointer_array= *rref_pointer_array;
00389
00390 if (having)
00391 {
00392 nesting_map save_allow_sum_func= session->lex().allow_sum_func;
00393 session->setWhere("having clause");
00394 session->lex().allow_sum_func|= 1 << select_lex_arg->nest_level;
00395 select_lex->having_fix_field= 1;
00396 bool having_fix_rc= (!having->fixed &&
00397 (having->fix_fields(session, &having) ||
00398 having->check_cols(1)));
00399 select_lex->having_fix_field= 0;
00400 if (having_fix_rc || session->is_error())
00401 return(-1);
00402 session->lex().allow_sum_func= save_allow_sum_func;
00403 }
00404
00405 {
00406 Item_subselect *subselect;
00407 Item_in_subselect *in_subs= NULL;
00408
00409
00410
00411
00412 if ((subselect= select_lex->master_unit()->item))
00413 {
00414 if (subselect->substype() == Item_subselect::IN_SUBS)
00415 in_subs= (Item_in_subselect*)subselect;
00416
00417 {
00418 bool do_materialize= true;
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 if (do_materialize &&
00449 in_subs &&
00450 !select_lex->master_unit()->first_select()->next_select() &&
00451 select_lex->master_unit()->first_select()->leaf_tables &&
00452 session->lex().sql_command == SQLCOM_SELECT)
00453 {
00454 if (in_subs->is_top_level_item() &&
00455 !in_subs->is_correlated &&
00456 in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED)
00457 in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
00458 }
00459
00460 Item_subselect::trans_res trans_res;
00461 if ((trans_res= subselect->select_transformer(this)) !=
00462 Item_subselect::RES_OK)
00463 {
00464 return((trans_res == Item_subselect::RES_ERROR));
00465 }
00466 }
00467 }
00468 }
00469
00470 if (order)
00471 {
00472 Order *ord;
00473 for (ord= order; ord; ord= ord->next)
00474 {
00475 Item *item= *ord->item;
00476 if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
00477 item->split_sum_func(session, ref_pointer_array, all_fields);
00478 }
00479 }
00480
00481 if (having && having->with_sum_func)
00482 having->split_sum_func(session, ref_pointer_array, all_fields,
00483 &having, true);
00484 if (select_lex->inner_sum_func_list)
00485 {
00486 Item_sum *end=select_lex->inner_sum_func_list;
00487 Item_sum *item_sum= end;
00488 do
00489 {
00490 item_sum= item_sum->next;
00491 item_sum->split_sum_func(session, ref_pointer_array,
00492 all_fields, item_sum->ref_by, false);
00493 } while (item_sum != end);
00494 }
00495
00496 if (select_lex->inner_refs_list.size() &&
00497 fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
00498 return(-1);
00499
00500
00501
00502
00503
00504
00505
00506 if (! group_list &&
00507 select_lex->full_group_by_flag.test(NON_AGG_FIELD_USED) &&
00508 select_lex->full_group_by_flag.test(SUM_FUNC_USED))
00509 {
00510 my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
00511 ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
00512 return(-1);
00513 }
00514 {
00515
00516 send_group_parts= 0;
00517 for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
00518 send_group_parts++;
00519 }
00520
00521 if (error)
00522 return(-1);
00523
00524
00525
00526
00527
00528
00529
00530 if (result && result->prepare(fields_list, unit_arg))
00531 return(-1);
00532
00533
00534 count_field_types(select_lex, &tmp_table_param, all_fields, 0);
00535 ref_pointer_array_size= all_fields.size() * sizeof(Item*);
00536 this->group= group_list != 0;
00537 unit= unit_arg;
00538
00539 #ifdef RESTRICTED_GROUP
00540 if (sum_func_count && !group_list && (func_count || field_count))
00541 {
00542 my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
00543 return(-1);
00544 }
00545 #endif
00546 if (select_lex->olap == ROLLUP_TYPE && rollup_init())
00547 return(-1);
00548
00549 if (alloc_func_list())
00550 return(-1);
00551
00552 return 0;
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 void Join::remove_subq_pushed_predicates(Item **where)
00585 {
00586 if (conds->type() == Item::FUNC_ITEM &&
00587 ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
00588 ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
00589 ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
00590 test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
00591 ((Item_func *)conds)->arguments()[0]))
00592 {
00593 *where= 0;
00594 return;
00595 }
00596 }
00597
00609 int Join::optimize()
00610 {
00611
00612 if (optimized)
00613 return 0;
00614 optimized= 1;
00615
00616 session->set_proc_info("optimizing");
00617 row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
00618 unit->select_limit_cnt);
00619
00620 select_limit= unit->select_limit_cnt;
00621 if (having || (select_options & OPTION_FOUND_ROWS))
00622 select_limit= HA_POS_ERROR;
00623 do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
00624
00625 if (session->lex().ignore)
00626 session->lex().current_select->no_error= 1;
00627
00628 #ifdef HAVE_REF_TO_FIELDS // Not done yet
00629
00630 if (having && !group_list && !sum_func_count)
00631 {
00632 if (!conds)
00633 {
00634 conds= having;
00635 having= 0;
00636 }
00637 else
00638 {
00639 conds= new Item_cond_and(conds,having);
00640
00641
00642
00643
00644
00645 conds->fix_fields(session, &conds);
00646 conds->change_ref_to_fields(session, tables_list);
00647 conds->top_level_item();
00648 having= 0;
00649 }
00650 }
00651 #endif
00652
00653
00654 conds= simplify_joins(this, join_list, conds, true);
00655 build_bitmap_for_nested_joins(join_list, 0);
00656
00657 conds= optimize_cond(this, conds, join_list, &cond_value);
00658 if (session->is_error())
00659 {
00660 error= 1;
00661 return 1;
00662 }
00663
00664 {
00665 having= optimize_cond(this, having, join_list, &having_value);
00666 if (session->is_error())
00667 {
00668 error= 1;
00669 return 1;
00670 }
00671 if (select_lex->where)
00672 select_lex->cond_value= cond_value;
00673 if (select_lex->having)
00674 select_lex->having_value= having_value;
00675
00676 if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
00677 (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
00678 {
00679 zero_result_cause= having_value == Item::COND_FALSE ?
00680 "Impossible HAVING" : "Impossible WHERE";
00681 tables = 0;
00682 goto setup_subq_exit;
00683 }
00684 }
00685
00686
00687 if (tables_list && tmp_table_param.sum_func_count && ! group_list)
00688 {
00689 int res;
00690
00691
00692
00693
00694
00695
00696 if ((res= optimizer::sum_query(select_lex->leaf_tables, all_fields, conds)))
00697 {
00698 if (res == HA_ERR_KEY_NOT_FOUND)
00699 {
00700 zero_result_cause= "No matching min/max row";
00701 tables = 0;
00702 goto setup_subq_exit;
00703 }
00704 if (res > 1)
00705 {
00706 error= res;
00707 return 1;
00708 }
00709 if (res < 0)
00710 {
00711 zero_result_cause= "No matching min/max row";
00712 tables = 0;
00713 goto setup_subq_exit;
00714 }
00715 zero_result_cause= "Select tables optimized away";
00716 tables_list= 0;
00717 const_tables= tables;
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 if (conds && !(session->lex().describe & DESCRIBE_EXTENDED))
00729 {
00730 COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
00731 conds= table_independent_conds;
00732 }
00733 goto setup_subq_exit;
00734 }
00735 }
00736 if (!tables_list)
00737 {
00738 error= 0;
00739 return 0;
00740 }
00741 error= -1;
00742 sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
00743
00744
00745 session->set_proc_info("statistics");
00746 if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
00747 session->is_fatal_error)
00748 {
00749 return 1;
00750 }
00751
00752
00753 select_distinct= select_distinct && (const_tables != tables);
00754 session->set_proc_info("preparing");
00755 if (result->initialize_tables(this))
00756 {
00757 return 1;
00758 }
00759 if (const_table_map != found_const_table_map &&
00760 !(select_options & SELECT_DESCRIBE) &&
00761 (!conds ||
00762 !(conds->used_tables() & RAND_TABLE_BIT) ||
00763 select_lex->master_unit() == &session->lex().unit))
00764 {
00765 zero_result_cause= "no matching row in const table";
00766 goto setup_subq_exit;
00767 }
00768 if (!(session->options & OPTION_BIG_SELECTS) &&
00769 best_read > (double) session->variables.max_join_size &&
00770 !(select_options & SELECT_DESCRIBE))
00771 {
00772 my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
00773 error= -1;
00774 return 1;
00775 }
00776 if (const_tables && !(select_options & SELECT_NO_UNLOCK))
00777 session->unlockSomeTables(table, const_tables);
00778 if (!conds && outer_join)
00779 {
00780
00781 conds=new Item_int((int64_t) 1,1);
00782 }
00783 select= optimizer::make_select(*table, const_table_map,
00784 const_table_map, conds, 1, &error);
00785 if (error)
00786 {
00787 error= -1;
00788 return 1;
00789 }
00790
00791 reset_nj_counters(join_list);
00792 make_outerjoin_info(this);
00793
00794
00795
00796
00797
00798
00799
00800 if (conds)
00801 {
00802 conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
00803 conds->update_used_tables();
00804 }
00805
00806
00807
00808
00809
00810 for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
00811 {
00812 if (*tab->on_expr_ref)
00813 {
00814 *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
00815 tab->cond_equal,
00816 map2table);
00817 (*tab->on_expr_ref)->update_used_tables();
00818 }
00819 }
00820
00821 if (conds &&!outer_join && const_table_map != found_const_table_map &&
00822 (select_options & SELECT_DESCRIBE) &&
00823 select_lex->master_unit() == &session->lex().unit)
00824 {
00825 conds=new Item_int(0, 1);
00826 }
00827
00828 if (make_join_select(this, select, conds))
00829 {
00830 zero_result_cause=
00831 "Impossible WHERE noticed after reading const tables";
00832 goto setup_subq_exit;
00833 }
00834
00835 error= -1;
00836
00837
00838 {
00839 Order *org_order= order;
00840 order= remove_constants(this, order,conds,1, &simple_order);
00841 if (session->is_error())
00842 {
00843 error= 1;
00844 return 1;
00845 }
00846
00847
00848
00849
00850
00851 if (!order && org_order)
00852 skip_sort_order= 1;
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 if (tables - const_tables == 1 && (group_list || select_distinct) &&
00867 ! tmp_table_param.sum_func_count &&
00868 (! join_tab[const_tables].select ||
00869 ! join_tab[const_tables].select->quick ||
00870 join_tab[const_tables].select->quick->get_type() !=
00871 optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
00872 {
00873 if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
00874 {
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 if (! order || test_if_subpart(group_list, order))
00891 order= skip_sort_order ? 0 : group_list;
00892
00893
00894
00895
00896 join_tab->table->keys_in_use_for_order_by=
00897 join_tab->table->keys_in_use_for_group_by;
00898 group_list= 0;
00899 group= 0;
00900 }
00901 if (select_distinct &&
00902 list_contains_unique_index(join_tab[const_tables].table,
00903 find_field_in_item_list,
00904 (void *) &fields_list))
00905 {
00906 select_distinct= 0;
00907 }
00908 }
00909 if (group_list || tmp_table_param.sum_func_count)
00910 {
00911 if (! hidden_group_fields && rollup.getState() == Rollup::STATE_NONE)
00912 select_distinct=0;
00913 }
00914 else if (select_distinct && tables - const_tables == 1)
00915 {
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 JoinTable *tab= &join_tab[const_tables];
00932 bool all_order_fields_used;
00933 if (order)
00934 skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
00935 &tab->table->keys_in_use_for_order_by);
00936 if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
00937 order, fields_list, all_fields,
00938 &all_order_fields_used)))
00939 {
00940 bool skip_group= (skip_sort_order &&
00941 test_if_skip_sort_order(tab, group_list, select_limit, 1,
00942 &tab->table->keys_in_use_for_group_by) != 0);
00943 count_field_types(select_lex, &tmp_table_param, all_fields, 0);
00944 if ((skip_group && all_order_fields_used) ||
00945 select_limit == HA_POS_ERROR ||
00946 (order && !skip_sort_order))
00947 {
00948
00949 select_distinct= 0;
00950 no_order= !order;
00951 if (all_order_fields_used)
00952 {
00953 if (order && skip_sort_order)
00954 {
00955
00956
00957
00958
00959 tmp_table_param.quick_group=0;
00960 }
00961 order=0;
00962 }
00963 group=1;
00964 }
00965 else
00966 group_list= 0;
00967 }
00968 else if (session->is_fatal_error)
00969 return 1;
00970 }
00971 simple_group= 0;
00972 {
00973 Order *old_group_list;
00974 group_list= remove_constants(this, (old_group_list= group_list), conds,
00975 rollup.getState() == Rollup::STATE_NONE,
00976 &simple_group);
00977 if (session->is_error())
00978 {
00979 error= 1;
00980 return 1;
00981 }
00982 if (old_group_list && !group_list)
00983 select_distinct= 0;
00984 }
00985 if (!group_list && group)
00986 {
00987 order=0;
00988 simple_order=1;
00989 select_distinct= 0;
00990 group_optimized_away= 1;
00991 }
00992
00993 calc_group_buffer(this, group_list);
00994 send_group_parts= tmp_table_param.group_parts;
00995
00996 if (test_if_subpart(group_list, order) ||
00997 (!group_list && tmp_table_param.sum_func_count))
00998 order=0;
00999
01000
01001 if (full_join)
01002 {
01003 if (group_list)
01004 simple_group=0;
01005 if (order)
01006 simple_order=0;
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 need_tmp= (const_tables != tables &&
01019 ((select_distinct || !simple_order || !simple_group) ||
01020 (group_list && order) ||
01021 test(select_options & OPTION_BUFFER_RESULT)));
01022
01023
01024 make_join_readinfo(*this);
01025
01026
01027 if (setup_subquery_materialization())
01028 return 1;
01029
01030
01031 cache_const_exprs();
01032
01033
01034
01035
01036 if (!group_list && !order &&
01037 unit->item && unit->item->substype() == Item_subselect::IN_SUBS &&
01038 tables == 1 && conds &&
01039 !unit->is_union())
01040 {
01041 if (!having)
01042 {
01043 Item *where= conds;
01044 if (join_tab[0].type == AM_EQ_REF && join_tab[0].ref.items[0]->name == in_left_expr_name)
01045 {
01046 remove_subq_pushed_predicates(&where);
01047 save_index_subquery_explain_info(join_tab, where);
01048 join_tab[0].type= AM_UNIQUE_SUBQUERY;
01049 error= 0;
01050 return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
01051 }
01052 else if (join_tab[0].type == AM_REF &&
01053 join_tab[0].ref.items[0]->name == in_left_expr_name)
01054 {
01055 remove_subq_pushed_predicates(&where);
01056 save_index_subquery_explain_info(join_tab, where);
01057 join_tab[0].type= AM_INDEX_SUBQUERY;
01058 error= 0;
01059 return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
01060 }
01061 }
01062 else if (join_tab[0].type == AM_REF_OR_NULL &&
01063 join_tab[0].ref.items[0]->name == in_left_expr_name &&
01064 having->name == in_having_cond)
01065 {
01066 join_tab[0].type= AM_INDEX_SUBQUERY;
01067 error= 0;
01068 conds= remove_additional_cond(conds);
01069 save_index_subquery_explain_info(join_tab, conds);
01070 return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, conds, having, 1)));
01071 }
01072
01073 }
01074
01075
01076
01077
01078
01079
01080 if (need_tmp || select_distinct || group_list || order)
01081 {
01082 for (uint32_t i = const_tables; i < tables; i++)
01083 join_tab[i].table->prepare_for_position();
01084 }
01085
01086 if (const_tables != tables)
01087 {
01088
01089
01090
01091
01092
01093
01094 if ((order || group_list) &&
01095 (join_tab[const_tables].type != AM_ALL) &&
01096 (join_tab[const_tables].type != AM_REF_OR_NULL) &&
01097 ((order && simple_order) || (group_list && simple_group)))
01098 {
01099 if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
01100 return 1;
01101 }
01102 }
01103
01104 if (!(select_options & SELECT_BIG_RESULT) &&
01105 ((group_list &&
01106 (!simple_group ||
01107 !test_if_skip_sort_order(&join_tab[const_tables], group_list,
01108 unit->select_limit_cnt, 0,
01109 &join_tab[const_tables].table->
01110 keys_in_use_for_group_by))) ||
01111 select_distinct) &&
01112 tmp_table_param.quick_group)
01113 {
01114 need_tmp=1; simple_order=simple_group=0;
01115 }
01116 if (order)
01117 {
01118
01119
01120
01121
01122 for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
01123 {
01124 Item *item= *tmp_order->item;
01125 if (item->is_expensive())
01126 {
01127
01128 need_tmp=1; simple_order=simple_group=0;
01129 break;
01130 }
01131 }
01132 }
01133 }
01134
01135 tmp_having= having;
01136 if (select_options & SELECT_DESCRIBE)
01137 {
01138 error= 0;
01139 return 0;
01140 }
01141 having= 0;
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 if (join_tab->is_using_loose_index_scan())
01155 tmp_table_param.precomputed_group_by= true;
01156
01157
01158 if (need_tmp)
01159 {
01160 session->set_proc_info("Creating tmp table");
01161
01162 init_items_ref_array();
01163
01164 tmp_table_param.hidden_field_count= all_fields.size() - fields_list.size();
01165 Order *tmp_group= (((not simple_group) or not (getDebug().test(debug::NO_KEY_GROUP))) ? group_list : NULL);
01166
01167
01168
01169
01170
01171
01172
01173 ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
01174 !tmp_group &&
01175 !session->lex().current_select->with_sum_func) ?
01176 select_limit : HA_POS_ERROR;
01177
01178 if (!(exec_tmp_table1=
01179 create_tmp_table(session, &tmp_table_param, all_fields,
01180 tmp_group,
01181 group_list ? 0 : select_distinct,
01182 group_list && simple_group,
01183 select_options,
01184 tmp_rows_limit,
01185 (char *) "")))
01186 {
01187 return 1;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 if (tmp_having && (sort_and_group || (exec_tmp_table1->distinct && !group_list)))
01201 having= tmp_having;
01202
01203
01204 if (group_list && simple_group)
01205 {
01206 session->set_proc_info("Sorting for group");
01207 if (create_sort_index(session, this, group_list,
01208 HA_POS_ERROR, HA_POS_ERROR, false) ||
01209 alloc_group_fields(this, group_list) ||
01210 make_sum_func_list(all_fields, fields_list, 1) ||
01211 setup_sum_funcs(session, sum_funcs))
01212 {
01213 return 1;
01214 }
01215 group_list=0;
01216 }
01217 else
01218 {
01219 if (make_sum_func_list(all_fields, fields_list, 0) ||
01220 setup_sum_funcs(session, sum_funcs))
01221 {
01222 return 1;
01223 }
01224
01225 if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
01226 {
01227 session->set_proc_info("Sorting for order");
01228 if (create_sort_index(session, this, order, HA_POS_ERROR, HA_POS_ERROR, true))
01229 {
01230 return 1;
01231 }
01232 order=0;
01233 }
01234 }
01235
01236
01237
01238
01239
01240
01241
01242 if (exec_tmp_table1->distinct)
01243 {
01244 table_map used_tables= session->used_tables;
01245 JoinTable *last_join_tab= join_tab+tables-1;
01246 do
01247 {
01248 if (used_tables & last_join_tab->table->map)
01249 break;
01250 last_join_tab->not_used_in_distinct=1;
01251 } while (last_join_tab-- != join_tab);
01252
01253 if (order && skip_sort_order)
01254 {
01255
01256 if (test_if_skip_sort_order(&join_tab[const_tables],
01257 order, unit->select_limit_cnt, 0,
01258 &join_tab[const_tables].table->
01259 keys_in_use_for_order_by))
01260 order= 0;
01261 }
01262 }
01263
01264
01265
01266
01267
01268 if (select_lex->uncacheable.any() && not is_top_level_join())
01269 init_save_join_tab();
01270 }
01271
01272 error= 0;
01273 return 0;
01274
01275 setup_subq_exit:
01276
01277
01278
01279 if (setup_subquery_materialization())
01280 return 1;
01281 error= 0;
01282 return 0;
01283 }
01284
01288 void Join::restore_tmp()
01289 {
01290 memcpy(tmp_join, this, (size_t) sizeof(Join));
01291 }
01292
01293 int Join::reinit()
01294 {
01295 unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
01296 select_lex->offset_limit->val_uint() :
01297 0UL);
01298
01299 first_record= 0;
01300
01301 if (exec_tmp_table1)
01302 {
01303 exec_tmp_table1->cursor->extra(HA_EXTRA_RESET_STATE);
01304 exec_tmp_table1->cursor->ha_delete_all_rows();
01305 exec_tmp_table1->free_io_cache();
01306 exec_tmp_table1->filesort_free_buffers();
01307 }
01308 if (exec_tmp_table2)
01309 {
01310 exec_tmp_table2->cursor->extra(HA_EXTRA_RESET_STATE);
01311 exec_tmp_table2->cursor->ha_delete_all_rows();
01312 exec_tmp_table2->free_io_cache();
01313 exec_tmp_table2->filesort_free_buffers();
01314 }
01315 if (items0)
01316 set_items_ref_array(items0);
01317
01318 if (join_tab_save)
01319 memcpy(join_tab, join_tab_save, sizeof(JoinTable) * tables);
01320
01321 if (tmp_join)
01322 restore_tmp();
01323
01324
01325 if (sum_funcs)
01326 {
01327 Item_sum *func, **func_ptr= sum_funcs;
01328 while ((func= *(func_ptr++)))
01329 func->clear();
01330 }
01331
01332 return 0;
01333 }
01334
01345 void Join::init_save_join_tab()
01346 {
01347 tmp_join= (Join*)session->mem.alloc(sizeof(Join));
01348
01349 error= 0;
01350 restore_tmp();
01351 }
01352
01353 void Join::save_join_tab()
01354 {
01355 if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
01356 {
01357 join_tab_save= (JoinTable*)session->mem.memdup(join_tab, sizeof(JoinTable) * tables);
01358 }
01359 }
01360
01372 void Join::exec()
01373 {
01374 List<Item> *columns_list= &fields_list;
01375 int tmp_error;
01376
01377 session->set_proc_info("executing");
01378 error= 0;
01379
01380 if (!tables_list && (tables || !select_lex->with_sum_func))
01381 {
01382
01383 if (select_options & SELECT_DESCRIBE)
01384 {
01385 optimizer::ExplainPlan planner(this,
01386 false,
01387 false,
01388 false,
01389 (zero_result_cause ? zero_result_cause : "No tables used"));
01390 planner.printPlan();
01391 }
01392 else
01393 {
01394 result->send_fields(*columns_list);
01395
01396
01397
01398
01399
01400 if (cond_value != Item::COND_FALSE &&
01401 (!conds || conds->val_int()) &&
01402 (!having || having->val_int()))
01403 {
01404 if (do_send_rows && result->send_data(fields_list))
01405 error= 1;
01406 else
01407 {
01408 error= (int) result->send_eof();
01409 send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : session->sent_row_count);
01410 }
01411 }
01412 else
01413 {
01414 error= (int) result->send_eof();
01415 send_records= 0;
01416 }
01417 }
01418
01419 session->limit_found_rows= send_records;
01420 session->examined_row_count= 0;
01421 return;
01422 }
01423
01424
01425
01426
01427
01428 if (tables)
01429 session->limit_found_rows= 0;
01430
01431 if (zero_result_cause)
01432 {
01433 return_zero_rows(this, result, select_lex->leaf_tables, *columns_list, send_row_on_empty_set(), select_options, zero_result_cause, having);
01434 return;
01435 }
01436
01437 if (select_options & SELECT_DESCRIBE)
01438 {
01439
01440
01441
01442
01443
01444 if (!order && !no_order && (!skip_sort_order || !need_tmp))
01445 {
01446
01447 order= group_list;
01448 simple_order= simple_group;
01449 skip_sort_order= 0;
01450 }
01451 if (order && (order != group_list || !(select_options & SELECT_BIG_RESULT)))
01452 {
01453 if (const_tables == tables
01454 || ((simple_order || skip_sort_order)
01455 && test_if_skip_sort_order(&join_tab[const_tables], order, select_limit, 0, &join_tab[const_tables].table->keys_in_use_for_query)))
01456 order= 0;
01457 }
01458 having= tmp_having;
01459 optimizer::ExplainPlan planner(this,
01460 need_tmp,
01461 order != 0 && ! skip_sort_order,
01462 select_distinct,
01463 ! tables ? "No tables used" : NULL);
01464 planner.printPlan();
01465 return;
01466 }
01467
01468 Join *curr_join= this;
01469 List<Item> *curr_all_fields= &all_fields;
01470 List<Item> *curr_fields_list= &fields_list;
01471 Table *curr_tmp_table= 0;
01472
01473
01474
01475
01476
01477 curr_join->examined_rows= 0;
01478
01479
01480 if (need_tmp)
01481 {
01482 if (tmp_join)
01483 {
01484
01485
01486
01487
01488
01489
01490 curr_join= tmp_join;
01491 }
01492 curr_tmp_table= exec_tmp_table1;
01493
01494
01495 session->set_proc_info("Copying to tmp table");
01496 if (! curr_join->sort_and_group && curr_join->const_tables != curr_join->tables)
01497 curr_join->join_tab[curr_join->const_tables].sorted= 0;
01498 if ((tmp_error= do_select(curr_join, NULL, curr_tmp_table)))
01499 {
01500 error= tmp_error;
01501 return;
01502 }
01503 curr_tmp_table->cursor->info(HA_STATUS_VARIABLE);
01504
01505 if (curr_join->having)
01506 curr_join->having= curr_join->tmp_having= 0;
01507
01508
01509 curr_join->all_fields= *curr_all_fields;
01510 if (!items1)
01511 {
01512 items1= items0 + all_fields.size();
01513 if (sort_and_group || curr_tmp_table->group)
01514 {
01515 if (change_to_use_tmp_fields(session, items1,
01516 tmp_fields_list1, tmp_all_fields1,
01517 fields_list.size(), all_fields))
01518 return;
01519 }
01520 else
01521 {
01522 if (change_refs_to_tmp_fields(session, items1,
01523 tmp_fields_list1, tmp_all_fields1,
01524 fields_list.size(), all_fields))
01525 return;
01526 }
01527 curr_join->tmp_all_fields1= tmp_all_fields1;
01528 curr_join->tmp_fields_list1= tmp_fields_list1;
01529 curr_join->items1= items1;
01530 }
01531 curr_all_fields= &tmp_all_fields1;
01532 curr_fields_list= &tmp_fields_list1;
01533 curr_join->set_items_ref_array(items1);
01534
01535 if (sort_and_group || curr_tmp_table->group)
01536 {
01537 curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.sum_func_count
01538 + curr_join->tmp_table_param.func_count;
01539 curr_join->tmp_table_param.sum_func_count= 0;
01540 curr_join->tmp_table_param.func_count= 0;
01541 }
01542 else
01543 {
01544 curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.func_count;
01545 curr_join->tmp_table_param.func_count= 0;
01546 }
01547
01548 if (curr_tmp_table->group)
01549 {
01550 if (!curr_join->order && !curr_join->no_order && !skip_sort_order)
01551 curr_join->order= curr_join->group_list;
01552 curr_join->group_list= 0;
01553 }
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list, curr_join->order) || curr_join->select_distinct))
01564 || (curr_join->select_distinct && curr_join->tmp_table_param.using_indirect_summary_function))
01565 {
01566
01567 curr_join->join_free();
01568 make_simple_join(curr_join, curr_tmp_table);
01569 calc_group_buffer(curr_join, group_list);
01570 count_field_types(select_lex, &curr_join->tmp_table_param,
01571 curr_join->tmp_all_fields1,
01572 curr_join->select_distinct && !curr_join->group_list);
01573 curr_join->tmp_table_param.hidden_field_count= curr_join->tmp_all_fields1.size()
01574 - curr_join->tmp_fields_list1.size();
01575
01576 if (exec_tmp_table2)
01577 {
01578 curr_tmp_table= exec_tmp_table2;
01579 }
01580 else
01581 {
01582
01583
01584
01585
01586
01587
01588
01589 if (curr_join->join_tab->is_using_loose_index_scan())
01590 curr_join->tmp_table_param.precomputed_group_by= true;
01591
01592 if (!(curr_tmp_table=
01593 exec_tmp_table2= create_tmp_table(session,
01594 &curr_join->tmp_table_param,
01595 *curr_all_fields,
01596 NULL,
01597 curr_join->select_distinct &&
01598 !curr_join->group_list,
01599 1, curr_join->select_options,
01600 HA_POS_ERROR,
01601 (char *) "")))
01602 {
01603 return;
01604 }
01605
01606 curr_join->exec_tmp_table2= exec_tmp_table2;
01607 }
01608 if (curr_join->group_list)
01609 {
01610 session->set_proc_info("Creating sort index");
01611 if (curr_join->join_tab == join_tab)
01612 save_join_tab();
01613 if (create_sort_index(session, curr_join, curr_join->group_list, HA_POS_ERROR, HA_POS_ERROR, false) ||
01614 make_group_fields(this, curr_join))
01615 {
01616 return;
01617 }
01618 sortorder= curr_join->sortorder;
01619 }
01620
01621 session->set_proc_info("Copying to group table");
01622 tmp_error= -1;
01623 if (curr_join != this)
01624 {
01625 if (sum_funcs2)
01626 {
01627 curr_join->sum_funcs= sum_funcs2;
01628 curr_join->sum_funcs_end= sum_funcs_end2;
01629 }
01630 else
01631 {
01632 curr_join->alloc_func_list();
01633 sum_funcs2= curr_join->sum_funcs;
01634 sum_funcs_end2= curr_join->sum_funcs_end;
01635 }
01636 }
01637 if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, 1, true))
01638 return;
01639 curr_join->group_list= 0;
01640
01641 if (!curr_join->sort_and_group && (curr_join->const_tables != curr_join->tables))
01642 curr_join->join_tab[curr_join->const_tables].sorted= 0;
01643
01644 if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs)
01645 || (tmp_error= do_select(curr_join, NULL, curr_tmp_table)))
01646 {
01647 error= tmp_error;
01648 return;
01649 }
01650 curr_join->join_tab->read_record.end_read_record();
01651 curr_join->const_tables= curr_join->tables;
01652 curr_join->join_tab[0].table= 0;
01653
01654
01655 if (!items2)
01656 {
01657 items2= items1 + all_fields.size();
01658 if (change_to_use_tmp_fields(session, items2,
01659 tmp_fields_list2, tmp_all_fields2,
01660 fields_list.size(), tmp_all_fields1))
01661 return;
01662 curr_join->tmp_fields_list2= tmp_fields_list2;
01663 curr_join->tmp_all_fields2= tmp_all_fields2;
01664 }
01665 curr_fields_list= &curr_join->tmp_fields_list2;
01666 curr_all_fields= &curr_join->tmp_all_fields2;
01667 curr_join->set_items_ref_array(items2);
01668 curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.sum_func_count;
01669 curr_join->tmp_table_param.sum_func_count= 0;
01670 }
01671 if (curr_tmp_table->distinct)
01672 curr_join->select_distinct=0;
01673
01674 curr_join->join_free();
01675 if (curr_join->select_distinct && ! curr_join->group_list)
01676 {
01677 session->set_proc_info("Removing duplicates");
01678 if (curr_join->tmp_having)
01679 curr_join->tmp_having->update_used_tables();
01680
01681 if (remove_duplicates(curr_join, curr_tmp_table,
01682 *curr_fields_list, curr_join->tmp_having))
01683 return;
01684
01685 curr_join->tmp_having=0;
01686 curr_join->select_distinct=0;
01687 }
01688 curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
01689 make_simple_join(curr_join, curr_tmp_table);
01690 calc_group_buffer(curr_join, curr_join->group_list);
01691 count_field_types(select_lex, &curr_join->tmp_table_param, *curr_all_fields, 0);
01692
01693 }
01694
01695 if (curr_join->group || curr_join->tmp_table_param.sum_func_count)
01696 {
01697 if (make_group_fields(this, curr_join))
01698 return;
01699
01700 if (! items3)
01701 {
01702 if (! items0)
01703 init_items_ref_array();
01704 items3= ref_pointer_array + (all_fields.size() * 4);
01705 setup_copy_fields(session, &curr_join->tmp_table_param,
01706 items3, tmp_fields_list3, tmp_all_fields3,
01707 curr_fields_list->size(), *curr_all_fields);
01708 tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
01709 tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
01710 tmp_table_param.save_copy_field_end= curr_join->tmp_table_param.copy_field_end;
01711 curr_join->tmp_all_fields3= tmp_all_fields3;
01712 curr_join->tmp_fields_list3= tmp_fields_list3;
01713 }
01714 else
01715 {
01716 curr_join->tmp_table_param.copy_funcs= tmp_table_param.save_copy_funcs;
01717 curr_join->tmp_table_param.copy_field= tmp_table_param.save_copy_field;
01718 curr_join->tmp_table_param.copy_field_end= tmp_table_param.save_copy_field_end;
01719 }
01720 curr_fields_list= &tmp_fields_list3;
01721 curr_all_fields= &tmp_all_fields3;
01722 curr_join->set_items_ref_array(items3);
01723
01724 if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
01725 1, true) ||
01726 setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
01727 session->is_fatal_error)
01728 return;
01729 }
01730 if (curr_join->group_list || curr_join->order)
01731 {
01732 session->set_proc_info("Sorting result");
01733
01734 if (curr_join->tmp_having && ! curr_join->group_list && ! curr_join->sort_and_group)
01735 {
01736
01737 curr_join->tmp_having->update_used_tables();
01738 JoinTable *curr_table= &curr_join->join_tab[curr_join->const_tables];
01739 table_map used_tables= (curr_join->const_table_map |
01740 curr_table->table->map);
01741
01742 Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having, used_tables, used_tables, 0);
01743 if (sort_table_cond)
01744 {
01745 if (!curr_table->select)
01746 curr_table->select= new optimizer::SqlSelect;
01747 if (!curr_table->select->cond)
01748 curr_table->select->cond= sort_table_cond;
01749 else
01750 {
01751 curr_table->select->cond= new Item_cond_and(curr_table->select->cond, sort_table_cond);
01752
01753
01754
01755
01756 curr_table->select->cond->quick_fix_field();
01757 }
01758 curr_table->select_cond= curr_table->select->cond;
01759 curr_table->select_cond->top_level_item();
01760 curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having, ~ (table_map) 0, ~used_tables, 0);
01761 }
01762 }
01763 {
01764 if (group)
01765 curr_join->select_limit= HA_POS_ERROR;
01766 else
01767 {
01768
01769
01770
01771
01772 JoinTable *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
01773 JoinTable *end_table= &curr_join->join_tab[curr_join->tables];
01774 for (; curr_table < end_table ; curr_table++)
01775 {
01776
01777
01778
01779
01780 if (curr_table->select_cond ||
01781 (curr_table->keyuse && !curr_table->first_inner))
01782 {
01783
01784 curr_join->select_limit= HA_POS_ERROR;
01785 break;
01786 }
01787 }
01788 }
01789 if (curr_join->join_tab == join_tab)
01790 save_join_tab();
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800 if (create_sort_index(session, curr_join,
01801 curr_join->group_list ?
01802 curr_join->group_list : curr_join->order,
01803 curr_join->select_limit,
01804 (select_options & OPTION_FOUND_ROWS ?
01805 HA_POS_ERROR : unit->select_limit_cnt),
01806 curr_join->group_list ? true : false))
01807 return;
01808
01809 sortorder= curr_join->sortorder;
01810 if (curr_join->const_tables != curr_join->tables &&
01811 !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
01812 {
01813
01814
01815
01816
01817
01818 skip_sort_order= 1;
01819 }
01820 }
01821 }
01822
01823 if (session->is_error())
01824 {
01825 error= session->is_error();
01826 return;
01827 }
01828 curr_join->having= curr_join->tmp_having;
01829 curr_join->fields= curr_fields_list;
01830
01831 session->set_proc_info("Sending data");
01832 result->send_fields(*curr_fields_list);
01833 error= do_select(curr_join, curr_fields_list, NULL);
01834 session->limit_found_rows= curr_join->send_records;
01835
01836
01837 session->examined_row_count+= curr_join->examined_rows;
01838
01839
01840
01841
01842
01843
01844 if (items0 && (session->lex().describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE)
01845 set_items_ref_array(items0);
01846
01847 return;
01848 }
01849
01856 int Join::destroy()
01857 {
01858 select_lex->join= 0;
01859
01860 if (tmp_join)
01861 {
01862 if (join_tab != tmp_join->join_tab)
01863 {
01864 JoinTable *tab, *end;
01865 for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
01866 tab->cleanup();
01867 }
01868 tmp_join->tmp_join= 0;
01869 tmp_table_param.copy_field=0;
01870 return(tmp_join->destroy());
01871 }
01872 cond_equal= 0;
01873
01874 cleanup(1);
01875 exec_tmp_table1= NULL;
01876 exec_tmp_table2= NULL;
01877 delete select;
01878 keyuse.free();
01879 return error;
01880 }
01881
01904 bool Join::setup_subquery_materialization()
01905 {
01906 for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
01907 un= un->next_unit())
01908 {
01909 for (Select_Lex *sl= un->first_select(); sl; sl= sl->next_select())
01910 {
01911 Item_subselect *subquery_predicate= sl->master_unit()->item;
01912 if (subquery_predicate &&
01913 subquery_predicate->substype() == Item_subselect::IN_SUBS)
01914 {
01915 Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
01916 if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
01917 in_subs->setup_engine())
01918 return true;
01919 }
01920 }
01921 }
01922 return false;
01923 }
01924
01967 void Join::join_free()
01968 {
01969 Select_Lex_Unit *tmp_unit;
01970 Select_Lex *sl;
01971
01972
01973
01974
01975 bool full= (select_lex->uncacheable.none() && ! session->lex().describe);
01976 bool can_unlock= full;
01977
01978 cleanup(full);
01979
01980 for (tmp_unit= select_lex->first_inner_unit();
01981 tmp_unit;
01982 tmp_unit= tmp_unit->next_unit())
01983 for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
01984 {
01985 Item_subselect *subselect= sl->master_unit()->item;
01986 bool full_local= full && (!subselect ||
01987 (subselect->is_evaluated() &&
01988 !subselect->is_uncacheable()));
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998 sl->cleanup_all_joins(full_local);
01999
02000 can_unlock= can_unlock && full_local;
02001 }
02002
02003
02004
02005
02006
02007 if (can_unlock && lock && session->open_tables.lock &&
02008 !(select_options & SELECT_NO_UNLOCK) &&
02009 !select_lex->subquery_in_having &&
02010 (select_lex == (session->lex().unit.fake_select_lex ?
02011 session->lex().unit.fake_select_lex : &session->lex().select_lex)))
02012 {
02013
02014
02015
02016
02017 session->unlockReadTables(lock);
02018 lock= 0;
02019 }
02020
02021 return;
02022 }
02023
02024
02036 void Join::cleanup(bool full)
02037 {
02038 if (table)
02039 {
02040
02041
02042
02043
02044 if (tables > const_tables)
02045 {
02046 table[const_tables]->free_io_cache();
02047 table[const_tables]->filesort_free_buffers(full);
02048 }
02049 }
02050
02051 if (join_tab)
02052 {
02053 JoinTable *tab,*end;
02054
02055 if (full)
02056 {
02057 for (tab= join_tab, end= tab+tables; tab != end; tab++)
02058 tab->cleanup();
02059 table= 0;
02060 }
02061 else
02062 {
02063 for (tab= join_tab, end= tab+tables; tab != end; tab++)
02064 {
02065 if (tab->table)
02066 tab->table->cursor->ha_index_or_rnd_end();
02067 }
02068 }
02069 }
02070
02071
02072
02073
02074
02075 if (full)
02076 {
02077 if (tmp_join)
02078 tmp_table_param.copy_field= 0;
02079 group_fields.delete_elements();
02080
02081
02082
02083
02084 tmp_table_param.copy_funcs.clear();
02085
02086
02087
02088
02089
02090
02091 if (tmp_join &&
02092 tmp_join != this &&
02093 tmp_join->tmp_table_param.copy_field ==
02094 tmp_table_param.copy_field)
02095 {
02096 tmp_join->tmp_table_param.copy_field=
02097 tmp_join->tmp_table_param.save_copy_field= 0;
02098 }
02099 tmp_table_param.cleanup();
02100 }
02101 return;
02102 }
02103
02104
02105
02106
02107 static void clear_tables(Join *join)
02108 {
02109
02110
02111
02112
02113 for (uint32_t i= join->const_tables; i < join->tables; i++)
02114 {
02115 join->table[i]->mark_as_null_row();
02116 }
02117 }
02118
02128 bool Join::alloc_func_list()
02129 {
02130 uint32_t func_count, group_parts;
02131
02132 func_count= tmp_table_param.sum_func_count;
02133
02134
02135
02136
02137 if (rollup.getState() != Rollup::STATE_NONE)
02138 func_count*= (send_group_parts+1);
02139
02140 group_parts= send_group_parts;
02141
02142
02143
02144
02145 if (select_distinct)
02146 {
02147 group_parts+= fields_list.size();
02148
02149
02150
02151
02152 if (order)
02153 {
02154 Order *ord;
02155 for (ord= order; ord; ord= ord->next)
02156 group_parts++;
02157 }
02158 }
02159
02160
02161 sum_funcs= (Item_sum**) session->mem.calloc(sizeof(Item_sum**) * (func_count+1) +
02162 sizeof(Item_sum***) * (group_parts+1));
02163 sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
02164 return(sum_funcs == 0);
02165 }
02166
02180 bool Join::make_sum_func_list(List<Item> &field_list,
02181 List<Item> &send_fields,
02182 bool before_group_by,
02183 bool recompute)
02184 {
02185 List<Item>::iterator it(field_list.begin());
02186 Item_sum **func;
02187 Item *item;
02188
02189 if (*sum_funcs && !recompute)
02190 return false;
02191
02192 func= sum_funcs;
02193 while ((item=it++))
02194 {
02195 if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
02196 (!((Item_sum*) item)->depended_from() ||
02197 ((Item_sum *)item)->depended_from() == select_lex))
02198 *func++= (Item_sum*) item;
02199 }
02200 if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
02201 {
02202 rollup.setState(Rollup::STATE_READY);
02203 if (rollup_make_fields(field_list, send_fields, &func))
02204 return true;
02205 }
02206 else if (rollup.getState() == Rollup::STATE_NONE)
02207 {
02208 for (uint32_t i=0 ; i <= send_group_parts ;i++)
02209 sum_funcs_end[i]= func;
02210 }
02211 else if (rollup.getState() == Rollup::STATE_READY)
02212 return false;
02213 *func=0;
02214 return false;
02215 }
02216
02218 bool Join::rollup_init()
02219 {
02220
02221 tmp_table_param.quick_group= 0;
02222 rollup.setState(Rollup::STATE_INITED);
02223
02224
02225
02226
02227
02228 tmp_table_param.group_parts= send_group_parts;
02229
02230 rollup.setNullItems((Item_null_result**) session->mem.alloc((sizeof(Item*) + sizeof(Item**) + sizeof(List<Item>) + ref_pointer_array_size) * send_group_parts));
02231 rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
02232 rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
02233 Item** ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
02234
02235
02236
02237
02238
02239 for (uint32_t i= 0 ; i < send_group_parts ; i++)
02240 {
02241 rollup.getNullItems()[i]= new (session->mem) Item_null_result();
02242 List<Item> *rollup_fields= &rollup.getFields()[i];
02243 rollup_fields->clear();
02244 rollup.getRefPointerArrays()[i]= ref_array;
02245 ref_array+= all_fields.size();
02246 }
02247
02248 for (uint32_t i= 0 ; i < send_group_parts; i++)
02249 {
02250 for (uint32_t j= 0 ; j < fields_list.size() ; j++)
02251 {
02252 rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
02253 }
02254 }
02255
02256 List<Item>::iterator it(all_fields.begin());
02257 while (Item* item= it++)
02258 {
02259 Order *group_tmp;
02260 bool found_in_group= 0;
02261
02262 for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
02263 {
02264 if (*group_tmp->item == item)
02265 {
02266 item->maybe_null= 1;
02267 found_in_group= 1;
02268 if (item->const_item())
02269 {
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 Item* new_item= new Item_func_rollup_const(item);
02284 new_item->fix_fields(session, NULL);
02285 *it.ref()= new_item;
02286 for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
02287 {
02288 if (*tmp->item == item)
02289 *tmp->item= new_item;
02290 }
02291 }
02292 }
02293 }
02294 if (item->type() == Item::FUNC_ITEM && !found_in_group)
02295 {
02296 bool changed= false;
02297 if (change_group_ref(session, (Item_func *) item, group_list, &changed))
02298 return 1;
02299
02300
02301
02302
02303
02304 if (changed)
02305 item->with_sum_func= 1;
02306 }
02307 }
02308 return 0;
02309 }
02310
02326 bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
02327 {
02328 List<Item>::iterator it(fields_arg.begin());
02329 Item *first_field= &sel_fields.front();
02330 uint32_t level;
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353 for (level=0 ; level < send_group_parts ; level++)
02354 {
02355 uint32_t i;
02356 uint32_t pos= send_group_parts - level -1;
02357 bool real_fields= 0;
02358 Item *item;
02359 List<Item>::iterator new_it(rollup.getFields()[pos].begin());
02360 Item **ref_array_start= rollup.getRefPointerArrays()[pos];
02361 Order *start_group;
02362
02363
02364 Item **ref_array= ref_array_start + fields_arg.size()-1;
02365
02366
02367 sum_funcs_end[pos+1]= *func;
02368
02369
02370 for (i= 0, start_group= group_list ;i++ < pos ;start_group= start_group->next)
02371 {}
02372
02373 it= fields_arg.begin();
02374 while ((item= it++))
02375 {
02376 if (item == first_field)
02377 {
02378 real_fields= 1;
02379 ref_array= ref_array_start;
02380 }
02381
02382 if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
02383 (!((Item_sum*) item)->depended_from() ||
02384 ((Item_sum *)item)->depended_from() == select_lex))
02385
02386 {
02387
02388
02389
02390
02391
02392
02393
02394
02395 item= item->copy_or_same(session);
02396 ((Item_sum*) item)->make_unique();
02397 *(*func)= (Item_sum*) item;
02398 (*func)++;
02399 }
02400 else
02401 {
02402
02403 Order *group_tmp;
02404 for (group_tmp= start_group, i= pos ;
02405 group_tmp ; group_tmp= group_tmp->next, i++)
02406 {
02407 if (*group_tmp->item == item)
02408 {
02409
02410
02411
02412
02413 Item_null_result *null_item= new (session->mem) Item_null_result();
02414 item->maybe_null= 1;
02415 null_item->result_field= item->get_tmp_table_field();
02416 item= null_item;
02417 break;
02418 }
02419 }
02420 }
02421 *ref_array= item;
02422 if (real_fields)
02423 {
02424 (void) new_it++;
02425 new_it.replace(item);
02426 ref_array++;
02427 }
02428 else
02429 ref_array--;
02430 }
02431 }
02432 sum_funcs_end[0]= *func;
02433 return 0;
02434 }
02435
02454 int Join::rollup_send_data(uint32_t idx)
02455 {
02456 for (uint32_t i= send_group_parts ; i-- > idx ; )
02457 {
02458
02459 memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
02460
02461 if ((!having || having->val_int()))
02462 {
02463 if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
02464 {
02465 return 1;
02466 }
02467 send_records++;
02468 }
02469 }
02470
02471 set_items_ref_array(current_ref_pointer_array);
02472
02473 return 0;
02474 }
02475
02495 int Join::rollup_write_data(uint32_t idx, Table *table_arg)
02496 {
02497 for (uint32_t i= send_group_parts ; i-- > idx ; )
02498 {
02499
02500 memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
02501 ref_pointer_array_size);
02502 if ((!having || having->val_int()))
02503 {
02504 List<Item>::iterator it(rollup.getFields()[i].begin());
02505 while (Item* item= it++)
02506 {
02507 if (item->type() == Item::NULL_ITEM && item->is_result_field())
02508 item->save_in_result_field(1);
02509 }
02510 copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
02511 if (table_arg->cursor->insertRecord(table_arg->getInsertRecord()))
02512 {
02513 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
02514 return 1;
02515 }
02516 }
02517 }
02518
02519 set_items_ref_array(current_ref_pointer_array);
02520
02521 return 0;
02522 }
02523
02528 void Join::clear()
02529 {
02530 clear_tables(this);
02531 copy_fields(&tmp_table_param);
02532
02533 if (sum_funcs)
02534 {
02535 Item_sum *func, **func_ptr= sum_funcs;
02536 while ((func= *(func_ptr++)))
02537 func->clear();
02538 }
02539 }
02540
02551 bool Join::change_result(select_result *res)
02552 {
02553 result= res;
02554 if (result->prepare(fields_list, select_lex->master_unit()))
02555 {
02556 return true;
02557 }
02558 return false;
02559 }
02560
02565 void Join::cache_const_exprs()
02566 {
02567 bool cache_flag= false;
02568 bool *analyzer_arg= &cache_flag;
02569
02570
02571 if (const_tables == tables)
02572 return;
02573
02574 if (conds)
02575 conds->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
02576 &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
02577 cache_flag= false;
02578 if (having)
02579 having->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
02580 &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
02581
02582 for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
02583 {
02584 if (*tab->on_expr_ref)
02585 {
02586 cache_flag= false;
02587 (*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
02588 (unsigned char **)&analyzer_arg,
02589 &Item::cache_const_expr_transformer,
02590 (unsigned char *)&cache_flag);
02591 }
02592 }
02593 }
02594
02606 enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
02607 {
02608 bool not_used_in_distinct= join_tab->not_used_in_distinct;
02609 ha_rows found_records= join->found_records;
02610 COND *select_cond= join_tab->select_cond;
02611
02612 if (error > 0 || (join->session->is_error()))
02613 return NESTED_LOOP_ERROR;
02614 if (error < 0)
02615 return NESTED_LOOP_NO_MORE_ROWS;
02616 if (join->session->getKilled())
02617 {
02618 join->session->send_kill_message();
02619 return NESTED_LOOP_KILLED;
02620 }
02621 if (!select_cond || select_cond->val_int())
02622 {
02623
02624
02625
02626
02627 bool found= 1;
02628 while (join_tab->first_unmatched && found)
02629 {
02630
02631
02632
02633
02634 JoinTable *first_unmatched= join_tab->first_unmatched;
02635
02636
02637
02638
02639
02640 first_unmatched->found= 1;
02641 for (JoinTable *tab= first_unmatched; tab <= join_tab; tab++)
02642 {
02643 if (tab->table->reginfo.not_exists_optimize)
02644 return NESTED_LOOP_NO_MORE_ROWS;
02645
02646
02647
02648
02649
02650
02651 if (tab->select_cond && !tab->select_cond->val_int())
02652 {
02653
02654 if (tab == join_tab)
02655 found= 0;
02656 else
02657 {
02658
02659
02660
02661
02662 join->return_tab= tab;
02663 return NESTED_LOOP_OK;
02664 }
02665 }
02666 }
02667
02668
02669
02670
02671 if ((first_unmatched= first_unmatched->first_upper) &&
02672 first_unmatched->last_inner != join_tab)
02673 first_unmatched= 0;
02674 join_tab->first_unmatched= first_unmatched;
02675 }
02676
02677 JoinTable *return_tab= join->return_tab;
02678 join_tab->found_match= true;
02679
02680
02681
02682
02683
02684
02685 join->examined_rows++;
02686 join->session->row_count++;
02687
02688 if (found)
02689 {
02690 enum enum_nested_loop_state rc;
02691
02692 rc= (*join_tab->next_select)(join, join_tab+1, 0);
02693 if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
02694 return rc;
02695 if (return_tab < join->return_tab)
02696 join->return_tab= return_tab;
02697
02698 if (join->return_tab < join_tab)
02699 return NESTED_LOOP_OK;
02700
02701
02702
02703
02704
02705 if (not_used_in_distinct && found_records != join->found_records)
02706 return NESTED_LOOP_NO_MORE_ROWS;
02707 }
02708 else
02709 join_tab->read_record.cursor->unlock_row();
02710 }
02711 else
02712 {
02713
02714
02715
02716
02717 join->examined_rows++;
02718 join->session->row_count++;
02719 join_tab->read_record.cursor->unlock_row();
02720 }
02721 return NESTED_LOOP_OK;
02722 }
02723
02730 enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
02731 {
02732
02733
02734
02735
02736 JoinTable *last_inner_tab= join_tab->last_inner;
02737
02738 COND *select_cond;
02739 for ( ; join_tab <= last_inner_tab ; join_tab++)
02740 {
02741
02742 join_tab->found= 1;
02743 join_tab->not_null_compl= 0;
02744
02745 join_tab->table->restoreRecordAsDefault();
02746 join_tab->table->mark_as_null_row();
02747 select_cond= join_tab->select_cond;
02748
02749 if (select_cond && !select_cond->val_int())
02750 return NESTED_LOOP_OK;
02751 }
02752 join_tab--;
02753
02754
02755
02756
02757
02758
02759 for ( ; ; )
02760 {
02761 JoinTable *first_unmatched= join_tab->first_unmatched;
02762 if ((first_unmatched= first_unmatched->first_upper) && first_unmatched->last_inner != join_tab)
02763 first_unmatched= 0;
02764 join_tab->first_unmatched= first_unmatched;
02765 if (! first_unmatched)
02766 break;
02767 first_unmatched->found= 1;
02768 for (JoinTable *tab= first_unmatched; tab <= join_tab; tab++)
02769 {
02770 if (tab->select_cond && !tab->select_cond->val_int())
02771 {
02772 join->return_tab= tab;
02773 return NESTED_LOOP_OK;
02774 }
02775 }
02776 }
02777
02778
02779
02780
02781
02782
02783 return (*join_tab->next_select)(join, join_tab+1, 0);
02784 }
02785
02786 enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
02787 {
02788 enum_nested_loop_state rc= NESTED_LOOP_OK;
02789 int error;
02790 ReadRecord *info;
02791
02792 join_tab->table->null_row= 0;
02793 if (!join_tab->cache.records)
02794 {
02795 return NESTED_LOOP_OK;
02796 }
02797
02798 if (skip_last)
02799 {
02800 (void) join_tab->cache.store_record_in_cache();
02801 }
02802
02803
02804 if (join_tab->use_quick == 2)
02805 {
02806 delete join_tab->select->quick;
02807 join_tab->select->quick= 0;
02808 }
02809
02810 if ((error=join_init_read_record(join_tab)))
02811 {
02812 join_tab->cache.reset_cache_write();
02813 return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
02814 }
02815
02816 for (JoinTable *tmp=join->join_tab; tmp != join_tab ; tmp++)
02817 {
02818 tmp->status=tmp->table->status;
02819 tmp->table->status=0;
02820 }
02821
02822 info= &join_tab->read_record;
02823 do
02824 {
02825 if (join->session->getKilled())
02826 {
02827 join->session->send_kill_message();
02828 return NESTED_LOOP_KILLED;
02829 }
02830 optimizer::SqlSelect *select= join_tab->select;
02831 if (rc == NESTED_LOOP_OK &&
02832 (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
02833 {
02834 uint32_t i;
02835 join_tab->cache.reset_cache_read();
02836 for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
02837 {
02838 join_tab->readCachedRecord();
02839 if (!select || !select->skip_record())
02840 {
02841 int res= 0;
02842
02843 rc= (join_tab->next_select)(join,join_tab+1,0);
02844 if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
02845 {
02846 join_tab->cache.reset_cache_write();
02847 return rc;
02848 }
02849
02850 if (res == -1)
02851 return NESTED_LOOP_ERROR;
02852 }
02853 }
02854 }
02855 } while (!(error=info->read_record(info)));
02856
02857 if (skip_last)
02858 join_tab->readCachedRecord();
02859 join_tab->cache.reset_cache_write();
02860 if (error > 0)
02861 return NESTED_LOOP_ERROR;
02862 for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
02863 tmp2->table->status=tmp2->status;
02864 return NESTED_LOOP_OK;
02865 }
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891 enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
02892 {
02893 if (! end_of_records)
02894 {
02895 int error;
02896 if (join->having && join->having->val_int() == 0)
02897 return NESTED_LOOP_OK;
02898 error= 0;
02899 if (join->do_send_rows)
02900 error=join->result->send_data(*join->fields);
02901 if (error)
02902 return NESTED_LOOP_ERROR;
02903 if (++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows)
02904 {
02905 if (join->select_options & OPTION_FOUND_ROWS)
02906 {
02907 JoinTable *jt=join->join_tab;
02908 if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
02909 && !join->send_group_parts && !join->having && !jt->select_cond &&
02910 !(jt->select && jt->select->quick) &&
02911 (jt->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
02912 (jt->ref.key < 0))
02913 {
02914
02915 Table *table= jt->table;
02916
02917 join->select_options^= OPTION_FOUND_ROWS;
02918 if (table->sort.record_pointers ||
02919 (table->sort.io_cache && table->sort.io_cache->inited()))
02920 {
02921
02922 join->send_records= table->sort.found_records;
02923 }
02924 else
02925 {
02926 table->cursor->info(HA_STATUS_VARIABLE);
02927 join->send_records= table->cursor->stats.records;
02928 }
02929 }
02930 else
02931 {
02932 join->do_send_rows= 0;
02933 if (join->unit->fake_select_lex)
02934 join->unit->fake_select_lex->select_limit= 0;
02935 return NESTED_LOOP_OK;
02936 }
02937 }
02938 return NESTED_LOOP_QUERY_LIMIT;
02939 }
02940 else if (join->send_records >= join->fetch_limit)
02941 {
02942
02943
02944
02945
02946 return NESTED_LOOP_CURSOR_LIMIT;
02947 }
02948 }
02949
02950 return NESTED_LOOP_OK;
02951 }
02952
02953 enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
02954 {
02955 Table *table= join->tmp_table;
02956
02957 if (join->session->getKilled())
02958 {
02959 join->session->send_kill_message();
02960 return NESTED_LOOP_KILLED;
02961 }
02962 if (!end_of_records)
02963 {
02964 copy_fields(&join->tmp_table_param);
02965 if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
02966 return NESTED_LOOP_ERROR;
02967 if (!join->having || join->having->val_int())
02968 {
02969 int error;
02970 join->found_records++;
02971 if ((error=table->cursor->insertRecord(table->getInsertRecord())))
02972 {
02973 if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
02974 {
02975 return NESTED_LOOP_OK;
02976 }
02977
02978 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
02979 return NESTED_LOOP_ERROR;
02980 }
02981 if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
02982 {
02983 if (!(join->select_options & OPTION_FOUND_ROWS))
02984 return NESTED_LOOP_QUERY_LIMIT;
02985 join->do_send_rows= 0;
02986 join->unit->select_limit_cnt= HA_POS_ERROR;
02987 return NESTED_LOOP_OK;
02988 }
02989 }
02990 }
02991
02992 return NESTED_LOOP_OK;
02993 }
02994
02996 enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
02997 {
02998 Table *table= join->tmp_table;
02999 Order *group;
03000 int error;
03001
03002 if (end_of_records)
03003 return NESTED_LOOP_OK;
03004 if (join->session->getKilled())
03005 {
03006 join->session->send_kill_message();
03007 return NESTED_LOOP_KILLED;
03008 }
03009
03010 join->found_records++;
03011 copy_fields(&join->tmp_table_param);
03012
03013 for (group=table->group ; group ; group=group->next)
03014 {
03015 Item *item= *group->item;
03016 item->save_org_in_field(group->field);
03017
03018 if (item->maybe_null)
03019 group->buff[-1]= (char) group->field->is_null();
03020 }
03021 if (!table->cursor->index_read_map(table->getUpdateRecord(),
03022 join->tmp_table_param.group_buff,
03023 HA_WHOLE_KEY,
03024 HA_READ_KEY_EXACT))
03025 {
03026 table->restoreRecord();
03027 update_tmptable_sum_func(join->sum_funcs,table);
03028 if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
03029 table->getInsertRecord())))
03030 {
03031 table->print_error(error,MYF(0));
03032 return NESTED_LOOP_ERROR;
03033 }
03034 return NESTED_LOOP_OK;
03035 }
03036
03037
03038
03039
03040
03041
03042 KeyPartInfo *key_part;
03043 for (group=table->group,key_part=table->key_info[0].key_part;
03044 group ;
03045 group=group->next,key_part++)
03046 {
03047 if (key_part->null_bit)
03048 memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
03049 }
03050 init_tmptable_sum_functions(join->sum_funcs);
03051 if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
03052 return NESTED_LOOP_ERROR;
03053 if ((error=table->cursor->insertRecord(table->getInsertRecord())))
03054 {
03055 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
03056 return NESTED_LOOP_ERROR;
03057 }
03058 join->send_records++;
03059 return NESTED_LOOP_OK;
03060 }
03061
03063 enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
03064 {
03065 Table *table= join->tmp_table;
03066 int error;
03067
03068 if (end_of_records)
03069 return NESTED_LOOP_OK;
03070 if (join->session->getKilled())
03071 {
03072 join->session->send_kill_message();
03073 return NESTED_LOOP_KILLED;
03074 }
03075
03076 init_tmptable_sum_functions(join->sum_funcs);
03077 copy_fields(&join->tmp_table_param);
03078 if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
03079 return NESTED_LOOP_ERROR;
03080
03081 if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
03082 join->send_records++;
03083 else
03084 {
03085 if ((int) table->get_dup_key(error) < 0)
03086 {
03087 table->print_error(error,MYF(0));
03088 return NESTED_LOOP_ERROR;
03089 }
03090 if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
03091 {
03092 table->print_error(error,MYF(0));
03093 return NESTED_LOOP_ERROR;
03094 }
03095 table->restoreRecord();
03096 update_tmptable_sum_func(join->sum_funcs,table);
03097 if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
03098 table->getInsertRecord())))
03099 {
03100 table->print_error(error,MYF(0));
03101 return NESTED_LOOP_ERROR;
03102 }
03103 }
03104 return NESTED_LOOP_OK;
03105 }
03106
03119 static bool make_group_fields(Join *main_join, Join *curr_join)
03120 {
03121 if (main_join->group_fields_cache.size())
03122 {
03123 curr_join->group_fields= main_join->group_fields_cache;
03124 curr_join->sort_and_group= 1;
03125 }
03126 else
03127 {
03128 if (alloc_group_fields(curr_join, curr_join->group_list))
03129 return 1;
03130 main_join->group_fields_cache= curr_join->group_fields;
03131 }
03132 return (0);
03133 }
03134
03138 static void calc_group_buffer(Join *join, Order *group)
03139 {
03140 uint32_t key_length=0, parts=0, null_parts=0;
03141
03142 if (group)
03143 join->group= 1;
03144 for (; group ; group=group->next)
03145 {
03146 Item *group_item= *group->item;
03147 Field *field= group_item->get_tmp_table_field();
03148 if (field)
03149 {
03150 enum_field_types type;
03151 if ((type= field->type()) == DRIZZLE_TYPE_BLOB)
03152 key_length+=MAX_BLOB_WIDTH;
03153 else if (type == DRIZZLE_TYPE_VARCHAR)
03154 key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
03155 else
03156 key_length+= field->pack_length();
03157 }
03158 else
03159 {
03160 switch (group_item->result_type()) {
03161 case REAL_RESULT:
03162 key_length+= sizeof(double);
03163 break;
03164
03165 case INT_RESULT:
03166 key_length+= sizeof(int64_t);
03167 break;
03168
03169 case DECIMAL_RESULT:
03170 key_length+= class_decimal_get_binary_size(group_item->max_length -
03171 (group_item->decimals ? 1 : 0),
03172 group_item->decimals);
03173 break;
03174
03175 case STRING_RESULT:
03176 {
03177 enum enum_field_types type= group_item->field_type();
03178
03179
03180
03181
03182
03183 if (field::isDateTime(type))
03184 {
03185 key_length+= 8;
03186 }
03187 else
03188 {
03189
03190
03191
03192
03193
03194 key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
03195 }
03196
03197 break;
03198 }
03199
03200 case ROW_RESULT:
03201
03202 assert(0);
03203 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
03204 }
03205 }
03206
03207 parts++;
03208
03209 if (group_item->maybe_null)
03210 null_parts++;
03211 }
03212
03213 join->tmp_table_param.group_length=key_length+null_parts;
03214 join->tmp_table_param.group_parts=parts;
03215 join->tmp_table_param.group_null_parts=null_parts;
03216 }
03217
03223 static bool alloc_group_fields(Join *join, Order *group)
03224 {
03225 if (group)
03226 {
03227 for (; group ; group=group->next)
03228 {
03229 Cached_item *tmp= new_Cached_item(join->session, *group->item);
03230 if (!tmp)
03231 return true;
03232 join->group_fields.push_front(tmp);
03233 }
03234 }
03235 join->sort_and_group=1;
03236 return false;
03237 }
03238
03239 static uint32_t cache_record_length(Join *join,uint32_t idx)
03240 {
03241 uint32_t length=0;
03242 JoinTable **pos,**end;
03243 Session *session=join->session;
03244
03245 for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
03246 pos != end ;
03247 pos++)
03248 {
03249 JoinTable *join_tab= *pos;
03250 if (!join_tab->used_fieldlength)
03251 calc_used_field_length(session, join_tab);
03252 length+=join_tab->used_fieldlength;
03253 }
03254 return length;
03255 }
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307 static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
03308 {
03309 double found=1.0;
03310 optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
03311 for (optimizer::Position *pos= join->getSpecificPosInPartialPlan(idx - 1);
03312 pos != pos_end;
03313 pos--)
03314 {
03315 if (pos->examinePosition(found_ref))
03316 {
03317 found_ref|= pos->getRefDependMap();
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334 if (pos->getFanout() > DBL_EPSILON)
03335 found*= pos->getFanout();
03336 }
03337 }
03338 return found;
03339 }
03340
03344 static bool get_best_combination(Join *join)
03345 {
03346 uint32_t i,tablenr;
03347 table_map used_tables;
03348 JoinTable *join_tab,*j;
03349 optimizer::KeyUse *keyuse;
03350 uint32_t table_count;
03351 Session *session=join->session;
03352 optimizer::Position cur_pos;
03353
03354 table_count=join->tables;
03355 join->join_tab=join_tab= new (session->mem) JoinTable[table_count];
03356 join->full_join=0;
03357
03358 used_tables= OUTER_REF_TABLE_BIT;
03359 for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
03360 {
03361 Table *form;
03362 cur_pos= join->getPosFromOptimalPlan(tablenr);
03363 *j= *cur_pos.getJoinTable();
03364 form=join->table[tablenr]=j->table;
03365 used_tables|= form->map;
03366 form->reginfo.join_tab=j;
03367 if (!*j->on_expr_ref)
03368 form->reginfo.not_exists_optimize=0;
03369 if (j->type == AM_CONST)
03370 continue;
03371
03372 j->ref.key = -1;
03373 j->ref.key_parts=0;
03374
03375 if (j->type == AM_SYSTEM)
03376 continue;
03377 if (j->keys.none() || ! (keyuse= cur_pos.getKeyUse()))
03378 {
03379 j->type= AM_ALL;
03380 if (tablenr != join->const_tables)
03381 join->full_join=1;
03382 }
03383 else if (create_ref_for_key(join, j, keyuse, used_tables))
03384 return true;
03385 }
03386
03387 for (i=0 ; i < table_count ; i++)
03388 join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
03389 update_depend_map(join);
03390 return 0;
03391 }
03392
03394 static void set_position(Join *join,
03395 uint32_t idx,
03396 JoinTable *table,
03397 optimizer::KeyUse *key)
03398 {
03399 optimizer::Position tmp_pos(1.0,
03400 0.0,
03401 table,
03402 key,
03403 0);
03404 join->setPosInPartialPlan(idx, tmp_pos);
03405
03406
03407 JoinTable **pos=join->best_ref+idx+1;
03408 JoinTable *next=join->best_ref[idx];
03409 for (;next != table ; pos++)
03410 {
03411 JoinTable *tmp=pos[0];
03412 pos[0]=next;
03413 next=tmp;
03414 }
03415 join->best_ref[idx]=table;
03416 }
03417
03436 static bool choose_plan(Join *join, table_map join_tables)
03437 {
03438 uint32_t search_depth= join->session->variables.optimizer_search_depth;
03439 uint32_t prune_level= join->session->variables.optimizer_prune_level;
03440 bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
03441
03442 join->cur_embedding_map.reset();
03443 reset_nj_counters(join->join_list);
03444
03445
03446
03447
03448
03449
03450
03451
03452 internal::my_qsort(join->best_ref + join->const_tables,
03453 join->tables - join->const_tables, sizeof(JoinTable*),
03454 straight_join ? join_tab_cmp_straight : join_tab_cmp);
03455 if (straight_join)
03456 {
03457 optimize_straight_join(join, join_tables);
03458 }
03459 else
03460 {
03461 if (search_depth == 0)
03462
03463 search_depth= determine_search_depth(join);
03464 if (greedy_search(join, join_tables, search_depth, prune_level))
03465 return true;
03466 }
03467
03468
03469
03470
03471
03472
03473
03474 if (join->session->lex().is_single_level_stmt())
03475 join->session->status_var.last_query_cost= join->best_read;
03476 return false;
03477 }
03478
03503 static void best_access_path(Join *join,
03504 JoinTable *s,
03505 Session *session,
03506 table_map remaining_tables,
03507 uint32_t idx,
03508 double record_count,
03509 double)
03510 {
03511 optimizer::KeyUse *best_key= NULL;
03512 uint32_t best_max_key_part= 0;
03513 bool found_constraint= 0;
03514 double best= DBL_MAX;
03515 double best_time= DBL_MAX;
03516 double records= DBL_MAX;
03517 table_map best_ref_depends_map= 0;
03518 double tmp;
03519 ha_rows rec;
03520
03521 if (s->keyuse)
03522 {
03523 Table *table= s->table;
03524 optimizer::KeyUse *keyuse= NULL;
03525 optimizer::KeyUse *start_key= NULL;
03526 double best_records= DBL_MAX;
03527 uint32_t max_key_part=0;
03528
03529
03530 rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;
03531 for (keyuse= s->keyuse; keyuse->getTable() == table; )
03532 {
03533 key_part_map found_part= 0;
03534 table_map found_ref= 0;
03535 uint32_t key= keyuse->getKey();
03536 KeyInfo *keyinfo= table->key_info + key;
03537
03538 key_part_map const_part= 0;
03539
03540 key_part_map ref_or_null_part= 0;
03541
03542
03543 start_key= keyuse;
03544
03545 do
03546 {
03547 uint32_t keypart= keyuse->getKeypart();
03548 table_map best_part_found_ref= 0;
03549 double best_prev_record_reads= DBL_MAX;
03550
03551 do
03552 {
03553
03554
03555
03556
03557
03558 if (! (remaining_tables & keyuse->getUsedTables()) &&
03559 ! (ref_or_null_part && (keyuse->getOptimizeFlags() &
03560 KEY_OPTIMIZE_REF_OR_NULL)))
03561 {
03562 found_part|= keyuse->getKeypartMap();
03563 if (! (keyuse->getUsedTables() & ~join->const_table_map))
03564 const_part|= keyuse->getKeypartMap();
03565
03566 double tmp2= prev_record_reads(join, idx, (found_ref |
03567 keyuse->getUsedTables()));
03568 if (tmp2 < best_prev_record_reads)
03569 {
03570 best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
03571 best_prev_record_reads= tmp2;
03572 }
03573 if (rec > keyuse->getTableRows())
03574 rec= keyuse->getTableRows();
03575
03576
03577
03578
03579 if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
03580 ref_or_null_part|= keyuse->getKeypartMap();
03581 }
03582
03583 keyuse++;
03584 } while (keyuse->getTable() == table && keyuse->getKey() == key &&
03585 keyuse->getKeypart() == keypart);
03586 found_ref|= best_part_found_ref;
03587 } while (keyuse->getTable() == table && keyuse->getKey() == key);
03588
03589
03590
03591
03592 if (!found_part)
03593 continue;
03594
03595 if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
03596 rec= MATCHING_ROWS_IN_OTHER_TABLE;
03597
03598 {
03599 found_constraint= 1;
03600
03601
03602
03603
03604 if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
03605 !ref_or_null_part)
03606 {
03607 max_key_part= UINT32_MAX;
03608 if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
03609 {
03610 tmp = prev_record_reads(join, idx, found_ref);
03611 records=1.0;
03612 }
03613 else
03614 {
03615 if (!found_ref)
03616 {
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634 if (table->quick_keys.test(key))
03635 records= (double) table->quick_rows[key];
03636 else
03637 {
03638
03639 records= (double) s->records/rec;
03640 }
03641 }
03642 else
03643 {
03644 if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
03645 {
03646 records=
03647 ((double) s->records / (double) rec *
03648 (1.0 +
03649 ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
03650 (double) table->getShare()->max_key_length)));
03651 if (records < 2.0)
03652 records=2.0;
03653 }
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664 if (table->quick_keys.test(key) &&
03665 const_part & (1 << table->quick_key_parts[key]) &&
03666 table->quick_n_ranges[key] == 1 &&
03667 records > (double) table->quick_rows[key])
03668 {
03669 records= (double) table->quick_rows[key];
03670 }
03671 }
03672
03673 tmp= records;
03674 set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
03675 if (table->covering_keys.test(key))
03676 {
03677
03678 tmp= record_count * table->cursor->index_only_read_time(key, tmp);
03679 }
03680 else
03681 tmp= record_count * min(tmp,s->worst_seeks);
03682 }
03683 }
03684 else
03685 {
03686
03687
03688
03689
03690
03691 if ((found_part & 1) &&
03692 (!(table->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
03693 found_part == PREV_BITS(uint, keyinfo->key_parts)))
03694 {
03695 max_key_part= max_part_bit(found_part);
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735 if (table->quick_keys.test(key) && !found_ref &&
03736 table->quick_key_parts[key] == max_key_part &&
03737 table->quick_n_ranges[key] == 1+((ref_or_null_part)?1:0))
03738 {
03739 tmp= records= (double) table->quick_rows[key];
03740 }
03741 else
03742 {
03743
03744 if ((records= keyinfo->rec_per_key[max_key_part-1]))
03745 {
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762 if (!found_ref && table->quick_keys.test(key) &&
03763 table->quick_key_parts[key] > max_key_part &&
03764 records < (double)table->quick_rows[key])
03765 records= (double)table->quick_rows[key];
03766
03767 tmp= records;
03768 }
03769 else
03770 {
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785 double rec_per_key;
03786 if (!(rec_per_key=(double)
03787 keyinfo->rec_per_key[keyinfo->key_parts-1]))
03788 rec_per_key=(double) s->records/rec+1;
03789
03790 if (!s->records)
03791 tmp = 0;
03792 else if (rec_per_key/(double) s->records >= 0.01)
03793 tmp = rec_per_key;
03794 else
03795 {
03796 double a=s->records*0.01;
03797 if (keyinfo->key_parts > 1)
03798 tmp= (max_key_part * (rec_per_key - a) +
03799 a*keyinfo->key_parts - rec_per_key)/
03800 (keyinfo->key_parts-1);
03801 else
03802 tmp= a;
03803 set_if_bigger(tmp,1.0);
03804 }
03805 records = (uint32_t) tmp;
03806 }
03807
03808 if (ref_or_null_part)
03809 {
03810
03811 tmp *= 2.0;
03812 records *= 2.0;
03813 }
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 if (table->quick_keys.test(key) &&
03828 table->quick_key_parts[key] <= max_key_part &&
03829 const_part & (1 << table->quick_key_parts[key]) &&
03830 table->quick_n_ranges[key] == 1 + ((ref_or_null_part &
03831 const_part) ? 1 : 0) &&
03832 records > (double) table->quick_rows[key])
03833 {
03834 tmp= records= (double) table->quick_rows[key];
03835 }
03836 }
03837
03838
03839 set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
03840 if (table->covering_keys.test(key))
03841 {
03842
03843 tmp= record_count * table->cursor->index_only_read_time(key, tmp);
03844 }
03845 else
03846 tmp= record_count * min(tmp,s->worst_seeks);
03847 }
03848 else
03849 tmp= best_time;
03850 }
03851
03852 }
03853 if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
03854 {
03855 best_time= tmp + records/(double) TIME_FOR_COMPARE;
03856 best= tmp;
03857 best_records= records;
03858 best_key= start_key;
03859 best_max_key_part= max_key_part;
03860 best_ref_depends_map= found_ref;
03861 }
03862 }
03863 records= best_records;
03864 }
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894 if ((records >= s->found_records || best > s->read_time) &&
03895 ! (s->quick && best_key && s->quick->index == best_key->getKey() &&
03896 best_max_key_part >= s->table->quick_key_parts[best_key->getKey()]) &&
03897 ! ((s->table->cursor->getEngine()->check_flag(HTON_BIT_TABLE_SCAN_ON_INDEX)) &&
03898 ! s->table->covering_keys.none() && best_key && !s->quick) &&
03899 ! (s->table->force_index && best_key && !s->quick))
03900 {
03901 ha_rows rnd_records= s->found_records;
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911 if (found_constraint)
03912 rnd_records-= rnd_records/4;
03913
03914
03915
03916
03917
03918 if (s->table->quick_condition_rows != s->found_records)
03919 rnd_records= s->table->quick_condition_rows;
03920
03921
03922
03923
03924
03925
03926 if (s->quick)
03927 {
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937 tmp= record_count *
03938 (s->quick->read_time +
03939 (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
03940 }
03941 else
03942 {
03943
03944 tmp= s->table->cursor->scan_time();
03945 if (s->table->map & join->outer_join)
03946 {
03947
03948
03949
03950
03951
03952 tmp= record_count *
03953 (tmp +
03954 (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
03955 }
03956 else
03957 {
03958
03959 tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
03960 record_count /
03961 (double) session->variables.join_buff_size));
03962
03963
03964
03965
03966
03967
03968
03969 tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
03970 }
03971 }
03972
03973
03974
03975
03976
03977
03978 if (best == DBL_MAX ||
03979 (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
03980 best + record_count/(double) TIME_FOR_COMPARE*records))
03981 {
03982
03983
03984
03985
03986 best= tmp;
03987 records= rnd_records;
03988 best_key= 0;
03989
03990 best_ref_depends_map= 0;
03991 }
03992 }
03993
03994
03995 optimizer::Position tmp_pos(records,
03996 best,
03997 s,
03998 best_key,
03999 best_ref_depends_map);
04000 join->setPosInPartialPlan(idx, tmp_pos);
04001
04002 if (!best_key &&
04003 idx == join->const_tables &&
04004 s->table == join->sort_by_table &&
04005 join->unit->select_limit_cnt >= records)
04006 join->sort_by_table= (Table*) 1;
04007
04008 return;
04009 }
04010
04033 static void optimize_straight_join(Join *join, table_map join_tables)
04034 {
04035 JoinTable *s;
04036 optimizer::Position partial_pos;
04037 uint32_t idx= join->const_tables;
04038 double record_count= 1.0;
04039 double read_time= 0.0;
04040
04041 for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
04042 {
04043
04044 best_access_path(join, s, join->session, join_tables, idx,
04045 record_count, read_time);
04046
04047 partial_pos= join->getPosFromPartialPlan(idx);
04048 record_count*= partial_pos.getFanout();
04049 read_time+= partial_pos.getCost();
04050 join_tables&= ~(s->table->map);
04051 ++idx;
04052 }
04053
04054 read_time+= record_count / (double) TIME_FOR_COMPARE;
04055 partial_pos= join->getPosFromPartialPlan(join->const_tables);
04056 if (join->sort_by_table &&
04057 partial_pos.hasTableForSorting(join->sort_by_table))
04058 read_time+= record_count;
04059 join->copyPartialPlanIntoOptimalPlan(idx);
04060 join->best_read= read_time;
04061 }
04062
04143 static bool greedy_search(Join *join,
04144 table_map remaining_tables,
04145 uint32_t search_depth,
04146 uint32_t prune_level)
04147 {
04148 double record_count= 1.0;
04149 double read_time= 0.0;
04150 uint32_t idx= join->const_tables;
04151 uint32_t best_idx;
04152 uint32_t size_remain;
04153 optimizer::Position best_pos;
04154 JoinTable *best_table;
04155
04156
04157 size_remain= internal::my_count_bits(remaining_tables);
04158
04159 do {
04160
04161 join->best_read= DBL_MAX;
04162 if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
04163 read_time, search_depth, prune_level))
04164 return true;
04165
04166 if (size_remain <= search_depth)
04167 {
04168
04169
04170
04171
04172 return false;
04173 }
04174
04175
04176 best_pos= join->getPosFromOptimalPlan(idx);
04177 best_table= best_pos.getJoinTable();
04178
04179
04180
04181
04182
04183 join->setPosInPartialPlan(idx, best_pos);
04184
04185
04186
04187
04188
04189
04190 check_interleaving_with_nj (best_table);
04191
04192
04193
04194
04195 best_idx= idx;
04196 JoinTable *pos= join->best_ref[best_idx];
04197 while (pos && best_table != pos)
04198 pos= join->best_ref[++best_idx];
04199 assert((pos != NULL));
04200
04201 std::swap(join->best_ref[idx], join->best_ref[best_idx]);
04202
04203
04204 optimizer::Position partial_pos= join->getPosFromPartialPlan(idx);
04205 record_count*= partial_pos.getFanout();
04206 read_time+= partial_pos.getCost();
04207
04208 remaining_tables&= ~(best_table->table->map);
04209 --size_remain;
04210 ++idx;
04211 } while (true);
04212 }
04213
04214
04331 static bool best_extension_by_limited_search(Join *join,
04332 table_map remaining_tables,
04333 uint32_t idx,
04334 double record_count,
04335 double read_time,
04336 uint32_t search_depth,
04337 uint32_t prune_level)
04338 {
04339 Session *session= join->session;
04340 if (session->getKilled())
04341 return true;
04342
04343
04344
04345
04346
04347 JoinTable *s;
04348 double best_record_count= DBL_MAX;
04349 double best_read_time= DBL_MAX;
04350 optimizer::Position partial_pos;
04351
04352 for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
04353 {
04354 table_map real_table_bit= s->table->map;
04355 if ((remaining_tables & real_table_bit) &&
04356 ! (remaining_tables & s->dependent) &&
04357 (! idx || ! check_interleaving_with_nj(s)))
04358 {
04359 double current_record_count, current_read_time;
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369 best_access_path(join, s, session, remaining_tables, idx,
04370 record_count, read_time);
04371
04372 partial_pos= join->getPosFromPartialPlan(idx);
04373 current_record_count= record_count * partial_pos.getFanout();
04374 current_read_time= read_time + partial_pos.getCost();
04375
04376
04377 if ((current_read_time +
04378 current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
04379 {
04380 restore_prev_nj_state(s);
04381 continue;
04382 }
04383
04384
04385
04386
04387
04388 if (prune_level == 1)
04389 {
04390 if (best_record_count > current_record_count ||
04391 best_read_time > current_read_time ||
04392 (idx == join->const_tables && s->table == join->sort_by_table))
04393 {
04394 if (best_record_count >= current_record_count &&
04395 best_read_time >= current_read_time &&
04396
04397 (! (s->key_dependent & remaining_tables) ||
04398 partial_pos.isConstTable()))
04399 {
04400 best_record_count= current_record_count;
04401 best_read_time= current_read_time;
04402 }
04403 }
04404 else
04405 {
04406 restore_prev_nj_state(s);
04407 continue;
04408 }
04409 }
04410
04411 if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
04412 {
04413 std::swap(join->best_ref[idx], *pos);
04414 if (best_extension_by_limited_search(join,
04415 remaining_tables & ~real_table_bit,
04416 idx + 1,
04417 current_record_count,
04418 current_read_time,
04419 search_depth - 1,
04420 prune_level))
04421 return true;
04422 std::swap(join->best_ref[idx], *pos);
04423 }
04424 else
04425 {
04426
04427
04428
04429 partial_pos= join->getPosFromPartialPlan(join->const_tables);
04430 current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
04431 if (join->sort_by_table &&
04432 partial_pos.hasTableForSorting(join->sort_by_table))
04433
04434 current_read_time+= current_record_count;
04435 if ((search_depth == 1) || (current_read_time < join->best_read))
04436 {
04437 join->copyPartialPlanIntoOptimalPlan(idx + 1);
04438 join->best_read= current_read_time - 0.001;
04439 }
04440 }
04441 restore_prev_nj_state(s);
04442 }
04443 }
04444 return false;
04445 }
04446
04478 static uint32_t determine_search_depth(Join *join)
04479 {
04480 uint32_t table_count= join->tables - join->const_tables;
04481 uint32_t search_depth;
04482
04483 uint32_t max_tables_for_exhaustive_opt= 7;
04484
04485 if (table_count <= max_tables_for_exhaustive_opt)
04486 search_depth= table_count+1;
04487 else
04488
04489
04490
04491
04492 search_depth= max_tables_for_exhaustive_opt;
04493
04494 return search_depth;
04495 }
04496
04497 static void make_simple_join(Join *join,Table *tmp_table)
04498 {
04499
04500
04501
04502
04503 if (!join->table_reexec)
04504 {
04505 join->table_reexec= new (join->session->mem) Table*;
04506 if (join->tmp_join)
04507 join->tmp_join->table_reexec= join->table_reexec;
04508 }
04509 if (!join->join_tab_reexec)
04510 {
04511 join->join_tab_reexec= new (join->session->mem) JoinTable;
04512 if (join->tmp_join)
04513 join->tmp_join->join_tab_reexec= join->join_tab_reexec;
04514 }
04515 Table** tableptr= join->table_reexec;
04516 JoinTable* join_tab= join->join_tab_reexec;
04517
04518 join->join_tab=join_tab;
04519 join->table=tableptr; tableptr[0]=tmp_table;
04520 join->tables=1;
04521 join->const_tables=0;
04522 join->const_table_map=0;
04523 join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
04524 join->tmp_table_param.func_count=0;
04525 join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
04526 join->first_record=join->sort_and_group=0;
04527 join->send_records=(ha_rows) 0;
04528 join->group=0;
04529 join->row_limit=join->unit->select_limit_cnt;
04530 join->do_send_rows = (join->row_limit) ? 1 : 0;
04531
04532 join_tab->table=tmp_table;
04533 join_tab->select=0;
04534 join_tab->select_cond=0;
04535 join_tab->quick=0;
04536 join_tab->type= AM_ALL;
04537 join_tab->keys.set();
04538 join_tab->info=0;
04539 join_tab->on_expr_ref=0;
04540 join_tab->last_inner= 0;
04541 join_tab->first_unmatched= 0;
04542 join_tab->ref.key = -1;
04543 join_tab->not_used_in_distinct=0;
04544 join_tab->read_first_record= join_init_read_record;
04545 join_tab->join=join;
04546 join_tab->ref.key_parts= 0;
04547 join_tab->read_record.init();
04548 tmp_table->status=0;
04549 tmp_table->null_row=0;
04550 }
04551
04593 static void make_outerjoin_info(Join *join)
04594 {
04595 for (uint32_t i=join->const_tables ; i < join->tables ; i++)
04596 {
04597 JoinTable *tab=join->join_tab+i;
04598 Table *table=tab->table;
04599 TableList *tbl= table->pos_in_table_list;
04600 TableList *embedding= tbl->getEmbedding();
04601
04602 if (tbl->outer_join)
04603 {
04604
04605
04606
04607
04608
04609 tab->last_inner= tab->first_inner= tab;
04610 tab->on_expr_ref= &tbl->on_expr;
04611 tab->cond_equal= tbl->cond_equal;
04612 if (embedding)
04613 tab->first_upper= embedding->getNestedJoin()->first_nested;
04614 }
04615 for ( ; embedding ; embedding= embedding->getEmbedding())
04616 {
04617
04618 if (!embedding->on_expr)
04619 continue;
04620 NestedJoin *nested_join= embedding->getNestedJoin();
04621 if (!nested_join->counter_)
04622 {
04623
04624
04625
04626
04627 nested_join->first_nested= tab;
04628 tab->on_expr_ref= &embedding->on_expr;
04629 tab->cond_equal= tbl->cond_equal;
04630 if (embedding->getEmbedding())
04631 tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
04632 }
04633 if (!tab->first_inner)
04634 tab->first_inner= nested_join->first_nested;
04635 if (++nested_join->counter_ < nested_join->join_list.size())
04636 break;
04637
04638 nested_join->first_nested->last_inner= tab;
04639 }
04640 }
04641 return;
04642 }
04643
04644 static bool make_join_select(Join *join,
04645 optimizer::SqlSelect *select,
04646 COND *cond)
04647 {
04648 Session *session= join->session;
04649 optimizer::Position cur_pos;
04650 if (select)
04651 {
04652 add_not_null_conds(join);
04653 table_map used_tables;
04654 if (cond)
04655 {
04656 if (join->tables > 1)
04657 cond->update_used_tables();
04658 if (join->const_tables == join->tables &&
04659 session->lex().current_select->master_unit() ==
04660 &session->lex().unit)
04661 join->const_table_map|=RAND_TABLE_BIT;
04662 {
04663 COND *const_cond=
04664 make_cond_for_table(cond,
04665 join->const_table_map,
04666 0, 1);
04667 for (JoinTable *tab= join->join_tab+join->const_tables;
04668 tab < join->join_tab+join->tables ; tab++)
04669 {
04670 if (*tab->on_expr_ref)
04671 {
04672 JoinTable *cond_tab= tab->first_inner;
04673 COND *tmp= make_cond_for_table(*tab->on_expr_ref,
04674 join->const_table_map,
04675 ( table_map) 0, 0);
04676 if (!tmp)
04677 continue;
04678 tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
04679 if (! tmp)
04680 return 1;
04681 tmp->quick_fix_field();
04682 cond_tab->select_cond= !cond_tab->select_cond ? tmp :
04683 new Item_cond_and(cond_tab->select_cond,
04684 tmp);
04685 if (! cond_tab->select_cond)
04686 return 1;
04687 cond_tab->select_cond->quick_fix_field();
04688 }
04689 }
04690 if (const_cond && ! const_cond->val_int())
04691 {
04692 return 1;
04693 }
04694 }
04695 }
04696 used_tables=((select->const_tables=join->const_table_map) |
04697 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
04698 for (uint32_t i=join->const_tables ; i < join->tables ; i++)
04699 {
04700 JoinTable *tab=join->join_tab+i;
04701
04702
04703
04704
04705 JoinTable *first_inner_tab= tab->first_inner;
04706 table_map current_map= tab->table->map;
04707 bool use_quick_range=0;
04708 COND *tmp;
04709
04710
04711
04712
04713
04714 if (i == join->tables-1)
04715 current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
04716 used_tables|=current_map;
04717
04718 if (tab->type == AM_REF && tab->quick &&
04719 (uint32_t) tab->ref.key == tab->quick->index &&
04720 tab->ref.key_length < tab->quick->max_used_key_length)
04721 {
04722
04723 tab->type= AM_ALL;
04724 use_quick_range= 1;
04725 tab->use_quick= 1;
04726 tab->ref.key= -1;
04727 tab->ref.key_parts= 0;
04728 cur_pos= join->getPosFromOptimalPlan(i);
04729 cur_pos.setFanout(tab->quick->records);
04730
04731
04732
04733
04734 if (i != join->const_tables && join->tables > join->const_tables + 1)
04735 join->full_join= 1;
04736 }
04737
04738 if (join->full_join and not session->lex().current_select->is_cross and not cond)
04739 {
04740 my_error(ER_CARTESIAN_JOIN_ATTEMPTED, MYF(0));
04741 return 1;
04742 }
04743
04744 tmp= NULL;
04745 if (cond)
04746 tmp= make_cond_for_table(cond,used_tables,current_map, 0);
04747 if (cond && !tmp && tab->quick)
04748 {
04749 if (tab->type != AM_ALL)
04750 {
04751
04752
04753
04754
04755
04756 delete tab->quick;
04757 tab->quick= 0;
04758 }
04759 else
04760 {
04761
04762
04763
04764
04765
04766 tmp= new Item_int((int64_t) 1,1);
04767 }
04768
04769 }
04770 if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
04771 tab->type == AM_EQ_REF)
04772 {
04773 optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)session->mem.memdup(select, sizeof(*select)));
04774
04775
04776
04777
04778
04779
04780 if (cond && tmp)
04781 {
04782
04783
04784
04785
04786 if (! (tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
04787 return 1;
04788 tab->select_cond=sel->cond=tmp;
04789 }
04790 else
04791 tab->select_cond= sel->cond= NULL;
04792
04793 sel->head=tab->table;
04794 if (tab->quick)
04795 {
04796
04797
04798 if (tab->needed_reg.none() && tab->type != AM_EQ_REF
04799 && (tab->type != AM_REF || (uint32_t) tab->ref.key == tab->quick->index))
04800 {
04801 sel->quick=tab->quick;
04802 sel->quick_keys.reset();
04803 sel->needed_reg.reset();
04804 }
04805 else
04806 {
04807 delete tab->quick;
04808 }
04809 tab->quick= 0;
04810 }
04811 uint32_t ref_key= static_cast<uint32_t>(sel->head->reginfo.join_tab->ref.key + 1);
04812 if (i == join->const_tables && ref_key)
04813 {
04814 if (tab->const_keys.any() &&
04815 tab->table->reginfo.impossible_range)
04816 return 1;
04817 }
04818 else if (tab->type == AM_ALL && ! use_quick_range)
04819 {
04820 if (tab->const_keys.any() &&
04821 tab->table->reginfo.impossible_range)
04822 return 1;
04823
04824
04825
04826
04827
04828
04829
04830 cur_pos= join->getPosFromOptimalPlan(i);
04831 if ((cond && (! ((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
04832 (! tab->const_keys.none() && (i == join->const_tables) &&
04833 (join->unit->select_limit_cnt < cur_pos.getFanout()) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
04834 {
04835
04836 COND *orig_cond= sel->cond;
04837 sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
04838
04839
04840
04841
04842
04843
04844
04845
04846 if (sel->cond && ! sel->cond->fixed)
04847 sel->cond->quick_fix_field();
04848
04849 if (sel->test_quick_select(session, tab->keys,
04850 used_tables & ~ current_map,
04851 (join->select_options &
04852 OPTION_FOUND_ROWS ?
04853 HA_POS_ERROR :
04854 join->unit->select_limit_cnt), 0,
04855 false) < 0)
04856 {
04857
04858
04859
04860
04861 sel->cond=orig_cond;
04862 if (! *tab->on_expr_ref ||
04863 sel->test_quick_select(session, tab->keys,
04864 used_tables & ~ current_map,
04865 (join->select_options &
04866 OPTION_FOUND_ROWS ?
04867 HA_POS_ERROR :
04868 join->unit->select_limit_cnt),0,
04869 false) < 0)
04870 return 1;
04871 }
04872 else
04873 sel->cond=orig_cond;
04874
04875
04876 if (sel->quick)
04877 {
04878 cur_pos= join->getPosFromOptimalPlan(i);
04879 cur_pos.setFanout(static_cast<double>(sel->quick->records));
04880 }
04881 }
04882 else
04883 {
04884 sel->needed_reg= tab->needed_reg;
04885 sel->quick_keys.reset();
04886 }
04887 if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
04888 !((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
04889 {
04890 tab->keys= sel->quick_keys;
04891 tab->keys|= sel->needed_reg;
04892 tab->use_quick= (!sel->needed_reg.none() &&
04893 (select->quick_keys.none() ||
04894 (select->quick &&
04895 (select->quick->records >= 100L)))) ?
04896 2 : 1;
04897 sel->read_tables= used_tables & ~current_map;
04898 }
04899 if (i != join->const_tables && tab->use_quick != 2)
04900 {
04901 if (cond &&
04902 (tmp=make_cond_for_table(cond,
04903 join->const_table_map |
04904 current_map,
04905 current_map, 0)))
04906 {
04907 tab->cache.select= (optimizer::SqlSelect*)session->mem.memdup(sel, sizeof(optimizer::SqlSelect));
04908 tab->cache.select->cond= tmp;
04909 tab->cache.select->read_tables= join->const_table_map;
04910 }
04911 }
04912 }
04913 }
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925 for (JoinTable *join_tab= join->join_tab+join->const_tables;
04926 join_tab < join->join_tab+join->tables ; join_tab++)
04927 {
04928 if (*join_tab->on_expr_ref)
04929 {
04930 JoinTable *cond_tab= join_tab->first_inner;
04931 tmp= make_cond_for_table(*join_tab->on_expr_ref,
04932 join->const_table_map,
04933 (table_map) 0, 0);
04934 if (!tmp)
04935 continue;
04936 tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
04937 if (! tmp)
04938 return 1;
04939 tmp->quick_fix_field();
04940 cond_tab->select_cond= !cond_tab->select_cond ? tmp :
04941 new Item_cond_and(cond_tab->select_cond,tmp);
04942 if (! cond_tab->select_cond)
04943 return 1;
04944 cond_tab->select_cond->quick_fix_field();
04945 }
04946 }
04947
04948
04949 JoinTable *last_tab= tab;
04950 while (first_inner_tab && first_inner_tab->last_inner == last_tab)
04951 {
04952
04953
04954
04955
04956 COND *on_expr= *first_inner_tab->on_expr_ref;
04957
04958 table_map used_tables2= (join->const_table_map |
04959 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
04960 for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
04961 {
04962 current_map= tab->table->map;
04963 used_tables2|= current_map;
04964 COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
04965 current_map, 0);
04966 if (tmp_cond)
04967 {
04968 JoinTable *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
04969
04970
04971
04972
04973 if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
04974 tmp_cond,
04975 first_inner_tab)))
04976 return 1;
04977
04978
04979
04980
04981 tmp_cond= new Item_func_trig_cond(tmp_cond,
04982 &first_inner_tab->
04983 not_null_compl);
04984 if (tmp_cond)
04985 tmp_cond->quick_fix_field();
04986
04987 cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
04988 new Item_cond_and(cond_tab->select_cond,
04989 tmp_cond);
04990 if (! cond_tab->select_cond)
04991 return 1;
04992 cond_tab->select_cond->quick_fix_field();
04993 }
04994 }
04995 first_inner_tab= first_inner_tab->first_upper;
04996 }
04997 }
04998 }
04999 return 0;
05000 }
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023 static void make_join_readinfo(Join& join)
05024 {
05025 bool sorted= true;
05026
05027 for (uint32_t i= join.const_tables; i < join.tables; i++)
05028 {
05029 JoinTable *tab=join.join_tab+i;
05030 Table *table=tab->table;
05031 tab->read_record.table= table;
05032 tab->read_record.cursor= table->cursor;
05033 tab->next_select=sub_select;
05034
05035
05036
05037
05038 tab->sorted= sorted;
05039 sorted= false;
05040
05041 if (tab->insideout_match_tab)
05042 {
05043 tab->insideout_buf= join.session->mem.alloc(tab->table->key_info[tab->index].key_length);
05044 }
05045
05046 optimizer::AccessMethodFactory::create(tab->type)->getStats(*table, *tab);
05047 }
05048
05049 join.join_tab[join.tables-1].next_select= NULL;
05050 }
05051
05053 static void update_depend_map(Join *join)
05054 {
05055 JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
05056
05057 for (; join_tab != end ; join_tab++)
05058 {
05059 table_reference_st *ref= &join_tab->ref;
05060 table_map depend_map= 0;
05061 Item **item=ref->items;
05062 uint32_t i;
05063 for (i=0 ; i < ref->key_parts ; i++,item++)
05064 depend_map|=(*item)->used_tables();
05065 ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
05066 depend_map&= ~OUTER_REF_TABLE_BIT;
05067 for (JoinTable **tab=join->map2table; depend_map; tab++,depend_map>>=1 )
05068 {
05069 if (depend_map & 1)
05070 ref->depend_map|=(*tab)->ref.depend_map;
05071 }
05072 }
05073 }
05074
05076 static void update_depend_map(Join *join, Order *order)
05077 {
05078 for (; order ; order=order->next)
05079 {
05080 table_map depend_map;
05081 order->item[0]->update_used_tables();
05082 order->depend_map=depend_map=order->item[0]->used_tables();
05083
05084 if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
05085 && !order->item[0]->with_sum_func)
05086 {
05087 for (JoinTable **tab=join->map2table; depend_map; tab++, depend_map>>=1)
05088 {
05089 if (depend_map & 1)
05090 order->depend_map|=(*tab)->ref.depend_map;
05091 }
05092 }
05093 }
05094 }
05095
05114 static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
05115 {
05116 if (join->tables == join->const_tables)
05117 return change_list ? 0 : first_order;
05118
05119 Order *order,**prev_ptr;
05120 table_map first_table= join->join_tab[join->const_tables].table->map;
05121 table_map not_const_tables= ~join->const_table_map;
05122 table_map ref;
05123
05124 prev_ptr= &first_order;
05125 *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
05126
05127
05128
05129 update_depend_map(join, first_order);
05130 for (order=first_order; order ; order=order->next)
05131 {
05132 table_map order_tables=order->item[0]->used_tables();
05133 if (order->item[0]->with_sum_func)
05134 *simple_order=0;
05135 else if (!(order_tables & not_const_tables))
05136 {
05137 if (order->item[0]->with_subselect)
05138 order->item[0]->val_str(&order->item[0]->str_value);
05139 continue;
05140 }
05141 else
05142 {
05143 if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))
05144 *simple_order=0;
05145 else
05146 {
05147 Item *comp_item=0;
05148 if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
05149 {
05150 continue;
05151 }
05152 if ((ref=order_tables & (not_const_tables ^ first_table)))
05153 {
05154 if (!(order_tables & first_table) &&
05155 only_eq_ref_tables(join,first_order, ref))
05156 {
05157 continue;
05158 }
05159 *simple_order=0;
05160 }
05161 }
05162 }
05163 if (change_list)
05164 *prev_ptr= order;
05165 prev_ptr= &order->next;
05166 }
05167 if (change_list)
05168 *prev_ptr=0;
05169 if (prev_ptr == &first_order)
05170 *simple_order=1;
05171 return(first_order);
05172 }
05173
05174 static void return_zero_rows(Join *join, select_result *result, TableList *tables, List<Item> &fields, bool send_row, uint64_t select_options, const char *info, Item *having)
05175 {
05176 if (select_options & SELECT_DESCRIBE)
05177 {
05178 optimizer::ExplainPlan planner(join, false, false, false, info);
05179 planner.printPlan();
05180 return;
05181 }
05182
05183 join->join_free();
05184
05185 if (send_row)
05186 {
05187 for (TableList *table= tables; table; table= table->next_leaf)
05188 table->table->mark_as_null_row();
05189 if (having && having->val_int() == 0)
05190 send_row=0;
05191 }
05192 result->send_fields(fields);
05193 if (send_row)
05194 {
05195 List<Item>::iterator it(fields.begin());
05196 while (Item* item= it++)
05197 item->no_rows_in_result();
05198 result->send_data(fields);
05199 }
05200 result->send_eof();
05201
05202 join->session->limit_found_rows= join->session->examined_row_count= 0;
05203 }
05204
05325 static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
05326 {
05327 NestedJoin *nested_join;
05328 TableList *prev_table= 0;
05329 List<TableList>::iterator li(join_list->begin());
05330
05331
05332
05333
05334
05335 while (TableList* table= li++)
05336 {
05337 table_map used_tables;
05338 table_map not_null_tables= (table_map) 0;
05339
05340 if ((nested_join= table->getNestedJoin()))
05341 {
05342
05343
05344
05345
05346 if (table->on_expr)
05347 {
05348 Item *expr= table->on_expr;
05349
05350
05351
05352
05353
05354
05355
05356
05357 expr= simplify_joins(join, &nested_join->join_list, expr, false);
05358
05359 if (!table->prep_on_expr || expr != table->on_expr)
05360 {
05361 assert(expr);
05362
05363 table->on_expr= expr;
05364 table->prep_on_expr= expr->copy_andor_structure(join->session);
05365 }
05366 }
05367 nested_join->used_tables= (table_map) 0;
05368 nested_join->not_null_tables=(table_map) 0;
05369 conds= simplify_joins(join, &nested_join->join_list, conds, top);
05370 used_tables= nested_join->used_tables;
05371 not_null_tables= nested_join->not_null_tables;
05372 }
05373 else
05374 {
05375 if (!table->prep_on_expr)
05376 table->prep_on_expr= table->on_expr;
05377 used_tables= table->table->map;
05378 if (conds)
05379 not_null_tables= conds->not_null_tables();
05380 }
05381
05382 if (table->getEmbedding())
05383 {
05384 table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
05385 table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
05386 }
05387
05388 if (!table->outer_join || (used_tables & not_null_tables))
05389 {
05390
05391
05392
05393
05394 table->outer_join= 0;
05395 if (table->on_expr)
05396 {
05397
05398 if (conds)
05399 {
05400 conds= and_conds(conds, table->on_expr);
05401 conds->top_level_item();
05402
05403 assert(!conds->fixed);
05404 conds->fix_fields(join->session, &conds);
05405 }
05406 else
05407 conds= table->on_expr;
05408 table->prep_on_expr= table->on_expr= 0;
05409 }
05410 }
05411
05412 if (!top)
05413 continue;
05414
05415
05416
05417
05418
05419 if (table->on_expr)
05420 {
05421 table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
05422 if (table->getEmbedding())
05423 {
05424 table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
05425
05426
05427
05428
05429 table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
05430 }
05431 else
05432 table->setDepTables(table->getDepTables() & ~table->table->map);
05433 }
05434
05435 if (prev_table)
05436 {
05437
05438
05439 if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
05440 prev_table->straight)
05441 prev_table->setDepTables(prev_table->getDepTables() | used_tables);
05442 if (prev_table->on_expr)
05443 {
05444 prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
05445 table_map prev_used_tables= prev_table->getNestedJoin() ?
05446 prev_table->getNestedJoin()->used_tables :
05447 prev_table->table->map;
05448
05449
05450
05451
05452
05453
05454 if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
05455 prev_table->setDepTables(prev_table->getDepTables() | used_tables);
05456 }
05457 }
05458 prev_table= table;
05459 }
05460
05461
05462
05463
05464
05465 li= join_list->begin();
05466 while (TableList* table= li++)
05467 {
05468 nested_join= table->getNestedJoin();
05469 if (nested_join && !table->on_expr)
05470 {
05471 List<TableList>::iterator it(nested_join->join_list.begin());
05472 while (TableList* tbl= it++)
05473 {
05474 tbl->setEmbedding(table->getEmbedding());
05475 tbl->setJoinList(table->getJoinList());
05476 }
05477 li.replace(nested_join->join_list);
05478 }
05479 }
05480 return(conds);
05481 }
05482
05483 static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
05484 {
05485 entry->reginfo.lock_type=TL_WRITE;
05486
05487
05488 uint32_t field_count= 0;
05489 List<Item>::iterator it(fields.begin());
05490 while (Item* item=it++)
05491 {
05492 if (item->get_tmp_table_field() && ! item->const_item())
05493 field_count++;
05494 }
05495
05496 if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
05497 {
05498 join->unit->select_limit_cnt= 1;
05499 return 0;
05500 }
05501 Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
05502 uint32_t offset= field_count ? entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0;
05503 uint32_t reclength= entry->getShare()->getRecordLength() - offset;
05504
05505 entry->free_io_cache();
05506 entry->cursor->info(HA_STATUS_VARIABLE);
05507 int error;
05508 if (entry->getShare()->db_type() == heap_engine ||
05509 (!entry->getShare()->blob_fields &&
05510 ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records < join->session->variables.sortbuff_size)))
05511 {
05512 error= remove_dup_with_hash_index(join->session, entry, field_count, first_field, reclength, having);
05513 }
05514 else
05515 {
05516 error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
05517 }
05518 free_blobs(first_field);
05519 return error;
05520 }
05521
05525 static int setup_without_group(Session *session,
05526 Item **ref_pointer_array,
05527 TableList *tables,
05528 TableList *,
05529 List<Item> &fields,
05530 List<Item> &all_fields,
05531 COND **conds,
05532 Order *order,
05533 Order *group,
05534 bool *hidden_group_fields)
05535 {
05536 int res;
05537 nesting_map save_allow_sum_func=session->lex().allow_sum_func;
05538
05539 session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
05540 res= session->setup_conds(tables, conds);
05541
05542 session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
05543 res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields, order);
05544 session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
05545 res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields, group, hidden_group_fields);
05546 session->lex().allow_sum_func= save_allow_sum_func;
05547 return res;
05548 }
05549
05558 static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
05559 {
05560 int error;
05561 Table *table;
05562 uint32_t i;
05563 uint32_t table_count;
05564 uint32_t const_count;
05565 uint32_t key;
05566 table_map found_const_table_map;
05567 table_map all_table_map;
05568 table_map found_ref;
05569 table_map refs;
05570 key_map const_ref;
05571 key_map eq_part;
05572 Table **table_vector= NULL;
05573 JoinTable *stat= NULL;
05574 JoinTable *stat_end= NULL;
05575 JoinTable *s= NULL;
05576 JoinTable **stat_ref= NULL;
05577 optimizer::KeyUse *keyuse= NULL;
05578 optimizer::KeyUse *start_keyuse= NULL;
05579 table_map outer_join= 0;
05580 vector<optimizer::SargableParam> sargables;
05581 JoinTable *stat_vector[MAX_TABLES+1];
05582 optimizer::Position *partial_pos;
05583
05584 table_count= join->tables;
05585 stat= (JoinTable*) join->session->mem.calloc(sizeof(JoinTable)*table_count);
05586 stat_ref= new (join->session->mem) JoinTable*[MAX_TABLES];
05587 table_vector= new (join->session->mem) Table*[2 * table_count];
05588
05589 join->best_ref=stat_vector;
05590
05591 stat_end=stat+table_count;
05592 found_const_table_map= all_table_map=0;
05593 const_count=0;
05594
05595 for (s= stat, i= 0;
05596 tables;
05597 s++, tables= tables->next_leaf, i++)
05598 {
05599 TableList *embedding= tables->getEmbedding();
05600 stat_vector[i]=s;
05601 s->keys.reset();
05602 s->const_keys.reset();
05603 s->checked_keys.reset();
05604 s->needed_reg.reset();
05605 table_vector[i]=s->table=table=tables->table;
05606 table->pos_in_table_list= tables;
05607 assert(table->cursor);
05608 error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
05609 if (error)
05610 {
05611 table->print_error(error, MYF(0));
05612 return 1;
05613 }
05614 table->quick_keys.reset();
05615 table->reginfo.join_tab=s;
05616 table->reginfo.not_exists_optimize=0;
05617 memset(table->const_key_parts, 0, sizeof(key_part_map)*table->getShare()->sizeKeys());
05618 all_table_map|= table->map;
05619 s->join=join;
05620 s->info=0;
05621
05622 s->dependent= tables->getDepTables();
05623 s->key_dependent= 0;
05624 table->quick_condition_rows= table->cursor->stats.records;
05625
05626 s->on_expr_ref= &tables->on_expr;
05627 if (*s->on_expr_ref)
05628 {
05629
05630 if (!table->cursor->stats.records && !embedding)
05631 {
05632 s->dependent= 0;
05633 set_position(join, const_count++, s, NULL);
05634 continue;
05635 }
05636 outer_join|= table->map;
05637 s->embedding_map.reset();
05638 for (;embedding; embedding= embedding->getEmbedding())
05639 s->embedding_map|= embedding->getNestedJoin()->nj_map;
05640 continue;
05641 }
05642 if (embedding && !(false && ! embedding->getEmbedding()))
05643 {
05644
05645 s->embedding_map.reset();
05646 do
05647 {
05648 NestedJoin *nested_join= embedding->getNestedJoin();
05649 s->embedding_map|= nested_join->nj_map;
05650 s->dependent|= embedding->getDepTables();
05651 embedding= embedding->getEmbedding();
05652 outer_join|= nested_join->used_tables;
05653 }
05654 while (embedding);
05655 continue;
05656 }
05657 if ((table->cursor->stats.records <= 1) && !s->dependent &&
05658 (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
05659 !join->no_const_tables)
05660 {
05661 set_position(join, const_count++, s, NULL);
05662 }
05663 }
05664 stat_vector[i]=0;
05665 join->outer_join=outer_join;
05666
05667 if (join->outer_join)
05668 {
05669
05670
05671
05672
05673
05674
05675
05676
05677 for (i= 0; i < table_count; i++)
05678 {
05679 uint32_t j;
05680 table= stat[i].table;
05681
05682 if (!table->reginfo.join_tab->dependent)
05683 continue;
05684
05685 for (j= 0, s= stat; j < table_count; j++, s++)
05686 {
05687 if (s->dependent & table->map)
05688 {
05689 table_map was_dependent= s->dependent;
05690 s->dependent |= table->reginfo.join_tab->dependent;
05691 if (i > j && s->dependent != was_dependent)
05692 {
05693 i= j= 1;
05694 break;
05695 }
05696 }
05697 }
05698 }
05699
05700 for (i= 0, s= stat ; i < table_count ; i++, s++)
05701 {
05702 if (s->dependent & s->table->map)
05703 {
05704 join->tables=0;
05705 my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
05706 return 1;
05707 }
05708 if (outer_join & s->table->map)
05709 s->table->maybe_null= 1;
05710
05711 s->key_dependent= s->dependent;
05712 }
05713 }
05714
05715 if (conds || outer_join)
05716 update_ref_and_keys(join->session, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, sargables);
05717
05718
05719 join->const_table_map= 0;
05720
05721 optimizer::Position *p_pos= join->getFirstPosInPartialPlan();
05722 optimizer::Position *p_end= join->getSpecificPosInPartialPlan(const_count);
05723 while (p_pos < p_end)
05724 {
05725 int tmp;
05726 s= p_pos->getJoinTable();
05727 s->type= AM_SYSTEM;
05728 join->const_table_map|=s->table->map;
05729 if ((tmp= s->joinReadConstTable(p_pos)))
05730 {
05731 if (tmp > 0)
05732 return 1;
05733 }
05734 else
05735 found_const_table_map|= s->table->map;
05736 p_pos++;
05737 }
05738
05739
05740 int ref_changed;
05741 do
05742 {
05743 more_const_tables_found:
05744 ref_changed = 0;
05745 found_ref=0;
05746
05747
05748
05749
05750
05751
05752 for (JoinTable **pos= stat_vector+const_count; (s= *pos); pos++)
05753 {
05754 table= s->table;
05755
05756
05757
05758
05759
05760
05761 if ((keyuse= s->keyuse) && *s->on_expr_ref && s->embedding_map.none())
05762 {
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773 while (keyuse->getTable() == table)
05774 {
05775 if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
05776 keyuse->getVal()->is_null() && keyuse->isNullRejected())
05777 {
05778 s->type= AM_CONST;
05779 table->mark_as_null_row();
05780 found_const_table_map|= table->map;
05781 join->const_table_map|= table->map;
05782 set_position(join, const_count++, s, NULL);
05783 goto more_const_tables_found;
05784 }
05785 keyuse++;
05786 }
05787 }
05788
05789 if (s->dependent)
05790 {
05791
05792 if (s->dependent & ~(found_const_table_map))
05793 continue;
05794 if (table->cursor->stats.records <= 1L &&
05795 (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
05796 !table->pos_in_table_list->getEmbedding())
05797 {
05798 int tmp= 0;
05799 s->type= AM_SYSTEM;
05800 join->const_table_map|=table->map;
05801 set_position(join, const_count++, s, NULL);
05802 partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
05803 if ((tmp= s->joinReadConstTable(partial_pos)))
05804 {
05805 if (tmp > 0)
05806 return 1;
05807 }
05808 else
05809 found_const_table_map|= table->map;
05810 continue;
05811 }
05812 }
05813
05814 if ((keyuse=s->keyuse))
05815 {
05816 s->type= AM_REF;
05817 while (keyuse->getTable() == table)
05818 {
05819 start_keyuse= keyuse;
05820 key= keyuse->getKey();
05821 s->keys.set(key);
05822
05823 refs= 0;
05824 const_ref.reset();
05825 eq_part.reset();
05826 do
05827 {
05828 if (keyuse->getVal()->type() != Item::NULL_ITEM &&
05829 ! keyuse->getOptimizeFlags())
05830 {
05831 if (! ((~found_const_table_map) & keyuse->getUsedTables()))
05832 const_ref.set(keyuse->getKeypart());
05833 else
05834 refs|= keyuse->getUsedTables();
05835 eq_part.set(keyuse->getKeypart());
05836 }
05837 keyuse++;
05838 } while (keyuse->getTable() == table && keyuse->getKey() == key);
05839
05840 if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
05841 ! table->pos_in_table_list->getEmbedding())
05842 {
05843 if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
05844 {
05845 if (const_ref == eq_part)
05846 {
05847 int tmp;
05848 ref_changed = 1;
05849 s->type= AM_CONST;
05850 join->const_table_map|= table->map;
05851 set_position(join, const_count++, s, start_keyuse);
05852 if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
05853 return 1;
05854 partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
05855 if ((tmp=s->joinReadConstTable(partial_pos)))
05856 {
05857 if (tmp > 0)
05858 return 1;
05859 }
05860 else
05861 found_const_table_map|= table->map;
05862 break;
05863 }
05864 else
05865 found_ref|= refs;
05866 }
05867 else if (const_ref == eq_part)
05868 s->const_keys.set(key);
05869 }
05870 }
05871 }
05872 }
05873 } while (join->const_table_map & found_ref && ref_changed);
05874
05875
05876
05877
05878
05879 if (const_count && ! sargables.empty())
05880 {
05881 BOOST_FOREACH(vector<optimizer::SargableParam>::reference iter, sargables)
05882 {
05883 Field& field= *iter.getField();
05884 JoinTable *join_tab= field.getTable()->reginfo.join_tab;
05885 key_map possible_keys= field.key_start & field.getTable()->keys_in_use_for_query;
05886 bool is_const= true;
05887 for (uint32_t j= 0; j < iter.getNumValues(); j++)
05888 is_const&= iter.isConstItem(j);
05889 if (is_const)
05890 join_tab[0].const_keys|= possible_keys;
05891 }
05892 }
05893
05894
05895
05896 for (s=stat ; s < stat_end ; s++)
05897 {
05898 if (s->type == AM_SYSTEM || s->type == AM_CONST)
05899 {
05900
05901 s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
05902 continue;
05903 }
05904
05905 s->found_records=s->records=s->table->cursor->stats.records;
05906 s->read_time=(ha_rows) s->table->cursor->scan_time();
05907
05908
05909
05910
05911
05912
05913 s->worst_seeks= min((double) s->found_records / 10,
05914 (double) s->read_time*3);
05915 if (s->worst_seeks < 2.0)
05916 s->worst_seeks=2.0;
05917
05918
05919
05920
05921
05922 add_group_and_distinct_keys(join, s);
05923
05924 if (s->const_keys.any() &&
05925 !s->table->pos_in_table_list->getEmbedding())
05926 {
05927 ha_rows records;
05928 optimizer::SqlSelect *select= NULL;
05929 select= optimizer::make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
05930 if (! select)
05931 return 1;
05932 records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
05933 s->quick=select->quick;
05934 s->needed_reg=select->needed_reg;
05935 select->quick=0;
05936
05937 if (records == 0 && s->table->reginfo.impossible_range)
05938 {
05939
05940
05941
05942
05943
05944
05945 join->const_table_map|= s->table->map;
05946 set_position(join, const_count++, s, NULL);
05947 s->type= AM_CONST;
05948 if (*s->on_expr_ref)
05949 {
05950
05951 s->info= "Impossible ON condition";
05952 found_const_table_map|= s->table->map;
05953 s->type= AM_CONST;
05954 s->table->mark_as_null_row();
05955 }
05956 }
05957 if (records != HA_POS_ERROR)
05958 {
05959 s->found_records=records;
05960 s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
05961 }
05962 delete select;
05963 }
05964 }
05965
05966 join->join_tab=stat;
05967 join->map2table=stat_ref;
05968 join->table= join->all_tables=table_vector;
05969 join->const_tables=const_count;
05970 join->found_const_table_map=found_const_table_map;
05971
05972
05973 if (join->const_tables != join->tables)
05974 {
05975 optimize_keyuse(join, keyuse_array);
05976
05977
05978 DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->getQueryString()->c_str(), join->session->thread_id);
05979 bool res= choose_plan(join, all_table_map & ~join->const_table_map);
05980 DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
05981 if (res)
05982 return true;
05983 }
05984 else
05985 {
05986 join->copyPartialPlanIntoOptimalPlan(join->const_tables);
05987 join->best_read= 1.0;
05988 }
05989
05990 return join->session->getKilled() || get_best_combination(join);
05991 }
05992
06012 static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused)
06013 {
06014 List<TableList>::iterator li(join_list->begin());
06015 while (TableList* table= li++)
06016 {
06017 if (NestedJoin* nested_join= table->getNestedJoin())
06018 {
06019
06020
06021
06022
06023
06024
06025
06026
06027
06028
06029
06030 if (nested_join->join_list.size() != 1)
06031 {
06032
06033 if (table->on_expr)
06034 nested_join->nj_map.set(first_unused++);
06035 first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
06036 first_unused);
06037 }
06038 }
06039 }
06040 return(first_unused);
06041 }
06042
06043
06048 static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
06049 {
06050 table_map map= 0;
06051
06052 if (!a)
06053 a= b;
06054 else if (!b)
06055 b= a;
06056
06057 for (; a && b; a=a->next,b=b->next)
06058 {
06059 if (!(*a->item)->eq(*b->item,1))
06060 return NULL;
06061 map|= a->item[0]->used_tables();
06062 }
06063 if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
06064 return NULL;
06065
06066 for (; !(map & tables->table->map); tables= tables->next_leaf) {};
06067 if (map != tables->table->map)
06068 return NULL;
06069 return tables->table;
06070 }
06071
06081 static void reset_nj_counters(List<TableList> *join_list)
06082 {
06083 List<TableList>::iterator li(join_list->begin());
06084 while (TableList* table= li++)
06085 {
06086 NestedJoin *nested_join;
06087 if ((nested_join= table->getNestedJoin()))
06088 {
06089 nested_join->counter_= 0;
06090 reset_nj_counters(&nested_join->join_list);
06091 }
06092 }
06093 }
06094
06101 static bool test_if_subpart(Order *a, Order *b)
06102 {
06103 for (; a && b; a=a->next,b=b->next)
06104 {
06105 if ((*a->item)->eq(*b->item,1))
06106 a->asc=b->asc;
06107 else
06108 return 0;
06109 }
06110 return test(!b);
06111 }
06112
06165 static void restore_prev_nj_state(JoinTable *last)
06166 {
06167 TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
06168 Join *join= last->join;
06169 for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
06170 {
06171 NestedJoin *nest= last_emb->getNestedJoin();
06172
06173 bool was_fully_covered= nest->is_fully_covered();
06174
06175 if (--nest->counter_ == 0)
06176 join->cur_embedding_map&= ~nest->nj_map;
06177
06178 if (!was_fully_covered)
06179 break;
06180
06181 join->cur_embedding_map|= nest->nj_map;
06182 }
06183 }
06184
06189 static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab)
06190 {
06191 if (!join_tab->ref.key_parts)
06192 return false;
06193
06194 Item_cond_and *cond=new Item_cond_and();
06195 Table *table=join_tab->table;
06196
06197 for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
06198 {
06199 Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
06200 Item *value=join_tab->ref.items[i];
06201 cond->add(new Item_func_equal(new Item_field(field), value));
06202 }
06203 if (session->is_fatal_error)
06204 return true;
06205
06206 if (!cond->fixed)
06207 cond->fix_fields(session, (Item**)&cond);
06208 int error = 0;
06209 if (join_tab->select)
06210 {
06211 cond->add(join_tab->select->cond);
06212 join_tab->select_cond=join_tab->select->cond=cond;
06213 }
06214 else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0, &error)))
06215 join_tab->select_cond=cond;
06216
06217 return error;
06218 }
06219
06220 static void free_blobs(Field **ptr)
06221 {
06222 for (; *ptr ; ptr++)
06223 {
06224 if ((*ptr)->flags & BLOB_FLAG)
06225 ((Field_blob *) (*ptr))->free();
06226 }
06227 }
06228
06233 }