70
70
extern std::bitset<12> test_flags;
72
72
/** 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,
73
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
74
static void calc_group_buffer(JOIN *join,order_st *group);
75
static bool alloc_group_fields(JOIN *join,order_st *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
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,
83
static bool choose_plan(JOIN *join,table_map join_tables);
84
static void best_access_path(JOIN *join, JoinTable *s,
86
86
table_map remaining_tables,
88
88
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,
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,
93
93
table_map remaining_tables,
95
95
double record_count,
98
98
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,
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_st *order);
106
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
107
static int return_zero_rows(JOIN *join,
108
108
select_result *res,
109
109
TableList *tables,
110
110
List<Item> &fields,
112
112
uint64_t select_options,
113
113
const char *info,
115
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top);
116
static int remove_duplicates(Join *join,Table *entry,List<Item> &fields, Item *having);
115
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
116
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
117
117
static int setup_without_group(Session *session,
118
118
Item **ref_pointer_array,
119
119
TableList *tables,
121
121
List<Item> &fields,
122
122
List<Item> &all_fields,
126
126
bool *hidden_group_fields);
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
127
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
128
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
129
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
129
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
130
static void reset_nj_counters(List<TableList> *join_list);
131
static bool test_if_subpart(Order *a,Order *b);
131
static bool test_if_subpart(order_st *a,order_st *b);
132
132
static void restore_prev_nj_state(JoinTable *last);
133
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
134
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
1089
1103
If this join belongs to an uncacheable subquery save
1090
1104
the original join
1092
if (select_lex->uncacheable.any() &&
1093
! is_top_level_join() &&
1106
if (select_lex->uncacheable && !is_top_level_join() &&
1094
1107
init_save_join_tab())
1104
/* Even with zero matching rows, subqueries in the HAVING clause
1105
may need to be evaluated if there are aggregate functions in the query.
1107
if (setup_subquery_materialization())
1114
1116
Restore values in temporary join.
1116
void Join::restore_tmp()
1118
void JOIN::restore_tmp()
1118
memcpy(tmp_join, this, (size_t) sizeof(Join));
1120
memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1123
1125
unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1126
select_lex->offset_limit->val_uint() :
1170
1172
@retval 0 success.
1171
1173
@retval 1 error occurred.
1173
bool Join::init_save_join_tab()
1175
bool JOIN::init_save_join_tab()
1175
if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1177
if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1178
1179
error= 0; // Ensure that tmp_join.error= 0
1184
bool Join::save_join_tab()
1184
bool JOIN::save_join_tab()
1186
if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
1186
if (!join_tab_save && select_lex->master_unit()->uncacheable)
1188
1188
if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1189
sizeof(JoinTable) * tables)))
1791
1787
is called after all rows are sent, but before EOF packet is sent.
1793
1789
For a simple SELECT with no subqueries this function performs a full
1794
cleanup of the Join and calls unlockReadTables to free used base
1790
cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1797
If a Join is executed for a subquery or if it has a subquery, we can't
1793
If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1794
do the full cleanup and need to do a partial cleanup only.
1799
- If a Join is not the top level join, we must not unlock the tables
1795
- If a JOIN is not the top level join, we must not unlock the tables
1800
1796
because the outer select may not have been evaluated yet, and we
1801
1797
can't unlock only selected tables of a query.
1802
- Additionally, if this Join corresponds to a correlated subquery, we
1798
- Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1799
should not free quick selects and join buffers because they will be
1804
1800
needed for the next execution of the correlated subquery.
1805
- However, if this is a Join for a [sub]select, which is not
1801
- However, if this is a JOIN for a [sub]select, which is not
1806
1802
a correlated subquery itself, but has subqueries, we can free it
1807
fully and also free Joins of all its subqueries. The exception
1803
fully and also free JOINs of all its subqueries. The exception
1808
1804
is a subquery in SELECT list, e.g: @n
1809
1805
SELECT a, (select cmax(b) from t1) group by c @n
1810
1806
This subquery will not be evaluated at first sweep and its value will
2817
2806
if (!end_of_records)
2819
2808
copy_fields(&join->tmp_table_param);
2820
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
return NESTED_LOOP_ERROR;
2809
copy_funcs(join->tmp_table_param.items_to_copy);
2822
2810
if (!join->having || join->having->val_int())
2825
2813
join->found_records++;
2826
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2814
if ((error=table->cursor->insertRecord(table->record[0])))
2828
2816
if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2830
return NESTED_LOOP_OK;
2833
2819
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2834
2820
return NESTED_LOOP_ERROR; // Table is_full error
2873
2859
if (item->maybe_null)
2874
2860
group->buff[-1]= (char) group->field->is_null();
2876
if (!table->cursor->index_read_map(table->getUpdateRecord(),
2862
if (!table->cursor->index_read_map(table->record[1],
2877
2863
join->tmp_table_param.group_buff,
2879
2865
HA_READ_KEY_EXACT))
2880
2866
{ /* Update old record */
2881
2867
table->restoreRecord();
2882
2868
update_tmptable_sum_func(join->sum_funcs,table);
2883
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
table->getInsertRecord())))
2869
if ((error= table->cursor->updateRecord(table->record[1],
2886
2872
table->print_error(error,MYF(0));
2887
2873
return NESTED_LOOP_ERROR;
2900
2886
group=group->next,key_part++)
2902
2888
if (key_part->null_bit)
2903
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
2889
memcpy(table->record[0]+key_part->offset, group->buff, 1);
2905
2891
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())))
2892
copy_funcs(join->tmp_table_param.items_to_copy);
2893
if ((error=table->cursor->insertRecord(table->record[0])))
2910
2895
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
2896
return NESTED_LOOP_ERROR; // Table is_full error
2942
2926
table->print_error(error,MYF(0));
2943
2927
return NESTED_LOOP_ERROR;
2945
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
2929
if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
2947
2931
table->print_error(error,MYF(0));
2948
2932
return NESTED_LOOP_ERROR;
2950
2934
table->restoreRecord();
2951
2935
update_tmptable_sum_func(join->sum_funcs,table);
2952
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
table->getInsertRecord())))
2936
if ((error= table->cursor->updateRecord(table->record[1],
2955
2939
table->print_error(error,MYF(0));
2956
2940
return NESTED_LOOP_ERROR;
3016
3000
case REAL_RESULT:
3017
3001
key_length+= sizeof(double);
3020
3003
case INT_RESULT:
3021
3004
key_length+= sizeof(int64_t);
3024
3006
case DECIMAL_RESULT:
3025
3007
key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
3008
(group_item->decimals ? 1 : 0),
3027
3009
group_item->decimals);
3030
3011
case STRING_RESULT:
3032
enum enum_field_types type= group_item->field_type();
3013
enum enum_field_types type= group_item->field_type();
3015
As items represented as DATE/TIME fields in the group buffer
3016
have STRING_RESULT result type, we increase the length
3017
by 8 as maximum pack length of such fields.
3019
if (type == DRIZZLE_TYPE_DATE ||
3020
type == DRIZZLE_TYPE_DATETIME ||
3021
type == DRIZZLE_TYPE_TIMESTAMP)
3034
As items represented as DATE/TIME fields in the group buffer
3035
have STRING_RESULT result type, we increase the length
3036
by 8 as maximum pack length of such fields.
3028
Group strings are taken as varstrings and require an length field.
3029
A field is not yet created by create_tmp_field()
3030
and the sizes should match up.
3038
if (type == DRIZZLE_TYPE_DATE ||
3039
type == DRIZZLE_TYPE_DATETIME ||
3040
type == DRIZZLE_TYPE_TIMESTAMP)
3047
Group strings are taken as varstrings and require an length field.
3048
A field is not yet created by create_tmp_field()
3049
and the sizes should match up.
3051
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3032
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3057
3037
/* This case should never be choosen */
3059
3039
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3065
3043
if (group_item->maybe_null)
3069
3046
join->tmp_table_param.group_length=key_length+null_parts;
3070
3047
join->tmp_table_param.group_parts=parts;
3071
3048
join->tmp_table_param.group_null_parts=null_parts;
4996
4967
Returns new sort order
4998
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
4969
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
5000
4971
if (join->tables == join->const_tables)
5001
4972
return change_list ? 0 : first_order; // No need to sort
5003
Order *order,**prev_ptr;
4974
order_st *order,**prev_ptr;
5004
4975
table_map first_table= join->join_tab[join->const_tables].table->map;
5005
4976
table_map not_const_tables= ~join->const_table_map;
5319
5290
if (table->on_expr)
5321
table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
if (table->getEmbedding())
5292
table->dep_tables|= table->on_expr->used_tables();
5293
if (table->embedding)
5324
table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
5295
table->dep_tables&= ~table->embedding->nested_join->used_tables;
5326
5297
Embedding table depends on tables used
5327
5298
in embedded on expressions.
5329
table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
5300
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5332
table->setDepTables(table->getDepTables() & ~table->table->map);
5303
table->dep_tables&= ~table->table->map;
5335
5306
if (prev_table)
5337
//If this is straight join, set prev table to be dependent on all tables
5338
//from this nested join, so that correct join order is selected.
5339
if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
5340
prev_table->straight)
5341
prev_table->setDepTables(prev_table->getDepTables() | used_tables);
5308
/* The order of tables is reverse: prev_table follows table */
5309
if (prev_table->straight)
5310
prev_table->dep_tables|= used_tables;
5342
5311
if (prev_table->on_expr)
5344
prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
prev_table->getNestedJoin()->used_tables :
5313
prev_table->dep_tables|= table->on_expr_dep_tables;
5314
table_map prev_used_tables= prev_table->nested_join ?
5315
prev_table->nested_join->used_tables :
5347
5316
prev_table->table->map;
5349
5318
If on expression contains only references to inner tables
5405
5374
join->unit->select_limit_cnt= 1; // Only send first row
5408
Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
5377
Field **first_field=entry->field+entry->s->fields - field_count;
5409
5378
offset= (field_count ?
5410
entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
reclength= entry->getShare()->getRecordLength() - offset;
5379
entry->field[entry->s->fields - field_count]->
5380
offset(entry->record[0]) : 0);
5381
reclength= entry->s->reclength-offset;
5413
5383
entry->free_io_cache(); // Safety
5414
5384
entry->cursor->info(HA_STATUS_VARIABLE);
5415
if (entry->getShare()->db_type() == heap_engine ||
5416
(!entry->getShare()->blob_fields &&
5385
if (entry->s->db_type() == heap_engine ||
5386
(!entry->s->blob_fields &&
5417
5387
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
session->variables.sortbuff_size)))
5388
session->variables.sortbuff_size)))
5420
5389
error= remove_dup_with_hash_index(join->session, entry,
5421
field_count, first_field,
5390
field_count, first_field,
5426
error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5393
error= remove_dup_with_compare(join->session, entry, first_field, offset,
5429
5396
free_blobs(first_field);
5553
5518
outer_join|= table->map;
5554
5519
s->embedding_map.reset();
5555
for (;embedding; embedding= embedding->getEmbedding())
5556
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5520
for (;embedding; embedding= embedding->embedding)
5521
s->embedding_map|= embedding->nested_join->nj_map;
5559
if (embedding && !(false && ! embedding->getEmbedding()))
5524
if (embedding && !(false && ! embedding->embedding))
5561
5526
/* s belongs to a nested join, maybe to several embedded joins */
5562
5527
s->embedding_map.reset();
5565
nested_join_st *nested_join= embedding->getNestedJoin();
5530
nested_join_st *nested_join= embedding->nested_join;
5566
5531
s->embedding_map|= nested_join->nj_map;
5567
s->dependent|= embedding->getDepTables();
5568
embedding= embedding->getEmbedding();
5532
s->dependent|= embedding->dep_tables;
5533
embedding= embedding->embedding;
5569
5534
outer_join|= nested_join->used_tables;
5571
5536
while (embedding);
6026
5989
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
5991
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
5992
joins counters and join->cur_embedding_map. It is ok to call this
5993
function for the first table in join order (for which
6071
5994
check_interleaving_with_nj has not been called)
6073
5996
@param last join table to remove, it is assumed to be the last in current
6074
5997
partial join order.
6077
5999
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())
6001
TableList *last_emb= last->table->pos_in_table_list->embedding;
6002
JOIN *join= last->join;
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)
6093
join->cur_embedding_map|= nest->nj_map;
6005
if (last_emb->on_expr)
6007
if (!(--last_emb->nested_join->counter_))
6008
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6009
else if (last_emb->nested_join->join_list.elements-1 ==
6010
last_emb->nested_join->counter_)
6011
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6015
last_emb= last_emb->embedding;
6098
6021
Create a condition for a const reference and add this to the
6099
6022
currenct select for the table.