45
43
#include "drizzled/join_cache.h"
46
44
#include "drizzled/show.h"
47
45
#include "drizzled/field/blob.h"
48
#include "drizzled/optimizer/position.h"
49
#include "drizzled/optimizer/sargable_param.h"
50
#include "drizzled/optimizer/key_use.h"
51
#include "drizzled/optimizer/range.h"
52
#include "drizzled/optimizer/sum.h"
53
#include "drizzled/optimizer/explain_plan.h"
54
#include "drizzled/optimizer/access_method_factory.h"
55
#include "drizzled/optimizer/access_method.h"
56
#include "drizzled/records.h"
57
#include "drizzled/probes.h"
58
#include "drizzled/internal/my_bit.h"
59
#include "drizzled/internal/my_sys.h"
60
#include "drizzled/internal/iocache.h"
69
extern plugin::StorageEngine *heap_engine;
70
extern std::bitset<12> test_flags;
46
#include "mysys/my_bit.h"
72
48
/** Declarations of static functions used in this source file. */
73
static bool make_group_fields(Join *main_join, Join *curr_join);
74
static void calc_group_buffer(Join *join, Order *group);
75
static bool alloc_group_fields(Join *join, Order *group);
76
static uint32_t cache_record_length(Join *join, uint32_t index);
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
78
static bool get_best_combination(Join *join);
79
static void set_position(Join *join,
82
optimizer::KeyUse *key);
83
static bool choose_plan(Join *join,table_map join_tables);
84
static void best_access_path(Join *join, JoinTable *s,
49
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
50
static void calc_group_buffer(JOIN *join,order_st *group);
51
static bool alloc_group_fields(JOIN *join,order_st *group);
53
TODO: 'find_best' is here only temporarily until 'greedy_search' is
56
static bool find_best(JOIN *join,table_map rest_tables,uint32_t index, double record_count,double read_time);
57
static uint32_t cache_record_length(JOIN *join, uint32_t index);
58
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
59
static bool get_best_combination(JOIN *join);
60
static void set_position(JOIN *join,uint32_t index,JOIN_TAB *table,KEYUSE *key);
61
static bool choose_plan(JOIN *join,table_map join_tables);
62
static void best_access_path(JOIN *join, JOIN_TAB *s,
86
64
table_map remaining_tables,
88
66
double record_count,
90
static void optimize_straight_join(Join *join, table_map join_tables);
91
static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
92
static bool best_extension_by_limited_search(Join *join,
68
static void optimize_straight_join(JOIN *join, table_map join_tables);
69
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
70
static bool best_extension_by_limited_search(JOIN *join,
93
71
table_map remaining_tables,
95
73
double record_count,
98
76
uint32_t prune_level);
99
static uint32_t determine_search_depth(Join* join);
100
static bool make_simple_join(Join *join,Table *tmp_table);
101
static void make_outerjoin_info(Join *join);
102
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
103
static bool make_join_readinfo(Join *join);
104
static void update_depend_map(Join *join);
105
static void update_depend_map(Join *join, Order *order);
106
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
107
static int return_zero_rows(Join *join,
77
static uint32_t determine_search_depth(JOIN* join);
78
static bool make_simple_join(JOIN *join,Table *tmp_table);
79
static void make_outerjoin_info(JOIN *join);
80
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
81
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
82
static void update_depend_map(JOIN *join);
83
static void update_depend_map(JOIN *join, order_st *order);
84
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
85
static int return_zero_rows(JOIN *join,
108
86
select_result *res,
109
87
TableList *tables,
110
88
List<Item> &fields,
1725
exec_tmp_table1= NULL;
1726
exec_tmp_table2= NULL;
1749
if (exec_tmp_table1)
1750
exec_tmp_table1->free_tmp_table(session);
1751
if (exec_tmp_table2)
1752
exec_tmp_table2->free_tmp_table(session);
1728
1754
delete_dynamic(&keyuse);
1759
Convert candidate subquery predicates to semi-joins
1762
JOIN::flatten_subqueries()
1765
Convert candidate subquery predicates to semi-joins.
1771
bool JOIN::flatten_subqueries()
1773
Item_in_subselect **in_subq;
1774
Item_in_subselect **in_subq_end;
1776
if (sj_subselects.elements() == 0)
1779
/* 1. Fix children subqueries */
1780
for (in_subq= sj_subselects.front(), in_subq_end= sj_subselects.back();
1781
in_subq != in_subq_end; in_subq++)
1783
JOIN *child_join= (*in_subq)->unit->first_select()->join;
1784
child_join->outer_tables = child_join->tables;
1785
if (child_join->flatten_subqueries())
1787
(*in_subq)->sj_convert_priority=
1788
(*in_subq)->is_correlated * MAX_TABLES + child_join->outer_tables;
1791
bool outer_join_disable_semi_join= false;
1793
* Temporary measure: disable semi-joins when they are together with outer
1796
* @see LP Bug #314911
1798
for (TableList *tbl= select_lex->leaf_tables; tbl; tbl=tbl->next_leaf)
1800
TableList *embedding= tbl->embedding;
1801
if (tbl->on_expr || (tbl->embedding && !(embedding->sj_on_expr &&
1802
!embedding->embedding)))
1804
in_subq= sj_subselects.front();
1805
outer_join_disable_semi_join= true;
1809
if (! outer_join_disable_semi_join)
1812
2. Pick which subqueries to convert:
1813
sort the subquery array
1814
- prefer correlated subqueries over uncorrelated;
1815
- prefer subqueries that have greater number of outer tables;
1817
sj_subselects.sort(subq_sj_candidate_cmp);
1818
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
1819
/* Replace all subqueries to be flattened with Item_int(1) */
1820
for (in_subq= sj_subselects.front();
1821
in_subq != in_subq_end &&
1822
tables + ((*in_subq)->sj_convert_priority % MAX_TABLES) < MAX_TABLES;
1825
if (replace_where_subcondition(this, *in_subq, new Item_int(1), false))
1829
for (in_subq= sj_subselects.front();
1830
in_subq != in_subq_end &&
1831
tables + ((*in_subq)->sj_convert_priority % MAX_TABLES) < MAX_TABLES;
1834
if (convert_subq_to_sj(this, *in_subq))
1839
/* 3. Finalize those we didn't convert */
1840
for (; in_subq!= in_subq_end; in_subq++)
1842
JOIN *child_join= (*in_subq)->unit->first_select()->join;
1843
Item_subselect::trans_res res;
1844
(*in_subq)->changed= 0;
1845
(*in_subq)->fixed= 0;
1846
res= (*in_subq)->select_transformer(child_join);
1847
if (res == Item_subselect::RES_ERROR)
1850
(*in_subq)->changed= 1;
1851
(*in_subq)->fixed= 1;
1853
Item *substitute= (*in_subq)->substitution;
1854
bool do_fix_fields= !(*in_subq)->substitution->fixed;
1855
if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
1858
//if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
1861
sj_subselects.clear();
1734
1866
Setup for execution all subqueries of a query, for which the optimizer
1735
1867
chose hash semi-join.
2894
3034
We can't copy all data as the key may have different format
2895
3035
as the row data (for example as with VARCHAR keys)
2897
KeyPartInfo *key_part;
3037
KEY_PART_INFO *key_part;
2898
3038
for (group=table->group,key_part=table->key_info[0].key_part;
2900
3040
group=group->next,key_part++)
2902
3042
if (key_part->null_bit)
2903
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3043
memcpy(table->record[0]+key_part->offset, group->buff, 1);
2905
3045
init_tmptable_sum_functions(join->sum_funcs);
2906
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2907
return NESTED_LOOP_ERROR;
2908
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3046
copy_funcs(join->tmp_table_param.items_to_copy);
3047
if ((error=table->file->ha_write_row(table->record[0])))
2910
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
return NESTED_LOOP_ERROR; // Table is_full error
3049
if (create_myisam_from_heap(join->session, table,
3050
join->tmp_table_param.start_recinfo,
3051
&join->tmp_table_param.recinfo,
3053
return NESTED_LOOP_ERROR; // Not a table_is_full error
3054
/* Change method to update rows */
3055
table->file->ha_index_init(0, 0);
3056
join->join_tab[join->tables-1].next_select= end_unique_update;
2913
3058
join->send_records++;
2914
3059
return NESTED_LOOP_OK;
2917
3062
/** Like end_update, but this is done with unique constraints instead of keys. */
2918
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
3063
enum_nested_loop_state end_unique_update(JOIN *join, JOIN_TAB *, bool end_of_records)
2920
3065
Table *table= join->tmp_table;
2923
3068
if (end_of_records)
2924
3069
return NESTED_LOOP_OK;
2925
if (join->session->getKilled()) // Aborted by user
3070
if (join->session->killed) // Aborted by user
2927
3072
join->session->send_kill_message();
2928
return NESTED_LOOP_KILLED;
3073
return NESTED_LOOP_KILLED; /* purecov: inspected */
2931
3076
init_tmptable_sum_functions(join->sum_funcs);
2932
3077
copy_fields(&join->tmp_table_param); // Groups are copied twice.
2933
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2934
return NESTED_LOOP_ERROR;
3078
copy_funcs(join->tmp_table_param.items_to_copy);
2936
if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
3080
if (!(error= table->file->ha_write_row(table->record[0])))
2937
3081
join->send_records++; // New group
2940
if ((int) table->get_dup_key(error) < 0)
3084
if ((int) table->file->get_dup_key(error) < 0)
2942
table->print_error(error,MYF(0));
2943
return NESTED_LOOP_ERROR;
3086
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3087
return NESTED_LOOP_ERROR; /* purecov: inspected */
2945
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
3089
if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
2947
table->print_error(error,MYF(0));
2948
return NESTED_LOOP_ERROR;
3091
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3092
return NESTED_LOOP_ERROR; /* purecov: inspected */
2950
3094
table->restoreRecord();
2951
3095
update_tmptable_sum_func(join->sum_funcs,table);
2952
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
table->getInsertRecord())))
3096
if ((error= table->file->ha_update_row(table->record[1],
2955
table->print_error(error,MYF(0));
2956
return NESTED_LOOP_ERROR;
3099
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3100
return NESTED_LOOP_ERROR; /* purecov: inspected */
2959
3103
return NESTED_LOOP_OK;
3094
static uint32_t cache_record_length(Join *join,uint32_t idx)
3233
- TODO: this function is here only temporarily until 'greedy_search' is
3234
tested and accepted.
3240
static bool find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count, double read_time)
3242
Session *session= join->session;
3243
if (session->killed)
3247
read_time+=record_count/(double) TIME_FOR_COMPARE;
3248
if (join->sort_by_table &&
3249
join->sort_by_table !=
3250
join->positions[join->const_tables].table->table)
3251
read_time+=record_count; // We have to make a temp table
3252
if (read_time < join->best_read)
3254
memcpy(join->best_positions, join->positions, sizeof(POSITION)*idx);
3255
join->best_read= read_time - 0.001;
3259
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
3260
return(false); /* Found better before */
3263
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
3264
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
3266
table_map real_table_bit=s->table->map;
3267
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
3268
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
3270
double records, best;
3271
advance_sj_state(rest_tables, s);
3272
best_access_path(join, s, session, rest_tables, idx, record_count,
3274
records= join->positions[idx].records_read;
3275
best= join->positions[idx].read_time;
3277
Go to the next level only if there hasn't been a better key on
3278
this level! This will cut down the search for a lot simple cases!
3280
double current_record_count=record_count*records;
3281
double current_read_time=read_time+best;
3282
if (best_record_count > current_record_count ||
3283
best_read_time > current_read_time ||
3284
(idx == join->const_tables && s->table == join->sort_by_table))
3286
if (best_record_count >= current_record_count &&
3287
best_read_time >= current_read_time &&
3288
(!(s->key_dependent & rest_tables) || records < 2.0))
3290
best_record_count=current_record_count;
3291
best_read_time=current_read_time;
3293
std::swap(join->best_ref[idx], *pos);
3294
if (find_best(join,rest_tables & ~real_table_bit,idx+1,
3295
current_record_count,current_read_time))
3297
std::swap(join->best_ref[idx], *pos);
3299
restore_prev_nj_state(s);
3300
restore_prev_sj_state(rest_tables, s);
3301
if (join->select_options & SELECT_STRAIGHT_JOIN)
3302
break; // Don't test all combinations
3308
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3096
3310
uint32_t length=0;
3097
JoinTable **pos,**end;
3311
JOIN_TAB **pos,**end;
3098
3312
Session *session=join->session;
3100
3314
for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
3104
JoinTable *join_tab= *pos;
3318
JOIN_TAB *join_tab= *pos;
3105
3319
if (!join_tab->used_fieldlength) /* Not calced yet */
3106
3320
calc_used_field_length(session, join_tab);
3107
3321
length+=join_tab->used_fieldlength;
3413
3660
if 1. expression doesn't refer to forward tables
3414
3661
2. we won't get two ref-or-null's
3416
if (! (remaining_tables & keyuse->getUsedTables()) &&
3417
! (ref_or_null_part && (keyuse->getOptimizeFlags() &
3418
KEY_OPTIMIZE_REF_OR_NULL)))
3663
if (!(remaining_tables & keyuse->used_tables) &&
3664
!(ref_or_null_part && (keyuse->optimize &
3665
KEY_OPTIMIZE_REF_OR_NULL)))
3420
found_part|= keyuse->getKeypartMap();
3421
if (! (keyuse->getUsedTables() & ~join->const_table_map))
3422
const_part|= keyuse->getKeypartMap();
3667
found_part|= keyuse->keypart_map;
3668
if (!(keyuse->used_tables & ~join->const_table_map))
3669
const_part|= keyuse->keypart_map;
3424
3671
double tmp2= prev_record_reads(join, idx, (found_ref |
3425
keyuse->getUsedTables()));
3672
keyuse->used_tables));
3426
3673
if (tmp2 < best_prev_record_reads)
3428
best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
3675
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3429
3676
best_prev_record_reads= tmp2;
3431
if (rec > keyuse->getTableRows())
3432
rec= keyuse->getTableRows();
3678
if (rec > keyuse->ref_table_rows)
3679
rec= keyuse->ref_table_rows;
3434
3681
If there is one 'key_column IS NULL' expression, we can
3435
3682
use this ref_or_null optimisation of this field
3437
if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
3438
ref_or_null_part|= keyuse->getKeypartMap();
3684
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
3685
ref_or_null_part |= keyuse->keypart_map;
3688
if (try_sj_inside_out && keyuse->sj_pred_no != UINT_MAX)
3690
if (!(remaining_tables & keyuse->used_tables))
3691
bound_sj_equalities |= 1UL << keyuse->sj_pred_no;
3694
handled_sj_equalities |= 1UL << keyuse->sj_pred_no;
3695
sj_insideout_map |= ((key_part_map)1) << keyuse->keypart;
3442
} while (keyuse->getTable() == table && keyuse->getKey() == key &&
3443
keyuse->getKeypart() == keypart);
3444
found_ref|= best_part_found_ref;
3445
} while (keyuse->getTable() == table && keyuse->getKey() == key);
3700
} while (keyuse->table == table && keyuse->key == key &&
3701
keyuse->keypart == keypart);
3702
found_ref|= best_part_found_ref;
3703
} while (keyuse->table == table && keyuse->key == key);
3448
3706
Assume that that each key matches a proportional part of table.
3708
if (!found_part && !handled_sj_equalities)
3451
3709
continue; // Nothing usable found
3453
3711
if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
3454
3712
rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
3714
bool sj_inside_out_scan= false;
3457
3716
found_constraint= 1;
3718
Check if InsideOut scan is applicable:
3719
1. All IN-equalities are either "bound" or "handled"
3720
2. Index keyparts are
3723
if (try_sj_inside_out &&
3724
table->covering_keys.test(key) &&
3725
(handled_sj_equalities | bound_sj_equalities) == // (1)
3726
PREV_BITS(uint64_t, s->emb_sj_nest->sj_in_exprs)) // (1)
3728
uint32_t n_fixed_parts= max_part_bit(found_part);
3729
if (n_fixed_parts != keyinfo->key_parts &&
3730
(PREV_BITS(uint, n_fixed_parts) | sj_insideout_map) ==
3731
PREV_BITS(uint, keyinfo->key_parts))
3734
Not all parts are fixed. Produce bitmap of remaining bits and
3735
check if all of them are covered.
3737
sj_inside_out_scan= true;
3741
It's a confluent ref scan.
3743
That is, all found KEYUSE elements refer to IN-equalities,
3744
and there is really no ref access because there is no
3745
t.keypart0 = {bound expression}
3747
Calculate the cost of complete loose index scan.
3749
records= (double)s->table->file->stats.records;
3751
/* The cost is entire index scan cost (divided by 2) */
3752
best_time= s->table->file->index_only_read_time(key, records);
3754
/* Now figure how many different keys we will get */
3756
if ((rpc= keyinfo->rec_per_key[keyinfo->key_parts-1]))
3757
records= records / rpc;
3460
3764
Check if we found full key
4523
4825
if (join->tables > 1)
4524
4826
cond->update_used_tables(); // Tablenr may have changed
4525
4827
if (join->const_tables == join->tables &&
4526
session->lex->current_select->master_unit() ==
4527
&session->lex->unit) // not upper level SELECT
4828
session->lex->current_select->master_unit() ==
4829
&session->lex->unit) // not upper level SELECT
4528
4830
join->const_table_map|=RAND_TABLE_BIT;
4529
4831
{ // Check const tables
4530
4832
COND *const_cond=
4531
make_cond_for_table(cond,
4532
join->const_table_map,
4534
for (JoinTable *tab= join->join_tab+join->const_tables;
4535
tab < join->join_tab+join->tables ; tab++)
4833
make_cond_for_table(cond,
4834
join->const_table_map,
4836
for (JOIN_TAB *tab= join->join_tab+join->const_tables;
4837
tab < join->join_tab+join->tables ; tab++)
4537
4839
if (*tab->on_expr_ref)
4539
JoinTable *cond_tab= tab->first_inner;
4841
JOIN_TAB *cond_tab= tab->first_inner;
4540
4842
COND *tmp= make_cond_for_table(*tab->on_expr_ref,
4541
join->const_table_map,
4843
join->const_table_map,
4545
4847
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4548
4850
tmp->quick_fix_field();
4549
4851
cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4550
new Item_cond_and(cond_tab->select_cond,
4552
if (! cond_tab->select_cond)
4852
new Item_cond_and(cond_tab->select_cond,
4854
if (!cond_tab->select_cond)
4554
4856
cond_tab->select_cond->quick_fix_field();
4557
if (const_cond && ! const_cond->val_int())
4859
if (const_cond && !const_cond->val_int())
4559
return 1; // Impossible const condition
4861
return(1); // Impossible const condition
4563
4865
used_tables=((select->const_tables=join->const_table_map) |
4564
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4866
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4565
4867
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4567
JoinTable *tab=join->join_tab+i;
4869
JOIN_TAB *tab=join->join_tab+i;
4569
first_inner is the X in queries like:
4570
SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
4572
JoinTable *first_inner_tab= tab->first_inner;
4871
first_inner is the X in queries like:
4872
SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
4874
JOIN_TAB *first_inner_tab= tab->first_inner;
4573
4875
table_map current_map= tab->table->map;
4574
4876
bool use_quick_range=0;
4578
Following force including random expression in last table condition.
4579
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
4880
Following force including random expression in last table condition.
4881
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
4581
4883
if (i == join->tables-1)
4582
current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4884
current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4583
4885
used_tables|=current_map;
4585
if (tab->type == AM_REF && tab->quick &&
4586
(uint32_t) tab->ref.key == tab->quick->index &&
4587
tab->ref.key_length < tab->quick->max_used_key_length)
4887
if (tab->type == JT_REF && tab->quick &&
4888
(uint32_t) tab->ref.key == tab->quick->index &&
4889
tab->ref.key_length < tab->quick->max_used_key_length)
4589
/* Range uses longer key; Use this instead of ref on key */
4891
/* Range uses longer key; Use this instead of ref on key */
4593
4895
tab->ref.key= -1;
4594
tab->ref.key_parts= 0; // Don't use ref key.
4595
cur_pos= join->getPosFromOptimalPlan(i);
4596
cur_pos.setFanout(rows2double(tab->quick->records));
4896
tab->ref.key_parts=0; // Don't use ref key.
4897
join->best_positions[i].records_read= rows2double(tab->quick->records);
4598
We will use join cache here : prevent sorting of the first
4599
table only and sort at the end.
4899
We will use join cache here : prevent sorting of the first
4900
table only and sort at the end.
4601
4902
if (i != join->const_tables && join->tables > join->const_tables + 1)
4602
4903
join->full_join= 1;
4607
4908
tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4608
4909
if (cond && !tmp && tab->quick)
4609
4910
{ // Outer join
4610
if (tab->type != AM_ALL)
4911
if (tab->type != JT_ALL)
4613
Don't use the quick method
4614
We come here in the case where we have 'key=constant' and
4615
the test is removed by make_cond_for_table()
4914
Don't use the quick method
4915
We come here in the case where we have 'key=constant' and
4916
the test is removed by make_cond_for_table()
4617
4918
delete tab->quick;
4623
Hack to handle the case where we only refer to a table
4624
in the ON part of an OUTER JOIN. In this case we want the code
4625
below to check if we should use 'quick' instead.
4924
Hack to handle the case where we only refer to a table
4925
in the ON part of an OUTER JOIN. In this case we want the code
4926
below to check if we should use 'quick' instead.
4627
4928
tmp= new Item_int((int64_t) 1,1); // Always true
4631
if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4632
tab->type == AM_EQ_REF)
4932
if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL ||
4933
tab->type == JT_EQ_REF)
4634
optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4635
session->memdup((unsigned char*) select,
4638
return 1; // End of memory
4935
SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
4936
session->memdup((unsigned char*) select,
4939
return(1); // End of memory
4640
If tab is an inner table of an outer join operation,
4641
add a match guard to the pushed down predicate.
4642
The guard will turn the predicate on only after
4643
the first match for outer tables is encountered.
4941
If tab is an inner table of an outer join operation,
4942
add a match guard to the pushed down predicate.
4943
The guard will turn the predicate on only after
4944
the first match for outer tables is encountered.
4645
4946
if (cond && tmp)
4648
Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
4649
a cond, so neutralize the hack above.
4651
if (! (tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
4949
Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
4950
a cond, so neutralize the hack above.
4952
if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
4653
4954
tab->select_cond=sel->cond=tmp;
4955
/* Push condition to storage engine if this is enabled
4956
and the condition is not guarded */
4957
tab->table->file->pushed_cond= NULL;
4958
if (session->variables.engine_condition_pushdown)
4961
make_cond_for_table(tmp, current_map, current_map, 0);
4964
/* Push condition to handler */
4965
if (!tab->table->file->cond_push(push_cond))
4966
tab->table->file->pushed_cond= push_cond;
4656
4971
tab->select_cond= sel->cond= NULL;
4658
sel->head=tab->table;
4661
/* Use quick key read if it's a constant and it's not used
4663
if (tab->needed_reg.none() && tab->type != AM_EQ_REF
4664
&& (tab->type != AM_REF || (uint32_t) tab->ref.key == tab->quick->index))
4666
sel->quick=tab->quick; // Use value from get_quick_...
4667
sel->quick_keys.reset();
4668
sel->needed_reg.reset();
4676
uint32_t ref_key= static_cast<uint32_t>(sel->head->reginfo.join_tab->ref.key + 1);
4677
if (i == join->const_tables && ref_key)
4679
if (tab->const_keys.any() &&
4680
tab->table->reginfo.impossible_range)
4683
else if (tab->type == AM_ALL && ! use_quick_range)
4685
if (tab->const_keys.any() &&
4686
tab->table->reginfo.impossible_range)
4687
return 1; // Impossible range
4689
We plan to scan all rows.
4690
Check again if we should use an index.
4691
We could have used an column from a previous table in
4692
the index if we are using limit and this is the first table
4695
cur_pos= join->getPosFromOptimalPlan(i);
4696
if ((cond && (! ((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
4697
(! tab->const_keys.none() && (i == join->const_tables) &&
4698
(join->unit->select_limit_cnt < cur_pos.getFanout()) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
4700
/* Join with outer join condition */
4701
COND *orig_cond= sel->cond;
4702
sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
4705
We can't call sel->cond->fix_fields,
4706
as it will break tab->on_expr if it's AND condition
4707
(fix_fields currently removes extra AND/OR levels).
4708
Yet attributes of the just built condition are not needed.
4709
Thus we call sel->cond->quick_fix_field for safety.
4711
if (sel->cond && ! sel->cond->fixed)
4712
sel->cond->quick_fix_field();
4714
if (sel->test_quick_select(session, tab->keys,
4715
used_tables & ~ current_map,
4716
(join->select_options &
4719
join->unit->select_limit_cnt), 0,
4973
sel->head=tab->table;
4976
/* Use quick key read if it's a constant and it's not used
4978
if (tab->needed_reg.none() && tab->type != JT_EQ_REF
4979
&& (tab->type != JT_REF || (uint32_t) tab->ref.key == tab->quick->index))
4981
sel->quick=tab->quick; // Use value from get_quick_...
4982
sel->quick_keys.reset();
4983
sel->needed_reg.reset();
4991
uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
4992
if (i == join->const_tables && ref_key)
4994
if (tab->const_keys.any() &&
4995
tab->table->reginfo.impossible_range)
4998
else if (tab->type == JT_ALL && ! use_quick_range)
5000
if (tab->const_keys.any() &&
5001
tab->table->reginfo.impossible_range)
5002
return(1); // Impossible range
5004
We plan to scan all rows.
5005
Check again if we should use an index.
5006
We could have used an column from a previous table in
5007
the index if we are using limit and this is the first table
5010
if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
5011
(!tab->const_keys.none() && (i == join->const_tables) && (join->unit->select_limit_cnt < join->best_positions[i].records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
5013
/* Join with outer join condition */
5014
COND *orig_cond=sel->cond;
5015
sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
5018
We can't call sel->cond->fix_fields,
5019
as it will break tab->on_expr if it's AND condition
5020
(fix_fields currently removes extra AND/OR levels).
5021
Yet attributes of the just built condition are not needed.
5022
Thus we call sel->cond->quick_fix_field for safety.
5024
if (sel->cond && !sel->cond->fixed)
5025
sel->cond->quick_fix_field();
5027
if (sel->test_quick_select(session, tab->keys,
5028
used_tables & ~ current_map,
5029
(join->select_options &
5032
join->unit->select_limit_cnt), 0,
4723
Before reporting "Impossible WHERE" for the whole query
4724
we have to check isn't it only "impossible ON" instead
5036
Before reporting "Impossible WHERE" for the whole query
5037
we have to check isn't it only "impossible ON" instead
4726
5039
sel->cond=orig_cond;
4727
if (! *tab->on_expr_ref ||
5040
if (!*tab->on_expr_ref ||
4728
5041
sel->test_quick_select(session, tab->keys,
4729
used_tables & ~ current_map,
4730
(join->select_options &
4733
join->unit->select_limit_cnt),0,
4735
return 1; // Impossible WHERE
5042
used_tables & ~ current_map,
5043
(join->select_options &
5046
join->unit->select_limit_cnt),0,
5048
return(1); // Impossible WHERE
4738
sel->cond=orig_cond;
5051
sel->cond=orig_cond;
4740
/* Fix for EXPLAIN */
4743
cur_pos= join->getPosFromOptimalPlan(i);
4744
cur_pos.setFanout(static_cast<double>(sel->quick->records));
4749
sel->needed_reg= tab->needed_reg;
4750
sel->quick_keys.reset();
5053
/* Fix for EXPLAIN */
5055
join->best_positions[i].records_read= (double)sel->quick->records;
5059
sel->needed_reg=tab->needed_reg;
5060
sel->quick_keys.reset();
4752
5062
if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
4753
5063
!((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
4755
tab->keys= sel->quick_keys;
5065
tab->keys= sel->quick_keys;
4756
5066
tab->keys|= sel->needed_reg;
4757
tab->use_quick= (!sel->needed_reg.none() &&
4758
(select->quick_keys.none() ||
4760
(select->quick->records >= 100L)))) ?
4762
sel->read_tables= used_tables & ~current_map;
4764
if (i != join->const_tables && tab->use_quick != 2)
4765
{ /* Read with cache */
5067
tab->use_quick= (!sel->needed_reg.none() &&
5068
(select->quick_keys.none() ||
5070
(select->quick->records >= 100L)))) ?
5072
sel->read_tables= used_tables & ~current_map;
5074
if (i != join->const_tables && tab->use_quick != 2)
5075
{ /* Read with cache */
4767
5077
(tmp=make_cond_for_table(cond,
4768
join->const_table_map |
4772
tab->cache.select= (optimizer::SqlSelect*)
4773
session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4774
tab->cache.select->cond= tmp;
4775
tab->cache.select->read_tables= join->const_table_map;
5078
join->const_table_map |
5082
tab->cache.select=(SQL_SELECT*)
5083
session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
5084
tab->cache.select->cond=tmp;
5085
tab->cache.select->read_tables=join->const_table_map;
4782
Push down conditions from all on expressions.
4783
Each of these conditions are guarded by a variable
4784
that turns if off just before null complemented row for
4785
outer joins is formed. Thus, the condition from an
4786
'on expression' are guaranteed not to be checked for
4787
the null complemented row.
5092
Push down conditions from all on expressions.
5093
Each of these conditions are guarded by a variable
5094
that turns if off just before null complemented row for
5095
outer joins is formed. Thus, the condition from an
5096
'on expression' are guaranteed not to be checked for
5097
the null complemented row.
4790
5100
/* First push down constant conditions from on expressions */
4791
for (JoinTable *join_tab= join->join_tab+join->const_tables;
4792
join_tab < join->join_tab+join->tables ; join_tab++)
5101
for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
5102
join_tab < join->join_tab+join->tables ; join_tab++)
4794
5104
if (*join_tab->on_expr_ref)
4796
JoinTable *cond_tab= join_tab->first_inner;
5106
JOIN_TAB *cond_tab= join_tab->first_inner;
4797
5107
tmp= make_cond_for_table(*join_tab->on_expr_ref,
4798
join->const_table_map,
5108
join->const_table_map,
4802
5112
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4805
5115
tmp->quick_fix_field();
4806
5116
cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4807
new Item_cond_and(cond_tab->select_cond,tmp);
4808
if (! cond_tab->select_cond)
5117
new Item_cond_and(cond_tab->select_cond,tmp);
5118
if (!cond_tab->select_cond)
4810
5120
cond_tab->select_cond->quick_fix_field();
4814
5124
/* Push down non-constant conditions from on expressions */
4815
JoinTable *last_tab= tab;
5125
JOIN_TAB *last_tab= tab;
4816
5126
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
4819
Table tab is the last inner table of an outer join.
4820
An on expression is always attached to it.
5129
Table tab is the last inner table of an outer join.
5130
An on expression is always attached to it.
4822
5132
COND *on_expr= *first_inner_tab->on_expr_ref;
4824
5134
table_map used_tables2= (join->const_table_map |
4825
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4826
for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
5135
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
5136
for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
4828
5138
current_map= tab->table->map;
4829
5139
used_tables2|= current_map;
4830
5140
COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
4834
JoinTable *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
5144
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
4836
First add the guards for match variables of
4837
all embedding outer join operations.
5146
First add the guards for match variables of
5147
all embedding outer join operations.
4839
5149
if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
4844
Now add the guard turning the predicate off for
4845
the null complemented row.
5154
Now add the guard turning the predicate off for
5155
the null complemented row.
4847
5157
tmp_cond= new Item_func_trig_cond(tmp_cond,
4851
5161
tmp_cond->quick_fix_field();
4852
/* Add the predicate to other pushed down predicates */
5162
/* Add the predicate to other pushed down predicates */
4853
5163
cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
4854
new Item_cond_and(cond_tab->select_cond,
4856
if (! cond_tab->select_cond)
5164
new Item_cond_and(cond_tab->select_cond,
5166
if (!cond_tab->select_cond)
4858
5168
cond_tab->select_cond->quick_fix_field();
4887
5197
true - Out of memory
4889
static bool make_join_readinfo(Join *join)
5199
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
5202
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
4893
for (uint32_t i= join->const_tables ; i < join->tables ; i++)
5205
for (i=join->const_tables ; i < join->tables ; i++)
4895
JoinTable *tab=join->join_tab+i;
5207
JOIN_TAB *tab=join->join_tab+i;
4896
5208
Table *table=tab->table;
5209
bool using_join_cache;
4897
5210
tab->read_record.table= table;
4898
tab->read_record.cursor= table->cursor;
5211
tab->read_record.file=table->file;
4899
5212
tab->next_select=sub_select; /* normal select */
4901
5214
TODO: don't always instruct first table's ref/range access method to
4902
5215
produce sorted output.
4904
5217
tab->sorted= sorted;
4905
sorted= false; // only first must be sorted
5218
sorted= 0; // only first must be sorted
4907
5219
if (tab->insideout_match_tab)
4909
if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
5221
if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
4915
optimizer::AccessMethodFactory &factory= optimizer::AccessMethodFactory::singleton();
4916
boost::shared_ptr<optimizer::AccessMethod> access_method(factory.createAccessMethod(tab->type));
4918
if (! access_method)
4922
* Is abort() the correct thing to call here? I call this here because it was what was called in
4923
* the default case for the switch statement that used to be here.
5226
switch (tab->type) {
5227
case JT_SYSTEM: // Only happens with left join
5228
table->status=STATUS_NO_RECORD;
5229
tab->read_first_record= join_read_system;
5230
tab->read_record.read_record= join_no_more_records;
5232
case JT_CONST: // Only happens with left join
5233
table->status=STATUS_NO_RECORD;
5234
tab->read_first_record= join_read_const;
5235
tab->read_record.read_record= join_no_more_records;
5236
if (table->covering_keys.test(tab->ref.key) &&
5240
table->file->extra(HA_EXTRA_KEYREAD);
5244
table->status=STATUS_NO_RECORD;
5247
delete tab->select->quick;
5248
tab->select->quick=0;
5252
tab->read_first_record= join_read_key;
5253
tab->read_record.read_record= join_no_more_records;
5254
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
5257
table->file->extra(HA_EXTRA_KEYREAD);
5260
push_index_cond(tab, tab->ref.key, true);
5262
case JT_REF_OR_NULL:
5264
table->status=STATUS_NO_RECORD;
5267
delete tab->select->quick;
5268
tab->select->quick=0;
5272
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
5275
table->file->extra(HA_EXTRA_KEYREAD);
5278
push_index_cond(tab, tab->ref.key, true);
5279
if (tab->type == JT_REF)
5281
tab->read_first_record= join_read_always_key;
5282
tab->read_record.read_record= tab->insideout_match_tab?
5283
join_read_next_same_diff : join_read_next_same;
5287
tab->read_first_record= join_read_always_key_or_null;
5288
tab->read_record.read_record= join_read_next_same_or_null;
5293
If previous table use cache
5294
If the incoming data set is already sorted don't use cache.
5296
table->status=STATUS_NO_RECORD;
5297
using_join_cache= false;
5298
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
5299
tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
5300
!tab->insideout_match_tab)
5302
if ((options & SELECT_DESCRIBE) ||
5303
!join_init_cache(join->session,join->join_tab+join->const_tables,
5304
i-join->const_tables))
5306
using_join_cache= true;
5307
tab[-1].next_select=sub_select_cache; /* Patch previous */
5310
/* These init changes read_record */
5311
if (tab->use_quick == 2)
5313
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
5314
tab->read_first_record= join_init_quick_read_record;
5316
status_var_increment(join->session->status_var.select_range_check_count);
5320
tab->read_first_record= join_init_read_record;
5321
if (i == join->const_tables)
5323
if (tab->select && tab->select->quick)
5326
status_var_increment(join->session->status_var.select_range_count);
5330
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5332
status_var_increment(join->session->status_var.select_scan_count);
5337
if (tab->select && tab->select->quick)
5340
status_var_increment(join->session->status_var.select_full_range_join_count);
5344
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5346
status_var_increment(join->session->status_var.select_full_join_count);
5349
if (!table->no_keyread)
5351
if (tab->select && tab->select->quick &&
5352
tab->select->quick->index != MAX_KEY && //not index_merge
5353
table->covering_keys.test(tab->select->quick->index))
5356
table->file->extra(HA_EXTRA_KEYREAD);
5358
else if (!table->covering_keys.none() &&
5359
!(tab->select && tab->select->quick))
5360
{ // Only read index tree
5361
if (!tab->insideout_match_tab)
5364
See bug #26447: "Using the clustered index for a table scan
5365
is always faster than using a secondary index".
5367
if (table->s->primary_key != MAX_KEY &&
5368
table->file->primary_key_is_clustered())
5369
tab->index= table->s->primary_key;
5371
tab->index= table->find_shortest_key(&table->covering_keys);
5373
tab->read_first_record= join_read_first;
5374
tab->type=JT_NEXT; // Read with index_first / index_next
5377
if (tab->select && tab->select->quick &&
5378
tab->select->quick->index != MAX_KEY && ! tab->table->key_read)
5379
push_index_cond(tab, tab->select->quick->index, !using_join_cache);
5383
break; /* purecov: deadcode */
5386
abort(); /* purecov: deadcode */
4928
access_method->getStats(table, tab);
4931
join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
5389
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
4936
5393
/** Update the dependency map for the tables. */
4937
static void update_depend_map(Join *join)
5394
static void update_depend_map(JOIN *join)
4939
JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5396
JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
4941
5398
for (; join_tab != end ; join_tab++)
4943
table_reference_st *ref= &join_tab->ref;
4944
table_map depend_map= 0;
5400
TABLE_REF *ref= &join_tab->ref;
5401
table_map depend_map=0;
4945
5402
Item **item=ref->items;
4947
5404
for (i=0 ; i < ref->key_parts ; i++,item++)
4948
5405
depend_map|=(*item)->used_tables();
4949
5406
ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
4950
5407
depend_map&= ~OUTER_REF_TABLE_BIT;
4951
for (JoinTable **tab=join->map2table; depend_map; tab++,depend_map>>=1 )
5408
for (JOIN_TAB **tab=join->map2table; depend_map; tab++,depend_map>>=1 )
4953
5410
if (depend_map & 1)
4954
5411
ref->depend_map|=(*tab)->ref.depend_map;
5520
5964
s->needed_reg.reset();
5521
5965
table_vector[i]=s->table=table=tables->table;
5522
5966
table->pos_in_table_list= tables;
5523
assert(table->cursor);
5524
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5967
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5527
table->print_error(error, MYF(0));
5970
table->file->print_error(error, MYF(0));
5530
5973
table->quick_keys.reset();
5531
5974
table->reginfo.join_tab=s;
5532
5975
table->reginfo.not_exists_optimize=0;
5533
5976
memset(table->const_key_parts, 0,
5534
sizeof(key_part_map)*table->getShare()->sizeKeys());
5977
sizeof(key_part_map)*table->s->keys);
5535
5978
all_table_map|= table->map;
5537
5980
s->info=0; // For describe
5539
s->dependent= tables->getDepTables();
5982
s->dependent= tables->dep_tables;
5540
5983
s->key_dependent= 0;
5541
table->quick_condition_rows= table->cursor->stats.records;
5984
if (tables->schema_table)
5985
table->file->stats.records= 2;
5986
table->quick_condition_rows= table->file->stats.records;
5543
5988
s->on_expr_ref= &tables->on_expr;
5544
5989
if (*s->on_expr_ref)
5546
5991
/* s is the only inner table of an outer join */
5547
if (!table->cursor->stats.records && !embedding)
5992
if (!table->file->stats.records && !embedding)
5548
5993
{ // Empty table
5549
5994
s->dependent= 0; // Ignore LEFT JOIN depend.
5550
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5995
set_position(join,const_count++,s,(KEYUSE*) 0);
5553
5998
outer_join|= table->map;
5554
s->embedding_map.reset();
5555
for (;embedding; embedding= embedding->getEmbedding())
5556
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5999
s->embedding_map= 0;
6000
for (;embedding; embedding= embedding->embedding)
6001
s->embedding_map|= embedding->nested_join->nj_map;
5559
if (embedding && !(false && ! embedding->getEmbedding()))
6004
if (embedding && !(embedding->sj_on_expr && ! embedding->embedding))
5561
6006
/* s belongs to a nested join, maybe to several embedded joins */
5562
s->embedding_map.reset();
6007
s->embedding_map= 0;
5565
nested_join_st *nested_join= embedding->getNestedJoin();
5566
s->embedding_map|= nested_join->nj_map;
5567
s->dependent|= embedding->getDepTables();
5568
embedding= embedding->getEmbedding();
6010
nested_join_st *nested_join= embedding->nested_join;
6011
s->embedding_map|=nested_join->nj_map;
6012
s->dependent|= embedding->dep_tables;
6013
embedding= embedding->embedding;
5569
6014
outer_join|= nested_join->used_tables;
5571
6016
while (embedding);
5574
if ((table->cursor->stats.records <= 1) && !s->dependent &&
5575
(table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
6019
if ((table->file->stats.records <= 1) && !s->dependent &&
6020
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5576
6021
!join->no_const_tables)
5578
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
6023
set_position(join,const_count++,s,(KEYUSE*) 0);
5581
6026
stat_vector[i]=0;
6026
6463
Nested joins perspective: Remove the last table from the join order.
6028
The algorithm is the reciprocal of check_interleaving_with_nj(), hence
6029
parent join nest nodes are updated only when the last table in its child
6030
node is removed. The ASCII graphic below will clarify.
6032
%A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
6033
represented by the below join nest tree.
6041
t1 x [ (t2 x t3) x (t4 x t5) ]
6044
At the point in time when check_interleaving_with_nj() adds the table t5 to
6045
the query execution plan, QEP, it also directs the node named NJ2 to mark
6046
the table as covered. NJ2 does so by incrementing its @c counter
6047
member. Since all of NJ2's tables are now covered by the QEP, the algorithm
6048
proceeds up the tree to NJ1, incrementing its counter as well. All join
6049
nests are now completely covered by the QEP.
6051
restore_prev_nj_state() does the above in reverse. As seen above, the node
6052
NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
6053
that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
6054
completely covers NJ2. The removal of t5 from the partial plan will first
6055
decrement NJ2's counter to 1. It will then detect that NJ2 went from being
6056
completely to partially covered, and hence the algorithm must continue
6057
upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
6058
will however not influence NJ1 since it did not un-cover the last table in
6062
restore_prev_nj_state()
6063
last join table to remove, it is assumed to be the last in current
6068
6465
Remove the last table from the partial join order and update the nested
6069
joins counters and join->cur_embedding_map. It is ok to call this
6070
function for the first table in join order (for which
6466
joins counters and join->cur_embedding_map. It is ok to call this
6467
function for the first table in join order (for which
6071
6468
check_interleaving_with_nj has not been called)
6073
6470
@param last join table to remove, it is assumed to be the last in current
6074
6471
partial join order.
6077
static void restore_prev_nj_state(JoinTable *last)
6079
TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
6080
Join *join= last->join;
6081
for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6083
nested_join_st *nest= last_emb->getNestedJoin();
6085
bool was_fully_covered= nest->is_fully_covered();
6087
if (--nest->counter_ == 0)
6088
join->cur_embedding_map&= ~nest->nj_map;
6090
if (!was_fully_covered)
6473
static void restore_prev_nj_state(JOIN_TAB *last)
6475
TableList *last_emb= last->table->pos_in_table_list->embedding;
6476
JOIN *join= last->join;
6479
if (last_emb->on_expr)
6481
if (!(--last_emb->nested_join->counter_))
6482
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6483
else if (last_emb->nested_join->join_list.elements-1 ==
6484
last_emb->nested_join->counter_)
6485
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6489
last_emb= last_emb->embedding;
6494
Determine if the set is already ordered for order_st BY, so it can
6495
disable join cache because it will change the ordering of the results.
6496
Code handles sort table that is at any location (not only first after
6497
the const tables) despite the fact that it's currently prohibited.
6498
We must disable join cache if the first non-const table alone is
6499
ordered. If there is a temp table the ordering is done as a last
6500
operation and doesn't prevent join cache usage.
6502
static uint32_t make_join_orderinfo(JOIN *join)
6506
return join->tables;
6508
for (i=join->const_tables ; i < join->tables ; i++)
6510
JOIN_TAB *tab= join->join_tab+i;
6511
Table *table= tab->table;
6512
if ((table == join->sort_by_table &&
6513
(!join->order || join->skip_sort_order)) ||
6514
(join->sort_by_table == (Table *) 1 && i != join->const_tables))
6093
join->cur_embedding_map|= nest->nj_map;
6523
Setup the strategies to eliminate semi-join duplicates.
6526
setup_semijoin_dups_elimination()
6527
join Join to process
6528
options Join options (needed to see if join buffering will be
6530
no_jbuf_after Another bit of information re where join buffering will
6534
Setup the strategies to eliminate semi-join duplicates. ATM there are 3
6537
1. DuplicateWeedout (use of temptable to remove duplicates based on rowids
6538
of row combinations)
6539
2. FirstMatch (pick only the 1st matching row combination of inner tables)
6540
3. InsideOut (scanning the sj-inner table in a way that groups duplicates
6541
together and picking the 1st one)
6543
The join order has "duplicate-generating ranges", and every range is
6544
served by one strategy or a combination of FirstMatch with with some
6547
"Duplicate-generating range" is defined as a range within the join order
6548
that contains all of the inner tables of a semi-join. All ranges must be
6549
disjoint, if tables of several semi-joins are interleaved, then the ranges
6550
are joined together, which is equivalent to converting
6551
SELECT ... WHERE oe1 IN (SELECT ie1 ...) AND oe2 IN (SELECT ie2 )
6553
SELECT ... WHERE (oe1, oe2) IN (SELECT ie1, ie2 ... ...)
6556
Applicability conditions are as follows:
6558
DuplicateWeedout strategy
6559
~~~~~~~~~~~~~~~~~~~~~~~~~
6561
(ot|nt)* [ it ((it|ot|nt)* (it|ot))] (nt)*
6562
+------+ +=========================+ +---+
6565
(1) - Prefix of OuterTables (those that participate in
6566
IN-equality and/or are correlated with subquery) and outer
6567
Noncorrelated Tables.
6568
(2) - The handled range. The range starts with the first sj-inner
6569
table, and covers all sj-inner and outer tables
6570
Within the range, Inner, Outer, outer Noncorrelated tables
6571
may follow in any order.
6572
(3) - The suffix of outer Noncorrelated tables.
6577
(ot|nt)* [ it ((it|nt)* it) ] (nt)*
6578
+------+ +==================+ +---+
6581
(1) - Prefix of outer and non-correlated tables
6582
(2) - The handled range, which may contain only inner and
6583
non-correlated tables.
6584
(3) - The suffix of outer Noncorrelated tables.
6589
(ot|ct|nt) [ insideout_tbl (ot|nt|it)* it ] (ot|nt)*
6590
+--------+ +===========+ +=============+ +------+
6593
(1) - Prefix that may contain any outer tables. The prefix must contain
6594
all the non-trivially correlated outer tables. (non-trivially means
6595
that the correlation is not just through the IN-equality).
6597
(2) - Inner table for which the InsideOut scan is performed.
6599
(3) - The remainder of the duplicate-generating range. It is served by
6600
application of FirstMatch strategy, with the exception that
6601
outer IN-correlated tables are considered to be non-correlated.
6603
(4) - THe suffix of outer and outer non-correlated tables.
6605
If several strategies are applicable, their relative priorities are:
6610
This function walks over the join order and sets up the strategies by
6611
setting appropriate members in join_tab structures.
6615
true Out of memory error
6617
static int setup_semijoin_dups_elimination(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
6619
table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
6622
0 - invalid (EOF marker),
6624
2 - Temptable (maybe confluent),
6625
3 - Temptable with join buffering
6628
uint32_t start_idx; /* Left range bound */
6629
uint32_t end_idx; /* Right range bound */
6631
For Temptable strategy: Bitmap of all outer and correlated tables from
6632
all involved join nests.
6634
table_map outer_tables;
6635
} dups_ranges [MAX_TABLES];
6637
TableList *emb_insideout_nest= NULL;
6638
table_map emb_sj_map= 0; /* A bitmap of sj-nests (that is, their sj-inner
6639
tables) whose ranges we're in */
6640
table_map emb_outer_tables= 0; /* sj-outer tables for those sj-nests */
6641
table_map range_start_map= 0; /* table_map at current range start */
6642
bool dealing_with_jbuf= false; /* true <=> table within cur range uses join buf */
6647
First pass: locate the duplicate-generating ranges and pick the strategies.
6649
for (i=join->const_tables ; i < join->tables ; i++)
6651
JOIN_TAB *tab=join->join_tab+i;
6652
Table *table=tab->table;
6653
cur_map |= table->map;
6655
if (tab->emb_sj_nest) // Encountered an sj-inner table
6659
dups_ranges[cur_range].start_idx= i;
6660
range_start_map= cur_map & ~table->map;
6662
Remember if this is a possible start of range that is covered by
6663
the InsideOut strategy (the reason that it is not covered could
6664
be that it overlaps with anther semi-join's range. we don't
6665
support InsideOut for joined ranges)
6667
if (join->best_positions[i].use_insideout_scan)
6668
emb_insideout_nest= tab->emb_sj_nest;
6671
emb_sj_map |= tab->emb_sj_nest->sj_inner_tables;
6672
emb_outer_tables |= tab->emb_sj_nest->nested_join->sj_depends_on;
6674
if (tab->emb_sj_nest != emb_insideout_nest)
6677
Two different semi-joins interleave. This cannot be handled by
6680
emb_insideout_nest= NULL;
6684
if (emb_sj_map) /* We're in duplicate-generating range */
6686
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
6687
tab->type == JT_ALL && tab->use_quick != 2 && !tab->first_inner &&
6688
i <= no_jbuf_after && !dealing_with_jbuf)
6691
This table uses join buffering, which makes use of FirstMatch or
6692
InsideOut strategies impossible for the current and (we assume)
6693
preceding duplicate-producing ranges.
6694
That is, for the join order:
6696
x x [ x x] x [x x x] x [x x X* x] x
6698
+-----+ +-----+ | join buffering use
6701
we'll have to remove r1 and r2 and use duplicate-elimination
6702
strategy that spans all the tables, starting from the very 1st
6705
dealing_with_jbuf= true;
6706
emb_insideout_nest= false;
6709
Absorb all preceding duplicate-eliminating ranges. Their strategies
6712
for (int prev_range= 0; prev_range < cur_range; prev_range++)
6714
dups_ranges[cur_range].outer_tables |=
6715
dups_ranges[prev_range].outer_tables;
6717
dups_ranges[0].start_idx= 0; /* Will need to start from the 1st table */
6718
dups_ranges[0].outer_tables= dups_ranges[cur_range].outer_tables;
6723
Check if we are at the end of duplicate-producing range. We are if
6725
1. It's an InsideOut range (which presumes all correlated tables are
6726
in the prefix), and all inner tables are in the join order prefix,
6728
2. It's a DuplicateElimination range (possibly covering several
6729
SJ-nests), and all inner, outer, and correlated tables of all
6730
sj-nests are in the join order prefix.
6732
bool end_of_range= false;
6733
if (emb_insideout_nest &&
6734
bitmap_covers(cur_map, emb_insideout_nest->sj_inner_tables))
6736
/* Save that this range is handled with InsideOut: */
6737
dups_ranges[cur_range].strategy= 1;
6740
else if (bitmap_covers(cur_map, emb_outer_tables | emb_sj_map))
6743
This is a complete range to be handled with either DuplicateWeedout
6746
dups_ranges[cur_range].strategy= dealing_with_jbuf? 3 : 2;
6748
This will hold tables from within the range that need to be put
6749
into the join buffer before we can use the FirstMatch on its tail.
6751
dups_ranges[cur_range].outer_tables= emb_outer_tables &
6758
dups_ranges[cur_range].end_idx= i+1;
6759
emb_sj_map= emb_outer_tables= 0;
6760
emb_insideout_nest= NULL;
6761
dealing_with_jbuf= false;
6762
dups_ranges[++cur_range].strategy= 0;
6767
Session *session= join->session;
6768
SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
6770
Second pass: setup the chosen strategies
6772
for (int j= 0; j < cur_range; j++)
6774
JOIN_TAB *tab=join->join_tab + dups_ranges[j].start_idx;
6776
if (dups_ranges[j].strategy == 1) // InsideOut strategy
6778
tab->insideout_match_tab= join->join_tab + dups_ranges[j].end_idx - 1;
6781
else // DuplicateWeedout strategy
6783
SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
6784
table_map weed_cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
6785
uint32_t jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
6786
uint32_t jt_null_bits= 0; // # null bits in tuple bytes
6787
SJ_TMP_TABLE::TAB *last_tab= sjtabs;
6788
uint32_t rowid_keep_flags= JOIN_TAB::CALL_POSITION | JOIN_TAB::KEEP_ROWID;
6789
JOIN_TAB *last_outer_tab= tab - 1;
6791
Walk through the range and remember
6792
- tables that need their rowids to be put into temptable
6793
- the last outer table
6795
for (; tab < join->join_tab + dups_ranges[j].end_idx; tab++)
6797
if (sj_table_is_included(join, tab))
6799
last_tab->join_tab= tab;
6800
last_tab->rowid_offset= jt_rowid_offset;
6801
jt_rowid_offset += tab->table->file->ref_length;
6802
if (tab->table->maybe_null)
6804
last_tab->null_byte= jt_null_bits / 8;
6805
last_tab->null_bit= jt_null_bits++;
6808
tab->table->prepare_for_position();
6809
tab->rowid_keep_flags= rowid_keep_flags;
6811
weed_cur_map |= tab->table->map;
6812
if (!tab->emb_sj_nest && bitmap_covers(weed_cur_map,
6813
dups_ranges[j].outer_tables))
6814
last_outer_tab= tab;
6817
if (jt_rowid_offset) /* Temptable has at least one rowid */
6819
SJ_TMP_TABLE *sjtbl;
6820
uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
6821
if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
6822
!(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
6824
memcpy(sjtbl->tabs, sjtabs, tabs_size);
6825
sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
6826
sjtbl->rowid_len= jt_rowid_offset;
6827
sjtbl->null_bits= jt_null_bits;
6828
sjtbl->null_bytes= (jt_null_bits + 7)/8;
6830
*next_sjtbl_ptr= sjtbl;
6831
next_sjtbl_ptr= &(sjtbl->next);
6835
create_duplicate_weedout_tmp_table(session,
6840
join->join_tab[dups_ranges[j].start_idx].flush_weedout_table= sjtbl;
6841
join->join_tab[dups_ranges[j].end_idx - 1].check_weed_out_table= sjtbl;
6843
tab= last_outer_tab + 1;
6844
jump_to= last_outer_tab;
6847
/* Create the FirstMatch tail */
6848
for (; tab < join->join_tab + dups_ranges[j].end_idx; tab++)
6850
if (tab->emb_sj_nest)
6851
tab->do_firstmatch= jump_to;
6859
static void cleanup_sj_tmp_tables(JOIN *join)
6861
for (SJ_TMP_TABLE *sj_tbl= join->sj_tmp_tables; sj_tbl;
6862
sj_tbl= sj_tbl->next)
6864
if (sj_tbl->tmp_table)
6866
sj_tbl->tmp_table->free_tmp_table(join->session);
6869
join->sj_tmp_tables= NULL;
6098
6873
Create a condition for a const reference and add this to the
6099
6874
currenct select for the table.
6101
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab)
6876
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab)
6103
6878
if (!join_tab->ref.key_parts)
6125
6901
error=(int) cond->add(join_tab->select->cond);
6126
6902
join_tab->select_cond=join_tab->select->cond=cond;
6128
else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6904
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
6130
6906
join_tab->select_cond=cond;
6132
6908
return(error ? true : false);
6912
@brief Replaces an expression destructively inside the expression tree of
6915
@note Because of current requirements for semijoin flattening, we do not
6916
need to recurse here, hence this function will only examine the top-level
6917
AND conditions. (see JOIN::prepare, comment above the line
6918
'if (do_materialize)'
6920
@param join The top-level query.
6921
@param old_cond The expression to be replaced.
6922
@param new_cond The expression to be substituted.
6923
@param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
6925
@return <code>true</code> if there was an error, <code>false</code> if
6928
static bool replace_where_subcondition(JOIN *join, Item *old_cond,
6929
Item *new_cond, bool do_fix_fields)
6931
if (join->conds == old_cond) {
6932
join->conds= new_cond;
6934
new_cond->fix_fields(join->session, &join->conds);
6938
if (join->conds->type() == Item::COND_ITEM) {
6939
List_iterator<Item> li(*((Item_cond*)join->conds)->argument_list());
6941
while ((item= li++))
6942
if (item == old_cond)
6944
li.replace(new_cond);
6946
new_cond->fix_fields(join->session, li.ref());
6955
Pull tables out of semi-join nests, if possible
6958
pull_out_semijoin_tables()
6959
join The join where to do the semi-join flattening
6962
Try to pull tables out of semi-join nests.
6965
When this function is called, the join may have several semi-join nests
6966
(possibly within different semi-join nests), but it is guaranteed that
6967
one semi-join nest does not contain another.
6970
A table can be pulled out of the semi-join nest if
6971
- It is a constant table
6975
* Pulled out tables have JOIN_TAB::emb_sj_nest == NULL (like the outer
6977
* Tables that were not pulled out have JOIN_TAB::emb_sj_nest.
6978
* Semi-join nests TableList::sj_inner_tables
6980
This operation is (and should be) performed at each PS execution since
6981
tables may become/cease to be constant across PS reexecutions.
6985
1 - Out of memory error
6987
static int pull_out_semijoin_tables(JOIN *join)
6990
List_iterator<TableList> sj_list_it(join->select_lex->sj_nests);
6992
/* Try pulling out of the each of the semi-joins */
6993
while ((sj_nest= sj_list_it++))
6995
/* Action #1: Mark the constant tables to be pulled out */
6996
table_map pulled_tables= 0;
6998
List_iterator<TableList> child_li(sj_nest->nested_join->join_list);
7000
while ((tbl= child_li++))
7004
tbl->table->reginfo.join_tab->emb_sj_nest= sj_nest;
7005
if (tbl->table->map & join->const_table_map)
7007
pulled_tables |= tbl->table->map;
7013
Action #2: Find which tables we can pull out based on
7014
update_ref_and_keys() data. Note that pulling one table out can allow
7015
us to pull out some other tables too.
7017
bool pulled_a_table;
7020
pulled_a_table= false;
7022
while ((tbl= child_li++))
7024
if (tbl->table && !(pulled_tables & tbl->table->map))
7026
if (find_eq_ref_candidate(tbl->table,
7027
sj_nest->nested_join->used_tables &
7030
pulled_a_table= true;
7031
pulled_tables |= tbl->table->map;
7035
} while (pulled_a_table);
7038
if ((sj_nest)->nested_join->used_tables == pulled_tables)
7040
(sj_nest)->sj_inner_tables= 0;
7041
while ((tbl= child_li++))
7044
tbl->table->reginfo.join_tab->emb_sj_nest= NULL;
7049
/* Record the bitmap of inner tables, mark the inner tables */
7050
table_map inner_tables=(sj_nest)->nested_join->used_tables &
7052
(sj_nest)->sj_inner_tables= inner_tables;
7053
while ((tbl= child_li++))
7057
if (inner_tables & tbl->table->map)
7058
tbl->table->reginfo.join_tab->emb_sj_nest= (sj_nest);
7060
tbl->table->reginfo.join_tab->emb_sj_nest= NULL;
7069
SemiJoinDuplicateElimination: Weed out duplicate row combinations
7072
do_sj_dups_weedout()
7076
1 The row combination is a duplicate (discard it)
7077
0 The row combination is not a duplicate (continue)
7079
static int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl)
7082
SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
7083
SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
7084
unsigned char *ptr= sjtbl->tmp_table->record[0] + 1;
7085
unsigned char *nulls_ptr= ptr;
7087
/* Put the the rowids tuple into table->record[0]: */
7089
// 1. Store the length
7090
if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
7092
*ptr= (unsigned char)(sjtbl->rowid_len + sjtbl->null_bytes);
7097
int2store(ptr, sjtbl->rowid_len + sjtbl->null_bytes);
7101
// 2. Zero the null bytes
7102
if (sjtbl->null_bytes)
7104
memset(ptr, 0, sjtbl->null_bytes);
7105
ptr += sjtbl->null_bytes;
7108
// 3. Put the rowids
7109
for (uint32_t i=0; tab != tab_end; tab++, i++)
7111
handler *h= tab->join_tab->table->file;
7112
if (tab->join_tab->table->maybe_null && tab->join_tab->table->null_row)
7114
/* It's a NULL-complemented row */
7115
*(nulls_ptr + tab->null_byte) |= tab->null_bit;
7116
memset(ptr + tab->rowid_offset, 0, h->ref_length);
7120
/* Copy the rowid value */
7121
if (tab->join_tab->rowid_keep_flags & JOIN_TAB::CALL_POSITION)
7122
h->position(tab->join_tab->table->record[0]);
7123
memcpy(ptr + tab->rowid_offset, h->ref, h->ref_length);
7127
error= sjtbl->tmp_table->file->ha_write_row(sjtbl->tmp_table->record[0]);
7130
/* create_myisam_from_heap will generate error if needed */
7131
if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
7132
create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo,
7133
&sjtbl->recinfo, error, 1))
7135
//return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
6135
7141
static void free_blobs(Field **ptr)
6137
7143
for (; *ptr ; ptr++)