45
42
#include "drizzled/join_cache.h"
46
43
#include "drizzled/show.h"
47
44
#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"
61
#include "drizzled/plugin/storage_engine.h"
63
#include <drizzled/debug.h>
45
#include "mysys/my_bit.h"
65
47
#include <algorithm>
67
49
using namespace std;
71
extern plugin::StorageEngine *heap_engine;
73
51
/** Declarations of static functions used in this source file. */
74
static bool make_group_fields(Join *main_join, Join *curr_join);
75
static void calc_group_buffer(Join *join, Order *group);
76
static bool alloc_group_fields(Join *join, Order *group);
77
static uint32_t cache_record_length(Join *join, uint32_t index);
78
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
79
static bool get_best_combination(Join *join);
80
static void set_position(Join *join,
83
optimizer::KeyUse *key);
84
static bool choose_plan(Join *join,table_map join_tables);
85
static void best_access_path(Join *join, JoinTable *s,
52
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
53
static void calc_group_buffer(JOIN *join,order_st *group);
54
static bool alloc_group_fields(JOIN *join,order_st *group);
56
TODO: 'find_best' is here only temporarily until 'greedy_search' is
59
static bool find_best(JOIN *join,table_map rest_tables,uint32_t index, double record_count,double read_time);
60
static uint32_t cache_record_length(JOIN *join, uint32_t index);
61
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
62
static bool get_best_combination(JOIN *join);
63
static void set_position(JOIN *join,uint32_t index,JoinTable *table,KeyUse *key);
64
static bool choose_plan(JOIN *join,table_map join_tables);
65
static void best_access_path(JOIN *join, JoinTable *s,
87
67
table_map remaining_tables,
89
69
double record_count,
91
static void optimize_straight_join(Join *join, table_map join_tables);
92
static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
93
static bool best_extension_by_limited_search(Join *join,
71
static void optimize_straight_join(JOIN *join, table_map join_tables);
72
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
73
static bool best_extension_by_limited_search(JOIN *join,
94
74
table_map remaining_tables,
96
76
double record_count,
99
79
uint32_t prune_level);
100
static uint32_t determine_search_depth(Join* join);
101
static bool make_simple_join(Join *join,Table *tmp_table);
102
static void make_outerjoin_info(Join *join);
103
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
104
static bool make_join_readinfo(Join *join);
105
static void update_depend_map(Join *join);
106
static void update_depend_map(Join *join, Order *order);
107
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
108
static int return_zero_rows(Join *join,
80
static uint32_t determine_search_depth(JOIN* join);
81
static bool make_simple_join(JOIN *join,Table *tmp_table);
82
static void make_outerjoin_info(JOIN *join);
83
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
84
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
85
static void update_depend_map(JOIN *join);
86
static void update_depend_map(JOIN *join, order_st *order);
87
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
88
static int return_zero_rows(JOIN *join,
109
89
select_result *res,
110
90
TableList *tables,
111
91
List<Item> &fields,
122
102
List<Item> &fields,
123
103
List<Item> &all_fields,
127
107
bool *hidden_group_fields);
128
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
108
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
129
109
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
130
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
110
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
131
111
static void reset_nj_counters(List<TableList> *join_list);
132
static bool test_if_subpart(Order *a,Order *b);
112
static bool test_if_subpart(order_st *a,order_st *b);
133
113
static void restore_prev_nj_state(JoinTable *last);
114
static uint32_t make_join_orderinfo(JOIN *join);
134
115
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
135
116
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
137
Join::Join(Session *session_arg,
138
List<Item> &fields_arg,
139
uint64_t select_options_arg,
140
select_result *result_arg) :
152
sort_and_group(false),
156
no_field_update(false),
158
resume_nested_loop(false),
159
no_const_tables(false),
160
select_distinct(false),
161
group_optimized_away(false),
165
skip_sort_order(false),
169
hidden_group_fields(false),
171
found_const_table_map(0),
178
fetch_limit(HA_POS_ERROR),
179
session(session_arg),
180
fields_list(fields_arg),
185
exec_tmp_table1(NULL),
186
exec_tmp_table2(NULL),
191
having_history(NULL),
192
select_options(select_options_arg),
194
lock(session_arg->lock),
196
all_fields(fields_arg),
200
ref_pointer_array(NULL),
205
ref_pointer_array_size(0),
206
zero_result_cause(NULL),
209
join_tab_reexec(NULL)
211
select_distinct= test(select_options & SELECT_DISTINCT);
212
if (&fields_list != &fields_arg) /* only copy if not same*/
213
fields_list= fields_arg;
214
memset(&keyuse, 0, sizeof(keyuse));
215
tmp_table_param.init();
216
tmp_table_param.end_write_records= HA_POS_ERROR;
217
rollup.setState(Rollup::STATE_NONE);
221
* This method is currently only used when a subselect EXPLAIN is performed.
222
* I pulled out the init() method and have simply reset the values to what
223
* was previously in the init() method. See the note about the hack in
226
void Join::reset(Session *session_arg,
227
List<Item> &fields_arg,
228
uint64_t select_options_arg,
229
select_result *result_arg)
242
sort_and_group= false;
246
no_field_update= false;
248
resume_nested_loop= false;
249
no_const_tables= false;
250
select_distinct= false;
251
group_optimized_away= false;
255
skip_sort_order= false;
259
hidden_group_fields= false;
261
found_const_table_map= 0;
268
fetch_limit= HA_POS_ERROR;
269
session= session_arg;
270
fields_list= fields_arg;
275
exec_tmp_table1= NULL;
276
exec_tmp_table2= NULL;
281
having_history= NULL;
282
select_options= select_options_arg;
284
lock= session_arg->lock;
286
all_fields= fields_arg;
290
ref_pointer_array= NULL;
295
ref_pointer_array_size= 0;
296
zero_result_cause= NULL;
299
join_tab_reexec= NULL;
300
select_distinct= test(select_options & SELECT_DISTINCT);
301
if (&fields_list != &fields_arg) /* only copy if not same*/
302
fields_list= fields_arg;
303
memset(&keyuse, 0, sizeof(keyuse));
304
tmp_table_param.init();
305
tmp_table_param.end_write_records= HA_POS_ERROR;
306
rollup.setState(Rollup::STATE_NONE);
309
bool Join::is_top_level_join() const
311
return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
312
select_lex == unit->fake_select_lex));
316
119
Prepare of whole select (including sub queries in future).
762
555
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
764
557
zero_result_cause= "no matching row in const table";
765
goto setup_subq_exit;
767
561
if (!(session->options & OPTION_BIG_SELECTS) &&
768
562
best_read > (double) session->variables.max_join_size &&
769
563
!(select_options & SELECT_DESCRIBE))
564
{ /* purecov: inspected */
771
565
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
775
569
if (const_tables && !(select_options & SELECT_NO_UNLOCK))
776
session->unlockSomeTables(table, const_tables);
570
mysql_unlock_some_tables(session, table, const_tables);
777
571
if (!conds && outer_join)
779
573
/* Handle the case where we have an OUTER JOIN without a WHERE */
780
574
conds=new Item_int((int64_t) 1,1); // Always true
782
select= optimizer::make_select(*table, const_table_map,
783
const_table_map, conds, 1, &error);
576
select= make_select(*table, const_table_map,
577
const_table_map, conds, 1, &error);
579
{ /* purecov: inspected */
580
error= -1; /* purecov: inspected */
875
668
We have found that grouping can be removed since groups correspond to
876
669
only one row anyway, but we still have to guarantee correct result
877
670
order. The line below effectively rewrites the query from GROUP BY
878
<fields> to ORDER BY <fields>. There are two exceptions:
671
<fields> to order_st BY <fields>. There are two exceptions:
879
672
- if skip_sort_order is set (see above), then we can simply skip
881
- we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
674
- we can only rewrite order_st BY if the order_st BY fields are 'compatible'
882
675
with the GROUP BY ones, i.e. either one is a prefix of another.
883
We only check if the ORDER BY is a prefix of GROUP BY. In this case
676
We only check if the order_st BY is a prefix of GROUP BY. In this case
884
677
test_if_subpart() copies the ASC/DESC attributes from the original
886
679
If GROUP BY is a prefix of order_st BY, then it is safe to leave
889
if (! order || test_if_subpart(group_list, order))
682
if (!order || test_if_subpart(group_list, order))
890
683
order= skip_sort_order ? 0 : group_list;
892
685
If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
1969
1755
is called after all rows are sent, but before EOF packet is sent.
1971
1757
For a simple SELECT with no subqueries this function performs a full
1972
cleanup of the Join and calls unlockReadTables to free used base
1758
cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1975
If a Join is executed for a subquery or if it has a subquery, we can't
1761
If a JOIN is executed for a subquery or if it has a subquery, we can't
1976
1762
do the full cleanup and need to do a partial cleanup only.
1977
- If a Join is not the top level join, we must not unlock the tables
1763
- If a JOIN is not the top level join, we must not unlock the tables
1978
1764
because the outer select may not have been evaluated yet, and we
1979
1765
can't unlock only selected tables of a query.
1980
- Additionally, if this Join corresponds to a correlated subquery, we
1766
- Additionally, if this JOIN corresponds to a correlated subquery, we
1981
1767
should not free quick selects and join buffers because they will be
1982
1768
needed for the next execution of the correlated subquery.
1983
- However, if this is a Join for a [sub]select, which is not
1769
- However, if this is a JOIN for a [sub]select, which is not
1984
1770
a correlated subquery itself, but has subqueries, we can free it
1985
fully and also free Joins of all its subqueries. The exception
1771
fully and also free JOINs of all its subqueries. The exception
1986
1772
is a subquery in SELECT list, e.g: @n
1987
1773
SELECT a, (select cmax(b) from t1) group by c @n
1988
1774
This subquery will not be evaluated at first sweep and its value will
2226
2003
((Item_sum *)item)->depended_from() == select_lex))
2227
2004
*func++= (Item_sum*) item;
2229
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2006
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2231
rollup.setState(Rollup::STATE_READY);
2008
rollup.state= ROLLUP::STATE_READY;
2232
2009
if (rollup_make_fields(field_list, send_fields, &func))
2233
return true; // Should never happen
2010
return(true); // Should never happen
2235
else if (rollup.getState() == Rollup::STATE_NONE)
2012
else if (rollup.state == ROLLUP::STATE_NONE)
2237
2014
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2015
sum_funcs_end[i]= func;
2240
else if (rollup.getState() == Rollup::STATE_READY)
2017
else if (rollup.state == ROLLUP::STATE_READY)
2241
2018
return(false); // Don't put end marker
2242
2019
*func=0; // End marker
2246
2023
/** Allocate memory needed for other rollup functions. */
2247
bool Join::rollup_init()
2024
bool JOIN::rollup_init()
2249
2027
Item **ref_array;
2251
2029
tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2252
rollup.setState(Rollup::STATE_INITED);
2030
rollup.state= ROLLUP::STATE_INITED;
2255
2033
Create pointers to the different sum function groups
2258
2036
tmp_table_param.group_parts= send_group_parts;
2260
rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
2262
sizeof(List<Item>) +
2263
ref_pointer_array_size)
2264
* send_group_parts ));
2265
if (! rollup.getNullItems())
2038
if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2040
sizeof(List<Item>) +
2041
ref_pointer_array_size)
2042
* send_group_parts )))
2270
rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
2271
rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
2272
ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
2045
rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
2046
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
2047
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2275
2050
Prepare space for field list for the different levels
2276
2051
These will be filled up in rollup_make_fields()
2278
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2053
for (i= 0 ; i < send_group_parts ; i++)
2280
rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2281
List<Item> *rollup_fields= &rollup.getFields()[i];
2055
rollup.null_items[i]= new (session->mem_root) Item_null_result();
2056
List<Item> *rollup_fields= &rollup.fields[i];
2282
2057
rollup_fields->empty();
2283
rollup.getRefPointerArrays()[i]= ref_array;
2058
rollup.ref_pointer_arrays[i]= ref_array;
2284
2059
ref_array+= all_fields.elements;
2287
for (uint32_t i= 0 ; i < send_group_parts; i++)
2061
for (i= 0 ; i < send_group_parts; i++)
2289
for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2291
rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2063
for (j=0 ; j < fields_list.elements ; j++)
2064
rollup.fields[i].push_back(rollup.null_items[i]);
2295
2066
List_iterator<Item> it(all_fields);
2297
2068
while ((item= it++))
2070
order_st *group_tmp;
2300
2071
bool found_in_group= 0;
2302
2073
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2537
2307
1 if write_data_failed()
2539
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2309
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2541
for (uint32_t i= send_group_parts ; i-- > idx ; )
2312
for (i= send_group_parts ; i-- > idx ; )
2543
2314
/* Get reference pointers to sum functions in place */
2544
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2545
ref_pointer_array_size);
2315
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2316
ref_pointer_array_size);
2546
2317
if ((!having || having->val_int()))
2548
2319
int write_error;
2550
List_iterator_fast<Item> it(rollup.getFields()[i]);
2321
List_iterator_fast<Item> it(rollup.fields[i]);
2551
2322
while ((item= it++))
2553
2324
if (item->type() == Item::NULL_ITEM && item->is_result_field())
2554
2325
item->save_in_result_field(1);
2556
2327
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2557
if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
2328
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
2559
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2330
if (create_myisam_from_heap(session, table_arg,
2331
tmp_table_param.start_recinfo,
2332
&tmp_table_param.recinfo,
2564
2338
/* Restore ref_pointer_array */
2565
2339
set_items_ref_array(current_ref_pointer_array);
2608
Cache constant expressions in WHERE, HAVING, ON conditions.
2611
void Join::cache_const_exprs()
2613
bool cache_flag= false;
2614
bool *analyzer_arg= &cache_flag;
2616
/* No need in cache if all tables are constant. */
2617
if (const_tables == tables)
2621
conds->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2622
&Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2625
having->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2626
&Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2628
for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
2630
if (*tab->on_expr_ref)
2633
(*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
2634
(unsigned char **)&analyzer_arg,
2635
&Item::cache_const_expr_transformer,
2636
(unsigned char *)&cache_flag);
2644
2383
Process one record of the nested loop join.
2999
2731
return NESTED_LOOP_OK;
3002
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
2734
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
3004
2736
Table *table= join->tmp_table;
3006
if (join->session->getKilled()) // Aborted by user
2738
if (join->session->killed) // Aborted by user
3008
2740
join->session->send_kill_message();
3009
return NESTED_LOOP_KILLED;
2741
return NESTED_LOOP_KILLED; /* purecov: inspected */
3011
2743
if (!end_of_records)
3013
2745
copy_fields(&join->tmp_table_param);
3014
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3015
return NESTED_LOOP_ERROR;
2746
copy_funcs(join->tmp_table_param.items_to_copy);
3016
2747
if (!join->having || join->having->val_int())
3019
2750
join->found_records++;
3020
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2751
if ((error=table->file->ha_write_row(table->record[0])))
3022
if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
3024
return NESTED_LOOP_OK;
3027
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3028
return NESTED_LOOP_ERROR; // Table is_full error
2753
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
2755
if (create_myisam_from_heap(join->session, table,
2756
join->tmp_table_param.start_recinfo,
2757
&join->tmp_table_param.recinfo,
2759
return NESTED_LOOP_ERROR; // Not a table_is_full error
2760
table->s->uniques= 0; // To ensure rows are the same
3030
2762
if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
3067
2799
if (item->maybe_null)
3068
2800
group->buff[-1]= (char) group->field->is_null();
3070
if (!table->cursor->index_read_map(table->getUpdateRecord(),
2802
if (!table->file->index_read_map(table->record[1],
3071
2803
join->tmp_table_param.group_buff,
3073
2805
HA_READ_KEY_EXACT))
3074
2806
{ /* Update old record */
3075
2807
table->restoreRecord();
3076
2808
update_tmptable_sum_func(join->sum_funcs,table);
3077
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3078
table->getInsertRecord())))
2809
if ((error= table->file->ha_update_row(table->record[1],
3080
table->print_error(error,MYF(0));
3081
return NESTED_LOOP_ERROR;
2812
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2813
return NESTED_LOOP_ERROR; /* purecov: inspected */
3083
2815
return NESTED_LOOP_OK;
3088
2820
We can't copy all data as the key may have different format
3089
2821
as the row data (for example as with VARCHAR keys)
3091
KeyPartInfo *key_part;
2823
KEY_PART_INFO *key_part;
3092
2824
for (group=table->group,key_part=table->key_info[0].key_part;
3094
2826
group=group->next,key_part++)
3096
2828
if (key_part->null_bit)
3097
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
2829
memcpy(table->record[0]+key_part->offset, group->buff, 1);
3099
2831
init_tmptable_sum_functions(join->sum_funcs);
3100
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3101
return NESTED_LOOP_ERROR;
3102
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2832
copy_funcs(join->tmp_table_param.items_to_copy);
2833
if ((error=table->file->ha_write_row(table->record[0])))
3104
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3105
return NESTED_LOOP_ERROR; // Table is_full error
2835
if (create_myisam_from_heap(join->session, table,
2836
join->tmp_table_param.start_recinfo,
2837
&join->tmp_table_param.recinfo,
2839
return NESTED_LOOP_ERROR; // Not a table_is_full error
2840
/* Change method to update rows */
2841
table->file->ha_index_init(0, 0);
2842
join->join_tab[join->tables-1].next_select= end_unique_update;
3107
2844
join->send_records++;
3108
2845
return NESTED_LOOP_OK;
3111
2848
/** Like end_update, but this is done with unique constraints instead of keys. */
3112
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
2849
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
3114
2851
Table *table= join->tmp_table;
3117
2854
if (end_of_records)
3118
2855
return NESTED_LOOP_OK;
3119
if (join->session->getKilled()) // Aborted by user
2856
if (join->session->killed) // Aborted by user
3121
2858
join->session->send_kill_message();
3122
return NESTED_LOOP_KILLED;
2859
return NESTED_LOOP_KILLED; /* purecov: inspected */
3125
2862
init_tmptable_sum_functions(join->sum_funcs);
3126
2863
copy_fields(&join->tmp_table_param); // Groups are copied twice.
3127
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3128
return NESTED_LOOP_ERROR;
2864
copy_funcs(join->tmp_table_param.items_to_copy);
3130
if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
2866
if (!(error= table->file->ha_write_row(table->record[0])))
3131
2867
join->send_records++; // New group
3134
if ((int) table->get_dup_key(error) < 0)
2870
if ((int) table->file->get_dup_key(error) < 0)
3136
table->print_error(error,MYF(0));
3137
return NESTED_LOOP_ERROR;
2872
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2873
return NESTED_LOOP_ERROR; /* purecov: inspected */
3139
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
2875
if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
3141
table->print_error(error,MYF(0));
3142
return NESTED_LOOP_ERROR;
2877
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2878
return NESTED_LOOP_ERROR; /* purecov: inspected */
3144
2880
table->restoreRecord();
3145
2881
update_tmptable_sum_func(join->sum_funcs,table);
3146
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3147
table->getInsertRecord())))
2882
if ((error= table->file->ha_update_row(table->record[1],
3149
table->print_error(error,MYF(0));
3150
return NESTED_LOOP_ERROR;
2885
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2886
return NESTED_LOOP_ERROR; /* purecov: inspected */
3153
2889
return NESTED_LOOP_OK;
3210
2946
case REAL_RESULT:
3211
2947
key_length+= sizeof(double);
3214
2949
case INT_RESULT:
3215
2950
key_length+= sizeof(int64_t);
3218
2952
case DECIMAL_RESULT:
3219
key_length+= class_decimal_get_binary_size(group_item->max_length -
2953
key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
2954
(group_item->decimals ? 1 : 0),
3221
2955
group_item->decimals);
3224
2957
case STRING_RESULT:
3226
enum enum_field_types type= group_item->field_type();
2959
enum enum_field_types type= group_item->field_type();
2961
As items represented as DATE/TIME fields in the group buffer
2962
have STRING_RESULT result type, we increase the length
2963
by 8 as maximum pack length of such fields.
2965
if (type == DRIZZLE_TYPE_DATE ||
2966
type == DRIZZLE_TYPE_DATETIME ||
2967
type == DRIZZLE_TYPE_TIMESTAMP)
3228
As items represented as DATE/TIME fields in the group buffer
3229
have STRING_RESULT result type, we increase the length
3230
by 8 as maximum pack length of such fields.
2974
Group strings are taken as varstrings and require an length field.
2975
A field is not yet created by create_tmp_field()
2976
and the sizes should match up.
3232
if (type == DRIZZLE_TYPE_DATE ||
3233
type == DRIZZLE_TYPE_TIME ||
3234
type == DRIZZLE_TYPE_DATETIME ||
3235
type == DRIZZLE_TYPE_MICROTIME ||
3236
type == DRIZZLE_TYPE_TIMESTAMP)
3243
Group strings are taken as varstrings and require an length field.
3244
A field is not yet created by create_tmp_field()
3245
and the sizes should match up.
3247
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
2978
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3254
2983
/* This case should never be choosen */
3256
2985
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3262
2989
if (group_item->maybe_null)
3266
2992
join->tmp_table_param.group_length=key_length+null_parts;
3267
2993
join->tmp_table_param.group_parts=parts;
3268
2994
join->tmp_table_param.group_null_parts=null_parts;
3291
static uint32_t cache_record_length(Join *join,uint32_t idx)
3019
- TODO: this function is here only temporarily until 'greedy_search' is
3020
tested and accepted.
3026
static bool find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count, double read_time)
3028
Session *session= join->session;
3029
Position partial_pos;
3030
if (session->killed)
3037
read_time+= record_count/(double) TIME_FOR_COMPARE;
3038
partial_pos= join->getPosFromPartialPlan(join->const_tables);
3039
if (join->sort_by_table &&
3040
join->sort_by_table !=
3041
partial_pos.table->table)
3043
read_time+= record_count; // We have to make a temp table
3045
if (read_time < join->best_read)
3047
join->copyPartialPlanIntoOptimalPlan(idx);
3048
join->best_read= read_time - 0.001;
3052
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
3054
return false; /* Found better before */
3058
double best_record_count= DBL_MAX;
3059
double best_read_time= DBL_MAX;
3060
for (JoinTable **pos= join->best_ref+idx ; (s= *pos) ; pos++)
3062
table_map real_table_bit= s->table->map;
3065
partial_pos= join->getPosFromPartialPlan(idx - 1);
3067
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
3068
(! idx || ! check_interleaving_with_nj(partial_pos.table, s)))
3070
double records, best;
3071
best_access_path(join, s, session, rest_tables, idx, record_count,
3073
partial_pos= join->getPosFromPartialPlan(idx);
3074
records= partial_pos.records_read;
3075
best= partial_pos.read_time;
3077
Go to the next level only if there hasn't been a better key on
3078
this level! This will cut down the search for a lot simple cases!
3080
double current_record_count= record_count * records;
3081
double current_read_time= read_time + best;
3082
if (best_record_count > current_record_count ||
3083
best_read_time > current_read_time ||
3084
(idx == join->const_tables && s->table == join->sort_by_table))
3086
if (best_record_count >= current_record_count &&
3087
best_read_time >= current_read_time &&
3088
(! (s->key_dependent & rest_tables) ||
3089
partial_pos.isConstTable()))
3091
best_record_count= current_record_count;
3092
best_read_time= current_read_time;
3094
std::swap(join->best_ref[idx], *pos);
3095
if (find_best(join,rest_tables & ~real_table_bit,idx+1,
3096
current_record_count,current_read_time))
3100
std::swap(join->best_ref[idx], *pos);
3102
restore_prev_nj_state(s);
3103
if (join->select_options & SELECT_STRAIGHT_JOIN)
3104
break; // Don't test all combinations
3110
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3293
3112
uint32_t length=0;
3294
3113
JoinTable **pos,**end;
3357
3176
Expected number of row combinations
3359
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
3178
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3361
3180
double found=1.0;
3362
optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3363
for (optimizer::Position *pos= join->getSpecificPosInPartialPlan(idx - 1);
3181
Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3182
for (Position *pos= join->getSpecificPosInPartialPlan(idx - 1);
3364
3183
pos != pos_end;
3367
if (pos->examinePosition(found_ref))
3186
if (pos->table->table->map & found_ref)
3369
found_ref|= pos->getRefDependMap();
3188
found_ref|= pos->ref_depend_map;
3371
For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
3190
For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3372
3191
with no matching row we will get position[t2].records_read==0.
3373
3192
Actually the size of output is one null-complemented row, therefore
3374
3193
we will use value of 1 whenever we get records_read==0.
3507
3324
Apply heuristic: pre-sort all access plans with respect to the number of
3508
3325
records accessed.
3510
internal::my_qsort(join->best_ref + join->const_tables,
3511
join->tables - join->const_tables, sizeof(JoinTable*),
3512
straight_join ? join_tab_cmp_straight : join_tab_cmp);
3327
my_qsort(join->best_ref + join->const_tables,
3328
join->tables - join->const_tables, sizeof(JoinTable*),
3329
straight_join ? join_tab_cmp_straight : join_tab_cmp);
3513
3330
if (straight_join)
3515
3332
optimize_straight_join(join, join_tables);
3519
if (search_depth == 0)
3520
/* Automatically determine a reasonable value for 'search_depth' */
3521
search_depth= determine_search_depth(join);
3522
if (greedy_search(join, join_tables, search_depth, prune_level))
3336
if (search_depth == MAX_TABLES+2)
3338
TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
3339
the greedy version. Will be removed when greedy_search is approved.
3341
join->best_read= DBL_MAX;
3342
if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
3347
if (search_depth == 0)
3348
/* Automatically determine a reasonable value for 'search_depth' */
3349
search_depth= determine_search_depth(join);
3350
if (greedy_search(join, join_tables, search_depth, prune_level))
3580
3409
{ /* Use key if possible */
3581
3410
Table *table= s->table;
3582
optimizer::KeyUse *keyuse= NULL;
3583
optimizer::KeyUse *start_key= NULL;
3411
KeyUse *keyuse,*start_key=0;
3584
3412
double best_records= DBL_MAX;
3585
3413
uint32_t max_key_part=0;
3587
3415
/* Test how we can use keys */
3588
3416
rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
3589
for (keyuse= s->keyuse; keyuse->getTable() == table; )
3417
for (keyuse=s->keyuse ; keyuse->table == table ;)
3591
3419
key_part_map found_part= 0;
3592
3420
table_map found_ref= 0;
3593
uint32_t key= keyuse->getKey();
3594
KeyInfo *keyinfo= table->key_info + key;
3421
uint32_t key= keyuse->key;
3422
KEY *keyinfo= table->key_info+key;
3595
3423
/* Bitmap of keyparts where the ref access is over 'keypart=const': */
3596
3424
key_part_map const_part= 0;
3597
3425
/* The or-null keypart in ref-or-null access: */
3613
3441
if 1. expression doesn't refer to forward tables
3614
3442
2. we won't get two ref-or-null's
3616
if (! (remaining_tables & keyuse->getUsedTables()) &&
3617
! (ref_or_null_part && (keyuse->getOptimizeFlags() &
3618
KEY_OPTIMIZE_REF_OR_NULL)))
3444
if (!(remaining_tables & keyuse->used_tables) &&
3445
!(ref_or_null_part && (keyuse->optimize &
3446
KEY_OPTIMIZE_REF_OR_NULL)))
3620
found_part|= keyuse->getKeypartMap();
3621
if (! (keyuse->getUsedTables() & ~join->const_table_map))
3622
const_part|= keyuse->getKeypartMap();
3448
found_part|= keyuse->keypart_map;
3449
if (!(keyuse->used_tables & ~join->const_table_map))
3450
const_part|= keyuse->keypart_map;
3624
3452
double tmp2= prev_record_reads(join, idx, (found_ref |
3625
keyuse->getUsedTables()));
3453
keyuse->used_tables));
3626
3454
if (tmp2 < best_prev_record_reads)
3628
best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
3456
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3629
3457
best_prev_record_reads= tmp2;
3631
if (rec > keyuse->getTableRows())
3632
rec= keyuse->getTableRows();
3459
if (rec > keyuse->ref_table_rows)
3460
rec= keyuse->ref_table_rows;
3634
3462
If there is one 'key_column IS NULL' expression, we can
3635
3463
use this ref_or_null optimisation of this field
3637
if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
3638
ref_or_null_part|= keyuse->getKeypartMap();
3465
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
3466
ref_or_null_part |= keyuse->keypart_map;
3642
} while (keyuse->getTable() == table && keyuse->getKey() == key &&
3643
keyuse->getKeypart() == keypart);
3644
found_ref|= best_part_found_ref;
3645
} while (keyuse->getTable() == table && keyuse->getKey() == key);
3470
} while (keyuse->table == table && keyuse->key == key &&
3471
keyuse->keypart == keypart);
3472
found_ref|= best_part_found_ref;
3473
} while (keyuse->table == table && keyuse->key == key);
3648
3476
Assume that that each key matches a proportional part of table.
4552
4377
return search_depth;
4555
static bool make_simple_join(Join *join,Table *tmp_table)
4380
static bool make_simple_join(JOIN *join,Table *tmp_table)
4557
4382
Table **tableptr;
4558
4383
JoinTable *join_tab;
4561
4386
Reuse Table * and JoinTable if already allocated by a previous call
4562
to this function through Join::exec (may happen for sub-queries).
4387
to this function through JOIN::exec (may happen for sub-queries).
4564
4389
if (!join->table_reexec)
4566
if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
4391
if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4392
return(true); /* purecov: inspected */
4568
4393
if (join->tmp_join)
4569
4394
join->tmp_join->table_reexec= join->table_reexec;
4571
4396
if (!join->join_tab_reexec)
4573
4398
if (!(join->join_tab_reexec=
4574
(JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
4576
new (join->join_tab_reexec) JoinTable();
4399
(JoinTable*) join->session->alloc(sizeof(JoinTable))))
4400
return(true); /* purecov: inspected */
4577
4401
if (join->tmp_join)
4578
4402
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
5093
4909
true - Out of memory
5095
static bool make_join_readinfo(Join *join)
4911
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4914
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
5099
for (uint32_t i= join->const_tables ; i < join->tables ; i++)
4917
for (i=join->const_tables ; i < join->tables ; i++)
5101
4919
JoinTable *tab=join->join_tab+i;
5102
4920
Table *table=tab->table;
4921
bool using_join_cache;
5103
4922
tab->read_record.table= table;
5104
tab->read_record.cursor= table->cursor;
4923
tab->read_record.file=table->file;
5105
4924
tab->next_select=sub_select; /* normal select */
5107
4926
TODO: don't always instruct first table's ref/range access method to
5108
4927
produce sorted output.
5110
4929
tab->sorted= sorted;
5111
sorted= false; // only first must be sorted
4930
sorted= 0; // only first must be sorted
5113
4931
if (tab->insideout_match_tab)
5115
if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
4933
if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
5121
optimizer::AccessMethodFactory &factory= optimizer::AccessMethodFactory::singleton();
5122
boost::shared_ptr<optimizer::AccessMethod> access_method(factory.createAccessMethod(tab->type));
5124
if (! access_method)
5128
* Is abort() the correct thing to call here? I call this here because it was what was called in
5129
* the default case for the switch statement that used to be here.
4938
switch (tab->type) {
4939
case AM_SYSTEM: // Only happens with left join
4940
table->status=STATUS_NO_RECORD;
4941
tab->read_first_record= join_read_system;
4942
tab->read_record.read_record= join_no_more_records;
4944
case AM_CONST: // Only happens with left join
4945
table->status=STATUS_NO_RECORD;
4946
tab->read_first_record= join_read_const;
4947
tab->read_record.read_record= join_no_more_records;
4948
if (table->covering_keys.test(tab->ref.key) &&
4952
table->file->extra(HA_EXTRA_KEYREAD);
4956
table->status=STATUS_NO_RECORD;
4959
delete tab->select->quick;
4960
tab->select->quick=0;
4964
tab->read_first_record= join_read_key;
4965
tab->read_record.read_record= join_no_more_records;
4966
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4969
table->file->extra(HA_EXTRA_KEYREAD);
4972
case AM_REF_OR_NULL:
4974
table->status=STATUS_NO_RECORD;
4977
delete tab->select->quick;
4978
tab->select->quick=0;
4982
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4985
table->file->extra(HA_EXTRA_KEYREAD);
4987
if (tab->type == AM_REF)
4989
tab->read_first_record= join_read_always_key;
4990
tab->read_record.read_record= tab->insideout_match_tab?
4991
join_read_next_same_diff : join_read_next_same;
4995
tab->read_first_record= join_read_always_key_or_null;
4996
tab->read_record.read_record= join_read_next_same_or_null;
5001
If previous table use cache
5002
If the incoming data set is already sorted don't use cache.
5004
table->status=STATUS_NO_RECORD;
5005
using_join_cache= false;
5006
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
5007
tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
5008
!tab->insideout_match_tab)
5010
if ((options & SELECT_DESCRIBE) ||
5011
!join_init_cache(join->session,join->join_tab+join->const_tables,
5012
i-join->const_tables))
5014
using_join_cache= true;
5015
tab[-1].next_select=sub_select_cache; /* Patch previous */
5018
/* These init changes read_record */
5019
if (tab->use_quick == 2)
5021
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
5022
tab->read_first_record= join_init_quick_read_record;
5024
status_var_increment(join->session->status_var.select_range_check_count);
5028
tab->read_first_record= join_init_read_record;
5029
if (i == join->const_tables)
5031
if (tab->select && tab->select->quick)
5034
status_var_increment(join->session->status_var.select_range_count);
5038
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5040
status_var_increment(join->session->status_var.select_scan_count);
5045
if (tab->select && tab->select->quick)
5048
status_var_increment(join->session->status_var.select_full_range_join_count);
5052
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5054
status_var_increment(join->session->status_var.select_full_join_count);
5057
if (!table->no_keyread)
5059
if (tab->select && tab->select->quick &&
5060
tab->select->quick->index != MAX_KEY && //not index_merge
5061
table->covering_keys.test(tab->select->quick->index))
5064
table->file->extra(HA_EXTRA_KEYREAD);
5066
else if (!table->covering_keys.none() &&
5067
!(tab->select && tab->select->quick))
5068
{ // Only read index tree
5069
if (!tab->insideout_match_tab)
5072
See bug #26447: "Using the clustered index for a table scan
5073
is always faster than using a secondary index".
5075
if (table->s->primary_key != MAX_KEY &&
5076
table->file->primary_key_is_clustered())
5077
tab->index= table->s->primary_key;
5079
tab->index= table->find_shortest_key(&table->covering_keys);
5081
tab->read_first_record= join_read_first;
5082
tab->type= AM_NEXT; // Read with index_first / index_next
5088
break; /* purecov: deadcode */
5091
abort(); /* purecov: deadcode */
5134
access_method->getStats(table, tab);
5137
join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
5094
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
5142
5098
/** Update the dependency map for the tables. */
5143
static void update_depend_map(Join *join)
5099
static void update_depend_map(JOIN *join)
5145
5101
JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5525
5476
if (table->on_expr)
5527
table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5528
if (table->getEmbedding())
5478
table->dep_tables|= table->on_expr->used_tables();
5479
if (table->embedding)
5530
table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
5481
table->dep_tables&= ~table->embedding->nested_join->used_tables;
5532
5483
Embedding table depends on tables used
5533
5484
in embedded on expressions.
5535
table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
5486
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5538
table->setDepTables(table->getDepTables() & ~table->table->map);
5489
table->dep_tables&= ~table->table->map;
5541
5492
if (prev_table)
5543
//If this is straight join, set prev table to be dependent on all tables
5544
//from this nested join, so that correct join order is selected.
5545
if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
5546
prev_table->straight)
5547
prev_table->setDepTables(prev_table->getDepTables() | used_tables);
5494
/* The order of tables is reverse: prev_table follows table */
5495
if (prev_table->straight)
5496
prev_table->dep_tables|= used_tables;
5548
5497
if (prev_table->on_expr)
5550
prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5551
table_map prev_used_tables= prev_table->getNestedJoin() ?
5552
prev_table->getNestedJoin()->used_tables :
5499
prev_table->dep_tables|= table->on_expr_dep_tables;
5500
table_map prev_used_tables= prev_table->nested_join ?
5501
prev_table->nested_join->used_tables :
5553
5502
prev_table->table->map;
5555
5504
If on expression contains only references to inner tables
5611
5560
join->unit->select_limit_cnt= 1; // Only send first row
5614
Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
5563
Field **first_field=entry->field+entry->s->fields - field_count;
5615
5564
offset= (field_count ?
5616
entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5617
reclength= entry->getShare()->getRecordLength() - offset;
5565
entry->field[entry->s->fields - field_count]->
5566
offset(entry->record[0]) : 0);
5567
reclength= entry->s->reclength-offset;
5619
5569
entry->free_io_cache(); // Safety
5620
entry->cursor->info(HA_STATUS_VARIABLE);
5621
if (entry->getShare()->db_type() == heap_engine ||
5622
(!entry->getShare()->blob_fields &&
5623
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5624
session->variables.sortbuff_size)))
5570
entry->file->info(HA_STATUS_VARIABLE);
5571
if (entry->s->db_type() == heap_engine ||
5572
(!entry->s->blob_fields &&
5573
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
5574
session->variables.sortbuff_size)))
5626
5575
error= remove_dup_with_hash_index(join->session, entry,
5627
field_count, first_field,
5576
field_count, first_field,
5632
error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5579
error= remove_dup_with_compare(join->session, entry, first_field, offset,
5635
5582
free_blobs(first_field);
5678
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5624
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5683
uint32_t table_count;
5684
uint32_t const_count;
5686
table_map found_const_table_map;
5687
table_map all_table_map;
5688
table_map found_ref;
5692
Table **table_vector= NULL;
5693
JoinTable *stat= NULL;
5694
JoinTable *stat_end= NULL;
5696
JoinTable **stat_ref= NULL;
5697
optimizer::KeyUse *keyuse= NULL;
5698
optimizer::KeyUse *start_keyuse= NULL;
5699
table_map outer_join= 0;
5700
vector<optimizer::SargableParam> sargables;
5628
uint32_t i,table_count,const_count,key;
5629
table_map found_const_table_map, all_table_map, found_ref, refs;
5630
key_map const_ref, eq_part;
5631
Table **table_vector;
5632
JoinTable *stat,*stat_end,*s,**stat_ref;
5633
KeyUse *keyuse,*start_keyuse;
5634
table_map outer_join=0;
5635
SARGABLE_PARAM *sargables= 0;
5701
5636
JoinTable *stat_vector[MAX_TABLES+1];
5702
optimizer::Position *partial_pos;
5637
Position *partial_pos;
5704
table_count= join->tables;
5705
stat= (JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5706
stat_ref= (JoinTable**) join->session->getMemRoot()->allocate(sizeof(JoinTable*)*MAX_TABLES);
5707
table_vector= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*)*(table_count*2));
5639
table_count=join->tables;
5640
stat=(JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5641
stat_ref=(JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
5642
table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5708
5643
if (! stat || ! stat_ref || ! table_vector)
5644
return 1; // Eom /* purecov: inspected */
5711
5646
join->best_ref=stat_vector;
5726
5661
s->needed_reg.reset();
5727
5662
table_vector[i]=s->table=table=tables->table;
5728
5663
table->pos_in_table_list= tables;
5729
assert(table->cursor);
5730
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5664
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5733
table->print_error(error, MYF(0));
5667
table->file->print_error(error, MYF(0));
5736
5670
table->quick_keys.reset();
5737
5671
table->reginfo.join_tab=s;
5738
5672
table->reginfo.not_exists_optimize=0;
5739
5673
memset(table->const_key_parts, 0,
5740
sizeof(key_part_map)*table->getShare()->sizeKeys());
5674
sizeof(key_part_map)*table->s->keys);
5741
5675
all_table_map|= table->map;
5743
5677
s->info=0; // For describe
5745
s->dependent= tables->getDepTables();
5679
s->dependent= tables->dep_tables;
5746
5680
s->key_dependent= 0;
5747
table->quick_condition_rows= table->cursor->stats.records;
5681
if (tables->schema_table)
5682
table->file->stats.records= 2;
5683
table->quick_condition_rows= table->file->stats.records;
5749
5685
s->on_expr_ref= &tables->on_expr;
5750
5686
if (*s->on_expr_ref)
5752
5688
/* s is the only inner table of an outer join */
5753
if (!table->cursor->stats.records && !embedding)
5689
if (!table->file->stats.records && !embedding)
5754
5690
{ // Empty table
5755
5691
s->dependent= 0; // Ignore LEFT JOIN depend.
5756
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5692
set_position(join,const_count++,s,(KeyUse*) 0);
5759
5695
outer_join|= table->map;
5760
5696
s->embedding_map.reset();
5761
for (;embedding; embedding= embedding->getEmbedding())
5762
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5697
for (;embedding; embedding= embedding->embedding)
5698
s->embedding_map|= embedding->nested_join->nj_map;
5765
if (embedding && !(false && ! embedding->getEmbedding()))
5701
if (embedding && !(false && ! embedding->embedding))
5767
5703
/* s belongs to a nested join, maybe to several embedded joins */
5768
5704
s->embedding_map.reset();
5771
NestedJoin *nested_join= embedding->getNestedJoin();
5707
nested_join_st *nested_join= embedding->nested_join;
5772
5708
s->embedding_map|= nested_join->nj_map;
5773
s->dependent|= embedding->getDepTables();
5774
embedding= embedding->getEmbedding();
5709
s->dependent|= embedding->dep_tables;
5710
embedding= embedding->embedding;
5775
5711
outer_join|= nested_join->used_tables;
5777
5713
while (embedding);
5780
if ((table->cursor->stats.records <= 1) && !s->dependent &&
5781
(table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5716
if ((table->file->stats.records <= 1) && !s->dependent &&
5717
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5782
5718
!join->no_const_tables)
5784
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5720
set_position(join,const_count++,s,(KeyUse*) 0);
5787
5723
stat_vector[i]=0;
5838
5760
if (conds || outer_join)
5839
5761
if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
5840
5762
conds, join->cond_equal,
5841
~outer_join, join->select_lex, sargables))
5763
~outer_join, join->select_lex, &sargables))
5844
5766
/* Read tables with 0 or 1 rows (system tables) */
5845
5767
join->const_table_map= 0;
5847
optimizer::Position *p_pos= join->getFirstPosInPartialPlan();
5848
optimizer::Position *p_end= join->getSpecificPosInPartialPlan(const_count);
5769
Position *p_pos= join->getFirstPosInPartialPlan();
5770
Position *p_end= join->getSpecificPosInPartialPlan(const_count);
5849
5771
while (p_pos < p_end)
5852
s= p_pos->getJoinTable();
5853
5775
s->type= AM_SYSTEM;
5854
5776
join->const_table_map|=s->table->map;
5855
if ((tmp= s->joinReadConstTable(p_pos)))
5777
if ((tmp= join_read_const_table(s, p_pos)))
5858
5780
return 1; // Fatal error
5896
5818
TODO. Apply single row substitution to null complemented inner tables
5897
5819
for nested outer join operations.
5899
while (keyuse->getTable() == table)
5821
while (keyuse->table == table)
5901
if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
5902
keyuse->getVal()->is_null() && keyuse->isNullRejected())
5823
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
5824
keyuse->val->is_null() && keyuse->null_rejecting)
5904
5826
s->type= AM_CONST;
5905
5827
table->mark_as_null_row();
5906
5828
found_const_table_map|= table->map;
5907
5829
join->const_table_map|= table->map;
5908
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5830
set_position(join,const_count++,s,(KeyUse*) 0);
5909
5831
goto more_const_tables_found;
5917
5839
// All dep. must be constants
5918
5840
if (s->dependent & ~(found_const_table_map))
5920
if (table->cursor->stats.records <= 1L &&
5921
(table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5922
!table->pos_in_table_list->getEmbedding())
5842
if (table->file->stats.records <= 1L &&
5843
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5844
!table->pos_in_table_list->embedding)
5923
5845
{ // system table
5925
5847
s->type= AM_SYSTEM;
5926
5848
join->const_table_map|=table->map;
5927
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5849
set_position(join,const_count++,s,(KeyUse*) 0);
5928
5850
partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5929
if ((tmp= s->joinReadConstTable(partial_pos)))
5851
if ((tmp= join_read_const_table(s, partial_pos)))
5932
5854
return 1; // Fatal error
5940
5862
if ((keyuse=s->keyuse))
5942
5864
s->type= AM_REF;
5943
while (keyuse->getTable() == table)
5865
while (keyuse->table == table)
5945
start_keyuse= keyuse;
5946
key= keyuse->getKey();
5867
start_keyuse=keyuse;
5947
5869
s->keys.set(key); // QQ: remove this ?
5951
5873
eq_part.reset();
5954
if (keyuse->getVal()->type() != Item::NULL_ITEM &&
5955
! keyuse->getOptimizeFlags())
5876
if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
5957
if (! ((~found_const_table_map) & keyuse->getUsedTables()))
5958
const_ref.set(keyuse->getKeypart());
5878
if (!((~found_const_table_map) & keyuse->used_tables))
5879
const_ref.set(keyuse->keypart);
5960
refs|= keyuse->getUsedTables();
5961
eq_part.set(keyuse->getKeypart());
5881
refs|=keyuse->used_tables;
5882
eq_part.set(keyuse->keypart);
5964
} while (keyuse->getTable() == table && keyuse->getKey() == key);
5885
} while (keyuse->table == table && keyuse->key == key);
5966
5887
if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5967
! table->pos_in_table_list->getEmbedding())
5888
!table->pos_in_table_list->embedding)
5969
5890
if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
6002
5923
Update info on indexes that can be used for search lookups as
6003
5924
reading const tables may has added new sargable predicates.
6005
if (const_count && ! sargables.empty())
5926
if (const_count && sargables)
6007
vector<optimizer::SargableParam>::iterator iter= sargables.begin();
6008
while (iter != sargables.end())
5928
for( ; sargables->field ; sargables++)
6010
Field *field= (*iter).getField();
6011
JoinTable *join_tab= field->getTable()->reginfo.join_tab;
5930
Field *field= sargables->field;
5931
JoinTable *join_tab= field->table->reginfo.join_tab;
6012
5932
key_map possible_keys= field->key_start;
6013
possible_keys&= field->getTable()->keys_in_use_for_query;
6014
bool is_const= true;
6015
for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
6016
is_const&= (*iter).isConstItem(j);
5933
possible_keys&= field->table->keys_in_use_for_query;
5935
for (uint32_t j=0; j < sargables->num_values; j++)
5936
is_const&= sargables->arg_value[j]->const_item();
6018
5938
join_tab[0].const_keys|= possible_keys;
6051
5970
add_group_and_distinct_keys(join, s);
6053
5972
if (s->const_keys.any() &&
6054
!s->table->pos_in_table_list->getEmbedding())
5973
!s->table->pos_in_table_list->embedding)
6056
5975
ha_rows records;
6057
optimizer::SqlSelect *select= NULL;
6058
select= optimizer::make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
5977
select= make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
6061
5980
records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
6062
5981
s->quick=select->quick;
6063
5982
s->needed_reg=select->needed_reg;
6064
5983
select->quick=0;
6066
5984
if (records == 0 && s->table->reginfo.impossible_range)
6247
6160
Nested joins perspective: Remove the last table from the join order.
6249
The algorithm is the reciprocal of check_interleaving_with_nj(), hence
6250
parent join nest nodes are updated only when the last table in its child
6251
node is removed. The ASCII graphic below will clarify.
6253
%A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
6254
represented by the below join nest tree.
6262
t1 x [ (t2 x t3) x (t4 x t5) ]
6265
At the point in time when check_interleaving_with_nj() adds the table t5 to
6266
the query execution plan, QEP, it also directs the node named NJ2 to mark
6267
the table as covered. NJ2 does so by incrementing its @c counter
6268
member. Since all of NJ2's tables are now covered by the QEP, the algorithm
6269
proceeds up the tree to NJ1, incrementing its counter as well. All join
6270
nests are now completely covered by the QEP.
6272
restore_prev_nj_state() does the above in reverse. As seen above, the node
6273
NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
6274
that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
6275
completely covers NJ2. The removal of t5 from the partial plan will first
6276
decrement NJ2's counter to 1. It will then detect that NJ2 went from being
6277
completely to partially covered, and hence the algorithm must continue
6278
upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
6279
will however not influence NJ1 since it did not un-cover the last table in
6283
restore_prev_nj_state()
6284
last join table to remove, it is assumed to be the last in current
6289
6162
Remove the last table from the partial join order and update the nested
6290
joins counters and join->cur_embedding_map. It is ok to call this
6291
function for the first table in join order (for which
6163
joins counters and join->cur_embedding_map. It is ok to call this
6164
function for the first table in join order (for which
6292
6165
check_interleaving_with_nj has not been called)
6294
6167
@param last join table to remove, it is assumed to be the last in current
6295
6168
partial join order.
6298
6170
static void restore_prev_nj_state(JoinTable *last)
6300
TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
6301
Join *join= last->join;
6302
for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6304
NestedJoin *nest= last_emb->getNestedJoin();
6306
bool was_fully_covered= nest->is_fully_covered();
6308
if (--nest->counter_ == 0)
6309
join->cur_embedding_map&= ~nest->nj_map;
6311
if (!was_fully_covered)
6172
TableList *last_emb= last->table->pos_in_table_list->embedding;
6173
JOIN *join= last->join;
6176
if (last_emb->on_expr)
6178
if (!(--last_emb->nested_join->counter_))
6179
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6180
else if (last_emb->nested_join->join_list.elements-1 ==
6181
last_emb->nested_join->counter_)
6182
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6186
last_emb= last_emb->embedding;
6191
Determine if the set is already ordered for order_st BY, so it can
6192
disable join cache because it will change the ordering of the results.
6193
Code handles sort table that is at any location (not only first after
6194
the const tables) despite the fact that it's currently prohibited.
6195
We must disable join cache if the first non-const table alone is
6196
ordered. If there is a temp table the ordering is done as a last
6197
operation and doesn't prevent join cache usage.
6199
static uint32_t make_join_orderinfo(JOIN *join)
6203
return join->tables;
6205
for (i=join->const_tables ; i < join->tables ; i++)
6207
JoinTable *tab= join->join_tab+i;
6208
Table *table= tab->table;
6209
if ((table == join->sort_by_table &&
6210
(!join->order || join->skip_sort_order)) ||
6211
(join->sort_by_table == (Table *) 1 && i != join->const_tables))
6314
join->cur_embedding_map|= nest->nj_map;