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;
1748
if (exec_tmp_table1)
1749
exec_tmp_table1->free_tmp_table(session);
1750
if (exec_tmp_table2)
1751
exec_tmp_table2->free_tmp_table(session);
1728
1753
delete_dynamic(&keyuse);
1758
Convert candidate subquery predicates to semi-joins
1761
JOIN::flatten_subqueries()
1764
Convert candidate subquery predicates to semi-joins.
1770
bool JOIN::flatten_subqueries()
1772
Item_in_subselect **in_subq;
1773
Item_in_subselect **in_subq_end;
1775
if (sj_subselects.elements() == 0)
1778
/* 1. Fix children subqueries */
1779
for (in_subq= sj_subselects.front(), in_subq_end= sj_subselects.back();
1780
in_subq != in_subq_end; in_subq++)
1782
JOIN *child_join= (*in_subq)->unit->first_select()->join;
1783
child_join->outer_tables = child_join->tables;
1784
if (child_join->flatten_subqueries())
1786
(*in_subq)->sj_convert_priority=
1787
(*in_subq)->is_correlated * MAX_TABLES + child_join->outer_tables;
1790
bool outer_join_disable_semi_join= false;
1792
* Temporary measure: disable semi-joins when they are together with outer
1795
* @see LP Bug #314911
1797
for (TableList *tbl= select_lex->leaf_tables; tbl; tbl=tbl->next_leaf)
1799
TableList *embedding= tbl->embedding;
1800
if (tbl->on_expr || (tbl->embedding && !(embedding->sj_on_expr &&
1801
!embedding->embedding)))
1803
in_subq= sj_subselects.front();
1804
outer_join_disable_semi_join= true;
1808
if (! outer_join_disable_semi_join)
1811
2. Pick which subqueries to convert:
1812
sort the subquery array
1813
- prefer correlated subqueries over uncorrelated;
1814
- prefer subqueries that have greater number of outer tables;
1816
sj_subselects.sort(subq_sj_candidate_cmp);
1817
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
1818
/* Replace all subqueries to be flattened with Item_int(1) */
1819
for (in_subq= sj_subselects.front();
1820
in_subq != in_subq_end &&
1821
tables + ((*in_subq)->sj_convert_priority % MAX_TABLES) < MAX_TABLES;
1824
if (replace_where_subcondition(this, *in_subq, new Item_int(1), false))
1828
for (in_subq= sj_subselects.front();
1829
in_subq != in_subq_end &&
1830
tables + ((*in_subq)->sj_convert_priority % MAX_TABLES) < MAX_TABLES;
1833
if (convert_subq_to_sj(this, *in_subq))
1838
/* 3. Finalize those we didn't convert */
1839
for (; in_subq!= in_subq_end; in_subq++)
1841
JOIN *child_join= (*in_subq)->unit->first_select()->join;
1842
Item_subselect::trans_res res;
1843
(*in_subq)->changed= 0;
1844
(*in_subq)->fixed= 0;
1845
res= (*in_subq)->select_transformer(child_join);
1846
if (res == Item_subselect::RES_ERROR)
1849
(*in_subq)->changed= 1;
1850
(*in_subq)->fixed= 1;
1852
Item *substitute= (*in_subq)->substitution;
1853
bool do_fix_fields= !(*in_subq)->substitution->fixed;
1854
if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
1857
//if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
1860
sj_subselects.clear();
1734
1865
Setup for execution all subqueries of a query, for which the optimizer
1735
1866
chose hash semi-join.
2894
3033
We can't copy all data as the key may have different format
2895
3034
as the row data (for example as with VARCHAR keys)
2897
KeyPartInfo *key_part;
3036
KEY_PART_INFO *key_part;
2898
3037
for (group=table->group,key_part=table->key_info[0].key_part;
2900
3039
group=group->next,key_part++)
2902
3041
if (key_part->null_bit)
2903
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3042
memcpy(table->record[0]+key_part->offset, group->buff, 1);
2905
3044
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())))
3045
copy_funcs(join->tmp_table_param.items_to_copy);
3046
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
3048
if (create_myisam_from_heap(join->session, table,
3049
join->tmp_table_param.start_recinfo,
3050
&join->tmp_table_param.recinfo,
3052
return NESTED_LOOP_ERROR; // Not a table_is_full error
3053
/* Change method to update rows */
3054
table->file->ha_index_init(0, 0);
3055
join->join_tab[join->tables-1].next_select= end_unique_update;
2913
3057
join->send_records++;
2914
3058
return NESTED_LOOP_OK;
2917
3061
/** 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)
3062
enum_nested_loop_state end_unique_update(JOIN *join, JOIN_TAB *, bool end_of_records)
2920
3064
Table *table= join->tmp_table;
2923
3067
if (end_of_records)
2924
3068
return NESTED_LOOP_OK;
2925
if (join->session->getKilled()) // Aborted by user
3069
if (join->session->killed) // Aborted by user
2927
3071
join->session->send_kill_message();
2928
return NESTED_LOOP_KILLED;
3072
return NESTED_LOOP_KILLED; /* purecov: inspected */
2931
3075
init_tmptable_sum_functions(join->sum_funcs);
2932
3076
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;
3077
copy_funcs(join->tmp_table_param.items_to_copy);
2936
if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
3079
if (!(error= table->file->ha_write_row(table->record[0])))
2937
3080
join->send_records++; // New group
2940
if ((int) table->get_dup_key(error) < 0)
3083
if ((int) table->file->get_dup_key(error) < 0)
2942
table->print_error(error,MYF(0));
2943
return NESTED_LOOP_ERROR;
3085
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3086
return NESTED_LOOP_ERROR; /* purecov: inspected */
2945
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
3088
if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
2947
table->print_error(error,MYF(0));
2948
return NESTED_LOOP_ERROR;
3090
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3091
return NESTED_LOOP_ERROR; /* purecov: inspected */
2950
3093
table->restoreRecord();
2951
3094
update_tmptable_sum_func(join->sum_funcs,table);
2952
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
table->getInsertRecord())))
3095
if ((error= table->file->ha_update_row(table->record[1],
2955
table->print_error(error,MYF(0));
2956
return NESTED_LOOP_ERROR;
3098
table->file->print_error(error,MYF(0)); /* purecov: inspected */
3099
return NESTED_LOOP_ERROR; /* purecov: inspected */
2959
3102
return NESTED_LOOP_OK;
3094
static uint32_t cache_record_length(Join *join,uint32_t idx)
3232
- TODO: this function is here only temporarily until 'greedy_search' is
3233
tested and accepted.
3239
static bool find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count, double read_time)
3241
Session *session= join->session;
3242
if (session->killed)
3246
read_time+=record_count/(double) TIME_FOR_COMPARE;
3247
if (join->sort_by_table &&
3248
join->sort_by_table !=
3249
join->positions[join->const_tables].table->table)
3250
read_time+=record_count; // We have to make a temp table
3251
if (read_time < join->best_read)
3253
memcpy(join->best_positions, join->positions, sizeof(POSITION)*idx);
3254
join->best_read= read_time - 0.001;
3258
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
3259
return(false); /* Found better before */
3262
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
3263
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
3265
table_map real_table_bit=s->table->map;
3266
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
3267
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
3269
double records, best;
3270
advance_sj_state(rest_tables, s);
3271
best_access_path(join, s, session, rest_tables, idx, record_count,
3273
records= join->positions[idx].records_read;
3274
best= join->positions[idx].read_time;
3276
Go to the next level only if there hasn't been a better key on
3277
this level! This will cut down the search for a lot simple cases!
3279
double current_record_count=record_count*records;
3280
double current_read_time=read_time+best;
3281
if (best_record_count > current_record_count ||
3282
best_read_time > current_read_time ||
3283
(idx == join->const_tables && s->table == join->sort_by_table))
3285
if (best_record_count >= current_record_count &&
3286
best_read_time >= current_read_time &&
3287
(!(s->key_dependent & rest_tables) || records < 2.0))
3289
best_record_count=current_record_count;
3290
best_read_time=current_read_time;
3292
std::swap(join->best_ref[idx], *pos);
3293
if (find_best(join,rest_tables & ~real_table_bit,idx+1,
3294
current_record_count,current_read_time))
3296
std::swap(join->best_ref[idx], *pos);
3298
restore_prev_nj_state(s);
3299
restore_prev_sj_state(rest_tables, s);
3300
if (join->select_options & SELECT_STRAIGHT_JOIN)
3301
break; // Don't test all combinations
3307
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3096
3309
uint32_t length=0;
3097
JoinTable **pos,**end;
3310
JOIN_TAB **pos,**end;
3098
3311
Session *session=join->session;
3100
3313
for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
3104
JoinTable *join_tab= *pos;
3317
JOIN_TAB *join_tab= *pos;
3105
3318
if (!join_tab->used_fieldlength) /* Not calced yet */
3106
3319
calc_used_field_length(session, join_tab);
3107
3320
length+=join_tab->used_fieldlength;
3413
3659
if 1. expression doesn't refer to forward tables
3414
3660
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)))
3662
if (!(remaining_tables & keyuse->used_tables) &&
3663
!(ref_or_null_part && (keyuse->optimize &
3664
KEY_OPTIMIZE_REF_OR_NULL)))
3420
found_part|= keyuse->getKeypartMap();
3421
if (! (keyuse->getUsedTables() & ~join->const_table_map))
3422
const_part|= keyuse->getKeypartMap();
3666
found_part|= keyuse->keypart_map;
3667
if (!(keyuse->used_tables & ~join->const_table_map))
3668
const_part|= keyuse->keypart_map;
3424
3670
double tmp2= prev_record_reads(join, idx, (found_ref |
3425
keyuse->getUsedTables()));
3671
keyuse->used_tables));
3426
3672
if (tmp2 < best_prev_record_reads)
3428
best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
3674
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3429
3675
best_prev_record_reads= tmp2;
3431
if (rec > keyuse->getTableRows())
3432
rec= keyuse->getTableRows();
3677
if (rec > keyuse->ref_table_rows)
3678
rec= keyuse->ref_table_rows;
3434
3680
If there is one 'key_column IS NULL' expression, we can
3435
3681
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();
3683
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
3684
ref_or_null_part |= keyuse->keypart_map;
3687
if (try_sj_inside_out && keyuse->sj_pred_no != UINT_MAX)
3689
if (!(remaining_tables & keyuse->used_tables))
3690
bound_sj_equalities |= 1UL << keyuse->sj_pred_no;
3693
handled_sj_equalities |= 1UL << keyuse->sj_pred_no;
3694
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);
3699
} while (keyuse->table == table && keyuse->key == key &&
3700
keyuse->keypart == keypart);
3701
found_ref|= best_part_found_ref;
3702
} while (keyuse->table == table && keyuse->key == key);
3448
3705
Assume that that each key matches a proportional part of table.
3707
if (!found_part && !handled_sj_equalities)
3451
3708
continue; // Nothing usable found
3453
3710
if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
3454
3711
rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
3713
bool sj_inside_out_scan= false;
3457
3715
found_constraint= 1;
3717
Check if InsideOut scan is applicable:
3718
1. All IN-equalities are either "bound" or "handled"
3719
2. Index keyparts are
3722
if (try_sj_inside_out &&
3723
table->covering_keys.test(key) &&
3724
(handled_sj_equalities | bound_sj_equalities) == // (1)
3725
PREV_BITS(uint64_t, s->emb_sj_nest->sj_in_exprs)) // (1)
3727
uint32_t n_fixed_parts= max_part_bit(found_part);
3728
if (n_fixed_parts != keyinfo->key_parts &&
3729
(PREV_BITS(uint, n_fixed_parts) | sj_insideout_map) ==
3730
PREV_BITS(uint, keyinfo->key_parts))
3733
Not all parts are fixed. Produce bitmap of remaining bits and
3734
check if all of them are covered.
3736
sj_inside_out_scan= true;
3740
It's a confluent ref scan.
3742
That is, all found KEYUSE elements refer to IN-equalities,
3743
and there is really no ref access because there is no
3744
t.keypart0 = {bound expression}
3746
Calculate the cost of complete loose index scan.
3748
records= (double)s->table->file->stats.records;
3750
/* The cost is entire index scan cost (divided by 2) */
3751
best_time= s->table->file->index_only_read_time(key, records);
3753
/* Now figure how many different keys we will get */
3755
if ((rpc= keyinfo->rec_per_key[keyinfo->key_parts-1]))
3756
records= records / rpc;
3460
3763
Check if we found full key
4523
4824
if (join->tables > 1)
4524
4825
cond->update_used_tables(); // Tablenr may have changed
4525
4826
if (join->const_tables == join->tables &&
4526
session->lex->current_select->master_unit() ==
4527
&session->lex->unit) // not upper level SELECT
4827
session->lex->current_select->master_unit() ==
4828
&session->lex->unit) // not upper level SELECT
4528
4829
join->const_table_map|=RAND_TABLE_BIT;
4529
4830
{ // Check const tables
4530
4831
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++)
4832
make_cond_for_table(cond,
4833
join->const_table_map,
4835
for (JOIN_TAB *tab= join->join_tab+join->const_tables;
4836
tab < join->join_tab+join->tables ; tab++)
4537
4838
if (*tab->on_expr_ref)
4539
JoinTable *cond_tab= tab->first_inner;
4840
JOIN_TAB *cond_tab= tab->first_inner;
4540
4841
COND *tmp= make_cond_for_table(*tab->on_expr_ref,
4541
join->const_table_map,
4842
join->const_table_map,
4545
4846
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4548
4849
tmp->quick_fix_field();
4549
4850
cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4550
new Item_cond_and(cond_tab->select_cond,
4552
if (! cond_tab->select_cond)
4851
new Item_cond_and(cond_tab->select_cond,
4853
if (!cond_tab->select_cond)
4554
4855
cond_tab->select_cond->quick_fix_field();
4557
if (const_cond && ! const_cond->val_int())
4858
if (const_cond && !const_cond->val_int())
4559
return 1; // Impossible const condition
4860
return(1); // Impossible const condition
4563
4864
used_tables=((select->const_tables=join->const_table_map) |
4564
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4865
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4565
4866
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4567
JoinTable *tab=join->join_tab+i;
4868
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;
4870
first_inner is the X in queries like:
4871
SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
4873
JOIN_TAB *first_inner_tab= tab->first_inner;
4573
4874
table_map current_map= tab->table->map;
4574
4875
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
4879
Following force including random expression in last table condition.
4880
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
4581
4882
if (i == join->tables-1)
4582
current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4883
current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4583
4884
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)
4886
if (tab->type == JT_REF && tab->quick &&
4887
(uint32_t) tab->ref.key == tab->quick->index &&
4888
tab->ref.key_length < tab->quick->max_used_key_length)
4589
/* Range uses longer key; Use this instead of ref on key */
4890
/* Range uses longer key; Use this instead of ref on key */
4593
4894
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));
4895
tab->ref.key_parts=0; // Don't use ref key.
4896
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.
4898
We will use join cache here : prevent sorting of the first
4899
table only and sort at the end.
4601
4901
if (i != join->const_tables && join->tables > join->const_tables + 1)
4602
4902
join->full_join= 1;
4607
4907
tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4608
4908
if (cond && !tmp && tab->quick)
4609
4909
{ // Outer join
4610
if (tab->type != AM_ALL)
4910
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()
4913
Don't use the quick method
4914
We come here in the case where we have 'key=constant' and
4915
the test is removed by make_cond_for_table()
4617
4917
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.
4923
Hack to handle the case where we only refer to a table
4924
in the ON part of an OUTER JOIN. In this case we want the code
4925
below to check if we should use 'quick' instead.
4627
4927
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)
4931
if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL ||
4932
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
4934
SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
4935
session->memdup((unsigned char*) select,
4938
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.
4940
If tab is an inner table of an outer join operation,
4941
add a match guard to the pushed down predicate.
4942
The guard will turn the predicate on only after
4943
the first match for outer tables is encountered.
4645
4945
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)))
4948
Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
4949
a cond, so neutralize the hack above.
4951
if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
4653
4953
tab->select_cond=sel->cond=tmp;
4954
/* Push condition to storage engine if this is enabled
4955
and the condition is not guarded */
4956
tab->table->file->pushed_cond= NULL;
4957
if (session->variables.engine_condition_pushdown)
4960
make_cond_for_table(tmp, current_map, current_map, 0);
4963
/* Push condition to handler */
4964
if (!tab->table->file->cond_push(push_cond))
4965
tab->table->file->pushed_cond= push_cond;
4656
4970
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,
4972
sel->head=tab->table;
4975
/* Use quick key read if it's a constant and it's not used
4977
if (tab->needed_reg.none() && tab->type != JT_EQ_REF
4978
&& (tab->type != JT_REF || (uint32_t) tab->ref.key == tab->quick->index))
4980
sel->quick=tab->quick; // Use value from get_quick_...
4981
sel->quick_keys.reset();
4982
sel->needed_reg.reset();
4990
uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
4991
if (i == join->const_tables && ref_key)
4993
if (tab->const_keys.any() &&
4994
tab->table->reginfo.impossible_range)
4997
else if (tab->type == JT_ALL && ! use_quick_range)
4999
if (tab->const_keys.any() &&
5000
tab->table->reginfo.impossible_range)
5001
return(1); // Impossible range
5003
We plan to scan all rows.
5004
Check again if we should use an index.
5005
We could have used an column from a previous table in
5006
the index if we are using limit and this is the first table
5009
if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
5010
(!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)))
5012
/* Join with outer join condition */
5013
COND *orig_cond=sel->cond;
5014
sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
5017
We can't call sel->cond->fix_fields,
5018
as it will break tab->on_expr if it's AND condition
5019
(fix_fields currently removes extra AND/OR levels).
5020
Yet attributes of the just built condition are not needed.
5021
Thus we call sel->cond->quick_fix_field for safety.
5023
if (sel->cond && !sel->cond->fixed)
5024
sel->cond->quick_fix_field();
5026
if (sel->test_quick_select(session, tab->keys,
5027
used_tables & ~ current_map,
5028
(join->select_options &
5031
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
5035
Before reporting "Impossible WHERE" for the whole query
5036
we have to check isn't it only "impossible ON" instead
4726
5038
sel->cond=orig_cond;
4727
if (! *tab->on_expr_ref ||
5039
if (!*tab->on_expr_ref ||
4728
5040
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
5041
used_tables & ~ current_map,
5042
(join->select_options &
5045
join->unit->select_limit_cnt),0,
5047
return(1); // Impossible WHERE
4738
sel->cond=orig_cond;
5050
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();
5052
/* Fix for EXPLAIN */
5054
join->best_positions[i].records_read= (double)sel->quick->records;
5058
sel->needed_reg=tab->needed_reg;
5059
sel->quick_keys.reset();
4752
5061
if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
4753
5062
!((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
4755
tab->keys= sel->quick_keys;
5064
tab->keys= sel->quick_keys;
4756
5065
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 */
5066
tab->use_quick= (!sel->needed_reg.none() &&
5067
(select->quick_keys.none() ||
5069
(select->quick->records >= 100L)))) ?
5071
sel->read_tables= used_tables & ~current_map;
5073
if (i != join->const_tables && tab->use_quick != 2)
5074
{ /* Read with cache */
4767
5076
(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;
5077
join->const_table_map |
5081
tab->cache.select=(SQL_SELECT*)
5082
session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
5083
tab->cache.select->cond=tmp;
5084
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.
5091
Push down conditions from all on expressions.
5092
Each of these conditions are guarded by a variable
5093
that turns if off just before null complemented row for
5094
outer joins is formed. Thus, the condition from an
5095
'on expression' are guaranteed not to be checked for
5096
the null complemented row.
4790
5099
/* 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++)
5100
for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
5101
join_tab < join->join_tab+join->tables ; join_tab++)
4794
5103
if (*join_tab->on_expr_ref)
4796
JoinTable *cond_tab= join_tab->first_inner;
5105
JOIN_TAB *cond_tab= join_tab->first_inner;
4797
5106
tmp= make_cond_for_table(*join_tab->on_expr_ref,
4798
join->const_table_map,
5107
join->const_table_map,
4802
5111
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4805
5114
tmp->quick_fix_field();
4806
5115
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)
5116
new Item_cond_and(cond_tab->select_cond,tmp);
5117
if (!cond_tab->select_cond)
4810
5119
cond_tab->select_cond->quick_fix_field();
4814
5123
/* Push down non-constant conditions from on expressions */
4815
JoinTable *last_tab= tab;
5124
JOIN_TAB *last_tab= tab;
4816
5125
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.
5128
Table tab is the last inner table of an outer join.
5129
An on expression is always attached to it.
4822
5131
COND *on_expr= *first_inner_tab->on_expr_ref;
4824
5133
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++)
5134
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
5135
for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
4828
5137
current_map= tab->table->map;
4829
5138
used_tables2|= current_map;
4830
5139
COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
4834
JoinTable *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
5143
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.
5145
First add the guards for match variables of
5146
all embedding outer join operations.
4839
5148
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.
5153
Now add the guard turning the predicate off for
5154
the null complemented row.
4847
5156
tmp_cond= new Item_func_trig_cond(tmp_cond,
4851
5160
tmp_cond->quick_fix_field();
4852
/* Add the predicate to other pushed down predicates */
5161
/* Add the predicate to other pushed down predicates */
4853
5162
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)
5163
new Item_cond_and(cond_tab->select_cond,
5165
if (!cond_tab->select_cond)
4858
5167
cond_tab->select_cond->quick_fix_field();
4887
5196
true - Out of memory
4889
static bool make_join_readinfo(Join *join)
5198
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
5201
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
4893
for (uint32_t i= join->const_tables ; i < join->tables ; i++)
5204
for (i=join->const_tables ; i < join->tables ; i++)
4895
JoinTable *tab=join->join_tab+i;
5206
JOIN_TAB *tab=join->join_tab+i;
4896
5207
Table *table=tab->table;
5208
bool using_join_cache;
4897
5209
tab->read_record.table= table;
4898
tab->read_record.cursor= table->cursor;
5210
tab->read_record.file=table->file;
4899
5211
tab->next_select=sub_select; /* normal select */
4901
5213
TODO: don't always instruct first table's ref/range access method to
4902
5214
produce sorted output.
4904
5216
tab->sorted= sorted;
4905
sorted= false; // only first must be sorted
5217
sorted= 0; // only first must be sorted
4907
5218
if (tab->insideout_match_tab)
4909
if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
5220
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.
5225
switch (tab->type) {
5226
case JT_SYSTEM: // Only happens with left join
5227
table->status=STATUS_NO_RECORD;
5228
tab->read_first_record= join_read_system;
5229
tab->read_record.read_record= join_no_more_records;
5231
case JT_CONST: // Only happens with left join
5232
table->status=STATUS_NO_RECORD;
5233
tab->read_first_record= join_read_const;
5234
tab->read_record.read_record= join_no_more_records;
5235
if (table->covering_keys.test(tab->ref.key) &&
5239
table->file->extra(HA_EXTRA_KEYREAD);
5243
table->status=STATUS_NO_RECORD;
5246
delete tab->select->quick;
5247
tab->select->quick=0;
5251
tab->read_first_record= join_read_key;
5252
tab->read_record.read_record= join_no_more_records;
5253
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
5256
table->file->extra(HA_EXTRA_KEYREAD);
5259
push_index_cond(tab, tab->ref.key, true);
5261
case JT_REF_OR_NULL:
5263
table->status=STATUS_NO_RECORD;
5266
delete tab->select->quick;
5267
tab->select->quick=0;
5271
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
5274
table->file->extra(HA_EXTRA_KEYREAD);
5277
push_index_cond(tab, tab->ref.key, true);
5278
if (tab->type == JT_REF)
5280
tab->read_first_record= join_read_always_key;
5281
tab->read_record.read_record= tab->insideout_match_tab?
5282
join_read_next_same_diff : join_read_next_same;
5286
tab->read_first_record= join_read_always_key_or_null;
5287
tab->read_record.read_record= join_read_next_same_or_null;
5292
If previous table use cache
5293
If the incoming data set is already sorted don't use cache.
5295
table->status=STATUS_NO_RECORD;
5296
using_join_cache= false;
5297
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
5298
tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
5299
!tab->insideout_match_tab)
5301
if ((options & SELECT_DESCRIBE) ||
5302
!join_init_cache(join->session,join->join_tab+join->const_tables,
5303
i-join->const_tables))
5305
using_join_cache= true;
5306
tab[-1].next_select=sub_select_cache; /* Patch previous */
5309
/* These init changes read_record */
5310
if (tab->use_quick == 2)
5312
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
5313
tab->read_first_record= join_init_quick_read_record;
5315
status_var_increment(join->session->status_var.select_range_check_count);
5319
tab->read_first_record= join_init_read_record;
5320
if (i == join->const_tables)
5322
if (tab->select && tab->select->quick)
5325
status_var_increment(join->session->status_var.select_range_count);
5329
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5331
status_var_increment(join->session->status_var.select_scan_count);
5336
if (tab->select && tab->select->quick)
5339
status_var_increment(join->session->status_var.select_full_range_join_count);
5343
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5345
status_var_increment(join->session->status_var.select_full_join_count);
5348
if (!table->no_keyread)
5350
if (tab->select && tab->select->quick &&
5351
tab->select->quick->index != MAX_KEY && //not index_merge
5352
table->covering_keys.test(tab->select->quick->index))
5355
table->file->extra(HA_EXTRA_KEYREAD);
5357
else if (!table->covering_keys.none() &&
5358
!(tab->select && tab->select->quick))
5359
{ // Only read index tree
5360
if (!tab->insideout_match_tab)
5363
See bug #26447: "Using the clustered index for a table scan
5364
is always faster than using a secondary index".
5366
if (table->s->primary_key != MAX_KEY &&
5367
table->file->primary_key_is_clustered())
5368
tab->index= table->s->primary_key;
5370
tab->index= table->find_shortest_key(&table->covering_keys);
5372
tab->read_first_record= join_read_first;
5373
tab->type=JT_NEXT; // Read with index_first / index_next
5376
if (tab->select && tab->select->quick &&
5377
tab->select->quick->index != MAX_KEY && ! tab->table->key_read)
5378
push_index_cond(tab, tab->select->quick->index, !using_join_cache);
5382
break; /* purecov: deadcode */
5385
abort(); /* purecov: deadcode */
4928
access_method->getStats(table, tab);
4931
join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
5388
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
4936
5392
/** Update the dependency map for the tables. */
4937
static void update_depend_map(Join *join)
5393
static void update_depend_map(JOIN *join)
4939
JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5395
JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
4941
5397
for (; join_tab != end ; join_tab++)
4943
table_reference_st *ref= &join_tab->ref;
4944
table_map depend_map= 0;
5399
TABLE_REF *ref= &join_tab->ref;
5400
table_map depend_map=0;
4945
5401
Item **item=ref->items;
4947
5403
for (i=0 ; i < ref->key_parts ; i++,item++)
4948
5404
depend_map|=(*item)->used_tables();
4949
5405
ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
4950
5406
depend_map&= ~OUTER_REF_TABLE_BIT;
4951
for (JoinTable **tab=join->map2table; depend_map; tab++,depend_map>>=1 )
5407
for (JOIN_TAB **tab=join->map2table; depend_map; tab++,depend_map>>=1 )
4953
5409
if (depend_map & 1)
4954
5410
ref->depend_map|=(*tab)->ref.depend_map;
5520
5963
s->needed_reg.reset();
5521
5964
table_vector[i]=s->table=table=tables->table;
5522
5965
table->pos_in_table_list= tables;
5523
assert(table->cursor);
5524
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5966
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5527
table->print_error(error, MYF(0));
5969
table->file->print_error(error, MYF(0));
5530
5972
table->quick_keys.reset();
5531
5973
table->reginfo.join_tab=s;
5532
5974
table->reginfo.not_exists_optimize=0;
5533
5975
memset(table->const_key_parts, 0,
5534
sizeof(key_part_map)*table->getShare()->sizeKeys());
5976
sizeof(key_part_map)*table->s->keys);
5535
5977
all_table_map|= table->map;
5537
5979
s->info=0; // For describe
5539
s->dependent= tables->getDepTables();
5981
s->dependent= tables->dep_tables;
5540
5982
s->key_dependent= 0;
5541
table->quick_condition_rows= table->cursor->stats.records;
5983
if (tables->schema_table)
5984
table->file->stats.records= 2;
5985
table->quick_condition_rows= table->file->stats.records;
5543
5987
s->on_expr_ref= &tables->on_expr;
5544
5988
if (*s->on_expr_ref)
5546
5990
/* s is the only inner table of an outer join */
5547
if (!table->cursor->stats.records && !embedding)
5991
if (!table->file->stats.records && !embedding)
5548
5992
{ // Empty table
5549
5993
s->dependent= 0; // Ignore LEFT JOIN depend.
5550
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5994
set_position(join,const_count++,s,(KEYUSE*) 0);
5553
5997
outer_join|= table->map;
5554
s->embedding_map.reset();
5555
for (;embedding; embedding= embedding->getEmbedding())
5556
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5998
s->embedding_map= 0;
5999
for (;embedding; embedding= embedding->embedding)
6000
s->embedding_map|= embedding->nested_join->nj_map;
5559
if (embedding && !(false && ! embedding->getEmbedding()))
6003
if (embedding && !(embedding->sj_on_expr && ! embedding->embedding))
5561
6005
/* s belongs to a nested join, maybe to several embedded joins */
5562
s->embedding_map.reset();
6006
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();
6009
nested_join_st *nested_join= embedding->nested_join;
6010
s->embedding_map|=nested_join->nj_map;
6011
s->dependent|= embedding->dep_tables;
6012
embedding= embedding->embedding;
5569
6013
outer_join|= nested_join->used_tables;
5571
6015
while (embedding);
5574
if ((table->cursor->stats.records <= 1) && !s->dependent &&
5575
(table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
6018
if ((table->file->stats.records <= 1) && !s->dependent &&
6019
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5576
6020
!join->no_const_tables)
5578
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
6022
set_position(join,const_count++,s,(KEYUSE*) 0);
5581
6025
stat_vector[i]=0;
6026
6462
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
6464
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
6465
joins counters and join->cur_embedding_map. It is ok to call this
6466
function for the first table in join order (for which
6071
6467
check_interleaving_with_nj has not been called)
6073
6469
@param last join table to remove, it is assumed to be the last in current
6074
6470
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)
6472
static void restore_prev_nj_state(JOIN_TAB *last)
6474
TableList *last_emb= last->table->pos_in_table_list->embedding;
6475
JOIN *join= last->join;
6478
if (last_emb->on_expr)
6480
if (!(--last_emb->nested_join->counter_))
6481
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6482
else if (last_emb->nested_join->join_list.elements-1 ==
6483
last_emb->nested_join->counter_)
6484
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6488
last_emb= last_emb->embedding;
6493
Determine if the set is already ordered for order_st BY, so it can
6494
disable join cache because it will change the ordering of the results.
6495
Code handles sort table that is at any location (not only first after
6496
the const tables) despite the fact that it's currently prohibited.
6497
We must disable join cache if the first non-const table alone is
6498
ordered. If there is a temp table the ordering is done as a last
6499
operation and doesn't prevent join cache usage.
6501
static uint32_t make_join_orderinfo(JOIN *join)
6505
return join->tables;
6507
for (i=join->const_tables ; i < join->tables ; i++)
6509
JOIN_TAB *tab= join->join_tab+i;
6510
Table *table= tab->table;
6511
if ((table == join->sort_by_table &&
6512
(!join->order || join->skip_sort_order)) ||
6513
(join->sort_by_table == (Table *) 1 && i != join->const_tables))
6093
join->cur_embedding_map|= nest->nj_map;
6522
Setup the strategies to eliminate semi-join duplicates.
6525
setup_semijoin_dups_elimination()
6526
join Join to process
6527
options Join options (needed to see if join buffering will be
6529
no_jbuf_after Another bit of information re where join buffering will
6533
Setup the strategies to eliminate semi-join duplicates. ATM there are 3
6536
1. DuplicateWeedout (use of temptable to remove duplicates based on rowids
6537
of row combinations)
6538
2. FirstMatch (pick only the 1st matching row combination of inner tables)
6539
3. InsideOut (scanning the sj-inner table in a way that groups duplicates
6540
together and picking the 1st one)
6542
The join order has "duplicate-generating ranges", and every range is
6543
served by one strategy or a combination of FirstMatch with with some
6546
"Duplicate-generating range" is defined as a range within the join order
6547
that contains all of the inner tables of a semi-join. All ranges must be
6548
disjoint, if tables of several semi-joins are interleaved, then the ranges
6549
are joined together, which is equivalent to converting
6550
SELECT ... WHERE oe1 IN (SELECT ie1 ...) AND oe2 IN (SELECT ie2 )
6552
SELECT ... WHERE (oe1, oe2) IN (SELECT ie1, ie2 ... ...)
6555
Applicability conditions are as follows:
6557
DuplicateWeedout strategy
6558
~~~~~~~~~~~~~~~~~~~~~~~~~
6560
(ot|nt)* [ it ((it|ot|nt)* (it|ot))] (nt)*
6561
+------+ +=========================+ +---+
6564
(1) - Prefix of OuterTables (those that participate in
6565
IN-equality and/or are correlated with subquery) and outer
6566
Noncorrelated Tables.
6567
(2) - The handled range. The range starts with the first sj-inner
6568
table, and covers all sj-inner and outer tables
6569
Within the range, Inner, Outer, outer Noncorrelated tables
6570
may follow in any order.
6571
(3) - The suffix of outer Noncorrelated tables.
6576
(ot|nt)* [ it ((it|nt)* it) ] (nt)*
6577
+------+ +==================+ +---+
6580
(1) - Prefix of outer and non-correlated tables
6581
(2) - The handled range, which may contain only inner and
6582
non-correlated tables.
6583
(3) - The suffix of outer Noncorrelated tables.
6588
(ot|ct|nt) [ insideout_tbl (ot|nt|it)* it ] (ot|nt)*
6589
+--------+ +===========+ +=============+ +------+
6592
(1) - Prefix that may contain any outer tables. The prefix must contain
6593
all the non-trivially correlated outer tables. (non-trivially means
6594
that the correlation is not just through the IN-equality).
6596
(2) - Inner table for which the InsideOut scan is performed.
6598
(3) - The remainder of the duplicate-generating range. It is served by
6599
application of FirstMatch strategy, with the exception that
6600
outer IN-correlated tables are considered to be non-correlated.
6602
(4) - THe suffix of outer and outer non-correlated tables.
6604
If several strategies are applicable, their relative priorities are:
6609
This function walks over the join order and sets up the strategies by
6610
setting appropriate members in join_tab structures.
6614
true Out of memory error
6616
static int setup_semijoin_dups_elimination(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
6618
table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
6621
0 - invalid (EOF marker),
6623
2 - Temptable (maybe confluent),
6624
3 - Temptable with join buffering
6627
uint32_t start_idx; /* Left range bound */
6628
uint32_t end_idx; /* Right range bound */
6630
For Temptable strategy: Bitmap of all outer and correlated tables from
6631
all involved join nests.
6633
table_map outer_tables;
6634
} dups_ranges [MAX_TABLES];
6636
TableList *emb_insideout_nest= NULL;
6637
table_map emb_sj_map= 0; /* A bitmap of sj-nests (that is, their sj-inner
6638
tables) whose ranges we're in */
6639
table_map emb_outer_tables= 0; /* sj-outer tables for those sj-nests */
6640
table_map range_start_map= 0; /* table_map at current range start */
6641
bool dealing_with_jbuf= false; /* true <=> table within cur range uses join buf */
6646
First pass: locate the duplicate-generating ranges and pick the strategies.
6648
for (i=join->const_tables ; i < join->tables ; i++)
6650
JOIN_TAB *tab=join->join_tab+i;
6651
Table *table=tab->table;
6652
cur_map |= table->map;
6654
if (tab->emb_sj_nest) // Encountered an sj-inner table
6658
dups_ranges[cur_range].start_idx= i;
6659
range_start_map= cur_map & ~table->map;
6661
Remember if this is a possible start of range that is covered by
6662
the InsideOut strategy (the reason that it is not covered could
6663
be that it overlaps with anther semi-join's range. we don't
6664
support InsideOut for joined ranges)
6666
if (join->best_positions[i].use_insideout_scan)
6667
emb_insideout_nest= tab->emb_sj_nest;
6670
emb_sj_map |= tab->emb_sj_nest->sj_inner_tables;
6671
emb_outer_tables |= tab->emb_sj_nest->nested_join->sj_depends_on;
6673
if (tab->emb_sj_nest != emb_insideout_nest)
6676
Two different semi-joins interleave. This cannot be handled by
6679
emb_insideout_nest= NULL;
6683
if (emb_sj_map) /* We're in duplicate-generating range */
6685
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
6686
tab->type == JT_ALL && tab->use_quick != 2 && !tab->first_inner &&
6687
i <= no_jbuf_after && !dealing_with_jbuf)
6690
This table uses join buffering, which makes use of FirstMatch or
6691
InsideOut strategies impossible for the current and (we assume)
6692
preceding duplicate-producing ranges.
6693
That is, for the join order:
6695
x x [ x x] x [x x x] x [x x X* x] x
6697
+-----+ +-----+ | join buffering use
6700
we'll have to remove r1 and r2 and use duplicate-elimination
6701
strategy that spans all the tables, starting from the very 1st
6704
dealing_with_jbuf= true;
6705
emb_insideout_nest= false;
6708
Absorb all preceding duplicate-eliminating ranges. Their strategies
6711
for (int prev_range= 0; prev_range < cur_range; prev_range++)
6713
dups_ranges[cur_range].outer_tables |=
6714
dups_ranges[prev_range].outer_tables;
6716
dups_ranges[0].start_idx= 0; /* Will need to start from the 1st table */
6717
dups_ranges[0].outer_tables= dups_ranges[cur_range].outer_tables;
6722
Check if we are at the end of duplicate-producing range. We are if
6724
1. It's an InsideOut range (which presumes all correlated tables are
6725
in the prefix), and all inner tables are in the join order prefix,
6727
2. It's a DuplicateElimination range (possibly covering several
6728
SJ-nests), and all inner, outer, and correlated tables of all
6729
sj-nests are in the join order prefix.
6731
bool end_of_range= false;
6732
if (emb_insideout_nest &&
6733
bitmap_covers(cur_map, emb_insideout_nest->sj_inner_tables))
6735
/* Save that this range is handled with InsideOut: */
6736
dups_ranges[cur_range].strategy= 1;
6739
else if (bitmap_covers(cur_map, emb_outer_tables | emb_sj_map))
6742
This is a complete range to be handled with either DuplicateWeedout
6745
dups_ranges[cur_range].strategy= dealing_with_jbuf? 3 : 2;
6747
This will hold tables from within the range that need to be put
6748
into the join buffer before we can use the FirstMatch on its tail.
6750
dups_ranges[cur_range].outer_tables= emb_outer_tables &
6757
dups_ranges[cur_range].end_idx= i+1;
6758
emb_sj_map= emb_outer_tables= 0;
6759
emb_insideout_nest= NULL;
6760
dealing_with_jbuf= false;
6761
dups_ranges[++cur_range].strategy= 0;
6766
Session *session= join->session;
6767
SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
6769
Second pass: setup the chosen strategies
6771
for (int j= 0; j < cur_range; j++)
6773
JOIN_TAB *tab=join->join_tab + dups_ranges[j].start_idx;
6775
if (dups_ranges[j].strategy == 1) // InsideOut strategy
6777
tab->insideout_match_tab= join->join_tab + dups_ranges[j].end_idx - 1;
6780
else // DuplicateWeedout strategy
6782
SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
6783
table_map weed_cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
6784
uint32_t jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
6785
uint32_t jt_null_bits= 0; // # null bits in tuple bytes
6786
SJ_TMP_TABLE::TAB *last_tab= sjtabs;
6787
uint32_t rowid_keep_flags= JOIN_TAB::CALL_POSITION | JOIN_TAB::KEEP_ROWID;
6788
JOIN_TAB *last_outer_tab= tab - 1;
6790
Walk through the range and remember
6791
- tables that need their rowids to be put into temptable
6792
- the last outer table
6794
for (; tab < join->join_tab + dups_ranges[j].end_idx; tab++)
6796
if (sj_table_is_included(join, tab))
6798
last_tab->join_tab= tab;
6799
last_tab->rowid_offset= jt_rowid_offset;
6800
jt_rowid_offset += tab->table->file->ref_length;
6801
if (tab->table->maybe_null)
6803
last_tab->null_byte= jt_null_bits / 8;
6804
last_tab->null_bit= jt_null_bits++;
6807
tab->table->prepare_for_position();
6808
tab->rowid_keep_flags= rowid_keep_flags;
6810
weed_cur_map |= tab->table->map;
6811
if (!tab->emb_sj_nest && bitmap_covers(weed_cur_map,
6812
dups_ranges[j].outer_tables))
6813
last_outer_tab= tab;
6816
if (jt_rowid_offset) /* Temptable has at least one rowid */
6818
SJ_TMP_TABLE *sjtbl;
6819
uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
6820
if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
6821
!(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
6823
memcpy(sjtbl->tabs, sjtabs, tabs_size);
6824
sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
6825
sjtbl->rowid_len= jt_rowid_offset;
6826
sjtbl->null_bits= jt_null_bits;
6827
sjtbl->null_bytes= (jt_null_bits + 7)/8;
6829
*next_sjtbl_ptr= sjtbl;
6830
next_sjtbl_ptr= &(sjtbl->next);
6834
create_duplicate_weedout_tmp_table(session,
6839
join->join_tab[dups_ranges[j].start_idx].flush_weedout_table= sjtbl;
6840
join->join_tab[dups_ranges[j].end_idx - 1].check_weed_out_table= sjtbl;
6842
tab= last_outer_tab + 1;
6843
jump_to= last_outer_tab;
6846
/* Create the FirstMatch tail */
6847
for (; tab < join->join_tab + dups_ranges[j].end_idx; tab++)
6849
if (tab->emb_sj_nest)
6850
tab->do_firstmatch= jump_to;
6858
static void cleanup_sj_tmp_tables(JOIN *join)
6860
for (SJ_TMP_TABLE *sj_tbl= join->sj_tmp_tables; sj_tbl;
6861
sj_tbl= sj_tbl->next)
6863
if (sj_tbl->tmp_table)
6865
sj_tbl->tmp_table->free_tmp_table(join->session);
6868
join->sj_tmp_tables= NULL;
6098
6872
Create a condition for a const reference and add this to the
6099
6873
currenct select for the table.
6101
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab)
6875
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab)
6103
6877
if (!join_tab->ref.key_parts)
6125
6900
error=(int) cond->add(join_tab->select->cond);
6126
6901
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,
6903
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
6130
6905
join_tab->select_cond=cond;
6132
6907
return(error ? true : false);
6911
@brief Replaces an expression destructively inside the expression tree of
6914
@note Because of current requirements for semijoin flattening, we do not
6915
need to recurse here, hence this function will only examine the top-level
6916
AND conditions. (see JOIN::prepare, comment above the line
6917
'if (do_materialize)'
6919
@param join The top-level query.
6920
@param old_cond The expression to be replaced.
6921
@param new_cond The expression to be substituted.
6922
@param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
6924
@return <code>true</code> if there was an error, <code>false</code> if
6927
static bool replace_where_subcondition(JOIN *join, Item *old_cond,
6928
Item *new_cond, bool do_fix_fields)
6930
if (join->conds == old_cond) {
6931
join->conds= new_cond;
6933
new_cond->fix_fields(join->session, &join->conds);
6937
if (join->conds->type() == Item::COND_ITEM) {
6938
List_iterator<Item> li(*((Item_cond*)join->conds)->argument_list());
6940
while ((item= li++))
6941
if (item == old_cond)
6943
li.replace(new_cond);
6945
new_cond->fix_fields(join->session, li.ref());
6954
Pull tables out of semi-join nests, if possible
6957
pull_out_semijoin_tables()
6958
join The join where to do the semi-join flattening
6961
Try to pull tables out of semi-join nests.
6964
When this function is called, the join may have several semi-join nests
6965
(possibly within different semi-join nests), but it is guaranteed that
6966
one semi-join nest does not contain another.
6969
A table can be pulled out of the semi-join nest if
6970
- It is a constant table
6974
* Pulled out tables have JOIN_TAB::emb_sj_nest == NULL (like the outer
6976
* Tables that were not pulled out have JOIN_TAB::emb_sj_nest.
6977
* Semi-join nests TableList::sj_inner_tables
6979
This operation is (and should be) performed at each PS execution since
6980
tables may become/cease to be constant across PS reexecutions.
6984
1 - Out of memory error
6986
static int pull_out_semijoin_tables(JOIN *join)
6989
List_iterator<TableList> sj_list_it(join->select_lex->sj_nests);
6991
/* Try pulling out of the each of the semi-joins */
6992
while ((sj_nest= sj_list_it++))
6994
/* Action #1: Mark the constant tables to be pulled out */
6995
table_map pulled_tables= 0;
6997
List_iterator<TableList> child_li(sj_nest->nested_join->join_list);
6999
while ((tbl= child_li++))
7003
tbl->table->reginfo.join_tab->emb_sj_nest= sj_nest;
7004
if (tbl->table->map & join->const_table_map)
7006
pulled_tables |= tbl->table->map;
7012
Action #2: Find which tables we can pull out based on
7013
update_ref_and_keys() data. Note that pulling one table out can allow
7014
us to pull out some other tables too.
7016
bool pulled_a_table;
7019
pulled_a_table= false;
7021
while ((tbl= child_li++))
7023
if (tbl->table && !(pulled_tables & tbl->table->map))
7025
if (find_eq_ref_candidate(tbl->table,
7026
sj_nest->nested_join->used_tables &
7029
pulled_a_table= true;
7030
pulled_tables |= tbl->table->map;
7034
} while (pulled_a_table);
7037
if ((sj_nest)->nested_join->used_tables == pulled_tables)
7039
(sj_nest)->sj_inner_tables= 0;
7040
while ((tbl= child_li++))
7043
tbl->table->reginfo.join_tab->emb_sj_nest= NULL;
7048
/* Record the bitmap of inner tables, mark the inner tables */
7049
table_map inner_tables=(sj_nest)->nested_join->used_tables &
7051
(sj_nest)->sj_inner_tables= inner_tables;
7052
while ((tbl= child_li++))
7056
if (inner_tables & tbl->table->map)
7057
tbl->table->reginfo.join_tab->emb_sj_nest= (sj_nest);
7059
tbl->table->reginfo.join_tab->emb_sj_nest= NULL;
7068
SemiJoinDuplicateElimination: Weed out duplicate row combinations
7071
do_sj_dups_weedout()
7075
1 The row combination is a duplicate (discard it)
7076
0 The row combination is not a duplicate (continue)
7078
static int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl)
7081
SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
7082
SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
7083
unsigned char *ptr= sjtbl->tmp_table->record[0] + 1;
7084
unsigned char *nulls_ptr= ptr;
7086
/* Put the the rowids tuple into table->record[0]: */
7088
// 1. Store the length
7089
if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
7091
*ptr= (unsigned char)(sjtbl->rowid_len + sjtbl->null_bytes);
7096
int2store(ptr, sjtbl->rowid_len + sjtbl->null_bytes);
7100
// 2. Zero the null bytes
7101
if (sjtbl->null_bytes)
7103
memset(ptr, 0, sjtbl->null_bytes);
7104
ptr += sjtbl->null_bytes;
7107
// 3. Put the rowids
7108
for (uint32_t i=0; tab != tab_end; tab++, i++)
7110
handler *h= tab->join_tab->table->file;
7111
if (tab->join_tab->table->maybe_null && tab->join_tab->table->null_row)
7113
/* It's a NULL-complemented row */
7114
*(nulls_ptr + tab->null_byte) |= tab->null_bit;
7115
memset(ptr + tab->rowid_offset, 0, h->ref_length);
7119
/* Copy the rowid value */
7120
if (tab->join_tab->rowid_keep_flags & JOIN_TAB::CALL_POSITION)
7121
h->position(tab->join_tab->table->record[0]);
7122
memcpy(ptr + tab->rowid_offset, h->ref, h->ref_length);
7126
error= sjtbl->tmp_table->file->ha_write_row(sjtbl->tmp_table->record[0]);
7129
/* create_myisam_from_heap will generate error if needed */
7130
if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
7131
create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo,
7132
&sjtbl->recinfo, error, 1))
7134
//return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
6135
7140
static void free_blobs(Field **ptr)
6137
7142
for (; *ptr ; ptr++)