00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00025 #include <config.h>
00026
00027 #include <string>
00028 #include <iostream>
00029 #include <algorithm>
00030 #include <vector>
00031
00032 #include <drizzled/sql_select.h>
00033
00034 #include <drizzled/error.h>
00035 #include <drizzled/gettext.h>
00036 #include <drizzled/util/test.h>
00037 #include <drizzled/name_resolution_context_state.h>
00038 #include <drizzled/nested_join.h>
00039 #include <drizzled/probes.h>
00040 #include <drizzled/show.h>
00041 #include <drizzled/item/cache.h>
00042 #include <drizzled/item/cmpfunc.h>
00043 #include <drizzled/item/copy_string.h>
00044 #include <drizzled/item/uint.h>
00045 #include <drizzled/cached_item.h>
00046 #include <drizzled/sql_base.h>
00047 #include <drizzled/field/blob.h>
00048 #include <drizzled/check_stack_overrun.h>
00049 #include <drizzled/lock.h>
00050 #include <drizzled/item/outer_ref.h>
00051 #include <drizzled/index_hint.h>
00052 #include <drizzled/records.h>
00053 #include <drizzled/internal/iocache.h>
00054 #include <drizzled/drizzled.h>
00055 #include <drizzled/plugin/storage_engine.h>
00056 #include <drizzled/sql_union.h>
00057 #include <drizzled/optimizer/key_field.h>
00058 #include <drizzled/optimizer/position.h>
00059 #include <drizzled/optimizer/sargable_param.h>
00060 #include <drizzled/optimizer/key_use.h>
00061 #include <drizzled/optimizer/range.h>
00062 #include <drizzled/optimizer/quick_range_select.h>
00063 #include <drizzled/optimizer/quick_ror_intersect_select.h>
00064 #include <drizzled/filesort.h>
00065 #include <drizzled/sql_lex.h>
00066 #include <drizzled/session.h>
00067 #include <drizzled/sort_field.h>
00068 #include <drizzled/select_result.h>
00069 #include <drizzled/key.h>
00070 #include <drizzled/my_hash.h>
00071
00072 using namespace std;
00073
00074 namespace drizzled {
00075
00076 static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b);
00077 static COND *build_equal_items(Session *session, COND *cond,
00078 COND_EQUAL *inherited,
00079 List<TableList> *join_list,
00080 COND_EQUAL **cond_equal_ref);
00081
00082 static Item* part_of_refkey(Table *form,Field *field);
00083 static bool cmp_buffer_with_ref(JoinTable *tab);
00084 static void change_cond_ref_to_const(Session *session,
00085 list<COND_CMP>& save_list,
00086 Item *and_father,
00087 Item *cond,
00088 Item *field,
00089 Item *value);
00090 static void copy_blobs(Field **ptr);
00091
00092 static bool eval_const_cond(COND *cond)
00093 {
00094 return ((Item_func*) cond)->val_int() ? true : false;
00095 }
00096
00097
00098
00099
00100
00101
00102 const char *subq_sj_cond_name= "0123456789ABCDEF0123456789abcdef0123456789ABCDEF0123456789abcdef-sj-cond";
00103
00104 static void copy_blobs(Field **ptr)
00105 {
00106 for (; *ptr ; ptr++)
00107 {
00108 if ((*ptr)->flags & BLOB_FLAG)
00109 {
00110 ((Field_blob *) (*ptr))->copy();
00111 }
00112 }
00113 }
00114
00118 bool handle_select(Session *session, LEX *lex, select_result *result,
00119 uint64_t setup_tables_done_option)
00120 {
00121 bool res;
00122 Select_Lex *select_lex= &lex->select_lex;
00123 DRIZZLE_SELECT_START(session->getQueryString()->c_str());
00124
00125 if (select_lex->master_unit()->is_union() or
00126 select_lex->master_unit()->fake_select_lex)
00127 {
00128 res= drizzle_union(session, lex, result, &lex->unit,
00129 setup_tables_done_option);
00130 }
00131 else
00132 {
00133 Select_Lex_Unit *unit= &lex->unit;
00134 unit->set_limit(unit->global_parameters);
00135 session->session_marker= 0;
00136
00137
00138
00139
00140
00141
00142 res= select_query(session,
00143 &select_lex->ref_pointer_array,
00144 (TableList*) select_lex->table_list.first,
00145 select_lex->with_wild,
00146 select_lex->item_list,
00147 select_lex->where,
00148 select_lex->order_list.size() +
00149 select_lex->group_list.size(),
00150 (Order*) select_lex->order_list.first,
00151 (Order*) select_lex->group_list.first,
00152 select_lex->having,
00153 select_lex->options | session->options |
00154 setup_tables_done_option,
00155 result, unit, select_lex);
00156 }
00157 res|= session->is_error();
00158
00159 if (unlikely(res))
00160 {
00161 result->abort();
00162 }
00163
00164 DRIZZLE_SELECT_DONE(res, session->limit_found_rows);
00165 return res;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 bool fix_inner_refs(Session *session,
00209 List<Item> &all_fields,
00210 Select_Lex *select,
00211 Item **ref_pointer_array)
00212 {
00213 Item_outer_ref *ref;
00214 bool res= false;
00215 bool direct_ref= false;
00216
00217 List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
00218 while ((ref= ref_it++))
00219 {
00220 Item *item= ref->outer_ref;
00221 Item **item_ref= ref->ref;
00222 Item_ref *new_ref;
00223
00224
00225
00226
00227
00228
00229
00230 if (ref_pointer_array && !ref->found_in_select_list)
00231 {
00232 int el= all_fields.size();
00233 ref_pointer_array[el]= item;
00234
00235 all_fields.push_front(item);
00236
00237
00238
00239
00240 item_ref= ref_pointer_array + el;
00241 }
00242
00243 if (ref->in_sum_func)
00244 {
00245 Item_sum *sum_func;
00246 if (ref->in_sum_func->nest_level > select->nest_level)
00247 {
00248 direct_ref= true;
00249 }
00250 else
00251 {
00252 for (sum_func= ref->in_sum_func; sum_func &&
00253 sum_func->aggr_level >= select->nest_level;
00254 sum_func= sum_func->in_sum_func)
00255 {
00256 if (sum_func->aggr_level == select->nest_level)
00257 {
00258 direct_ref= true;
00259 break;
00260 }
00261 }
00262 }
00263 }
00264
00265 new_ref= direct_ref ?
00266 new Item_direct_ref(ref->context, item_ref, ref->table_name,
00267 ref->field_name, ref->alias_name_used) :
00268 new Item_ref(ref->context, item_ref, ref->table_name,
00269 ref->field_name, ref->alias_name_used);
00270
00271 ref->outer_ref= new_ref;
00272 ref->ref= &ref->outer_ref;
00273
00274 if (!ref->fixed && ref->fix_fields(session, 0))
00275 {
00276 return true;
00277 }
00278 session->used_tables|= item->used_tables();
00279 }
00280 return res;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 void save_index_subquery_explain_info(JoinTable *join_tab, Item* where)
00307 {
00308 join_tab->packed_info= TAB_INFO_HAVE_VALUE;
00309
00310 if (join_tab->table->covering_keys.test(join_tab->ref.key))
00311 join_tab->packed_info |= TAB_INFO_USING_INDEX;
00312
00313 if (where)
00314 join_tab->packed_info |= TAB_INFO_USING_WHERE;
00315
00316 for (uint32_t i = 0; i < join_tab->ref.key_parts; i++)
00317 {
00318 if (join_tab->ref.cond_guards[i])
00319 {
00320 join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
00321 break;
00322 }
00323 }
00324 }
00325
00368 bool select_query(Session *session,
00369 Item ***rref_pointer_array,
00370 TableList *tables,
00371 uint32_t wild_num,
00372 List<Item> &fields,
00373 COND *conds,
00374 uint32_t og_num,
00375 Order *order,
00376 Order *group,
00377 Item *having,
00378 uint64_t select_options,
00379 select_result *result,
00380 Select_Lex_Unit *unit,
00381 Select_Lex *select_lex)
00382 {
00383 bool err;
00384 bool free_join= 1;
00385
00386 select_lex->context.resolve_in_select_list= true;
00387 Join *join;
00388 if (select_lex->join != 0)
00389 {
00390 join= select_lex->join;
00391
00392
00393
00394
00395 if (select_lex->linkage != DERIVED_TABLE_TYPE ||
00396 (select_options & SELECT_DESCRIBE))
00397 {
00398 if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
00399 {
00400
00401 if (join->change_result(result))
00402 {
00403 return true;
00404 }
00405 }
00406 else
00407 {
00408 if ((err= join->prepare(rref_pointer_array, tables, wild_num,
00409 conds, og_num, order, group, having, select_lex, unit)))
00410 {
00411 goto err;
00412 }
00413 }
00414 }
00415 free_join= 0;
00416 join->select_options= select_options;
00417 }
00418 else
00419 {
00420 join= new Join(session, fields, select_options, result);
00421 session->set_proc_info("init");
00422 session->used_tables=0;
00423 if ((err= join->prepare(rref_pointer_array, tables, wild_num, conds, og_num, order, group, having, select_lex, unit)))
00424 {
00425 goto err;
00426 }
00427 }
00428
00429 err= join->optimize();
00430 if (err)
00431 {
00432 goto err;
00433 }
00434
00435 if (session->lex().describe & DESCRIBE_EXTENDED)
00436 {
00437 join->conds_history= join->conds;
00438 join->having_history= (join->having?join->having:join->tmp_having);
00439 }
00440
00441 if (session->is_error())
00442 {
00443 goto err;
00444 }
00445
00446 join->exec();
00447
00448 if (session->lex().describe & DESCRIBE_EXTENDED)
00449 {
00450 select_lex->where= join->conds_history;
00451 select_lex->having= join->having_history;
00452 }
00453
00454 err:
00455 if (free_join)
00456 {
00457 session->set_proc_info("end");
00458 err|= select_lex->cleanup();
00459 return(err || session->is_error());
00460 }
00461 return(join->error);
00462 }
00463
00464 inline Item *and_items(Item* cond, Item *item)
00465 {
00466 return (cond? (new Item_cond_and(cond, item)) : item);
00467 }
00468
00469
00470
00471
00472
00473 ha_rows get_quick_record_count(Session *session, optimizer::SqlSelect *select, Table *table, const key_map *keys,ha_rows limit)
00474 {
00475 int error;
00476 if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
00477 {
00478 return 0;
00479 }
00480
00481 if (select)
00482 {
00483 select->head=table;
00484 table->reginfo.impossible_range=0;
00485 if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
00486 limit, 0, false)) == 1)
00487 {
00488 return(select->quick->records);
00489 }
00490
00491 if (error == -1)
00492 {
00493 table->reginfo.impossible_range=1;
00494 return 0;
00495 }
00496 }
00497
00498 return(HA_POS_ERROR);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00515 uint32_t max_part_bit(key_part_map bits)
00516 {
00517 uint32_t found;
00518 for (found=0; bits & 1 ; found++,bits>>=1) ;
00519
00520 return found;
00521 }
00522
00523 static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b)
00524 {
00525 int res;
00526 if (a->getTable()->tablenr != b->getTable()->tablenr)
00527 return static_cast<int>((a->getTable()->tablenr - b->getTable()->tablenr));
00528
00529 if (a->getKey() != b->getKey())
00530 return static_cast<int>((a->getKey() - b->getKey()));
00531
00532 if (a->getKeypart() != b->getKeypart())
00533 return static_cast<int>((a->getKeypart() - b->getKeypart()));
00534
00535
00536 if ((res= test((a->getUsedTables() & ~OUTER_REF_TABLE_BIT)) -
00537 test((b->getUsedTables() & ~OUTER_REF_TABLE_BIT))))
00538 return res;
00539
00540
00541 return static_cast<int>(((a->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL) -
00542 (b->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)));
00543 }
00544
00545
00566 void update_ref_and_keys(Session *session,
00567 DYNAMIC_ARRAY *keyuse,
00568 JoinTable *join_tab,
00569 uint32_t tables,
00570 COND *cond,
00571 COND_EQUAL *,
00572 table_map normal_tables,
00573 Select_Lex *select_lex,
00574 vector<optimizer::SargableParam> &sargables)
00575 {
00576 uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 optimizer::KeyField* key_fields= new (session->mem) optimizer::KeyField[((session->lex().current_select->cond_count+1)*2 + session->lex().current_select->between_count)*m+1];
00596 uint and_level= 0;
00597 optimizer::KeyField* end, *field;
00598 field= end= key_fields;
00599
00600 keyuse->init(sizeof(optimizer::KeyUse), 20, 64);
00601 if (cond)
00602 {
00603 add_key_fields(join_tab->join, &end, &and_level, cond, normal_tables,
00604 sargables);
00605 for (; field != end; field++)
00606 {
00607 add_key_part(keyuse, field);
00608
00609 if (field->getValue()->type() == Item::NULL_ITEM &&
00610 ! field->getField()->real_maybe_null())
00611 {
00612 field->getField()->getTable()->reginfo.not_exists_optimize= 1;
00613 }
00614 }
00615 }
00616 for (uint32_t i= 0; i < tables; i++)
00617 {
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 if (*join_tab[i].on_expr_ref)
00628 add_key_fields(join_tab->join, &end, &and_level,
00629 *join_tab[i].on_expr_ref,
00630 join_tab[i].table->map, sargables);
00631 }
00632
00633
00634 {
00635 List<TableList>::iterator li(join_tab->join->join_list->begin());
00636 TableList *table;
00637 while ((table= li++))
00638 {
00639 if (table->getNestedJoin())
00640 add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
00641 sargables);
00642 }
00643 }
00644
00645
00646 for ( ; field != end ; field++)
00647 add_key_part(keyuse,field);
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 if (keyuse->size())
00659 {
00660 optimizer::KeyUse key_end,*prev,*save_pos,*use;
00661
00662 internal::my_qsort(keyuse->buffer,keyuse->size(),sizeof(optimizer::KeyUse),
00663 (qsort_cmp) sort_keyuse);
00664
00665 memset(&key_end, 0, sizeof(key_end));
00666 keyuse->push_back(&key_end);
00667
00668 use= save_pos= (optimizer::KeyUse*)keyuse->buffer;
00669 prev= &key_end;
00670 uint found_eq_constant= 0;
00671 {
00672 for (uint32_t i= 0; i < keyuse->size()-1; i++, use++)
00673 {
00674 if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
00675 use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
00676
00677 if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
00678 {
00679 if (prev->getKeypart() + 1 < use->getKeypart() ||
00680 ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
00681 {
00682 continue;
00683 }
00684 }
00685 else if (use->getKeypart() != 0)
00686 {
00687 continue;
00688 }
00689
00690 #ifdef HAVE_VALGRIND
00691
00692 if (save_pos != use)
00693 #endif
00694 *save_pos= *use;
00695 prev=use;
00696 found_eq_constant= ! use->getUsedTables();
00697
00698 if (! use->getTable()->reginfo.join_tab->keyuse)
00699 {
00700 use->getTable()->reginfo.join_tab->keyuse= save_pos;
00701 }
00702 use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
00703 save_pos++;
00704 }
00705
00706 uint32_t i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
00707 reinterpret_cast<optimizer::KeyUse*>(keyuse->buffer)[i] = key_end;
00708 keyuse->set_size(i);
00709 }
00710 }
00711 }
00712
00716 void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
00717 {
00718 optimizer::KeyUse* keyuse= (optimizer::KeyUse*)keyuse_array->buffer;
00719 for (optimizer::KeyUse* end= keyuse+ keyuse_array->size() ; keyuse < end ; keyuse++)
00720 {
00721 table_map map;
00722
00723
00724
00725
00726
00727
00728
00729
00730 keyuse->setTableRows(~(ha_rows) 0);
00731
00732 if (keyuse->getUsedTables() & (map= (keyuse->getUsedTables() & ~join->const_table_map & ~OUTER_REF_TABLE_BIT)))
00733 {
00734 uint32_t tablenr;
00735 for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
00736 if (map == 1)
00737 {
00738 Table *tmp_table=join->all_tables[tablenr];
00739 keyuse->setTableRows(max(tmp_table->cursor->stats.records, (ha_rows)100));
00740 }
00741 }
00742
00743
00744
00745
00746
00747 if (keyuse->getUsedTables() == OUTER_REF_TABLE_BIT)
00748 {
00749 keyuse->setTableRows(1);
00750 }
00751 }
00752 }
00753
00754
00772 void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
00773 {
00774 List<Item_field> indexed_fields;
00775 List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
00776 Order *cur_group;
00777 Item_field *cur_item;
00778 key_map possible_keys(0);
00779
00780 if (join->group_list)
00781 {
00782 for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
00783 {
00784 (*cur_group->item)->walk(&Item::collect_item_field_processor, 0, (unsigned char*) &indexed_fields);
00785 }
00786 }
00787 else if (join->select_distinct)
00788 {
00789 List<Item> &select_items= join->fields_list;
00790 List<Item>::iterator select_items_it(select_items.begin());
00791 Item *item;
00792 while ((item= select_items_it++))
00793 {
00794 item->walk(&Item::collect_item_field_processor, 0, (unsigned char*) &indexed_fields);
00795 }
00796 }
00797 else
00798 {
00799 return;
00800 }
00801
00802 if (indexed_fields.size() == 0)
00803 {
00804 return;
00805 }
00806
00807
00808 cur_item= indexed_fields_it++;
00809 possible_keys|= cur_item->field->part_of_key;
00810 while ((cur_item= indexed_fields_it++))
00811 {
00812 possible_keys&= cur_item->field->part_of_key;
00813 }
00814
00815 if (possible_keys.any())
00816 join_tab->const_keys|= possible_keys;
00817 }
00818
00843 int join_tab_cmp(const void* ptr1, const void* ptr2)
00844 {
00845 JoinTable *jt1= *(JoinTable**) ptr1;
00846 JoinTable *jt2= *(JoinTable**) ptr2;
00847
00848 if (jt1->dependent & jt2->table->map)
00849 return 1;
00850
00851 if (jt2->dependent & jt1->table->map)
00852 return -1;
00853
00854 if (jt1->found_records > jt2->found_records)
00855 return 1;
00856
00857 if (jt1->found_records < jt2->found_records)
00858 return -1;
00859
00860 return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
00861 }
00862
00866 int join_tab_cmp_straight(const void* ptr1, const void* ptr2)
00867 {
00868 JoinTable *jt1= *(JoinTable**) ptr1;
00869 JoinTable *jt2= *(JoinTable**) ptr2;
00870
00871 if (jt1->dependent & jt2->table->map)
00872 return 1;
00873
00874 if (jt2->dependent & jt1->table->map)
00875 return -1;
00876
00877 return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
00878 }
00879
00883 void calc_used_field_length(Session *, JoinTable *join_tab)
00884 {
00885 uint32_t null_fields,blobs,fields,rec_length;
00886 Field **f_ptr,*field;
00887
00888 null_fields= blobs= fields= rec_length=0;
00889 for (f_ptr=join_tab->table->getFields() ; (field= *f_ptr) ; f_ptr++)
00890 {
00891 if (field->isReadSet())
00892 {
00893 uint32_t flags=field->flags;
00894 fields++;
00895 rec_length+=field->pack_length();
00896
00897 if (flags & BLOB_FLAG)
00898 {
00899 blobs++;
00900 }
00901
00902 if (!(flags & NOT_NULL_FLAG))
00903 {
00904 null_fields++;
00905 }
00906 }
00907 }
00908
00909 if (null_fields)
00910 {
00911 rec_length+=(join_tab->table->getNullFields() + 7)/8;
00912 }
00913
00914 if (join_tab->table->maybe_null)
00915 {
00916 rec_length+=sizeof(bool);
00917 }
00918
00919 if (blobs)
00920 {
00921 uint32_t blob_length=(uint32_t) (join_tab->table->cursor->stats.mean_rec_length-
00922 (join_tab->table->getRecordLength()- rec_length));
00923 rec_length+= max((uint32_t)4,blob_length);
00924 }
00925 join_tab->used_fields= fields;
00926 join_tab->used_fieldlength= rec_length;
00927 join_tab->used_blobs= blobs;
00928 }
00929
00930 StoredKey *get_store_key(Session *session,
00931 optimizer::KeyUse *keyuse,
00932 table_map used_tables,
00933 KeyPartInfo *key_part,
00934 unsigned char *key_buff,
00935 uint32_t maybe_null)
00936 {
00937 Item_ref *key_use_val= static_cast<Item_ref *>(keyuse->getVal());
00938 if (! ((~used_tables) & keyuse->getUsedTables()))
00939 {
00940 return new store_key_const_item(session,
00941 key_part->field,
00942 key_buff + maybe_null,
00943 maybe_null ? key_buff : 0,
00944 key_part->length,
00945 key_use_val);
00946 }
00947 else if (key_use_val->type() == Item::FIELD_ITEM ||
00948 (key_use_val->type() == Item::REF_ITEM &&
00949 key_use_val->ref_type() == Item_ref::OUTER_REF &&
00950 (*(Item_ref**)((Item_ref*)key_use_val)->ref)->ref_type() == Item_ref::DIRECT_REF &&
00951 key_use_val->real_item()->type() == Item::FIELD_ITEM))
00952 {
00953 return new store_key_field(session,
00954 key_part->field,
00955 key_buff + maybe_null,
00956 maybe_null ? key_buff : 0,
00957 key_part->length,
00958 ((Item_field*) key_use_val->real_item())->field,
00959 key_use_val->full_name());
00960 }
00961 return new store_key_item(session,
00962 key_part->field,
00963 key_buff + maybe_null,
00964 maybe_null ? key_buff : 0,
00965 key_part->length,
00966 key_use_val);
00967 }
00968
00975 bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
00976 {
00977 bool error;
00978 Table *table= field->getTable();
00979 Session *session= table->in_use;
00980 ha_rows cuted_fields=session->cuted_fields;
00981
00982
00983
00984
00985
00986
00987 enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
00988 session->count_cuted_fields= check_flag;
00989 error= item->save_in_field(field, 1);
00990 session->count_cuted_fields= old_count_cuted_fields;
00991 return error || cuted_fields != session->cuted_fields;
00992 }
00993
00994 inline void add_cond_and_fix(Item **e1, Item *e2)
00995 {
00996 if (*e1)
00997 {
00998 Item* res= new Item_cond_and(*e1, e2);
00999 *e1= res;
01000 res->quick_fix_field();
01001 }
01002 else
01003 {
01004 *e1= e2;
01005 }
01006 }
01007
01008 bool create_ref_for_key(Join *join,
01009 JoinTable *j,
01010 optimizer::KeyUse *org_keyuse,
01011 table_map used_tables)
01012 {
01013 optimizer::KeyUse *keyuse= org_keyuse;
01014 Session *session= join->session;
01015 uint32_t keyparts;
01016 uint32_t length;
01017 uint32_t key;
01018 Table *table= NULL;
01019 KeyInfo *keyinfo= NULL;
01020
01021
01022 table= j->table;
01023 key= keyuse->getKey();
01024 keyinfo= table->key_info + key;
01025
01026 {
01027 keyparts= length= 0;
01028 uint32_t found_part_ref_or_null= 0;
01029
01030
01031
01032
01033
01034 do
01035 {
01036 if (! (~used_tables & keyuse->getUsedTables()))
01037 {
01038 if (keyparts == keyuse->getKeypart() &&
01039 ! (found_part_ref_or_null & keyuse->getOptimizeFlags()))
01040 {
01041 keyparts++;
01042 length+= keyinfo->key_part[keyuse->getKeypart()].store_length;
01043 found_part_ref_or_null|= keyuse->getOptimizeFlags();
01044 }
01045 }
01046 keyuse++;
01047 } while (keyuse->getTable() == table && keyuse->getKey() == key);
01048 }
01049
01050
01051 keyinfo=table->key_info+key;
01052 j->ref.key_parts=keyparts;
01053 j->ref.key_length=length;
01054 j->ref.key=(int) key;
01055 j->ref.key_buff= (unsigned char*) session->mem.calloc(ALIGN_SIZE(length)*2);
01056 j->ref.key_copy= new (session->mem) StoredKey*[keyparts + 1];
01057 j->ref.items= new (session->mem) Item*[keyparts];
01058 j->ref.cond_guards= new (session->mem) bool*[keyparts];
01059 j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
01060 j->ref.key_err=1;
01061 j->ref.null_rejecting= 0;
01062 j->ref.disable_cache= false;
01063 keyuse=org_keyuse;
01064
01065 StoredKey **ref_key= j->ref.key_copy;
01066 unsigned char *key_buff= j->ref.key_buff, *null_ref_key= 0;
01067 bool keyuse_uses_no_tables= true;
01068 {
01069 for (uint32_t i= 0; i < keyparts; keyuse++, i++)
01070 {
01071 while (keyuse->getKeypart() != i or ((~used_tables) & keyuse->getUsedTables()))
01072 {
01073 keyuse++;
01074 }
01075
01076 uint32_t maybe_null= test(keyinfo->key_part[i].null_bit);
01077 j->ref.items[i]= keyuse->getVal();
01078 j->ref.cond_guards[i]= keyuse->getConditionalGuard();
01079 if (keyuse->isNullRejected())
01080 {
01081 j->ref.null_rejecting |= 1 << i;
01082 }
01083
01084 keyuse_uses_no_tables= keyuse_uses_no_tables && ! keyuse->getUsedTables();
01085 if (! keyuse->getUsedTables() && !(join->select_options & SELECT_DESCRIBE))
01086 {
01087 store_key_item tmp(session, keyinfo->key_part[i].field,
01088 key_buff + maybe_null,
01089 maybe_null ? key_buff : 0,
01090 keyinfo->key_part[i].length, keyuse->getVal());
01091 if (session->is_fatal_error)
01092 {
01093 return true;
01094 }
01095 tmp.copy();
01096 }
01097 else
01098 {
01099 *ref_key++= get_store_key(session,
01100 keyuse,join->const_table_map,
01101 &keyinfo->key_part[i],
01102 key_buff, maybe_null);
01103 }
01104
01105
01106
01107
01108
01109
01110 if ((keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
01111 null_ref_key= key_buff;
01112 key_buff+=keyinfo->key_part[i].store_length;
01113 }
01114 }
01115 *ref_key= 0;
01116 if (j->type == AM_CONST)
01117 {
01118 j->table->const_table= 1;
01119 }
01120 else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) || keyparts != keyinfo->key_parts || null_ref_key)
01121 {
01122
01123 j->type= null_ref_key ? AM_REF_OR_NULL : AM_REF;
01124 j->ref.null_ref_key= null_ref_key;
01125 }
01126 else if (keyuse_uses_no_tables)
01127 {
01128
01129
01130
01131
01132
01133
01134
01135 j->type= AM_CONST;
01136 }
01137 else
01138 {
01139 j->type= AM_EQ_REF;
01140 }
01141
01142 return 0;
01143 }
01144
01195 void add_not_null_conds(Join *join)
01196 {
01197 for (uint32_t i= join->const_tables; i < join->tables; i++)
01198 {
01199 JoinTable *tab=join->join_tab+i;
01200 if ((tab->type == AM_REF || tab->type == AM_EQ_REF ||
01201 tab->type == AM_REF_OR_NULL) &&
01202 !tab->table->maybe_null)
01203 {
01204 for (uint32_t keypart= 0; keypart < tab->ref.key_parts; keypart++)
01205 {
01206 if (tab->ref.null_rejecting & (1 << keypart))
01207 {
01208 Item *item= tab->ref.items[keypart];
01209 Item *notnull;
01210 assert(item->type() == Item::FIELD_ITEM);
01211 Item_field *not_null_item= (Item_field*)item;
01212 JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
01213
01214
01215
01216
01217
01218 if (!referred_tab || referred_tab->join != join)
01219 {
01220 continue;
01221 }
01222 notnull= new Item_func_isnotnull(not_null_item);
01223
01224
01225
01226
01227
01228
01229
01230 if (notnull->fix_fields(join->session, ¬null))
01231 {
01232 return;
01233 }
01234
01235 add_cond_and_fix(&referred_tab->select_cond, notnull);
01236 }
01237 }
01238 }
01239 }
01240 }
01241
01257 COND *add_found_match_trig_cond(JoinTable *tab, COND *cond, JoinTable *root_tab)
01258 {
01259 COND *tmp;
01260 assert(cond != 0);
01261 if (tab == root_tab)
01262 return cond;
01263 if ((tmp= add_found_match_trig_cond(tab->first_upper, cond, root_tab)))
01264 tmp= new Item_func_trig_cond(tmp, &tab->found);
01265 if (tmp)
01266 {
01267 tmp->quick_fix_field();
01268 tmp->update_used_tables();
01269 }
01270 return tmp;
01271 }
01272
01276 void JoinTable::cleanup()
01277 {
01278 safe_delete(select);
01279 safe_delete(quick);
01280
01281 if (cache.buff)
01282 {
01283 size_t size= cache.end - cache.buff;
01284 global_join_buffer.sub(size);
01285 free(cache.buff);
01286 }
01287 cache.buff= 0;
01288 limit= 0;
01289 if (table)
01290 {
01291 if (table->key_read)
01292 {
01293 table->key_read= 0;
01294 table->cursor->extra(HA_EXTRA_NO_KEYREAD);
01295 }
01296 table->cursor->ha_index_or_rnd_end();
01297
01298
01299
01300
01301 table->reginfo.join_tab= 0;
01302 }
01303 read_record.end_read_record();
01304 }
01305
01306 bool only_eq_ref_tables(Join *join,Order *order,table_map tables)
01307 {
01308 for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
01309 {
01310 if (tables & 1 && !eq_ref_table(join, order, *tab))
01311 {
01312 return 0;
01313 }
01314 }
01315 return 1;
01316 }
01317
01337 bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
01338 {
01339 if (tab->cached_eq_ref_table)
01340 {
01341 return tab->eq_ref_table;
01342 }
01343
01344 tab->cached_eq_ref_table=1;
01345
01346
01347 if (tab->type == AM_CONST && !tab->first_inner)
01348 {
01349 return (tab->eq_ref_table=1);
01350 }
01351
01352 if (tab->type != AM_EQ_REF || tab->table->maybe_null)
01353 {
01354 return (tab->eq_ref_table=0);
01355 }
01356
01357 Item **ref_item=tab->ref.items;
01358 Item **end=ref_item+tab->ref.key_parts;
01359 uint32_t found=0;
01360 table_map map=tab->table->map;
01361
01362 for (; ref_item != end ; ref_item++)
01363 {
01364 if (! (*ref_item)->const_item())
01365 {
01366 Order *order;
01367 for (order=start_order ; order ; order=order->next)
01368 {
01369 if ((*ref_item)->eq(order->item[0],0))
01370 break;
01371 }
01372
01373 if (order)
01374 {
01375 found++;
01376 assert(!(order->used & map));
01377 order->used|=map;
01378 continue;
01379 }
01380
01381 if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables()))
01382 {
01383 return (tab->eq_ref_table= 0);
01384 }
01385 }
01386 }
01387
01388 for (; found && start_order ; start_order=start_order->next)
01389 {
01390 if (start_order->used & map)
01391 {
01392 found--;
01393 continue;
01394 }
01395 if (start_order->depend_map & map)
01396 return (tab->eq_ref_table= 0);
01397 }
01398 return tab->eq_ref_table= 1;
01399 }
01400
01419 static Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field, bool *inherited_fl)
01420 {
01421 Item_equal *item= 0;
01422 bool in_upper_level= false;
01423 while (cond_equal)
01424 {
01425 List<Item_equal>::iterator li(cond_equal->current_level.begin());
01426 while ((item= li++))
01427 {
01428 if (item->contains(field))
01429 {
01430 goto finish;
01431 }
01432 }
01433 in_upper_level= true;
01434 cond_equal= cond_equal->upper_levels;
01435 }
01436 in_upper_level= false;
01437
01438 finish:
01439 *inherited_fl= in_upper_level;
01440 return item;
01441 }
01442
01524 static bool check_simple_equality(Item *left_item,
01525 Item *right_item,
01526 Item *item,
01527 COND_EQUAL *cond_equal)
01528 {
01529 if (left_item->type() == Item::FIELD_ITEM &&
01530 right_item->type() == Item::FIELD_ITEM &&
01531 !((Item_field*)left_item)->depended_from &&
01532 !((Item_field*)right_item)->depended_from)
01533 {
01534
01535
01536 Field *left_field= ((Item_field*) left_item)->field;
01537 Field *right_field= ((Item_field*) right_item)->field;
01538
01539 if (!left_field->eq_def(right_field))
01540 return false;
01541
01542
01543 bool left_copyfl, right_copyfl;
01544 Item_equal *left_item_equal=
01545 find_item_equal(cond_equal, left_field, &left_copyfl);
01546 Item_equal *right_item_equal=
01547 find_item_equal(cond_equal, right_field, &right_copyfl);
01548
01549
01550 if (left_field->eq(right_field))
01551 return (!(left_field->maybe_null() && !left_item_equal));
01552
01553 if (left_item_equal && left_item_equal == right_item_equal)
01554 {
01555
01556
01557
01558
01559
01560 return true;
01561 }
01562
01563 bool copy_item_name= test(item && item->name >= subq_sj_cond_name &&
01564 item->name < subq_sj_cond_name + 64);
01565
01566 if (left_copyfl)
01567 {
01568
01569 left_item_equal= new Item_equal(left_item_equal);
01570 cond_equal->current_level.push_back(left_item_equal);
01571 if (copy_item_name)
01572 {
01573 left_item_equal->name = item->name;
01574 }
01575 }
01576 if (right_copyfl)
01577 {
01578
01579 right_item_equal= new Item_equal(right_item_equal);
01580 cond_equal->current_level.push_back(right_item_equal);
01581 if (copy_item_name)
01582 {
01583 right_item_equal->name = item->name;
01584 }
01585 }
01586
01587 if (left_item_equal)
01588 {
01589
01590 if (! right_item_equal)
01591 left_item_equal->add((Item_field *) right_item);
01592 else
01593 {
01594
01595 left_item_equal->merge(right_item_equal);
01596
01597 List<Item_equal>::iterator li(cond_equal->current_level.begin());
01598 while ((li++) != right_item_equal) {};
01599 li.remove();
01600 }
01601 }
01602 else
01603 {
01604
01605 if (right_item_equal)
01606 {
01607 right_item_equal->add((Item_field *) left_item);
01608 if (copy_item_name)
01609 {
01610 right_item_equal->name = item->name;
01611 }
01612 }
01613 else
01614 {
01615
01616 Item_equal *item_equal= new Item_equal((Item_field *) left_item,
01617 (Item_field *) right_item);
01618 cond_equal->current_level.push_back(item_equal);
01619 if (copy_item_name)
01620 {
01621 item_equal->name = item->name;
01622 }
01623 }
01624 }
01625 return true;
01626 }
01627
01628 {
01629
01630 Item *const_item= 0;
01631 Item_field *field_item= 0;
01632 if (left_item->type() == Item::FIELD_ITEM &&
01633 !((Item_field*)left_item)->depended_from &&
01634 right_item->const_item())
01635 {
01636 field_item= (Item_field*) left_item;
01637 const_item= right_item;
01638 }
01639 else if (right_item->type() == Item::FIELD_ITEM &&
01640 !((Item_field*)right_item)->depended_from &&
01641 left_item->const_item())
01642 {
01643 field_item= (Item_field*) right_item;
01644 const_item= left_item;
01645 }
01646
01647 if (const_item &&
01648 field_item->result_type() == const_item->result_type())
01649 {
01650 bool copyfl;
01651
01652 if (field_item->result_type() == STRING_RESULT)
01653 {
01654 const charset_info_st * const cs= ((Field_str*) field_item->field)->charset();
01655 if (!item)
01656 {
01657 Item_func_eq *eq_item;
01658 eq_item= new Item_func_eq(left_item, right_item);
01659 eq_item->set_cmp_func();
01660 eq_item->quick_fix_field();
01661 item= eq_item;
01662 }
01663
01664 if ((cs != ((Item_func *) item)->compare_collation()) || !cs->coll->propagate())
01665 {
01666 return false;
01667 }
01668 }
01669
01670 Item_equal *item_equal = find_item_equal(cond_equal,
01671 field_item->field, ©fl);
01672 if (copyfl)
01673 {
01674 item_equal= new Item_equal(item_equal);
01675 cond_equal->current_level.push_back(item_equal);
01676 }
01677 if (item_equal)
01678 {
01679
01680
01681
01682
01683
01684 item_equal->add(const_item);
01685 }
01686 else
01687 {
01688 item_equal= new Item_equal(const_item, field_item);
01689 cond_equal->current_level.push_back(item_equal);
01690 }
01691 return true;
01692 }
01693 }
01694
01695 return false;
01696 }
01697
01723 static bool check_row_equality(Session *session,
01724 Item *left_row,
01725 Item_row *right_row,
01726 COND_EQUAL *cond_equal,
01727 List<Item>* eq_list)
01728 {
01729 uint32_t n= left_row->cols();
01730 for (uint32_t i= 0 ; i < n; i++)
01731 {
01732 bool is_converted;
01733 Item *left_item= left_row->element_index(i);
01734 Item *right_item= right_row->element_index(i);
01735 if (left_item->type() == Item::ROW_ITEM &&
01736 right_item->type() == Item::ROW_ITEM)
01737 {
01738 is_converted= check_row_equality(session,
01739 (Item_row *) left_item,
01740 (Item_row *) right_item,
01741 cond_equal, eq_list);
01742 if (!is_converted)
01743 {
01744 session->lex().current_select->cond_count++;
01745 }
01746 }
01747 else
01748 {
01749 is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
01750 session->lex().current_select->cond_count++;
01751 }
01752
01753 if (!is_converted)
01754 {
01755 Item_func_eq *eq_item;
01756 eq_item= new Item_func_eq(left_item, right_item);
01757 eq_item->set_cmp_func();
01758 eq_item->quick_fix_field();
01759 eq_list->push_back(eq_item);
01760 }
01761 }
01762 return true;
01763 }
01764
01794 static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal, List<Item> *eq_list)
01795 {
01796 if (item->type() == Item::FUNC_ITEM &&
01797 ((Item_func*) item)->functype() == Item_func::EQ_FUNC)
01798 {
01799 Item *left_item= ((Item_func*) item)->arguments()[0];
01800 Item *right_item= ((Item_func*) item)->arguments()[1];
01801
01802 if (left_item->type() == Item::ROW_ITEM &&
01803 right_item->type() == Item::ROW_ITEM)
01804 {
01805 session->lex().current_select->cond_count--;
01806 return check_row_equality(session,
01807 (Item_row *) left_item,
01808 (Item_row *) right_item,
01809 cond_equal, eq_list);
01810 }
01811 else
01812 {
01813 return check_simple_equality(left_item, right_item, item, cond_equal);
01814 }
01815 }
01816 return false;
01817 }
01818
01882 static COND *build_equal_items_for_cond(Session *session, COND *cond, COND_EQUAL *inherited)
01883 {
01884 Item_equal *item_equal;
01885 COND_EQUAL cond_equal;
01886 cond_equal.upper_levels= inherited;
01887
01888 if (cond->type() == Item::COND_ITEM)
01889 {
01890 List<Item> eq_list;
01891 bool and_level= ((Item_cond*) cond)->functype() ==
01892 Item_func::COND_AND_FUNC;
01893 List<Item> *args= ((Item_cond*) cond)->argument_list();
01894
01895 List<Item>::iterator li(args->begin());
01896 Item *item;
01897
01898 if (and_level)
01899 {
01900
01901
01902
01903
01904
01905
01906 while ((item= li++))
01907 {
01908
01909
01910
01911
01912
01913 if (check_equality(session, item, &cond_equal, &eq_list))
01914 {
01915 li.remove();
01916 }
01917 }
01918
01919 List<Item_equal>::iterator it(cond_equal.current_level.begin());
01920 while ((item_equal= it++))
01921 {
01922 item_equal->fix_length_and_dec();
01923 item_equal->update_used_tables();
01924 set_if_bigger(session->lex().current_select->max_equal_elems,
01925 item_equal->members());
01926 }
01927
01928 ((Item_cond_and*)cond)->cond_equal= cond_equal;
01929 inherited= &(((Item_cond_and*)cond)->cond_equal);
01930 }
01931
01932
01933
01934
01935 li= args->begin();
01936 while ((item= li++))
01937 {
01938 Item *new_item;
01939 if ((new_item= build_equal_items_for_cond(session, item, inherited)) != item)
01940 {
01941
01942
01943
01944
01945
01946
01947 li.replace(new_item);
01948 }
01949 }
01950 if (and_level)
01951 {
01952 args->concat(&eq_list);
01953 args->concat((List<Item> *)&cond_equal.current_level);
01954 }
01955 }
01956 else if (cond->type() == Item::FUNC_ITEM)
01957 {
01958 List<Item> eq_list;
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 if (check_equality(session, cond, &cond_equal, &eq_list))
01970 {
01971 int n= cond_equal.current_level.size() + eq_list.size();
01972
01973 if (n == 0)
01974 {
01975 return new Item_int((int64_t) 1,1);
01976 }
01977 else if (n == 1)
01978 {
01979 if ((item_equal= cond_equal.current_level.pop()))
01980 {
01981 item_equal->fix_length_and_dec();
01982 item_equal->update_used_tables();
01983 }
01984 else
01985 {
01986 item_equal= (Item_equal *) eq_list.pop();
01987 }
01988 set_if_bigger(session->lex().current_select->max_equal_elems,
01989 item_equal->members());
01990 return item_equal;
01991 }
01992 else
01993 {
01994
01995
01996
01997
01998 Item_cond_and *and_cond= new Item_cond_and(eq_list);
01999 and_cond->quick_fix_field();
02000 List<Item> *args= and_cond->argument_list();
02001 List<Item_equal>::iterator it(cond_equal.current_level.begin());
02002 while ((item_equal= it++))
02003 {
02004 item_equal->fix_length_and_dec();
02005 item_equal->update_used_tables();
02006 set_if_bigger(session->lex().current_select->max_equal_elems,
02007 item_equal->members());
02008 }
02009 and_cond->cond_equal= cond_equal;
02010 args->concat((List<Item> *)&cond_equal.current_level);
02011
02012 return and_cond;
02013 }
02014 }
02015
02016
02017
02018
02019
02020
02021 unsigned char *is_subst_valid= (unsigned char *) 1;
02022 cond= cond->compile(&Item::subst_argument_checker,
02023 &is_subst_valid,
02024 &Item::equal_fields_propagator,
02025 (unsigned char *) inherited);
02026 cond->update_used_tables();
02027 }
02028 return cond;
02029 }
02030
02096 static COND *build_equal_items(Session *session, COND *cond,
02097 COND_EQUAL *inherited,
02098 List<TableList> *join_list,
02099 COND_EQUAL **cond_equal_ref)
02100 {
02101 COND_EQUAL *cond_equal= 0;
02102
02103 if (cond)
02104 {
02105 cond= build_equal_items_for_cond(session, cond, inherited);
02106 cond->update_used_tables();
02107
02108 if (cond->type() == Item::COND_ITEM && ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
02109 {
02110 cond_equal= &((Item_cond_and*) cond)->cond_equal;
02111 }
02112 else if (cond->type() == Item::FUNC_ITEM &&
02113 ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
02114 {
02115 cond_equal= new COND_EQUAL;
02116 cond_equal->current_level.push_back((Item_equal *) cond);
02117 }
02118 }
02119 if (cond_equal)
02120 {
02121 cond_equal->upper_levels= inherited;
02122 inherited= cond_equal;
02123 }
02124 *cond_equal_ref= cond_equal;
02125
02126 if (join_list)
02127 {
02128 TableList *table;
02129 List<TableList>::iterator li(join_list->begin());
02130
02131 while ((table= li++))
02132 {
02133 if (table->on_expr)
02134 {
02135 List<TableList> *nested_join_list= table->getNestedJoin() ?
02136 &table->getNestedJoin()->join_list : NULL;
02137
02138
02139
02140
02141 table->on_expr= build_equal_items(session, table->on_expr, inherited,
02142 nested_join_list,
02143 &table->cond_equal);
02144 }
02145 }
02146 }
02147
02148 return cond;
02149 }
02150
02170 static int compare_fields_by_table_order(Item_field *field1,
02171 Item_field *field2,
02172 void *table_join_idx)
02173 {
02174 int cmp= 0;
02175 bool outer_ref= 0;
02176 if (field2->used_tables() & OUTER_REF_TABLE_BIT)
02177 {
02178 outer_ref= 1;
02179 cmp= -1;
02180 }
02181
02182 if (field2->used_tables() & OUTER_REF_TABLE_BIT)
02183 {
02184 outer_ref= 1;
02185 cmp++;
02186 }
02187
02188 if (outer_ref)
02189 {
02190 return cmp;
02191 }
02192
02193 JoinTable **idx= (JoinTable **) table_join_idx;
02194 cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
02195
02196 return cmp < 0 ? -1 : (cmp ? 1 : 0);
02197 }
02198
02238 static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, Item_equal *item_equal)
02239 {
02240 List<Item> eq_list;
02241 Item_func_eq *eq_item= 0;
02242 if (((Item *) item_equal)->const_item() && !item_equal->val_int())
02243 return new Item_int((int64_t) 0,1);
02244 Item *item_const= item_equal->get_const();
02245 Item_equal_iterator it(item_equal->begin());
02246 Item *head;
02247 if (item_const)
02248 {
02249 head= item_const;
02250 }
02251 else
02252 {
02253 head= item_equal->get_first();
02254 it++;
02255 }
02256 Item_field *item_field;
02257 while ((item_field= it++))
02258 {
02259 Item_equal *upper= item_field->find_item_equal(upper_levels);
02260 Item_field *item= item_field;
02261 if (upper)
02262 {
02263 if (item_const && upper->get_const())
02264 {
02265 item= 0;
02266 }
02267 else
02268 {
02269 Item_equal_iterator li(item_equal->begin());
02270 while ((item= li++) != item_field)
02271 {
02272 if (item->find_item_equal(upper_levels) == upper)
02273 {
02274 break;
02275 }
02276 }
02277 }
02278 }
02279 if (item == item_field)
02280 {
02281 if (eq_item)
02282 {
02283 eq_list.push_back(eq_item);
02284 }
02285
02286 eq_item= new Item_func_eq(item_field, head);
02287
02288 if (!eq_item)
02289 {
02290 return 0;
02291 }
02292 eq_item->set_cmp_func();
02293 eq_item->quick_fix_field();
02294 }
02295 }
02296
02297 if (!cond && !&eq_list.front())
02298 {
02299 if (!eq_item)
02300 {
02301 return new Item_int((int64_t) 1,1);
02302 }
02303 return eq_item;
02304 }
02305
02306 if (eq_item)
02307 {
02308 eq_list.push_back(eq_item);
02309 }
02310
02311 if (!cond)
02312 {
02313 cond= new Item_cond_and(eq_list);
02314 }
02315 else
02316 {
02317 assert(cond->type() == Item::COND_ITEM);
02318 ((Item_cond *) cond)->add_at_head(&eq_list);
02319 }
02320
02321 cond->quick_fix_field();
02322 cond->update_used_tables();
02323
02324 return cond;
02325 }
02326
02354 COND* substitute_for_best_equal_field(COND *cond, COND_EQUAL *cond_equal, void *table_join_idx)
02355 {
02356 Item_equal *item_equal;
02357
02358 if (cond->type() == Item::COND_ITEM)
02359 {
02360 List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
02361
02362 bool and_level= ((Item_cond*) cond)->functype() ==
02363 Item_func::COND_AND_FUNC;
02364 if (and_level)
02365 {
02366 cond_equal= &((Item_cond_and *) cond)->cond_equal;
02367 cond_list->disjoin((List<Item> *) &cond_equal->current_level);
02368
02369 List<Item_equal>::iterator it(cond_equal->current_level.begin());
02370 while ((item_equal= it++))
02371 {
02372 item_equal->sort(&compare_fields_by_table_order, table_join_idx);
02373 }
02374 }
02375
02376 List<Item>::iterator li(cond_list->begin());
02377 Item *item;
02378 while ((item= li++))
02379 {
02380 Item *new_item =substitute_for_best_equal_field(item, cond_equal,
02381 table_join_idx);
02382
02383
02384
02385
02386 if (new_item != item)
02387 li.replace(new_item);
02388 }
02389
02390 if (and_level)
02391 {
02392 List<Item_equal>::iterator it(cond_equal->current_level.begin());
02393 while ((item_equal= it++))
02394 {
02395 cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
02396
02397
02398
02399 if (cond->type() != Item::COND_ITEM)
02400 break;
02401 }
02402 }
02403
02404 if (cond->type() == Item::COND_ITEM && !((Item_cond*)cond)->argument_list()->size())
02405 {
02406 cond= new Item_int((int32_t)cond->val_bool());
02407 }
02408
02409 }
02410 else if (cond->type() == Item::FUNC_ITEM &&
02411 ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
02412 {
02413 item_equal= (Item_equal *) cond;
02414 item_equal->sort(&compare_fields_by_table_order, table_join_idx);
02415 if (cond_equal && &cond_equal->current_level.front() == item_equal)
02416 {
02417 cond_equal= 0;
02418 }
02419
02420 return eliminate_item_equal(0, cond_equal, item_equal);
02421 }
02422 else
02423 {
02424 cond->transform(&Item::replace_equal_field, 0);
02425 }
02426
02427 return cond;
02428 }
02429
02442 void update_const_equal_items(COND *cond, JoinTable *tab)
02443 {
02444 if (!(cond->used_tables() & tab->table->map))
02445 return;
02446
02447 if (cond->type() == Item::COND_ITEM)
02448 {
02449 List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
02450 List<Item>::iterator li(cond_list->begin());
02451 Item *item;
02452 while ((item= li++))
02453 update_const_equal_items(item, tab);
02454 }
02455 else if (cond->type() == Item::FUNC_ITEM &&
02456 ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
02457 {
02458 Item_equal *item_equal= (Item_equal *) cond;
02459 bool contained_const= item_equal->get_const() != NULL;
02460 item_equal->update_const();
02461 if (!contained_const && item_equal->get_const())
02462 {
02463
02464 Item_equal_iterator it(item_equal->begin());
02465 Item_field *item_field;
02466 while ((item_field= it++))
02467 {
02468 Field *field= item_field->field;
02469 JoinTable *stat= field->getTable()->reginfo.join_tab;
02470 key_map possible_keys= field->key_start;
02471 possible_keys&= field->getTable()->keys_in_use_for_query;
02472 stat[0].const_keys|= possible_keys;
02473
02474
02475
02476
02477
02478
02479 if (possible_keys.any())
02480 {
02481 Table *field_tab= field->getTable();
02482 optimizer::KeyUse *use;
02483 for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
02484 if (possible_keys.test(use->getKey()) &&
02485 field_tab->key_info[use->getKey()].key_part[use->getKeypart()].field ==
02486 field)
02487 field_tab->const_key_parts[use->getKey()]|= use->getKeypartMap();
02488 }
02489 }
02490 }
02491 }
02492 }
02493
02494
02495
02496
02497
02498 static void change_cond_ref_to_const(Session *session,
02499 list<COND_CMP>& save_list,
02500 Item *and_father,
02501 Item *cond,
02502 Item *field,
02503 Item *value)
02504 {
02505 if (cond->type() == Item::COND_ITEM)
02506 {
02507 bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
02508 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
02509 Item *item;
02510 while ((item=li++))
02511 change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
02512
02513 return;
02514 }
02515
02516 if (cond->eq_cmp_result() == Item::COND_OK)
02517 {
02518 return;
02519 }
02520
02521 Item_bool_func2 *func= (Item_bool_func2*) cond;
02522 Item **args= func->arguments();
02523 Item *left_item= args[0];
02524 Item *right_item= args[1];
02525 Item_func::Functype functype= func->functype();
02526
02527 if (right_item->eq(field,0) && left_item != value &&
02528 right_item->cmp_context == field->cmp_context &&
02529 (left_item->result_type() != STRING_RESULT ||
02530 value->result_type() != STRING_RESULT ||
02531 left_item->collation.collation == value->collation.collation))
02532 {
02533 Item *tmp=value->clone_item();
02534 if (tmp)
02535 {
02536 tmp->collation.set(right_item->collation);
02537 args[1]= tmp;
02538 func->update_used_tables();
02539 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
02540 and_father != cond &&
02541 ! left_item->const_item())
02542 {
02543 cond->marker=1;
02544 save_list.push_back( COND_CMP(and_father, func) );
02545 }
02546 func->set_cmp_func();
02547 }
02548 }
02549 else if (left_item->eq(field,0) && right_item != value &&
02550 left_item->cmp_context == field->cmp_context &&
02551 (right_item->result_type() != STRING_RESULT ||
02552 value->result_type() != STRING_RESULT ||
02553 right_item->collation.collation == value->collation.collation))
02554 {
02555 Item *tmp= value->clone_item();
02556 if (tmp)
02557 {
02558 tmp->collation.set(left_item->collation);
02559 *args= tmp;
02560 value= tmp;
02561 func->update_used_tables();
02562 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
02563 and_father != cond &&
02564 ! right_item->const_item())
02565 {
02566 args[0]= args[1];
02567 args[1]= value;
02568 cond->marker=1;
02569 save_list.push_back( COND_CMP(and_father, func) );
02570 }
02571 func->set_cmp_func();
02572 }
02573 }
02574 }
02575
02584 Item *remove_additional_cond(Item* conds)
02585 {
02586 if (conds->name == in_additional_cond)
02587 {
02588 return 0;
02589 }
02590
02591 if (conds->type() == Item::COND_ITEM)
02592 {
02593 Item_cond *cnd= (Item_cond*) conds;
02594 List<Item>::iterator li(cnd->argument_list()->begin());
02595 Item *item;
02596 while ((item= li++))
02597 {
02598 if (item->name == in_additional_cond)
02599 {
02600 li.remove();
02601 if (cnd->argument_list()->size() == 1)
02602 {
02603 return &cnd->argument_list()->front();
02604 }
02605
02606 return conds;
02607 }
02608 }
02609 }
02610 return conds;
02611 }
02612
02613 static void propagate_cond_constants(Session *session,
02614 list<COND_CMP>& save_list,
02615 COND *and_father,
02616 COND *cond)
02617 {
02618 if (cond->type() == Item::COND_ITEM)
02619 {
02620 bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
02621 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
02622 Item *item;
02623 list<COND_CMP> save;
02624 while ((item=li++))
02625 {
02626 propagate_cond_constants(session, save, and_level ? cond : item, item);
02627 }
02628 if (and_level)
02629 {
02630
02631 for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
02632 {
02633 Item **args= iter->second->arguments();
02634 if (not args[0]->const_item())
02635 {
02636 change_cond_ref_to_const(session, save, iter->first,
02637 iter->first, args[0], args[1] );
02638 }
02639 }
02640 }
02641 }
02642 else if (and_father != cond && !cond->marker)
02643 {
02644 if (cond->type() == Item::FUNC_ITEM &&
02645 (((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
02646 ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC))
02647 {
02648 Item_func_eq *func=(Item_func_eq*) cond;
02649 Item **args= func->arguments();
02650 bool left_const= args[0]->const_item();
02651 bool right_const= args[1]->const_item();
02652 if (!(left_const && right_const) && args[0]->result_type() == args[1]->result_type())
02653 {
02654 if (right_const)
02655 {
02656 resolve_const_item(session, &args[1], args[0]);
02657 func->update_used_tables();
02658 change_cond_ref_to_const(session, save_list, and_father, and_father,
02659 args[0], args[1]);
02660 }
02661 else if (left_const)
02662 {
02663 resolve_const_item(session, &args[0], args[1]);
02664 func->update_used_tables();
02665 change_cond_ref_to_const(session, save_list, and_father, and_father,
02666 args[1], args[0]);
02667 }
02668 }
02669 }
02670 }
02671 }
02672
02763 bool check_interleaving_with_nj(JoinTable *next_tab)
02764 {
02765 TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
02766 Join *join= next_tab->join;
02767
02768 if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
02769 {
02770
02771
02772
02773
02774 return true;
02775 }
02776
02777
02778
02779
02780
02781 for (;next_emb; next_emb= next_emb->getEmbedding())
02782 {
02783 next_emb->getNestedJoin()->counter_++;
02784 if (next_emb->getNestedJoin()->counter_ == 1)
02785 {
02786
02787
02788
02789
02790
02791 join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
02792 }
02793
02794 if (next_emb->getNestedJoin()->join_list.size() != next_emb->getNestedJoin()->counter_)
02795 {
02796 break;
02797 }
02798
02799
02800
02801
02802
02803 join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
02804 }
02805 return false;
02806 }
02807
02808 COND *optimize_cond(Join *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
02809 {
02810 Session *session= join->session;
02811
02812 if (conds == NULL)
02813 {
02814 *cond_value= Item::COND_TRUE;
02815 }
02816 else
02817 {
02818
02819
02820
02821
02822
02823
02824
02825
02826 conds= build_equal_items(join->session, conds, NULL, join_list,
02827 &join->cond_equal);
02828
02829
02830 list<COND_CMP> temp;
02831 propagate_cond_constants(session, temp, conds, conds);
02832
02833
02834
02835
02836 conds= remove_eq_conds(session, conds, cond_value) ;
02837 }
02838 return(conds);
02839 }
02840
02851 COND *remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value)
02852 {
02853 if (cond->type() == Item::COND_ITEM)
02854 {
02855 bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
02856
02857 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
02858 Item::cond_result tmp_cond_value;
02859 bool should_fix_fields= false;
02860
02861 *cond_value= Item::COND_UNDEF;
02862 Item *item;
02863 while ((item= li++))
02864 {
02865 Item *new_item= remove_eq_conds(session, item, &tmp_cond_value);
02866 if (! new_item)
02867 {
02868 li.remove();
02869 }
02870 else if (item != new_item)
02871 {
02872 li.replace(new_item);
02873 should_fix_fields= true;
02874 }
02875
02876 if (*cond_value == Item::COND_UNDEF)
02877 {
02878 *cond_value= tmp_cond_value;
02879 }
02880
02881 switch (tmp_cond_value)
02882 {
02883 case Item::COND_OK:
02884 if (and_level || (*cond_value == Item::COND_FALSE))
02885 *cond_value= tmp_cond_value;
02886 break;
02887 case Item::COND_FALSE:
02888 if (and_level)
02889 {
02890 *cond_value= tmp_cond_value;
02891 return (COND *) NULL;
02892 }
02893 break;
02894 case Item::COND_TRUE:
02895 if (! and_level)
02896 {
02897 *cond_value= tmp_cond_value;
02898 return (COND *) NULL;
02899 }
02900 break;
02901 case Item::COND_UNDEF:
02902 break;
02903 }
02904 }
02905
02906 if (should_fix_fields)
02907 {
02908 cond->update_used_tables();
02909 }
02910
02911 if (! ((Item_cond*) cond)->argument_list()->size() || *cond_value != Item::COND_OK)
02912 {
02913 return (COND*) NULL;
02914 }
02915
02916 if (((Item_cond*) cond)->argument_list()->size() == 1)
02917 {
02918
02919 item= &((Item_cond*) cond)->argument_list()->front();
02920 ((Item_cond*) cond)->argument_list()->clear();
02921
02922 return item;
02923 }
02924 }
02925 else if (cond->type() == Item::FUNC_ITEM && ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
02926 {
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937 Item_func_isnull *func= (Item_func_isnull*) cond;
02938 Item **args= func->arguments();
02939 if (args[0]->type() == Item::FIELD_ITEM)
02940 {
02941 Field *field= ((Item_field*) args[0])->field;
02942 if (field->flags & AUTO_INCREMENT_FLAG
02943 && ! field->getTable()->maybe_null
02944 && session->options & OPTION_AUTO_IS_NULL
02945 && (
02946 session->first_successful_insert_id_in_prev_stmt > 0
02947 && session->substitute_null_with_insert_id
02948 )
02949 )
02950 {
02951 COND *new_cond= new Item_func_eq(args[0], new Item_int("last_insert_id()",
02952 session->read_first_successful_insert_id_in_prev_stmt(), MY_INT64_NUM_DECIMAL_DIGITS));
02953 cond= new_cond;
02954
02955
02956
02957
02958
02959 cond->fix_fields(session, &cond);
02960
02961
02962
02963
02964 session->substitute_null_with_insert_id= false;
02965 }
02966 #ifdef NOTDEFINED
02967
02968 else if (
02969 ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME))
02970 && (field->flags & NOT_NULL_FLAG)
02971 && ! field->table->maybe_null)
02972 {
02973 COND* new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2));
02974 cond= new_cond;
02975
02976
02977
02978
02979
02980 cond->fix_fields(session, &cond);
02981 }
02982 #endif
02983 }
02984 if (cond->const_item())
02985 {
02986 *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
02987 return (COND *) NULL;
02988 }
02989 }
02990 else if (cond->const_item() && !cond->is_expensive())
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001 {
03002 *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
03003 return (COND *) NULL;
03004 }
03005 else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
03006 {
03007
03008 Item *left_item= ((Item_func*) cond)->arguments()[0];
03009 Item *right_item= ((Item_func*) cond)->arguments()[1];
03010 if (left_item->eq(right_item,1))
03011 {
03012 if (!left_item->maybe_null || ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
03013 {
03014 return (COND*) NULL;
03015 }
03016 }
03017 }
03018 *cond_value= Item::COND_OK;
03019 return cond;
03020 }
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045 static bool test_if_equality_guarantees_uniqueness(Item *l, Item *r)
03046 {
03047 return r->const_item() &&
03048
03049 (Arg_comparator::can_compare_as_dates(l, r, 0) ||
03050
03051 (r->result_type() == l->result_type() &&
03052
03053 (l->result_type() != STRING_RESULT ||
03054 l->collation.collation == r->collation.collation)));
03055 }
03056
03060 bool const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
03061 {
03062 if (cond->type() == Item::COND_ITEM)
03063 {
03064 bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
03065 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
03066
03067 Item *item;
03068 while ((item=li++))
03069 {
03070 bool res=const_expression_in_where(item, comp_item, const_item);
03071 if (res)
03072 {
03073 if (and_level)
03074 {
03075 return true;
03076 }
03077 }
03078 else if (and_level == false)
03079 {
03080 return false;
03081 }
03082 }
03083 return and_level ? false : true;
03084 }
03085 else if (cond->eq_cmp_result() != Item::COND_OK)
03086 {
03087 Item_func* func= (Item_func*) cond;
03088 if (func->functype() != Item_func::EQUAL_FUNC &&
03089 func->functype() != Item_func::EQ_FUNC)
03090 {
03091 return false;
03092 }
03093
03094 Item *left_item= ((Item_func*) cond)->arguments()[0];
03095 Item *right_item= ((Item_func*) cond)->arguments()[1];
03096
03097 if (left_item->eq(comp_item,1))
03098 {
03099 if (test_if_equality_guarantees_uniqueness (left_item, right_item))
03100 {
03101 if (*const_item)
03102 {
03103 return right_item->eq(*const_item, 1);
03104 }
03105 *const_item=right_item;
03106 return true;
03107 }
03108 }
03109 else if (right_item->eq(comp_item,1))
03110 {
03111 if (test_if_equality_guarantees_uniqueness (right_item, left_item))
03112 {
03113 if (*const_item)
03114 {
03115 return left_item->eq(*const_item, 1);
03116 }
03117 *const_item=left_item;
03118 return true;
03119 }
03120 }
03121 }
03122
03123 return false;
03124 }
03125
03137 Next_select_func setup_end_select_func(Join *join)
03138 {
03139 Table *table= join->tmp_table;
03140 Tmp_Table_Param *tmp_tbl= &join->tmp_table_param;
03141 Next_select_func end_select;
03142
03143
03144 if (table)
03145 {
03146 if (table->group && tmp_tbl->sum_func_count &&
03147 !tmp_tbl->precomputed_group_by)
03148 {
03149 if (table->getShare()->sizeKeys())
03150 {
03151 end_select= end_update;
03152 }
03153 else
03154 {
03155 end_select= end_unique_update;
03156 }
03157 }
03158 else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
03159 {
03160 end_select= end_write_group;
03161 }
03162 else
03163 {
03164 end_select= end_write;
03165 if (tmp_tbl->precomputed_group_by)
03166 {
03167
03168
03169
03170
03171
03172
03173
03174 memcpy(tmp_tbl->items_to_copy + tmp_tbl->func_count,
03175 join->sum_funcs,
03176 sizeof(Item*)*tmp_tbl->sum_func_count);
03177 tmp_tbl->items_to_copy[tmp_tbl->func_count+tmp_tbl->sum_func_count]= 0;
03178 }
03179 }
03180 }
03181 else
03182 {
03183 if ((join->sort_and_group) && !tmp_tbl->precomputed_group_by)
03184 {
03185 end_select= end_send_group;
03186 }
03187 else
03188 {
03189 end_select= end_send;
03190 }
03191 }
03192
03193 return end_select;
03194 }
03195
03206 int do_select(Join *join, List<Item> *fields, Table *table)
03207 {
03208 int rc= 0;
03209 enum_nested_loop_state error= NESTED_LOOP_OK;
03210 JoinTable *join_tab= NULL;
03211
03212 join->tmp_table= table;
03213 join->fields= fields;
03214
03215 if (table)
03216 {
03217 table->cursor->extra(HA_EXTRA_WRITE_CACHE);
03218 table->emptyRecord();
03219 if (table->group && join->tmp_table_param.sum_func_count &&
03220 table->getShare()->sizeKeys() && !table->cursor->inited)
03221 {
03222 int tmp_error;
03223 tmp_error= table->cursor->startIndexScan(0, 0);
03224 if (tmp_error != 0)
03225 {
03226 table->print_error(tmp_error, MYF(0));
03227 return -1;
03228 }
03229 }
03230 }
03231
03232
03233 Next_select_func end_select= setup_end_select_func(join);
03234 if (join->tables)
03235 {
03236 join->join_tab[join->tables-1].next_select= end_select;
03237
03238 join_tab=join->join_tab+join->const_tables;
03239 }
03240
03241 join->send_records=0;
03242 if (join->tables == join->const_tables)
03243 {
03244
03245
03246
03247
03248 if (!join->conds || join->conds->val_int())
03249 {
03250 error= (*end_select)(join, 0, 0);
03251 if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
03252 error= (*end_select)(join, 0, 1);
03253
03254
03255
03256
03257
03258
03259 join->examined_rows++;
03260 join->session->row_count++;
03261 assert(join->examined_rows <= 1);
03262 }
03263 else if (join->send_row_on_empty_set())
03264 {
03265 List<Item> *columns_list= fields;
03266 rc= join->result->send_data(*columns_list);
03267 }
03268 }
03269 else
03270 {
03271 assert(join->tables);
03272 error= sub_select(join,join_tab,0);
03273 if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
03274 {
03275 error= sub_select(join,join_tab,1);
03276 }
03277
03278 if (error == NESTED_LOOP_QUERY_LIMIT)
03279 {
03280 error= NESTED_LOOP_OK;
03281 }
03282 }
03283
03284 if (error == NESTED_LOOP_NO_MORE_ROWS)
03285 {
03286 error= NESTED_LOOP_OK;
03287 }
03288
03289 if (error == NESTED_LOOP_OK)
03290 {
03291
03292
03293
03294
03295 if (!table)
03296 {
03297
03298
03299
03300
03301 join->join_free();
03302 if (join->result->send_eof())
03303 {
03304 rc= 1;
03305 }
03306 }
03307 }
03308 else
03309 {
03310 rc= -1;
03311 }
03312
03313 if (table)
03314 {
03315 int tmp, new_errno= 0;
03316 if ((tmp=table->cursor->extra(HA_EXTRA_NO_CACHE)))
03317 {
03318 new_errno= tmp;
03319 }
03320
03321 if ((tmp=table->cursor->ha_index_or_rnd_end()))
03322 {
03323 new_errno= tmp;
03324 }
03325
03326 if (new_errno)
03327 {
03328 table->print_error(new_errno,MYF(0));
03329 }
03330 }
03331 return(join->session->is_error() ? -1 : rc);
03332 }
03333
03334 enum_nested_loop_state sub_select_cache(Join *join, JoinTable *join_tab, bool end_of_records)
03335 {
03336 enum_nested_loop_state rc;
03337
03338 if (end_of_records)
03339 {
03340 rc= flush_cached_records(join,join_tab,false);
03341 if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
03342 rc= sub_select(join,join_tab,end_of_records);
03343 return rc;
03344 }
03345
03346 if (join->session->getKilled())
03347 {
03348 join->session->send_kill_message();
03349 return NESTED_LOOP_KILLED;
03350 }
03351
03352 if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
03353 {
03354 if (! join_tab->cache.store_record_in_cache())
03355 return NESTED_LOOP_OK;
03356 return flush_cached_records(join,join_tab,false);
03357 }
03358 rc= flush_cached_records(join, join_tab, true);
03359 if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
03360 {
03361 rc= sub_select(join, join_tab, end_of_records);
03362 }
03363
03364 return rc;
03365 }
03366
03486 enum_nested_loop_state sub_select(Join *join, JoinTable *join_tab, bool end_of_records)
03487 {
03488 join_tab->table->null_row=0;
03489 if (end_of_records)
03490 {
03491 return (*join_tab->next_select)(join,join_tab+1,end_of_records);
03492 }
03493
03494 int error;
03495 enum_nested_loop_state rc;
03496 ReadRecord *info= &join_tab->read_record;
03497
03498 if (join->resume_nested_loop)
03499 {
03500
03501 if (join_tab < join->join_tab + join->tables - 1)
03502 {
03503 rc= (*join_tab->next_select)(join, join_tab + 1, 0);
03504 }
03505 else
03506 {
03507 join->resume_nested_loop= false;
03508 rc= NESTED_LOOP_OK;
03509 }
03510 }
03511 else
03512 {
03513 join->return_tab= join_tab;
03514
03515 if (join_tab->last_inner)
03516 {
03517
03518
03519
03520 join_tab->found=0;
03521 join_tab->not_null_compl= 1;
03522
03523
03524 join_tab->last_inner->first_unmatched= join_tab;
03525 }
03526 join->session->row_count= 0;
03527
03528 error= (*join_tab->read_first_record)(join_tab);
03529 rc= evaluate_join_record(join, join_tab, error);
03530 }
03531
03532
03533
03534
03535
03536 while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab)
03537 {
03538 error= info->read_record(info);
03539 rc= evaluate_join_record(join, join_tab, error);
03540 }
03541
03542 if (rc == NESTED_LOOP_NO_MORE_ROWS and join_tab->last_inner && !join_tab->found)
03543 {
03544 rc= evaluate_null_complemented_join_record(join, join_tab);
03545 }
03546
03547 if (rc == NESTED_LOOP_NO_MORE_ROWS)
03548 {
03549 rc= NESTED_LOOP_OK;
03550 }
03551
03552 return rc;
03553 }
03554
03555 int safe_index_read(JoinTable *tab)
03556 {
03557 int error;
03558 Table *table= tab->table;
03559 if ((error=table->cursor->index_read_map(table->getInsertRecord(),
03560 tab->ref.key_buff,
03561 make_prev_keypart_map(tab->ref.key_parts),
03562 HA_READ_KEY_EXACT)))
03563 return table->report_error(error);
03564 return 0;
03565 }
03566
03579 int join_read_const(JoinTable *tab)
03580 {
03581 int error;
03582 Table *table= tab->table;
03583 if (table->status & STATUS_GARBAGE)
03584 {
03585 table->status= 0;
03586 if (cp_buffer_from_ref(tab->join->session, &tab->ref))
03587 {
03588 error= HA_ERR_KEY_NOT_FOUND;
03589 }
03590 else
03591 {
03592 error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
03593 (unsigned char*) tab->ref.key_buff,
03594 make_prev_keypart_map(tab->ref.key_parts),
03595 HA_READ_KEY_EXACT);
03596 }
03597 if (error)
03598 {
03599 table->status= STATUS_NOT_FOUND;
03600 tab->table->mark_as_null_row();
03601 table->emptyRecord();
03602 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
03603 {
03604 return table->report_error(error);
03605 }
03606 return -1;
03607 }
03608 table->storeRecord();
03609 }
03610 else if (!(table->status & ~STATUS_NULL_ROW))
03611 {
03612 table->status=0;
03613 table->restoreRecord();
03614 }
03615 table->null_row=0;
03616 return table->status ? -1 : 0;
03617 }
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635 int join_read_key(JoinTable *tab)
03636 {
03637 int error;
03638 Table *table= tab->table;
03639
03640 if (!table->cursor->inited)
03641 {
03642 error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
03643 if (error != 0)
03644 {
03645 table->print_error(error, MYF(0));
03646 }
03647 }
03648
03649
03650 if (cmp_buffer_with_ref(tab) ||
03651 (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
03652 {
03653 if (tab->ref.key_err)
03654 {
03655 table->status=STATUS_NOT_FOUND;
03656 return -1;
03657 }
03658 error=table->cursor->index_read_map(table->getInsertRecord(),
03659 tab->ref.key_buff,
03660 make_prev_keypart_map(tab->ref.key_parts),
03661 HA_READ_KEY_EXACT);
03662 if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
03663 {
03664 return table->report_error(error);
03665 }
03666 }
03667 table->null_row=0;
03668 return table->status ? -1 : 0;
03669 }
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689 int join_read_always_key(JoinTable *tab)
03690 {
03691 int error;
03692 Table *table= tab->table;
03693
03694
03695 if (!table->cursor->inited)
03696 {
03697 error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
03698 if (error != 0)
03699 {
03700 return table->report_error(error);
03701 }
03702 }
03703
03704
03705 for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
03706 {
03707 if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
03708 {
03709 return -1;
03710 }
03711 }
03712
03713 if (cp_buffer_from_ref(tab->join->session, &tab->ref))
03714 {
03715 return -1;
03716 }
03717
03718 if ((error=table->cursor->index_read_map(table->getInsertRecord(),
03719 tab->ref.key_buff,
03720 make_prev_keypart_map(tab->ref.key_parts),
03721 HA_READ_KEY_EXACT)))
03722 {
03723 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
03724 {
03725 return table->report_error(error);
03726 }
03727 return -1;
03728 }
03729
03730 return 0;
03731 }
03732
03737 int join_read_last_key(JoinTable *tab)
03738 {
03739 int error;
03740 Table *table= tab->table;
03741
03742 if (!table->cursor->inited)
03743 {
03744 error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
03745 if (error != 0)
03746 return table->report_error(error);
03747 }
03748
03749 if (cp_buffer_from_ref(tab->join->session, &tab->ref))
03750 {
03751 return -1;
03752 }
03753
03754 if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
03755 tab->ref.key_buff,
03756 make_prev_keypart_map(tab->ref.key_parts))))
03757 {
03758 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
03759 {
03760 return table->report_error(error);
03761 }
03762 return -1;
03763 }
03764
03765 return 0;
03766 }
03767
03768 int join_no_more_records(ReadRecord *)
03769 {
03770 return -1;
03771 }
03772
03773 int join_read_next_same_diff(ReadRecord *info)
03774 {
03775 Table *table= info->table;
03776 JoinTable *tab=table->reginfo.join_tab;
03777 if (tab->insideout_match_tab->found_match)
03778 {
03779 KeyInfo *key= tab->table->key_info + tab->index;
03780 do
03781 {
03782 int error;
03783
03784 key_copy(tab->insideout_buf, info->record, key, 0);
03785
03786 if ((error=table->cursor->index_next_same(table->getInsertRecord(),
03787 tab->ref.key_buff,
03788 tab->ref.key_length)))
03789 {
03790 if (error != HA_ERR_END_OF_FILE)
03791 return table->report_error(error);
03792 table->status= STATUS_GARBAGE;
03793 return -1;
03794 }
03795 } while (!key_cmp(tab->table->key_info[tab->index].key_part,
03796 tab->insideout_buf, key->key_length));
03797 tab->insideout_match_tab->found_match= 0;
03798 return 0;
03799 }
03800 else
03801 {
03802 return join_read_next_same(info);
03803 }
03804 }
03805
03806 int join_read_next_same(ReadRecord *info)
03807 {
03808 int error;
03809 Table *table= info->table;
03810 JoinTable *tab=table->reginfo.join_tab;
03811
03812 if ((error=table->cursor->index_next_same(table->getInsertRecord(),
03813 tab->ref.key_buff,
03814 tab->ref.key_length)))
03815 {
03816 if (error != HA_ERR_END_OF_FILE)
03817 return table->report_error(error);
03818 table->status= STATUS_GARBAGE;
03819 return -1;
03820 }
03821
03822 return 0;
03823 }
03824
03825 int join_read_prev_same(ReadRecord *info)
03826 {
03827 int error;
03828 Table *table= info->table;
03829 JoinTable *tab=table->reginfo.join_tab;
03830
03831 if ((error=table->cursor->index_prev(table->getInsertRecord())))
03832 {
03833 return table->report_error(error);
03834 }
03835
03836 if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
03837 tab->ref.key_length))
03838 {
03839 table->status=STATUS_NOT_FOUND;
03840 error= -1;
03841 }
03842
03843 return error;
03844 }
03845
03846 int join_init_quick_read_record(JoinTable *tab)
03847 {
03848 if (test_if_quick_select(tab) == -1)
03849 {
03850 return -1;
03851 }
03852
03853 return join_init_read_record(tab);
03854 }
03855
03856 int init_read_record_seq(JoinTable *tab)
03857 {
03858 tab->read_record.init_reard_record_sequential();
03859
03860 if (tab->read_record.cursor->startTableScan(1))
03861 {
03862 return 1;
03863 }
03864 return (*tab->read_record.read_record)(&tab->read_record);
03865 }
03866
03867 int test_if_quick_select(JoinTable *tab)
03868 {
03869 safe_delete(tab->select->quick);
03870
03871 return tab->select->test_quick_select(tab->join->session, tab->keys,
03872 (table_map) 0, HA_POS_ERROR, 0, false);
03873 }
03874
03875 int join_init_read_record(JoinTable *tab)
03876 {
03877 if (tab->select && tab->select->quick && tab->select->quick->reset())
03878 {
03879 return 1;
03880 }
03881
03882 if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
03883 {
03884 return 1;
03885 }
03886
03887 return (*tab->read_record.read_record)(&tab->read_record);
03888 }
03889
03890 int join_read_first(JoinTable *tab)
03891 {
03892 int error;
03893 Table *table=tab->table;
03894 if (!table->key_read && table->covering_keys.test(tab->index) &&
03895 !table->no_keyread)
03896 {
03897 table->key_read= 1;
03898 table->cursor->extra(HA_EXTRA_KEYREAD);
03899 }
03900 tab->table->status= 0;
03901 tab->read_record.table=table;
03902 tab->read_record.cursor=table->cursor;
03903 tab->read_record.index=tab->index;
03904 tab->read_record.record=table->getInsertRecord();
03905 if (tab->insideout_match_tab)
03906 {
03907 tab->read_record.do_insideout_scan= tab;
03908 tab->read_record.read_record=join_read_next_different;
03909 tab->insideout_match_tab->found_match= 0;
03910 }
03911 else
03912 {
03913 tab->read_record.read_record=join_read_next;
03914 tab->read_record.do_insideout_scan= 0;
03915 }
03916
03917 if (!table->cursor->inited)
03918 {
03919 error= table->cursor->startIndexScan(tab->index, tab->sorted);
03920 if (error != 0)
03921 {
03922 table->report_error(error);
03923 return -1;
03924 }
03925 }
03926 if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
03927 {
03928 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
03929 table->report_error(error);
03930 return -1;
03931 }
03932
03933 return 0;
03934 }
03935
03936 int join_read_next_different(ReadRecord *info)
03937 {
03938 JoinTable *tab= info->do_insideout_scan;
03939 if (tab->insideout_match_tab->found_match)
03940 {
03941 KeyInfo *key= tab->table->key_info + tab->index;
03942 do
03943 {
03944 int error;
03945
03946 key_copy(tab->insideout_buf, info->record, key, 0);
03947
03948 if ((error=info->cursor->index_next(info->record)))
03949 {
03950 return info->table->report_error(error);
03951 }
03952 } while (!key_cmp(tab->table->key_info[tab->index].key_part,
03953 tab->insideout_buf, key->key_length));
03954 tab->insideout_match_tab->found_match= 0;
03955 return 0;
03956 }
03957 else
03958 {
03959 return join_read_next(info);
03960 }
03961 }
03962
03963 int join_read_next(ReadRecord *info)
03964 {
03965 int error;
03966 if ((error=info->cursor->index_next(info->record)))
03967 {
03968 return info->table->report_error(error);
03969 }
03970 return 0;
03971 }
03972
03973 int join_read_last(JoinTable *tab)
03974 {
03975 Table *table=tab->table;
03976 int error;
03977 if (!table->key_read && table->covering_keys.test(tab->index) &&
03978 !table->no_keyread)
03979 {
03980 table->key_read=1;
03981 table->cursor->extra(HA_EXTRA_KEYREAD);
03982 }
03983 tab->table->status=0;
03984 tab->read_record.read_record=join_read_prev;
03985 tab->read_record.table=table;
03986 tab->read_record.cursor=table->cursor;
03987 tab->read_record.index=tab->index;
03988 tab->read_record.record=table->getInsertRecord();
03989
03990 if (!table->cursor->inited)
03991 {
03992 error= table->cursor->startIndexScan(tab->index, 1);
03993 if (error != 0)
03994 {
03995 return table->report_error(error);
03996 }
03997 }
03998
03999 if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
04000 {
04001 return table->report_error(error);
04002 }
04003
04004 return 0;
04005 }
04006
04007 int join_read_prev(ReadRecord *info)
04008 {
04009 int error;
04010 if ((error= info->cursor->index_prev(info->record)))
04011 {
04012 return info->table->report_error(error);
04013 }
04014
04015 return 0;
04016 }
04017
04021 int join_read_always_key_or_null(JoinTable *tab)
04022 {
04023 int res;
04024
04025
04026 *tab->ref.null_ref_key= 0;
04027 if ((res= join_read_always_key(tab)) >= 0)
04028 {
04029 return res;
04030 }
04031
04032
04033 *tab->ref.null_ref_key= 1;
04034 return safe_index_read(tab);
04035 }
04036
04037 int join_read_next_same_or_null(ReadRecord *info)
04038 {
04039 int error;
04040 if ((error= join_read_next_same(info)) >= 0)
04041 {
04042 return error;
04043 }
04044 JoinTable *tab= info->table->reginfo.join_tab;
04045
04046
04047 if (*tab->ref.null_ref_key)
04048 {
04049 return -1;
04050 }
04051
04052 *tab->ref.null_ref_key= 1;
04053
04054 return safe_index_read(tab);
04055 }
04056
04057 enum_nested_loop_state end_send_group(Join *join, JoinTable *, bool end_of_records)
04058 {
04059 int idx= -1;
04060 enum_nested_loop_state ok_code= NESTED_LOOP_OK;
04061
04062 if (!join->first_record or end_of_records or (idx=test_if_item_cache_changed(join->group_fields)) >= 0)
04063 {
04064 if (join->first_record or
04065 (end_of_records && !join->group && !join->group_optimized_away))
04066 {
04067 if (idx < (int) join->send_group_parts)
04068 {
04069 int error=0;
04070 {
04071 if (!join->first_record)
04072 {
04073 List<Item>::iterator it(join->fields->begin());
04074 Item *item;
04075
04076 join->clear();
04077
04078 while ((item= it++))
04079 {
04080 item->no_rows_in_result();
04081 }
04082 }
04083 if (join->having && join->having->val_int() == 0)
04084 {
04085 error= -1;
04086 }
04087 else
04088 {
04089 if (join->do_send_rows)
04090 error=join->result->send_data(*join->fields) ? 1 : 0;
04091 join->send_records++;
04092 }
04093 if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
04094 {
04095 if (join->rollup_send_data((uint32_t) (idx+1)))
04096 error= 1;
04097 }
04098 }
04099
04100 if (error > 0)
04101 {
04102 return(NESTED_LOOP_ERROR);
04103 }
04104
04105 if (end_of_records)
04106 {
04107 return(NESTED_LOOP_OK);
04108 }
04109
04110 if (join->send_records >= join->unit->select_limit_cnt &&
04111 join->do_send_rows)
04112 {
04113 if (!(join->select_options & OPTION_FOUND_ROWS))
04114 {
04115 return(NESTED_LOOP_QUERY_LIMIT);
04116 }
04117 join->do_send_rows=0;
04118 join->unit->select_limit_cnt = HA_POS_ERROR;
04119 }
04120 else if (join->send_records >= join->fetch_limit)
04121 {
04122
04123
04124
04125
04126
04127
04128
04129
04130 ok_code= NESTED_LOOP_CURSOR_LIMIT;
04131 }
04132 }
04133 }
04134 else
04135 {
04136 if (end_of_records)
04137 {
04138 return(NESTED_LOOP_OK);
04139 }
04140 join->first_record=1;
04141 test_if_item_cache_changed(join->group_fields);
04142 }
04143 if (idx < (int) join->send_group_parts)
04144 {
04145
04146
04147
04148
04149 copy_fields(&join->tmp_table_param);
04150 if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
04151 {
04152 return(NESTED_LOOP_ERROR);
04153 }
04154 return(ok_code);
04155 }
04156 }
04157 if (update_sum_func(join->sum_funcs))
04158 return(NESTED_LOOP_ERROR);
04159 return(NESTED_LOOP_OK);
04160 }
04161
04162 enum_nested_loop_state end_write_group(Join *join, JoinTable *, bool end_of_records)
04163 {
04164 Table *table=join->tmp_table;
04165 int idx= -1;
04166
04167 if (join->session->getKilled())
04168 {
04169 join->session->send_kill_message();
04170 return NESTED_LOOP_KILLED;
04171 }
04172
04173 if (!join->first_record or end_of_records or (idx=test_if_item_cache_changed(join->group_fields)) >= 0)
04174 {
04175 if (join->first_record or (end_of_records && !join->group))
04176 {
04177 int send_group_parts= join->send_group_parts;
04178 if (idx < send_group_parts)
04179 {
04180 if (!join->first_record)
04181 {
04182
04183 join->clear();
04184 }
04185
04186 copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
04187
04188 if (!join->having || join->having->val_int())
04189 {
04190 int error= table->cursor->insertRecord(table->getInsertRecord());
04191
04192 if (error)
04193 {
04194 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
04195 return NESTED_LOOP_ERROR;
04196 }
04197 }
04198
04199 if (join->rollup.getState() != Rollup::STATE_NONE)
04200 {
04201 if (join->rollup_write_data((uint32_t) (idx+1), table))
04202 {
04203 return NESTED_LOOP_ERROR;
04204 }
04205 }
04206
04207 if (end_of_records)
04208 {
04209 return NESTED_LOOP_OK;
04210 }
04211 }
04212 }
04213 else
04214 {
04215 if (end_of_records)
04216 {
04217 return NESTED_LOOP_OK;
04218 }
04219 join->first_record=1;
04220 test_if_item_cache_changed(join->group_fields);
04221 }
04222 if (idx < (int) join->send_group_parts)
04223 {
04224 copy_fields(&join->tmp_table_param);
04225 if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
04226 {
04227 return NESTED_LOOP_ERROR;
04228 }
04229
04230 if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
04231 {
04232 return NESTED_LOOP_ERROR;
04233 }
04234
04235 return NESTED_LOOP_OK;
04236 }
04237 }
04238
04239 if (update_sum_func(join->sum_funcs))
04240 {
04241 return NESTED_LOOP_ERROR;
04242 }
04243
04244 return NESTED_LOOP_OK;
04245 }
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257 bool test_if_ref(Item_field *left_item,Item *right_item)
04258 {
04259 Field *field=left_item->field;
04260
04261 if (not field->getTable()->const_table && !field->getTable()->maybe_null)
04262 {
04263 Item *ref_item=part_of_refkey(field->getTable(),field);
04264 if (ref_item && ref_item->eq(right_item,1))
04265 {
04266 right_item= right_item->real_item();
04267 if (right_item->type() == Item::FIELD_ITEM)
04268 return (field->eq_def(((Item_field *) right_item)->field));
04269
04270 else if (right_item->type() == Item::CACHE_ITEM)
04271 return ((Item_cache *)right_item)->eq_def (field);
04272 if (right_item->const_item() && !(right_item->is_null()))
04273 {
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287 if (field->binary() &&
04288 field->real_type() != DRIZZLE_TYPE_VARCHAR &&
04289 field->decimals() == 0)
04290 {
04291 return ! store_val_in_field(field, right_item, CHECK_FIELD_WARN);
04292 }
04293 }
04294 }
04295 }
04296 return 0;
04297 }
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330 COND *make_cond_for_table(COND *cond, table_map tables, table_map used_table, bool exclude_expensive_cond)
04331 {
04332 if (used_table && !(cond->used_tables() & used_table) &&
04333
04334
04335
04336
04337
04338
04339 !((used_table & 1) && cond->is_expensive()))
04340 {
04341 return (COND*) 0;
04342 }
04343
04344 if (cond->type() == Item::COND_ITEM)
04345 {
04346 if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
04347 {
04348
04349 Item_cond_and *new_cond=new Item_cond_and;
04350 if (new_cond == NULL)
04351 {
04352 return (COND*) 0;
04353 }
04354 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
04355 Item *item;
04356 while ((item=li++))
04357 {
04358 Item *fix= make_cond_for_table(item,tables,used_table,
04359 exclude_expensive_cond);
04360 if (fix)
04361 {
04362 new_cond->argument_list()->push_back(fix);
04363 }
04364 }
04365 switch (new_cond->argument_list()->size())
04366 {
04367 case 0:
04368 return (COND*) 0;
04369
04370 case 1:
04371 return &new_cond->argument_list()->front();
04372
04373 default:
04374
04375
04376
04377
04378 new_cond->quick_fix_field();
04379 new_cond->used_tables_cache= ((Item_cond_and*) cond)->used_tables_cache & tables;
04380 return new_cond;
04381 }
04382 }
04383 else
04384 {
04385 Item_cond_or *new_cond=new Item_cond_or;
04386 if (new_cond == NULL)
04387 {
04388 return (COND*) 0;
04389 }
04390 List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
04391 Item *item;
04392 while ((item=li++))
04393 {
04394 Item *fix= make_cond_for_table(item,tables,0L, exclude_expensive_cond);
04395 if (!fix)
04396 {
04397 return (COND*) 0;
04398 }
04399 new_cond->argument_list()->push_back(fix);
04400 }
04401
04402
04403
04404
04405 new_cond->quick_fix_field();
04406 new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
04407 new_cond->top_level_item();
04408
04409 return new_cond;
04410 }
04411 }
04412
04413
04414
04415
04416
04417
04418
04419 if (cond->marker == 3 || (cond->used_tables() & ~tables) ||
04420
04421
04422
04423
04424 (!used_table && exclude_expensive_cond && cond->is_expensive()))
04425 {
04426 return (COND*) 0;
04427 }
04428
04429 if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
04430 {
04431 return cond;
04432 }
04433
04434
04435
04436
04437
04438 if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
04439 {
04440 Item *left_item= ((Item_func*) cond)->arguments()[0];
04441 Item *right_item= ((Item_func*) cond)->arguments()[1];
04442 if (left_item->type() == Item::FIELD_ITEM && test_if_ref((Item_field*) left_item,right_item))
04443 {
04444 cond->marker=3;
04445 return (COND*) 0;
04446 }
04447 if (right_item->type() == Item::FIELD_ITEM && test_if_ref((Item_field*) right_item,left_item))
04448 {
04449 cond->marker=3;
04450 return (COND*) 0;
04451 }
04452 }
04453 cond->marker=2;
04454 return cond;
04455 }
04456
04457 static Item *part_of_refkey(Table *table,Field *field)
04458 {
04459 if (!table->reginfo.join_tab)
04460 {
04461 return (Item*) 0;
04462 }
04463
04464 uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
04465 if (ref_parts)
04466 {
04467 KeyPartInfo *key_part=
04468 table->key_info[table->reginfo.join_tab->ref.key].key_part;
04469 uint32_t part;
04470
04471 for (part=0 ; part < ref_parts ; part++)
04472 {
04473 if (table->reginfo.join_tab->ref.cond_guards[part])
04474 {
04475 return 0;
04476 }
04477 }
04478
04479 for (part=0 ; part < ref_parts ; part++,key_part++)
04480 {
04481 if (field->eq(key_part->field) &&
04482 !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
04483
04484
04485 !(field->real_maybe_null()))
04486 {
04487 return table->reginfo.join_tab->ref.items[part];
04488 }
04489 }
04490 }
04491
04492 return (Item*) 0;
04493 }
04494
04515 static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
04516 {
04517 KeyPartInfo *key_part= NULL;
04518 KeyPartInfo *key_part_end= NULL;
04519 key_part= table->key_info[idx].key_part;
04520 key_part_end= key_part + table->key_info[idx].key_parts;
04521 key_part_map const_key_parts=table->const_key_parts[idx];
04522 int reverse= 0;
04523 bool on_primary_key= false;
04524
04525 for (; order ; order=order->next, const_key_parts>>=1)
04526 {
04527 Field *field=((Item_field*) (*order->item)->real_item())->field;
04528 int flag;
04529
04530
04531
04532
04533
04534 for (; const_key_parts & 1 ; const_key_parts>>= 1)
04535 {
04536 key_part++;
04537 }
04538
04539 if (key_part == key_part_end)
04540 {
04541
04542
04543
04544
04545
04546 if (!on_primary_key &&
04547 (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
04548 table->getShare()->hasPrimaryKey())
04549 {
04550 on_primary_key= true;
04551 key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
04552 key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
04553 const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
04554
04555 for (; const_key_parts & 1 ; const_key_parts>>= 1)
04556 {
04557 key_part++;
04558 }
04559
04560
04561
04562
04563
04564 if (key_part == key_part_end && reverse == 0)
04565 {
04566 return 1;
04567 }
04568 }
04569 else
04570 {
04571 return 0;
04572 }
04573 }
04574
04575 if (key_part->field != field)
04576 {
04577 return 0;
04578 }
04579
04580
04581 flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ?
04582 1 : -1);
04583 if (reverse && flag != reverse)
04584 {
04585 return 0;
04586 }
04587 reverse=flag;
04588 key_part++;
04589 }
04590 *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
04591 (uint32_t) (key_part - table->key_info[idx].key_part);
04592 if (reverse == -1 && !(table->index_flags(idx) & HA_READ_PREV))
04593 {
04594 reverse= 0;
04595 }
04596
04597 return(reverse);
04598 }
04599
04615 inline bool is_subkey(KeyPartInfo *key_part,
04616 KeyPartInfo *ref_key_part,
04617 KeyPartInfo *ref_key_part_end)
04618 {
04619 for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
04620 {
04621 if (! key_part->field->eq(ref_key_part->field))
04622 {
04623 return 0;
04624 }
04625 }
04626
04627 return 1;
04628 }
04629
04641 static uint32_t test_if_subkey(Order *order,
04642 Table *table,
04643 uint32_t ref,
04644 uint32_t ref_key_parts,
04645 const key_map *usable_keys)
04646 {
04647 uint32_t nr;
04648 uint32_t min_length= UINT32_MAX;
04649 uint32_t best= MAX_KEY;
04650 uint32_t not_used;
04651 KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
04652 KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
04653
04654 for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
04655 {
04656 if (usable_keys->test(nr) &&
04657 table->key_info[nr].key_length < min_length &&
04658 table->key_info[nr].key_parts >= ref_key_parts &&
04659 is_subkey(table->key_info[nr].key_part, ref_key_part,
04660 ref_key_part_end) &&
04661 test_if_order_by_key(order, table, nr, ¬_used))
04662 {
04663 min_length= table->key_info[nr].key_length;
04664 best= nr;
04665 }
04666 }
04667 return best;
04668 }
04669
04701 bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
04702 {
04703 for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
04704 {
04705 if (keynr == table->getShare()->getPrimaryKey() ||
04706 (table->key_info[keynr].flags & HA_NOSAME))
04707 {
04708 KeyInfo *keyinfo= table->key_info + keynr;
04709 KeyPartInfo *key_part= NULL;
04710 KeyPartInfo *key_part_end= NULL;
04711
04712 for (key_part=keyinfo->key_part,
04713 key_part_end=key_part+ keyinfo->key_parts;
04714 key_part < key_part_end;
04715 key_part++)
04716 {
04717 if (key_part->field->maybe_null() || ! find_func(key_part->field, data))
04718 {
04719 break;
04720 }
04721 }
04722
04723 if (key_part == key_part_end)
04724 {
04725 return 1;
04726 }
04727 }
04728 }
04729 return 0;
04730 }
04731
04745 bool find_field_in_order_list (Field *field, void *data)
04746 {
04747 Order *group= (Order *) data;
04748 bool part_found= 0;
04749 for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
04750 {
04751 Item *item= (*tmp_group->item)->real_item();
04752 if (item->type() == Item::FIELD_ITEM &&
04753 ((Item_field*) item)->field->eq(field))
04754 {
04755 part_found= 1;
04756 break;
04757 }
04758 }
04759 return part_found;
04760 }
04761
04775 bool find_field_in_item_list (Field *field, void *data)
04776 {
04777 List<Item> *fields= (List<Item> *) data;
04778 bool part_found= 0;
04779 List<Item>::iterator li(fields->begin());
04780 Item *item;
04781
04782 while ((item= li++))
04783 {
04784 if (item->type() == Item::FIELD_ITEM &&
04785 ((Item_field*) item)->field->eq(field))
04786 {
04787 part_found= 1;
04788 break;
04789 }
04790 }
04791 return part_found;
04792 }
04793
04819 bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
04820 {
04821 int32_t ref_key;
04822 uint32_t ref_key_parts;
04823 int order_direction;
04824 uint32_t used_key_parts;
04825 Table *table=tab->table;
04826 optimizer::SqlSelect *select= tab->select;
04827 key_map usable_keys;
04828 optimizer::QuickSelectInterface *save_quick= NULL;
04829
04830
04831
04832
04833
04834 usable_keys= *map;
04835
04836 for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
04837 {
04838 Item *item= (*tmp_order->item)->real_item();
04839 if (item->type() != Item::FIELD_ITEM)
04840 {
04841 usable_keys.reset();
04842 return 0;
04843 }
04844 usable_keys&= ((Item_field*) item)->field->part_of_sortkey;
04845 if (usable_keys.none())
04846 {
04847 return 0;
04848 }
04849 }
04850
04851 ref_key= -1;
04852
04853 if (tab->ref.key >= 0 && tab->ref.key_parts)
04854 {
04855 ref_key= tab->ref.key;
04856 ref_key_parts= tab->ref.key_parts;
04857 if (tab->type == AM_REF_OR_NULL)
04858 {
04859 return 0;
04860 }
04861 }
04862 else if (select && select->quick)
04863 {
04864 int quick_type= select->quick->get_type();
04865 save_quick= select->quick;
04866
04867
04868
04869
04870
04871
04872 if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
04873 quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
04874 quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT)
04875 {
04876 return 0;
04877 }
04878 ref_key= select->quick->index;
04879 ref_key_parts= select->quick->used_key_parts;
04880 }
04881
04882 if (ref_key >= 0)
04883 {
04884
04885
04886
04887 if (! usable_keys.test(ref_key))
04888 {
04889
04890
04891
04892 uint32_t new_ref_key;
04893
04894
04895
04896
04897 if (table->covering_keys.test(ref_key))
04898 usable_keys&= table->covering_keys;
04899
04900 if (tab->pre_idx_push_select_cond)
04901 tab->select_cond= tab->select->cond= tab->pre_idx_push_select_cond;
04902
04903 if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
04904 &usable_keys)) < MAX_KEY)
04905 {
04906
04907 if (tab->ref.key >= 0)
04908 {
04909
04910
04911
04912
04913
04914
04915
04916
04917 optimizer::KeyUse *keyuse= tab->keyuse;
04918 while (keyuse->getKey() != new_ref_key && keyuse->getTable() == tab->table)
04919 keyuse++;
04920
04921 if (create_ref_for_key(tab->join, tab, keyuse, tab->join->const_table_map))
04922 {
04923 return 0;
04924 }
04925 }
04926 else
04927 {
04928
04929
04930
04931
04932
04933
04934
04935
04936 key_map new_ref_key_map;
04937 new_ref_key_map.reset();
04938 new_ref_key_map.set(new_ref_key);
04939
04940 if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
04941 (tab->join->select_options &
04942 OPTION_FOUND_ROWS) ?
04943 HA_POS_ERROR :
04944 tab->join->unit->select_limit_cnt,0,
04945 true) <=
04946 0)
04947 {
04948 return 0;
04949 }
04950 }
04951 ref_key= new_ref_key;
04952 }
04953 }
04954
04955 if (usable_keys.test(ref_key) &&
04956 (order_direction= test_if_order_by_key(order,table,ref_key,
04957 &used_key_parts)))
04958 goto check_reverse_order;
04959 }
04960 {
04961
04962
04963
04964
04965
04966
04967 uint32_t nr;
04968 key_map keys;
04969 uint32_t best_key_parts= 0;
04970 int best_key_direction= 0;
04971 ha_rows best_records= 0;
04972 double read_time;
04973 int best_key= -1;
04974 bool is_best_covering= false;
04975 double fanout= 1;
04976 Join *join= tab->join;
04977 uint32_t tablenr= tab - join->join_tab;
04978 ha_rows table_records= table->cursor->stats.records;
04979 bool group= join->group && order == join->group_list;
04980 optimizer::Position cur_pos;
04981
04982
04983
04984
04985
04986
04987 if (select_limit >= table_records)
04988 {
04989
04990
04991
04992
04993 if (tab->type == AM_ALL && tab->join->tables > tab->join->const_tables + 1)
04994 {
04995 return 0;
04996 }
04997 keys= *table->cursor->keys_to_use_for_scanning();
04998 keys|= table->covering_keys;
04999
05000
05001
05002
05003
05004
05005 if (table->force_index)
05006 {
05007 keys|= (group ? table->keys_in_use_for_group_by :
05008 table->keys_in_use_for_order_by);
05009 }
05010 keys&= usable_keys;
05011 }
05012 else
05013 {
05014 keys= usable_keys;
05015 }
05016
05017 cur_pos= join->getPosFromOptimalPlan(tablenr);
05018 read_time= cur_pos.getCost();
05019
05020 for (uint32_t i= tablenr+1; i < join->tables; i++)
05021 {
05022 cur_pos= join->getPosFromOptimalPlan(i);
05023 fanout*= cur_pos.getFanout();
05024 }
05025
05026 for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
05027 {
05028 int direction;
05029 if (keys.test(nr) &&
05030 (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
05031 {
05032 bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043 if (is_covering ||
05044 select_limit != HA_POS_ERROR ||
05045 (ref_key < 0 && (group || table->force_index)))
05046 {
05047 double rec_per_key;
05048 double index_scan_time;
05049 KeyInfo *keyinfo= tab->table->key_info+nr;
05050 if (select_limit == HA_POS_ERROR)
05051 {
05052 select_limit= table_records;
05053 }
05054
05055 if (group)
05056 {
05057 rec_per_key= keyinfo->rec_per_key[used_key_parts-1];
05058 set_if_bigger(rec_per_key, 1.0);
05059
05060
05061
05062
05063
05064 if (select_limit > table_records/rec_per_key)
05065 {
05066 select_limit= table_records;
05067 }
05068 else
05069 {
05070 select_limit= (ha_rows) (select_limit*rec_per_key);
05071 }
05072 }
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083 select_limit= (ha_rows) (select_limit < fanout ?
05084 1 : select_limit/fanout);
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095 if (select_limit > table->quick_condition_rows)
05096 {
05097 select_limit= table_records;
05098 }
05099 else
05100 {
05101 select_limit= (ha_rows) (select_limit *
05102 (double) table_records /
05103 table->quick_condition_rows);
05104 }
05105 rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1];
05106 set_if_bigger(rec_per_key, 1.0);
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118 index_scan_time= select_limit/rec_per_key * min(rec_per_key, table->cursor->scan_time());
05119
05120 if (is_covering || (ref_key < 0 && (group || table->force_index)) || index_scan_time < read_time)
05121 {
05122 ha_rows quick_records= table_records;
05123 if (is_best_covering && !is_covering)
05124 {
05125 continue;
05126 }
05127
05128 if (table->quick_keys.test(nr))
05129 {
05130 quick_records= table->quick_rows[nr];
05131 }
05132
05133 if (best_key < 0 ||
05134 (select_limit <= min(quick_records,best_records) ?
05135 keyinfo->key_parts < best_key_parts :
05136 quick_records < best_records))
05137 {
05138 best_key= nr;
05139 best_key_parts= keyinfo->key_parts;
05140 best_records= quick_records;
05141 is_best_covering= is_covering;
05142 best_key_direction= direction;
05143 }
05144 }
05145 }
05146 }
05147 }
05148
05149 if (best_key >= 0)
05150 {
05151 bool quick_created= false;
05152 if (table->quick_keys.test(best_key) && best_key != ref_key)
05153 {
05154 key_map test_map;
05155 test_map.reset();
05156 test_map.set(best_key);
05157 quick_created=
05158 select->test_quick_select(join->session, test_map, 0,
05159 join->select_options & OPTION_FOUND_ROWS ?
05160 HA_POS_ERROR :
05161 join->unit->select_limit_cnt,
05162 true, false) > 0;
05163 }
05164 if (no_changes == false)
05165 {
05166 if (!quick_created)
05167 {
05168 tab->index= best_key;
05169 tab->read_first_record= best_key_direction > 0 ?
05170 join_read_first : join_read_last;
05171 tab->type= AM_NEXT;
05172 if (select && select->quick)
05173 {
05174 safe_delete(select->quick);
05175 }
05176 if (table->covering_keys.test(best_key))
05177 {
05178 table->key_read=1;
05179 table->cursor->extra(HA_EXTRA_KEYREAD);
05180 }
05181 table->cursor->ha_index_or_rnd_end();
05182 if (join->select_options & SELECT_DESCRIBE)
05183 {
05184 tab->ref.key= -1;
05185 tab->ref.key_parts= 0;
05186 if (select_limit < table_records)
05187 tab->limit= select_limit;
05188 }
05189 }
05190 else if (tab->type != AM_ALL)
05191 {
05192
05193
05194
05195
05196
05197 assert(tab->select->quick);
05198 tab->type= AM_ALL;
05199 tab->use_quick=1;
05200 tab->ref.key= -1;
05201 tab->ref.key_parts=0;
05202 tab->read_first_record= join_init_read_record;
05203 }
05204 }
05205 used_key_parts= best_key_parts;
05206 order_direction= best_key_direction;
05207 }
05208 else
05209 {
05210 return 0;
05211 }
05212 }
05213
05214 check_reverse_order:
05215 if (order_direction == -1)
05216 {
05217 if (select && select->quick)
05218 {
05219
05220
05221
05222
05223 if (! select->quick->reverse_sorted())
05224 {
05225 optimizer::QuickSelectDescending *tmp= NULL;
05226 bool error= false;
05227 int quick_type= select->quick->get_type();
05228 if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
05229 quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT ||
05230 quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
05231 quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX)
05232 {
05233 tab->limit= 0;
05234 select->quick= save_quick;
05235 return 0;
05236 }
05237
05238
05239 tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
05240 used_key_parts,
05241 &error);
05242 if (! tmp || error)
05243 {
05244 delete tmp;
05245 select->quick= save_quick;
05246 tab->limit= 0;
05247 return 0;
05248 }
05249 select->quick= tmp;
05250 }
05251 }
05252 else if (tab->type != AM_NEXT &&
05253 tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
05254 {
05255
05256
05257
05258
05259
05260
05261 tab->read_first_record= join_read_last_key;
05262 tab->read_record.read_record= join_read_prev_same;
05263 }
05264 }
05265 else if (select && select->quick)
05266 {
05267 select->quick->sorted= 1;
05268 }
05269
05270 return 1;
05271 }
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301 int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
05302 {
05303 uint32_t length= 0;
05304 ha_rows examined_rows;
05305 Table *table;
05306 optimizer::SqlSelect *select= NULL;
05307 JoinTable *tab;
05308
05309 if (join->tables == join->const_tables)
05310 return 0;
05311 tab= join->join_tab + join->const_tables;
05312 table= tab->table;
05313 select= tab->select;
05314
05315
05316
05317
05318
05319
05320
05321 if ((order != join->group_list ||
05322 !(join->select_options & SELECT_BIG_RESULT) ||
05323 (select && select->quick && (select->quick->get_type() == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))) &&
05324 test_if_skip_sort_order(tab,order,select_limit,0,
05325 is_order_by ? &table->keys_in_use_for_order_by :
05326 &table->keys_in_use_for_group_by))
05327 {
05328 return 0;
05329 }
05330
05331 for (Order *ord= join->order; ord; ord= ord->next)
05332 {
05333 length++;
05334 }
05335
05336 join->sortorder= make_unireg_sortorder(order, &length, join->sortorder);
05337 table->sort.io_cache= new internal::io_cache_st;
05338 table->status=0;
05339
05340
05341 if (select && !select->quick && tab->ref.key >= 0)
05342 {
05343 if (tab->quick)
05344 {
05345 select->quick=tab->quick;
05346 tab->quick=0;
05347
05348
05349
05350
05351 if (table->key_read && ((uint32_t) tab->ref.key != select->quick->index))
05352 {
05353 table->key_read=0;
05354 table->cursor->extra(HA_EXTRA_NO_KEYREAD);
05355 }
05356 }
05357 else
05358 {
05359
05360
05361
05362
05363
05364
05365 if (! (select->quick= (optimizer::get_quick_select_for_ref(session,
05366 table,
05367 &tab->ref,
05368 tab->found_records))))
05369 {
05370 return(-1);
05371 }
05372 }
05373 }
05374
05375 if (table->getShare()->getType())
05376 table->cursor->info(HA_STATUS_VARIABLE);
05377
05378 FileSort filesort(*session);
05379 table->sort.found_records=filesort.run(table,join->sortorder, length,
05380 select, filesort_limit, 0,
05381 examined_rows);
05382 tab->records= table->sort.found_records;
05383 if (select)
05384 {
05385 select->cleanup();
05386 tab->select= 0;
05387 }
05388 tab->select_cond=0;
05389 tab->last_inner= 0;
05390 tab->first_unmatched= 0;
05391 tab->type= AM_ALL;
05392 tab->read_first_record= join_init_read_record;
05393 tab->join->examined_rows+=examined_rows;
05394 if (table->key_read)
05395 {
05396 table->key_read=0;
05397 table->cursor->extra(HA_EXTRA_NO_KEYREAD);
05398 }
05399
05400 return(table->sort.found_records == HA_POS_ERROR);
05401 }
05402
05403 int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
05404 {
05405 Cursor *cursor=table->cursor;
05406 char *org_record,*new_record;
05407 unsigned char *record;
05408 int error;
05409 uint32_t reclength= table->getShare()->getRecordLength() - offset;
05410
05411 org_record=(char*) (record=table->getInsertRecord())+offset;
05412 new_record=(char*) table->getUpdateRecord()+offset;
05413
05414 if ((error= cursor->startTableScan(1)))
05415 goto err;
05416
05417 error=cursor->rnd_next(record);
05418 for (;;)
05419 {
05420 if (session->getKilled())
05421 {
05422 session->send_kill_message();
05423 error=0;
05424 goto err;
05425 }
05426 if (error)
05427 {
05428 if (error == HA_ERR_RECORD_DELETED)
05429 {
05430 continue;
05431 }
05432 if (error == HA_ERR_END_OF_FILE)
05433 {
05434 break;
05435 }
05436 goto err;
05437 }
05438 if (having && !having->val_int())
05439 {
05440 if ((error=cursor->deleteRecord(record)))
05441 {
05442 goto err;
05443 }
05444 error=cursor->rnd_next(record);
05445 continue;
05446 }
05447 copy_blobs(first_field);
05448 memcpy(new_record,org_record,reclength);
05449
05450
05451 bool found=0;
05452 for (;;)
05453 {
05454 if ((error=cursor->rnd_next(record)))
05455 {
05456 if (error == HA_ERR_RECORD_DELETED)
05457 {
05458 continue;
05459 }
05460 if (error == HA_ERR_END_OF_FILE)
05461 {
05462 break;
05463 }
05464
05465 goto err;
05466 }
05467 if (table->compare_record(first_field) == 0)
05468 {
05469 if ((error=cursor->deleteRecord(record)))
05470 {
05471 goto err;
05472 }
05473 }
05474 else if (!found)
05475 {
05476 found= 1;
05477 cursor->position(record);
05478 }
05479 }
05480 if (!found)
05481 {
05482 break;
05483 }
05484
05485 error= cursor->rnd_pos(record, cursor->ref);
05486 }
05487
05488 cursor->extra(HA_EXTRA_NO_CACHE);
05489 return 0;
05490 err:
05491 cursor->extra(HA_EXTRA_NO_CACHE);
05492 if (error)
05493 {
05494 table->print_error(error,MYF(0));
05495 }
05496 return 1;
05497 }
05498
05505 int remove_dup_with_hash_index(Session *session,
05506 Table *table,
05507 uint32_t field_count,
05508 Field **first_field,
05509 uint32_t key_length,
05510 Item *having)
05511 {
05512 unsigned char *key_pos, *record=table->getInsertRecord();
05513 int error;
05514 Cursor &cursor= *table->cursor;
05515 uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
05516 uint32_t *field_length;
05517 HASH hash;
05518 std::vector<unsigned char> key_buffer((key_length + extra_length) * (long) cursor.stats.records);
05519 std::vector<uint32_t> field_lengths(field_count);
05520
05521 {
05522 Field **ptr;
05523 uint32_t total_length= 0;
05524
05525 for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
05526 {
05527 uint32_t length= (*ptr)->sort_length();
05528 (*field_length++)= length;
05529 total_length+= length;
05530 }
05531 assert(total_length <= key_length);
05532 key_length= total_length;
05533 extra_length= ALIGN_SIZE(key_length)-key_length;
05534 }
05535
05536 hash_init(&hash, &my_charset_bin, (uint32_t) cursor.stats.records, 0, key_length, (hash_get_key) 0, 0, 0);
05537
05538 if ((error= cursor.startTableScan(1)))
05539 {
05540 goto err;
05541 }
05542
05543 key_pos= &key_buffer[0];
05544 for (;;)
05545 {
05546 if (session->getKilled())
05547 {
05548 session->send_kill_message();
05549 error=0;
05550 goto err;
05551 }
05552 if ((error=cursor.rnd_next(record)))
05553 {
05554 if (error == HA_ERR_RECORD_DELETED)
05555 {
05556 continue;
05557 }
05558
05559 if (error == HA_ERR_END_OF_FILE)
05560 {
05561 break;
05562 }
05563
05564 goto err;
05565 }
05566 if (having && !having->val_int())
05567 {
05568 if ((error=cursor.deleteRecord(record)))
05569 {
05570 goto err;
05571 }
05572 continue;
05573 }
05574
05575
05576 unsigned char* org_key_pos= key_pos;
05577 field_length= &field_lengths[0];
05578 for (Field **ptr= first_field ; *ptr ; ptr++)
05579 {
05580 (*ptr)->sort_string(key_pos,*field_length);
05581 key_pos+= *field_length++;
05582 }
05583
05584 if (hash_search(&hash, org_key_pos, key_length))
05585 {
05586
05587 if ((error=cursor.deleteRecord(record)))
05588 goto err;
05589 }
05590 else
05591 {
05592 (void) my_hash_insert(&hash, org_key_pos);
05593 }
05594 key_pos+=extra_length;
05595 }
05596 hash_free(&hash);
05597 cursor.extra(HA_EXTRA_NO_CACHE);
05598 (void) cursor.endTableScan();
05599 return 0;
05600
05601 err:
05602 hash_free(&hash);
05603 cursor.extra(HA_EXTRA_NO_CACHE);
05604 (void) cursor.endTableScan();
05605 if (error)
05606 {
05607 table->print_error(error,MYF(0));
05608 }
05609
05610 return 1;
05611 }
05612
05613 SortField* make_unireg_sortorder(Order* order, uint32_t* length, SortField* sortorder)
05614 {
05615 SortField *sort,*pos;
05616
05617 uint32_t count= 0;
05618 for (Order *tmp = order; tmp; tmp=tmp->next)
05619 count++;
05620 if (not sortorder)
05621 sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) * (max(count, *length) + 1));
05622 pos= sort= sortorder;
05623
05624 for (; order; order= order->next,pos++)
05625 {
05626 Item *item= order->item[0]->real_item();
05627 pos->field= 0; pos->item= 0;
05628
05629 if (item->type() == Item::FIELD_ITEM)
05630 {
05631 pos->field= ((Item_field*) item)->field;
05632 }
05633 else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
05634 {
05635 pos->field= ((Item_sum*) item)->get_tmp_table_field();
05636 }
05637 else if (item->type() == Item::COPY_STR_ITEM)
05638 {
05639 pos->item= ((Item_copy_string*) item)->item;
05640 }
05641 else
05642 {
05643 pos->item= *order->item;
05644 }
05645
05646 pos->reverse=! order->asc;
05647 }
05648 *length=count;
05649 return sort;
05650 }
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670 static bool cmp_buffer_with_ref(JoinTable *tab)
05671 {
05672 bool no_prev_key;
05673 if (!tab->ref.disable_cache)
05674 {
05675 if (!(no_prev_key= tab->ref.key_err))
05676 {
05677
05678 memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
05679 }
05680 }
05681 else
05682 {
05683 no_prev_key= true;
05684 }
05685
05686 if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->session, &tab->ref)) || no_prev_key)
05687 {
05688 return 1;
05689 }
05690 return (memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length) != 0);
05691 }
05692
05693 bool cp_buffer_from_ref(Session *session, table_reference_st *ref)
05694 {
05695 enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
05696 session->count_cuted_fields= CHECK_FIELD_IGNORE;
05697 bool result= 0;
05698
05699 for (StoredKey **copy=ref->key_copy ; *copy ; copy++)
05700 {
05701 if ((*copy)->copy() & 1)
05702 {
05703 result= 1;
05704 break;
05705 }
05706 }
05707 session->count_cuted_fields= save_count_cuted_fields;
05708 return result;
05709 }
05710
05711
05712
05713
05714
05747 static bool find_order_in_list(Session *session,
05748 Item **ref_pointer_array,
05749 TableList *tables,
05750 Order *order,
05751 List<Item> &fields,
05752 List<Item> &all_fields,
05753 bool is_group_field)
05754 {
05755 Item *order_item= *order->item;
05756 Item::Type order_item_type;
05757 Item **select_item;
05758 Field *from_field;
05759 uint32_t counter;
05760 enum_resolution_type resolution;
05761
05762
05763
05764
05765
05766 if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
05767 {
05768 uint32_t count= (uint32_t) order_item->val_int();
05769 if (!count || count > fields.size())
05770 {
05771 my_error(ER_BAD_FIELD_ERROR, MYF(0), order_item->full_name(), session->where());
05772 return true;
05773 }
05774 order->item= ref_pointer_array + count - 1;
05775 order->in_field_list= 1;
05776 order->counter= count;
05777 order->counter_used= 1;
05778 return false;
05779 }
05780
05781 select_item= find_item_in_list(session, order_item, fields, &counter, REPORT_EXCEPT_NOT_FOUND, &resolution);
05782 if (!select_item)
05783 {
05784 return true;
05785 }
05786
05787
05788
05789 if (select_item != not_found_item)
05790 {
05791 Item *view_ref= NULL;
05792
05793
05794
05795
05796
05797 if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed && order_item->fix_fields(session, order->item))
05798 {
05799 return true;
05800 }
05801
05802
05803 order_item_type= order_item->type();
05804 from_field= (Field*) not_found_field;
05805 if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
05806 order_item_type == Item::REF_ITEM)
05807 {
05808 from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
05809 NULL, &view_ref, IGNORE_ERRORS, false);
05810 if (!from_field)
05811 {
05812 from_field= (Field*) not_found_field;
05813 }
05814 }
05815
05816 if (from_field == not_found_field ||
05817 (from_field != view_ref_found ?
05818
05819 ((*select_item)->type() == Item::FIELD_ITEM &&
05820 ((Item_field*) (*select_item))->field->eq(from_field)) :
05821
05822
05823
05824
05825 ((*select_item)->type() == Item::REF_ITEM &&
05826 view_ref->type() == Item::REF_ITEM &&
05827 ((Item_ref *) (*select_item))->ref ==
05828 ((Item_ref *) view_ref)->ref)))
05829 {
05830
05831
05832
05833
05834
05835
05836
05837 order->item= ref_pointer_array + counter;
05838 order->in_field_list=1;
05839 return false;
05840 }
05841 else
05842 {
05843
05844
05845
05846
05847
05848
05849 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
05850 ER(ER_NON_UNIQ_ERROR),
05851 ((Item_ident*) order_item)->field_name,
05852 session->where());
05853 }
05854 }
05855
05856 order->in_field_list=0;
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868 if (!order_item->fixed &&
05869 (order_item->fix_fields(session, order->item) ||
05870 (order_item= *order->item)->check_cols(1) ||
05871 session->is_fatal_error))
05872 {
05873 return true;
05874 }
05875
05876 uint32_t el= all_fields.size();
05877 all_fields.push_front(order_item);
05878 ref_pointer_array[el]= order_item;
05879 order->item= ref_pointer_array + el;
05880 return false;
05881 }
05882
05889 int setup_order(Session *session,
05890 Item **ref_pointer_array,
05891 TableList *tables,
05892 List<Item> &fields,
05893 List<Item> &all_fields,
05894 Order *order)
05895 {
05896 session->setWhere("order clause");
05897 for (; order; order= order->next)
05898 {
05899 if (find_order_in_list(session, ref_pointer_array, tables, order, fields, all_fields, false))
05900 {
05901 return 1;
05902 }
05903 }
05904 return 0;
05905 }
05906
05932 int setup_group(Session *session,
05933 Item **ref_pointer_array,
05934 TableList *tables,
05935 List<Item> &fields,
05936 List<Item> &all_fields,
05937 Order *order,
05938 bool *hidden_group_fields)
05939 {
05940 *hidden_group_fields=0;
05941
05942 if (order == NULL)
05943 {
05944 return 0;
05945 }
05946
05947 uint32_t org_fields=all_fields.size();
05948
05949 session->setWhere("group statement");
05950 for (Order *ord= order; ord; ord= ord->next)
05951 {
05952 if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
05953 all_fields, true))
05954 {
05955 return 1;
05956 }
05957 (*ord->item)->marker= UNDEF_POS;
05958 if ((*ord->item)->with_sum_func)
05959 {
05960 my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
05961 return 1;
05962 }
05963 }
05964
05965
05966 {
05967
05968
05969
05970
05971
05972
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982 Item *item;
05983 Item_field *field;
05984 int cur_pos_in_select_list= 0;
05985 List<Item>::iterator li(fields.begin());
05986 List<Item_field>::iterator naf_it(session->lex().current_select->non_agg_fields.begin());
05987
05988 field= naf_it++;
05989 while (field && (item=li++))
05990 {
05991 if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 &&
05992 !item->const_item() &&
05993 !(item->real_item()->type() == Item::FIELD_ITEM &&
05994 item->used_tables() & OUTER_REF_TABLE_BIT))
05995 {
05996 while (field)
05997 {
05998
05999 if (field->marker < cur_pos_in_select_list)
06000 {
06001 goto next_field;
06002 }
06003
06004
06005 if (field->marker > cur_pos_in_select_list)
06006 {
06007 break;
06008 }
06009
06010
06011
06012
06013
06014 for (Order *ord= order; ord; ord= ord->next)
06015 {
06016 if ((*ord->item)->eq((Item*)field, 0))
06017 {
06018 goto next_field;
06019 }
06020 }
06021
06022
06023
06024
06025 my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
06026 return 1;
06027 next_field:
06028 field= naf_it++;
06029 }
06030 }
06031 cur_pos_in_select_list++;
06032 }
06033 }
06034
06035 if (org_fields != all_fields.size())
06036 {
06037 *hidden_group_fields=1;
06038 }
06039
06040 return 0;
06041 }
06042
06049 Order *create_distinct_group(Session *session,
06050 Item **ref_pointer_array,
06051 Order *order_list,
06052 List<Item> &fields,
06053 List<Item> &,
06054 bool *all_order_by_fields_used)
06055 {
06056 List<Item>::iterator li(fields.begin());
06057 Order *order,*group,**prev;
06058
06059 *all_order_by_fields_used= 1;
06060 while (Item* item=li++)
06061 {
06062 item->marker=0;
06063 }
06064
06065 prev= &group; group=0;
06066 for (order=order_list ; order; order=order->next)
06067 {
06068 if (order->in_field_list)
06069 {
06070 Order *ord=(Order*) session->mem.memdup(order,sizeof(Order));
06071 *prev=ord;
06072 prev= &ord->next;
06073 (*ord->item)->marker=1;
06074 }
06075 else
06076 {
06077 *all_order_by_fields_used= 0;
06078 }
06079 }
06080
06081 li= fields.begin();
06082 while (Item* item=li++)
06083 {
06084 if (!item->const_item() && !item->with_sum_func && !item->marker)
06085 {
06086
06087
06088
06089
06090 Order *ord_iter;
06091 for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
06092 {
06093 if ((*ord_iter->item)->eq(item, 1))
06094 {
06095 goto next_item;
06096 }
06097 }
06098
06099 Order *ord=(Order*) session->mem.calloc(sizeof(Order));
06100
06101
06102
06103
06104
06105
06106 ord->item= ref_pointer_array;
06107 ord->asc=1;
06108 *prev=ord;
06109 prev= &ord->next;
06110 }
06111 next_item:
06112 ref_pointer_array++;
06113 }
06114 *prev=0;
06115 return group;
06116 }
06117
06121 void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
06122 {
06123 List<Item>::iterator li(fields.begin());
06124 Item *field;
06125
06126 param->field_count=param->sum_func_count=param->func_count= param->hidden_field_count=0;
06127 param->quick_group=1;
06128
06129 while ((field=li++))
06130 {
06131 Item::Type real_type= field->real_item()->type();
06132 if (real_type == Item::FIELD_ITEM)
06133 {
06134 param->field_count++;
06135 }
06136 else if (real_type == Item::SUM_FUNC_ITEM)
06137 {
06138 if (! field->const_item())
06139 {
06140 Item_sum *sum_item=(Item_sum*) field->real_item();
06141 if (!sum_item->depended_from() ||
06142 sum_item->depended_from() == select_lex)
06143 {
06144 if (!sum_item->quick_group)
06145 {
06146 param->quick_group=0;
06147 }
06148 param->sum_func_count++;
06149
06150 for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
06151 {
06152 if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
06153 param->field_count++;
06154 else
06155 param->func_count++;
06156 }
06157 }
06158 param->func_count++;
06159 }
06160 }
06161 else
06162 {
06163 param->func_count++;
06164 if (reset_with_sum_func)
06165 {
06166 field->with_sum_func= 0;
06167 }
06168 }
06169 }
06170 }
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182
06183
06184 int test_if_item_cache_changed(List<Cached_item> &list)
06185 {
06186 List<Cached_item>::iterator li(list.begin());
06187 int idx= -1;
06188 Cached_item *buff;
06189
06190 for (int i=(int) list.size()-1 ; (buff=li++) ; i--)
06191 {
06192 if (buff->cmp())
06193 idx= i;
06194 }
06195 return idx;
06196 }
06197
06226 bool setup_copy_fields(Session *session,
06227 Tmp_Table_Param *param,
06228 Item **ref_pointer_array,
06229 List<Item> &res_selected_fields,
06230 List<Item> &res_all_fields,
06231 uint32_t elements,
06232 List<Item> &all_fields)
06233 {
06234 Item *pos;
06235 List<Item>::iterator li(all_fields.begin());
06236 CopyField *copy= NULL;
06237 res_selected_fields.clear();
06238 res_all_fields.clear();
06239 List<Item>::iterator itr(res_all_fields.begin());
06240 List<Item> extra_funcs;
06241 uint32_t border= all_fields.size() - elements;
06242
06243 if (param->field_count &&
06244 !(copy= param->copy_field= new CopyField[param->field_count]))
06245 {
06246 return true;
06247 }
06248
06249 param->copy_funcs.clear();
06250 for (uint32_t i= 0; (pos= li++); i++)
06251 {
06252 Field *field;
06253 unsigned char *tmp;
06254 Item *real_pos= pos->real_item();
06255 if (real_pos->type() == Item::FIELD_ITEM)
06256 {
06257 Item_field* item= new Item_field(session, ((Item_field*) real_pos));
06258 if (pos->type() == Item::REF_ITEM)
06259 {
06260
06261 Item_ref *ref= (Item_ref *) pos;
06262 item->db_name= ref->db_name;
06263 item->table_name= ref->table_name;
06264 item->name= ref->name;
06265 }
06266 pos= item;
06267
06268 if (item->field->flags & BLOB_FLAG)
06269 {
06270 pos= new Item_copy_string(pos);
06271
06272
06273
06274
06275
06276
06277
06278
06279
06280 param->copy_funcs.push_front(pos);
06281 }
06282 else
06283 {
06284
06285
06286
06287
06288 field= item->field;
06289 item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
06290
06291
06292
06293
06294
06295 if (!(tmp= (unsigned char*) memory::sql_alloc(field->pack_length()+2)))
06296 {
06297 goto err;
06298 }
06299
06300 if (copy)
06301 {
06302 copy->set(tmp, item->result_field);
06303 item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
06304 #ifdef HAVE_VALGRIND
06305 copy->to_ptr[copy->from_length]= 0;
06306 #endif
06307 copy++;
06308 }
06309 }
06310 }
06311 else if ((real_pos->type() == Item::FUNC_ITEM ||
06312 real_pos->type() == Item::SUBSELECT_ITEM ||
06313 real_pos->type() == Item::CACHE_ITEM ||
06314 real_pos->type() == Item::COND_ITEM) &&
06315 !real_pos->with_sum_func)
06316 {
06317 pos= real_pos;
06318
06319
06320
06321
06322
06323
06324 pos=new Item_copy_string(pos);
06325 if (i < border)
06326 {
06327 extra_funcs.push_back(pos);
06328 }
06329 else
06330 {
06331 param->copy_funcs.push_back(pos);
06332 }
06333 }
06334 res_all_fields.push_back(pos);
06335 ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
06336 pos;
06337 }
06338 param->copy_field_end= copy;
06339
06340 for (uint32_t i= 0; i < border; i++)
06341 {
06342 itr++;
06343 }
06344 itr.sublist(res_selected_fields, elements);
06345
06346
06347
06348
06349 param->copy_funcs.concat(&extra_funcs);
06350
06351 return 0;
06352
06353 err:
06354 if (copy)
06355 {
06356 delete[] param->copy_field;
06357 }
06358 param->copy_field=0;
06359 return true;
06360 }
06361
06368 void copy_fields(Tmp_Table_Param *param)
06369 {
06370 for (CopyField *ptr= param->copy_field; ptr != param->copy_field_end; ptr++)
06371 {
06372 (*ptr->do_copy)(ptr);
06373 }
06374
06375 List<Item>::iterator it(param->copy_funcs.begin());
06376 Item_copy_string *item;
06377 while ((item = (Item_copy_string*) it++))
06378 {
06379 item->copy();
06380 }
06381 }
06382
06399 bool change_to_use_tmp_fields(Session *session,
06400 Item **ref_pointer_array,
06401 List<Item> &res_selected_fields,
06402 List<Item> &res_all_fields,
06403 uint32_t elements,
06404 List<Item> &all_fields)
06405 {
06406 List<Item>::iterator it(all_fields.begin());
06407 Item *item_field,*item;
06408
06409 res_selected_fields.clear();
06410 res_all_fields.clear();
06411
06412 uint32_t i, border= all_fields.size() - elements;
06413 for (i= 0; (item= it++); i++)
06414 {
06415 Field *field;
06416
06417 if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) or
06418 (item->type() == Item::FUNC_ITEM and ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC))
06419 {
06420 item_field= item;
06421 }
06422 else
06423 {
06424 if (item->type() == Item::FIELD_ITEM)
06425 {
06426 item_field= item->get_tmp_table_item(session);
06427 }
06428 else if ((field= item->get_tmp_table_field()))
06429 {
06430 if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
06431 {
06432 item_field= ((Item_sum*) item)->result_item(field);
06433 }
06434 else
06435 {
06436 item_field= (Item*) new Item_field(field);
06437 }
06438
06439 if (item_field == NULL)
06440 {
06441 return true;
06442 }
06443
06444 if (item->real_item()->type() != Item::FIELD_ITEM)
06445 {
06446 field->orig_table= 0;
06447 }
06448
06449 item_field->name= item->name;
06450
06451 if (item->type() == Item::REF_ITEM)
06452 {
06453 Item_field *ifield= (Item_field *) item_field;
06454 Item_ref *iref= (Item_ref *) item;
06455 ifield->table_name= iref->table_name;
06456 ifield->db_name= iref->db_name;
06457 }
06458 }
06459 else
06460 {
06461 item_field= item;
06462 }
06463 }
06464 res_all_fields.push_back(item_field);
06465 ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]= item_field;
06466 }
06467
06468 List<Item>::iterator itr(res_all_fields.begin());
06469 for (i= 0; i < border; i++)
06470 itr++;
06471 itr.sublist(res_selected_fields, elements);
06472 return false;
06473 }
06474
06491 bool change_refs_to_tmp_fields(Session *session,
06492 Item **ref_pointer_array,
06493 List<Item> &res_selected_fields,
06494 List<Item> &res_all_fields,
06495 uint32_t elements,
06496 List<Item> &all_fields)
06497 {
06498 List<Item>::iterator it(all_fields.begin());
06499 Item *item, *new_item;
06500 res_selected_fields.clear();
06501 res_all_fields.clear();
06502
06503 uint32_t i, border= all_fields.size() - elements;
06504 for (i= 0; (item= it++); i++)
06505 {
06506 res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
06507 ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
06508 new_item;
06509 }
06510
06511 List<Item>::iterator itr(res_all_fields.begin());
06512 for (i= 0; i < border; i++)
06513 {
06514 itr++;
06515 }
06516 itr.sublist(res_selected_fields, elements);
06517
06518 return session->is_fatal_error;
06519 }
06520
06521
06522
06523
06524
06536 bool setup_sum_funcs(Session *session, Item_sum **func_ptr)
06537 {
06538 Item_sum *func;
06539 while ((func= *(func_ptr++)))
06540 {
06541 if (func->setup(session))
06542 {
06543 return true;
06544 }
06545 }
06546 return false;
06547 }
06548
06549 void init_tmptable_sum_functions(Item_sum **func_ptr)
06550 {
06551 Item_sum *func;
06552 while ((func= *(func_ptr++)))
06553 {
06554 func->reset_field();
06555 }
06556 }
06557
06559 void update_tmptable_sum_func(Item_sum **func_ptr, Table *)
06560 {
06561 Item_sum *func;
06562 while ((func= *(func_ptr++)))
06563 {
06564 func->update_field();
06565 }
06566 }
06567
06569 void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr)
06570 {
06571 for (; func_ptr != end_ptr ; func_ptr++)
06572 {
06573 (void) (*func_ptr)->save_in_result_field(1);
06574 }
06575 }
06576
06577 bool init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
06578 {
06579 for (; func_ptr != end_ptr ;func_ptr++)
06580 {
06581 if ((*func_ptr)->reset())
06582 return 1;
06583 }
06584
06585
06586 for ( ; *func_ptr ; func_ptr++)
06587 {
06588 if ((*func_ptr)->add())
06589 {
06590 return 1;
06591 }
06592 }
06593 return 0;
06594 }
06595
06596 bool update_sum_func(Item_sum **func_ptr)
06597 {
06598 Item_sum *func;
06599 for (; (func= (Item_sum*) *func_ptr) ; func_ptr++)
06600 {
06601 if (func->add())
06602 {
06603 return 1;
06604 }
06605 }
06606 return 0;
06607 }
06608
06610 bool copy_funcs(Item **func_ptr, const Session *session)
06611 {
06612 Item *func;
06613 for (; (func = *func_ptr) ; func_ptr++)
06614 {
06615 func->save_in_result_field(1);
06616
06617
06618
06619
06620
06621
06622 if (session->is_error())
06623 {
06624 return true;
06625 }
06626 }
06627 return false;
06628 }
06629
06636 void free_underlaid_joins(Session *, Select_Lex *select)
06637 {
06638 for (Select_Lex_Unit *unit= select->first_inner_unit();
06639 unit;
06640 unit= unit->next_unit())
06641 unit->cleanup();
06642 }
06643
06644
06645
06646
06647
06687 bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
06688 {
06689 if (expr->arg_count)
06690 {
06691 Name_resolution_context *context= &session->lex().current_select->context;
06692 Item **arg,**arg_end;
06693 bool arg_changed= false;
06694 for (arg= expr->arguments(),
06695 arg_end= expr->arguments()+expr->arg_count;
06696 arg != arg_end; arg++)
06697 {
06698 Item *item= *arg;
06699 if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
06700 {
06701 Order *group_tmp;
06702 for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
06703 {
06704 if (item->eq(*group_tmp->item,0))
06705 {
06706 Item* new_item= new Item_ref(context, group_tmp->item, 0, item->name);
06707 *arg= new_item;
06708 arg_changed= true;
06709 }
06710 }
06711 }
06712 else if (item->type() == Item::FUNC_ITEM)
06713 {
06714 if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
06715 {
06716 return 1;
06717 }
06718 }
06719 }
06720
06721 if (arg_changed)
06722 {
06723 expr->maybe_null= 1;
06724 *changed= true;
06725 }
06726 }
06727 return 0;
06728 }
06729
06730
06731 static void print_table_array(Session *session, String *str, TableList **table,
06732 TableList **end)
06733 {
06734 (*table)->print(session, str);
06735
06736 for (TableList **tbl= table + 1; tbl < end; tbl++)
06737 {
06738 TableList *curr= *tbl;
06739 if (curr->outer_join)
06740 {
06741
06742 str->append(STRING_WITH_LEN(" left join "));
06743 }
06744 else if (curr->straight)
06745 {
06746 str->append(STRING_WITH_LEN(" straight_join "));
06747 }
06748 else
06749 {
06750 str->append(STRING_WITH_LEN(" join "));
06751 }
06752 curr->print(session, str);
06753 if (curr->on_expr)
06754 {
06755 str->append(STRING_WITH_LEN(" on("));
06756 curr->on_expr->print(str);
06757 str->append(')');
06758 }
06759 }
06760 }
06761
06768 void print_join(Session *session, String *str,
06769 List<TableList> *tables)
06770 {
06771
06772 List<TableList>::iterator ti(tables->begin());
06773 TableList **table= new (session->mem) TableList*[tables->size()];
06774
06775 for (TableList **t= table + (tables->size() - 1); t >= table; t--)
06776 {
06777 *t= ti++;
06778 }
06779 assert(tables->size() >= 1);
06780 print_table_array(session, str, table, table + tables->size());
06781 }
06782
06783 void Select_Lex::print(Session *session, String *str)
06784 {
06785
06786 if (not session)
06787 {
06788 session= current_session;
06789 }
06790
06791
06792 str->append(STRING_WITH_LEN("select "));
06793
06794
06795 if (options & SELECT_STRAIGHT_JOIN)
06796 str->append(STRING_WITH_LEN("straight_join "));
06797
06798 if (options & SELECT_DISTINCT)
06799 str->append(STRING_WITH_LEN("distinct "));
06800
06801 if (options & SELECT_SMALL_RESULT)
06802 str->append(STRING_WITH_LEN("sql_small_result "));
06803
06804 if (options & SELECT_BIG_RESULT)
06805 str->append(STRING_WITH_LEN("sql_big_result "));
06806
06807 if (options & OPTION_BUFFER_RESULT)
06808 str->append(STRING_WITH_LEN("sql_buffer_result "));
06809
06810 if (options & OPTION_FOUND_ROWS)
06811 str->append(STRING_WITH_LEN("sql_calc_found_rows "));
06812
06813
06814 bool first= 1;
06815 List<Item>::iterator it(item_list.begin());
06816 Item *item;
06817 while ((item= it++))
06818 {
06819 if (first)
06820 {
06821 first= 0;
06822 }
06823 else
06824 {
06825 str->append(',');
06826 }
06827 item->print_item_w_name(str);
06828 }
06829
06830
06831
06832
06833
06834 if (table_list.size())
06835 {
06836 str->append(STRING_WITH_LEN(" from "));
06837
06838 print_join(session, str, &top_join_list);
06839 }
06840 else if (where)
06841 {
06842
06843
06844
06845
06846 str->append(STRING_WITH_LEN(" from DUAL "));
06847 }
06848
06849
06850 Item *cur_where= where;
06851 if (join)
06852 cur_where= join->conds;
06853 if (cur_where || cond_value != Item::COND_UNDEF)
06854 {
06855 str->append(STRING_WITH_LEN(" where "));
06856 if (cur_where)
06857 {
06858 cur_where->print(str);
06859 }
06860 else
06861 {
06862 str->append(cond_value != Item::COND_FALSE ? "1" : "0");
06863 }
06864 }
06865
06866
06867 if (group_list.size())
06868 {
06869 str->append(STRING_WITH_LEN(" group by "));
06870 print_order(str, (Order *) group_list.first);
06871 switch (olap)
06872 {
06873 case CUBE_TYPE:
06874 str->append(STRING_WITH_LEN(" with cube"));
06875 break;
06876 case ROLLUP_TYPE:
06877 str->append(STRING_WITH_LEN(" with rollup"));
06878 break;
06879 default:
06880 ;
06881 }
06882 }
06883
06884
06885 Item *cur_having= having;
06886 if (join)
06887 cur_having= join->having;
06888
06889 if (cur_having || having_value != Item::COND_UNDEF)
06890 {
06891 str->append(STRING_WITH_LEN(" having "));
06892 if (cur_having)
06893 {
06894 cur_having->print(str);
06895 }
06896 else
06897 {
06898 str->append(having_value != Item::COND_FALSE ? "1" : "0");
06899 }
06900 }
06901
06902 if (order_list.size())
06903 {
06904 str->append(STRING_WITH_LEN(" order by "));
06905 print_order(str, (Order *) order_list.first);
06906 }
06907
06908
06909 print_limit(session, str);
06910
06911
06912 }
06913
06918 }