48
45
#include "drizzled/optimizer/position.h"
49
46
#include "drizzled/optimizer/sargable_param.h"
50
47
#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>
48
#include "mysys/my_bit.h"
65
50
#include <algorithm>
67
52
using namespace std;
71
extern plugin::StorageEngine *heap_engine;
53
using namespace drizzled;
73
55
/** 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,
56
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
57
static void calc_group_buffer(JOIN *join,order_st *group);
58
static bool alloc_group_fields(JOIN *join,order_st *group);
59
static uint32_t cache_record_length(JOIN *join, uint32_t index);
60
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
61
static bool get_best_combination(JOIN *join);
62
static void set_position(JOIN *join,
83
65
optimizer::KeyUse *key);
84
static bool choose_plan(Join *join,table_map join_tables);
85
static void best_access_path(Join *join, JoinTable *s,
66
static bool choose_plan(JOIN *join,table_map join_tables);
67
static void best_access_path(JOIN *join, JoinTable *s,
87
69
table_map remaining_tables,
89
71
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,
73
static void optimize_straight_join(JOIN *join, table_map join_tables);
74
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
75
static bool best_extension_by_limited_search(JOIN *join,
94
76
table_map remaining_tables,
96
78
double record_count,
99
81
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,
82
static uint32_t determine_search_depth(JOIN* join);
83
static bool make_simple_join(JOIN *join,Table *tmp_table);
84
static void make_outerjoin_info(JOIN *join);
85
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
86
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
87
static void update_depend_map(JOIN *join);
88
static void update_depend_map(JOIN *join, order_st *order);
89
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
90
static int return_zero_rows(JOIN *join,
109
91
select_result *res,
110
92
TableList *tables,
111
93
List<Item> &fields,
122
104
List<Item> &fields,
123
105
List<Item> &all_fields,
127
109
bool *hidden_group_fields);
128
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
110
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
129
111
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);
112
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
131
113
static void reset_nj_counters(List<TableList> *join_list);
132
static bool test_if_subpart(Order *a,Order *b);
114
static bool test_if_subpart(order_st *a,order_st *b);
133
115
static void restore_prev_nj_state(JoinTable *last);
116
static uint32_t make_join_orderinfo(JOIN *join);
134
117
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
135
118
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
121
Prepare of whole select (including sub queries in future).
762
557
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
764
559
zero_result_cause= "no matching row in const table";
765
goto setup_subq_exit;
767
563
if (!(session->options & OPTION_BIG_SELECTS) &&
768
564
best_read > (double) session->variables.max_join_size &&
769
565
!(select_options & SELECT_DESCRIBE))
566
{ /* purecov: inspected */
771
567
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
775
571
if (const_tables && !(select_options & SELECT_NO_UNLOCK))
776
session->unlockSomeTables(table, const_tables);
572
mysql_unlock_some_tables(session, table, const_tables);
777
573
if (!conds && outer_join)
779
575
/* Handle the case where we have an OUTER JOIN without a WHERE */
780
576
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);
578
select= make_select(*table, const_table_map,
579
const_table_map, conds, 1, &error);
581
{ /* purecov: inspected */
582
error= -1; /* purecov: inspected */
875
670
We have found that grouping can be removed since groups correspond to
876
671
only one row anyway, but we still have to guarantee correct result
877
672
order. The line below effectively rewrites the query from GROUP BY
878
<fields> to ORDER BY <fields>. There are two exceptions:
673
<fields> to order_st BY <fields>. There are two exceptions:
879
674
- 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'
676
- we can only rewrite order_st BY if the order_st BY fields are 'compatible'
882
677
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
678
We only check if the order_st BY is a prefix of GROUP BY. In this case
884
679
test_if_subpart() copies the ASC/DESC attributes from the original
886
681
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))
684
if (!order || test_if_subpart(group_list, order))
890
685
order= skip_sort_order ? 0 : group_list;
892
687
If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
1969
1757
is called after all rows are sent, but before EOF packet is sent.
1971
1759
For a simple SELECT with no subqueries this function performs a full
1972
cleanup of the Join and calls unlockReadTables to free used base
1760
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
1763
If a JOIN is executed for a subquery or if it has a subquery, we can't
1976
1764
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
1765
- If a JOIN is not the top level join, we must not unlock the tables
1978
1766
because the outer select may not have been evaluated yet, and we
1979
1767
can't unlock only selected tables of a query.
1980
- Additionally, if this Join corresponds to a correlated subquery, we
1768
- Additionally, if this JOIN corresponds to a correlated subquery, we
1981
1769
should not free quick selects and join buffers because they will be
1982
1770
needed for the next execution of the correlated subquery.
1983
- However, if this is a Join for a [sub]select, which is not
1771
- However, if this is a JOIN for a [sub]select, which is not
1984
1772
a correlated subquery itself, but has subqueries, we can free it
1985
fully and also free Joins of all its subqueries. The exception
1773
fully and also free JOINs of all its subqueries. The exception
1986
1774
is a subquery in SELECT list, e.g: @n
1987
1775
SELECT a, (select cmax(b) from t1) group by c @n
1988
1776
This subquery will not be evaluated at first sweep and its value will
2226
2005
((Item_sum *)item)->depended_from() == select_lex))
2227
2006
*func++= (Item_sum*) item;
2229
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2008
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2231
rollup.setState(Rollup::STATE_READY);
2010
rollup.state= ROLLUP::STATE_READY;
2232
2011
if (rollup_make_fields(field_list, send_fields, &func))
2233
return true; // Should never happen
2012
return(true); // Should never happen
2235
else if (rollup.getState() == Rollup::STATE_NONE)
2014
else if (rollup.state == ROLLUP::STATE_NONE)
2237
2016
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2017
sum_funcs_end[i]= func;
2240
else if (rollup.getState() == Rollup::STATE_READY)
2019
else if (rollup.state == ROLLUP::STATE_READY)
2241
2020
return(false); // Don't put end marker
2242
2021
*func=0; // End marker
2246
2025
/** Allocate memory needed for other rollup functions. */
2247
bool Join::rollup_init()
2026
bool JOIN::rollup_init()
2249
2029
Item **ref_array;
2251
2031
tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2252
rollup.setState(Rollup::STATE_INITED);
2032
rollup.state= ROLLUP::STATE_INITED;
2255
2035
Create pointers to the different sum function groups
2258
2038
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())
2040
if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2042
sizeof(List<Item>) +
2043
ref_pointer_array_size)
2044
* 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);
2047
rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
2048
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
2049
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2275
2052
Prepare space for field list for the different levels
2276
2053
These will be filled up in rollup_make_fields()
2278
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2055
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];
2057
rollup.null_items[i]= new (session->mem_root) Item_null_result();
2058
List<Item> *rollup_fields= &rollup.fields[i];
2282
2059
rollup_fields->empty();
2283
rollup.getRefPointerArrays()[i]= ref_array;
2060
rollup.ref_pointer_arrays[i]= ref_array;
2284
2061
ref_array+= all_fields.elements;
2287
for (uint32_t i= 0 ; i < send_group_parts; i++)
2063
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]);
2065
for (j=0 ; j < fields_list.elements ; j++)
2066
rollup.fields[i].push_back(rollup.null_items[i]);
2295
2068
List_iterator<Item> it(all_fields);
2297
2070
while ((item= it++))
2072
order_st *group_tmp;
2300
2073
bool found_in_group= 0;
2302
2075
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2537
2309
1 if write_data_failed()
2539
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2311
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2541
for (uint32_t i= send_group_parts ; i-- > idx ; )
2314
for (i= send_group_parts ; i-- > idx ; )
2543
2316
/* Get reference pointers to sum functions in place */
2544
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2545
ref_pointer_array_size);
2317
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2318
ref_pointer_array_size);
2546
2319
if ((!having || having->val_int()))
2548
2321
int write_error;
2550
List_iterator_fast<Item> it(rollup.getFields()[i]);
2323
List_iterator_fast<Item> it(rollup.fields[i]);
2551
2324
while ((item= it++))
2553
2326
if (item->type() == Item::NULL_ITEM && item->is_result_field())
2554
2327
item->save_in_result_field(1);
2556
2329
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2557
if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
2330
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
2559
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2332
if (create_myisam_from_heap(session, table_arg,
2333
tmp_table_param.start_recinfo,
2334
&tmp_table_param.recinfo,
2564
2340
/* Restore ref_pointer_array */
2565
2341
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
2385
Process one record of the nested loop join.
2999
2733
return NESTED_LOOP_OK;
3002
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
2736
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
3004
2738
Table *table= join->tmp_table;
3006
if (join->session->getKilled()) // Aborted by user
2740
if (join->session->killed) // Aborted by user
3008
2742
join->session->send_kill_message();
3009
return NESTED_LOOP_KILLED;
2743
return NESTED_LOOP_KILLED; /* purecov: inspected */
3011
2745
if (!end_of_records)
3013
2747
copy_fields(&join->tmp_table_param);
3014
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3015
return NESTED_LOOP_ERROR;
2748
copy_funcs(join->tmp_table_param.items_to_copy);
3016
2749
if (!join->having || join->having->val_int())
3019
2752
join->found_records++;
3020
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2753
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
2755
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
2757
if (create_myisam_from_heap(join->session, table,
2758
join->tmp_table_param.start_recinfo,
2759
&join->tmp_table_param.recinfo,
2761
return NESTED_LOOP_ERROR; // Not a table_is_full error
2762
table->s->uniques= 0; // To ensure rows are the same
3030
2764
if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
3067
2801
if (item->maybe_null)
3068
2802
group->buff[-1]= (char) group->field->is_null();
3070
if (!table->cursor->index_read_map(table->getUpdateRecord(),
2804
if (!table->file->index_read_map(table->record[1],
3071
2805
join->tmp_table_param.group_buff,
3073
2807
HA_READ_KEY_EXACT))
3074
2808
{ /* Update old record */
3075
2809
table->restoreRecord();
3076
2810
update_tmptable_sum_func(join->sum_funcs,table);
3077
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3078
table->getInsertRecord())))
2811
if ((error= table->file->ha_update_row(table->record[1],
3080
table->print_error(error,MYF(0));
3081
return NESTED_LOOP_ERROR;
2814
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2815
return NESTED_LOOP_ERROR; /* purecov: inspected */
3083
2817
return NESTED_LOOP_OK;
3088
2822
We can't copy all data as the key may have different format
3089
2823
as the row data (for example as with VARCHAR keys)
3091
KeyPartInfo *key_part;
2825
KEY_PART_INFO *key_part;
3092
2826
for (group=table->group,key_part=table->key_info[0].key_part;
3094
2828
group=group->next,key_part++)
3096
2830
if (key_part->null_bit)
3097
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
2831
memcpy(table->record[0]+key_part->offset, group->buff, 1);
3099
2833
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())))
2834
copy_funcs(join->tmp_table_param.items_to_copy);
2835
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
2837
if (create_myisam_from_heap(join->session, table,
2838
join->tmp_table_param.start_recinfo,
2839
&join->tmp_table_param.recinfo,
2841
return NESTED_LOOP_ERROR; // Not a table_is_full error
2842
/* Change method to update rows */
2843
table->file->ha_index_init(0, 0);
2844
join->join_tab[join->tables-1].next_select= end_unique_update;
3107
2846
join->send_records++;
3108
2847
return NESTED_LOOP_OK;
3111
2850
/** 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)
2851
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
3114
2853
Table *table= join->tmp_table;
3117
2856
if (end_of_records)
3118
2857
return NESTED_LOOP_OK;
3119
if (join->session->getKilled()) // Aborted by user
2858
if (join->session->killed) // Aborted by user
3121
2860
join->session->send_kill_message();
3122
return NESTED_LOOP_KILLED;
2861
return NESTED_LOOP_KILLED; /* purecov: inspected */
3125
2864
init_tmptable_sum_functions(join->sum_funcs);
3126
2865
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;
2866
copy_funcs(join->tmp_table_param.items_to_copy);
3130
if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
2868
if (!(error= table->file->ha_write_row(table->record[0])))
3131
2869
join->send_records++; // New group
3134
if ((int) table->get_dup_key(error) < 0)
2872
if ((int) table->file->get_dup_key(error) < 0)
3136
table->print_error(error,MYF(0));
3137
return NESTED_LOOP_ERROR;
2874
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2875
return NESTED_LOOP_ERROR; /* purecov: inspected */
3139
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
2877
if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
3141
table->print_error(error,MYF(0));
3142
return NESTED_LOOP_ERROR;
2879
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2880
return NESTED_LOOP_ERROR; /* purecov: inspected */
3144
2882
table->restoreRecord();
3145
2883
update_tmptable_sum_func(join->sum_funcs,table);
3146
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3147
table->getInsertRecord())))
2884
if ((error= table->file->ha_update_row(table->record[1],
3149
table->print_error(error,MYF(0));
3150
return NESTED_LOOP_ERROR;
2887
table->file->print_error(error,MYF(0)); /* purecov: inspected */
2888
return NESTED_LOOP_ERROR; /* purecov: inspected */
3153
2891
return NESTED_LOOP_OK;
3210
2948
case REAL_RESULT:
3211
2949
key_length+= sizeof(double);
3214
2951
case INT_RESULT:
3215
2952
key_length+= sizeof(int64_t);
3218
2954
case DECIMAL_RESULT:
3219
key_length+= class_decimal_get_binary_size(group_item->max_length -
2955
key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
2956
(group_item->decimals ? 1 : 0),
3221
2957
group_item->decimals);
3224
2959
case STRING_RESULT:
3226
enum enum_field_types type= group_item->field_type();
2961
enum enum_field_types type= group_item->field_type();
2963
As items represented as DATE/TIME fields in the group buffer
2964
have STRING_RESULT result type, we increase the length
2965
by 8 as maximum pack length of such fields.
2967
if (type == DRIZZLE_TYPE_DATE ||
2968
type == DRIZZLE_TYPE_DATETIME ||
2969
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.
2976
Group strings are taken as varstrings and require an length field.
2977
A field is not yet created by create_tmp_field()
2978
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;
2980
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3254
2985
/* This case should never be choosen */
3256
2987
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3262
2991
if (group_item->maybe_null)
3266
2994
join->tmp_table_param.group_length=key_length+null_parts;
3267
2995
join->tmp_table_param.group_parts=parts;
3268
2996
join->tmp_table_param.group_null_parts=null_parts;
3580
3305
{ /* Use key if possible */
3581
3306
Table *table= s->table;
3582
optimizer::KeyUse *keyuse= NULL;
3583
optimizer::KeyUse *start_key= NULL;
3307
optimizer::KeyUse *keyuse,*start_key=0;
3584
3308
double best_records= DBL_MAX;
3585
3309
uint32_t max_key_part=0;
3587
3311
/* Test how we can use keys */
3588
3312
rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
3589
for (keyuse= s->keyuse; keyuse->getTable() == table; )
3313
for (keyuse=s->keyuse ; keyuse->table == table ;)
3591
3315
key_part_map found_part= 0;
3592
3316
table_map found_ref= 0;
3593
uint32_t key= keyuse->getKey();
3594
KeyInfo *keyinfo= table->key_info + key;
3317
uint32_t key= keyuse->key;
3318
KEY *keyinfo= table->key_info+key;
3595
3319
/* Bitmap of keyparts where the ref access is over 'keypart=const': */
3596
3320
key_part_map const_part= 0;
3597
3321
/* The or-null keypart in ref-or-null access: */
3613
3337
if 1. expression doesn't refer to forward tables
3614
3338
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)))
3340
if (!(remaining_tables & keyuse->used_tables) &&
3341
!(ref_or_null_part && (keyuse->optimize &
3342
KEY_OPTIMIZE_REF_OR_NULL)))
3620
found_part|= keyuse->getKeypartMap();
3621
if (! (keyuse->getUsedTables() & ~join->const_table_map))
3622
const_part|= keyuse->getKeypartMap();
3344
found_part|= keyuse->keypart_map;
3345
if (!(keyuse->used_tables & ~join->const_table_map))
3346
const_part|= keyuse->keypart_map;
3624
3348
double tmp2= prev_record_reads(join, idx, (found_ref |
3625
keyuse->getUsedTables()));
3349
keyuse->used_tables));
3626
3350
if (tmp2 < best_prev_record_reads)
3628
best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
3352
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3629
3353
best_prev_record_reads= tmp2;
3631
if (rec > keyuse->getTableRows())
3632
rec= keyuse->getTableRows();
3355
if (rec > keyuse->ref_table_rows)
3356
rec= keyuse->ref_table_rows;
3634
3358
If there is one 'key_column IS NULL' expression, we can
3635
3359
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();
3361
if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
3362
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);
3366
} while (keyuse->table == table && keyuse->key == key &&
3367
keyuse->keypart == keypart);
3368
found_ref|= best_part_found_ref;
3369
} while (keyuse->table == table && keyuse->key == key);
3648
3372
Assume that that each key matches a proportional part of table.
4552
4271
return search_depth;
4555
static bool make_simple_join(Join *join,Table *tmp_table)
4274
static bool make_simple_join(JOIN *join,Table *tmp_table)
4557
4276
Table **tableptr;
4558
4277
JoinTable *join_tab;
4561
4280
Reuse Table * and JoinTable if already allocated by a previous call
4562
to this function through Join::exec (may happen for sub-queries).
4281
to this function through JOIN::exec (may happen for sub-queries).
4564
4283
if (!join->table_reexec)
4566
if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
4285
if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4286
return(true); /* purecov: inspected */
4568
4287
if (join->tmp_join)
4569
4288
join->tmp_join->table_reexec= join->table_reexec;
4571
4290
if (!join->join_tab_reexec)
4573
4292
if (!(join->join_tab_reexec=
4574
(JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
4576
new (join->join_tab_reexec) JoinTable();
4293
(JoinTable*) join->session->alloc(sizeof(JoinTable))))
4294
return(true); /* purecov: inspected */
4577
4295
if (join->tmp_join)
4578
4296
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
5093
4803
true - Out of memory
5095
static bool make_join_readinfo(Join *join)
4805
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4808
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
5099
for (uint32_t i= join->const_tables ; i < join->tables ; i++)
4811
for (i=join->const_tables ; i < join->tables ; i++)
5101
4813
JoinTable *tab=join->join_tab+i;
5102
4814
Table *table=tab->table;
4815
bool using_join_cache;
5103
4816
tab->read_record.table= table;
5104
tab->read_record.cursor= table->cursor;
4817
tab->read_record.file=table->file;
5105
4818
tab->next_select=sub_select; /* normal select */
5107
4820
TODO: don't always instruct first table's ref/range access method to
5108
4821
produce sorted output.
5110
4823
tab->sorted= sorted;
5111
sorted= false; // only first must be sorted
4824
sorted= 0; // only first must be sorted
5113
4825
if (tab->insideout_match_tab)
5115
if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
4827
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.
4832
switch (tab->type) {
4833
case AM_SYSTEM: // Only happens with left join
4834
table->status=STATUS_NO_RECORD;
4835
tab->read_first_record= join_read_system;
4836
tab->read_record.read_record= join_no_more_records;
4838
case AM_CONST: // Only happens with left join
4839
table->status=STATUS_NO_RECORD;
4840
tab->read_first_record= join_read_const;
4841
tab->read_record.read_record= join_no_more_records;
4842
if (table->covering_keys.test(tab->ref.key) &&
4846
table->file->extra(HA_EXTRA_KEYREAD);
4850
table->status=STATUS_NO_RECORD;
4853
delete tab->select->quick;
4854
tab->select->quick=0;
4858
tab->read_first_record= join_read_key;
4859
tab->read_record.read_record= join_no_more_records;
4860
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4863
table->file->extra(HA_EXTRA_KEYREAD);
4866
case AM_REF_OR_NULL:
4868
table->status=STATUS_NO_RECORD;
4871
delete tab->select->quick;
4872
tab->select->quick=0;
4876
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4879
table->file->extra(HA_EXTRA_KEYREAD);
4881
if (tab->type == AM_REF)
4883
tab->read_first_record= join_read_always_key;
4884
tab->read_record.read_record= tab->insideout_match_tab?
4885
join_read_next_same_diff : join_read_next_same;
4889
tab->read_first_record= join_read_always_key_or_null;
4890
tab->read_record.read_record= join_read_next_same_or_null;
4895
If previous table use cache
4896
If the incoming data set is already sorted don't use cache.
4898
table->status=STATUS_NO_RECORD;
4899
using_join_cache= false;
4900
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
4901
tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
4902
!tab->insideout_match_tab)
4904
if ((options & SELECT_DESCRIBE) ||
4905
!join_init_cache(join->session,join->join_tab+join->const_tables,
4906
i-join->const_tables))
4908
using_join_cache= true;
4909
tab[-1].next_select=sub_select_cache; /* Patch previous */
4912
/* These init changes read_record */
4913
if (tab->use_quick == 2)
4915
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
4916
tab->read_first_record= join_init_quick_read_record;
4918
status_var_increment(join->session->status_var.select_range_check_count);
4922
tab->read_first_record= join_init_read_record;
4923
if (i == join->const_tables)
4925
if (tab->select && tab->select->quick)
4928
status_var_increment(join->session->status_var.select_range_count);
4932
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
4934
status_var_increment(join->session->status_var.select_scan_count);
4939
if (tab->select && tab->select->quick)
4942
status_var_increment(join->session->status_var.select_full_range_join_count);
4946
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
4948
status_var_increment(join->session->status_var.select_full_join_count);
4951
if (!table->no_keyread)
4953
if (tab->select && tab->select->quick &&
4954
tab->select->quick->index != MAX_KEY && //not index_merge
4955
table->covering_keys.test(tab->select->quick->index))
4958
table->file->extra(HA_EXTRA_KEYREAD);
4960
else if (!table->covering_keys.none() &&
4961
!(tab->select && tab->select->quick))
4962
{ // Only read index tree
4963
if (!tab->insideout_match_tab)
4966
See bug #26447: "Using the clustered index for a table scan
4967
is always faster than using a secondary index".
4969
if (table->s->primary_key != MAX_KEY &&
4970
table->file->primary_key_is_clustered())
4971
tab->index= table->s->primary_key;
4973
tab->index= table->find_shortest_key(&table->covering_keys);
4975
tab->read_first_record= join_read_first;
4976
tab->type= AM_NEXT; // Read with index_first / index_next
4982
break; /* purecov: deadcode */
4985
abort(); /* purecov: deadcode */
5134
access_method->getStats(table, tab);
5137
join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
4988
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
5142
4992
/** Update the dependency map for the tables. */
5143
static void update_depend_map(Join *join)
4993
static void update_depend_map(JOIN *join)
5145
4995
JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5525
5370
if (table->on_expr)
5527
table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5528
if (table->getEmbedding())
5372
table->dep_tables|= table->on_expr->used_tables();
5373
if (table->embedding)
5530
table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
5375
table->dep_tables&= ~table->embedding->nested_join->used_tables;
5532
5377
Embedding table depends on tables used
5533
5378
in embedded on expressions.
5535
table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
5380
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5538
table->setDepTables(table->getDepTables() & ~table->table->map);
5383
table->dep_tables&= ~table->table->map;
5541
5386
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);
5388
/* The order of tables is reverse: prev_table follows table */
5389
if (prev_table->straight)
5390
prev_table->dep_tables|= used_tables;
5548
5391
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 :
5393
prev_table->dep_tables|= table->on_expr_dep_tables;
5394
table_map prev_used_tables= prev_table->nested_join ?
5395
prev_table->nested_join->used_tables :
5553
5396
prev_table->table->map;
5555
5398
If on expression contains only references to inner tables
5611
5454
join->unit->select_limit_cnt= 1; // Only send first row
5614
Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
5457
Field **first_field=entry->field+entry->s->fields - field_count;
5615
5458
offset= (field_count ?
5616
entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5617
reclength= entry->getShare()->getRecordLength() - offset;
5459
entry->field[entry->s->fields - field_count]->
5460
offset(entry->record[0]) : 0);
5461
reclength= entry->s->reclength-offset;
5619
5463
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)))
5464
entry->file->info(HA_STATUS_VARIABLE);
5465
if (entry->s->db_type() == heap_engine ||
5466
(!entry->s->blob_fields &&
5467
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
5468
session->variables.sortbuff_size)))
5626
5469
error= remove_dup_with_hash_index(join->session, entry,
5627
field_count, first_field,
5470
field_count, first_field,
5632
error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5473
error= remove_dup_with_compare(join->session, entry, first_field, offset,
5635
5476
free_blobs(first_field);
5678
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5518
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;
5522
uint32_t i,table_count,const_count,key;
5523
table_map found_const_table_map, all_table_map, found_ref, refs;
5524
key_map const_ref, eq_part;
5525
Table **table_vector;
5526
JoinTable *stat,*stat_end,*s,**stat_ref;
5527
optimizer::KeyUse *keyuse,*start_keyuse;
5528
table_map outer_join=0;
5700
5529
vector<optimizer::SargableParam> sargables;
5701
5530
JoinTable *stat_vector[MAX_TABLES+1];
5702
5531
optimizer::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));
5533
table_count=join->tables;
5534
stat=(JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5535
stat_ref=(JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
5536
table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5708
5537
if (! stat || ! stat_ref || ! table_vector)
5538
return 1; // Eom /* purecov: inspected */
5711
5540
join->best_ref=stat_vector;
5726
5555
s->needed_reg.reset();
5727
5556
table_vector[i]=s->table=table=tables->table;
5728
5557
table->pos_in_table_list= tables;
5729
assert(table->cursor);
5730
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5558
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5733
table->print_error(error, MYF(0));
5561
table->file->print_error(error, MYF(0));
5736
5564
table->quick_keys.reset();
5737
5565
table->reginfo.join_tab=s;
5738
5566
table->reginfo.not_exists_optimize=0;
5739
5567
memset(table->const_key_parts, 0,
5740
sizeof(key_part_map)*table->getShare()->sizeKeys());
5568
sizeof(key_part_map)*table->s->keys);
5741
5569
all_table_map|= table->map;
5743
5571
s->info=0; // For describe
5745
s->dependent= tables->getDepTables();
5573
s->dependent= tables->dep_tables;
5746
5574
s->key_dependent= 0;
5747
table->quick_condition_rows= table->cursor->stats.records;
5575
if (tables->schema_table)
5576
table->file->stats.records= 2;
5577
table->quick_condition_rows= table->file->stats.records;
5749
5579
s->on_expr_ref= &tables->on_expr;
5750
5580
if (*s->on_expr_ref)
5752
5582
/* s is the only inner table of an outer join */
5753
if (!table->cursor->stats.records && !embedding)
5583
if (!table->file->stats.records && !embedding)
5754
5584
{ // Empty table
5755
5585
s->dependent= 0; // Ignore LEFT JOIN depend.
5756
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5586
set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5759
5589
outer_join|= table->map;
5760
5590
s->embedding_map.reset();
5761
for (;embedding; embedding= embedding->getEmbedding())
5762
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5591
for (;embedding; embedding= embedding->embedding)
5592
s->embedding_map|= embedding->nested_join->nj_map;
5765
if (embedding && !(false && ! embedding->getEmbedding()))
5595
if (embedding && !(false && ! embedding->embedding))
5767
5597
/* s belongs to a nested join, maybe to several embedded joins */
5768
5598
s->embedding_map.reset();
5771
NestedJoin *nested_join= embedding->getNestedJoin();
5601
nested_join_st *nested_join= embedding->nested_join;
5772
5602
s->embedding_map|= nested_join->nj_map;
5773
s->dependent|= embedding->getDepTables();
5774
embedding= embedding->getEmbedding();
5603
s->dependent|= embedding->dep_tables;
5604
embedding= embedding->embedding;
5775
5605
outer_join|= nested_join->used_tables;
5777
5607
while (embedding);
5780
if ((table->cursor->stats.records <= 1) && !s->dependent &&
5781
(table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5610
if ((table->file->stats.records <= 1) && !s->dependent &&
5611
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5782
5612
!join->no_const_tables)
5784
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5614
set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5787
5617
stat_vector[i]=0;
5896
5712
TODO. Apply single row substitution to null complemented inner tables
5897
5713
for nested outer join operations.
5899
while (keyuse->getTable() == table)
5715
while (keyuse->table == table)
5901
if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
5902
keyuse->getVal()->is_null() && keyuse->isNullRejected())
5717
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
5718
keyuse->val->is_null() && keyuse->null_rejecting)
5904
5720
s->type= AM_CONST;
5905
5721
table->mark_as_null_row();
5906
5722
found_const_table_map|= table->map;
5907
5723
join->const_table_map|= table->map;
5908
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5724
set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5909
5725
goto more_const_tables_found;
5917
5733
// All dep. must be constants
5918
5734
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())
5736
if (table->file->stats.records <= 1L &&
5737
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
5738
!table->pos_in_table_list->embedding)
5923
5739
{ // system table
5925
5741
s->type= AM_SYSTEM;
5926
5742
join->const_table_map|=table->map;
5927
set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5743
set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5928
5744
partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5929
if ((tmp= s->joinReadConstTable(partial_pos)))
5745
if ((tmp= join_read_const_table(s, partial_pos)))
5932
5748
return 1; // Fatal error
5940
5756
if ((keyuse=s->keyuse))
5942
5758
s->type= AM_REF;
5943
while (keyuse->getTable() == table)
5759
while (keyuse->table == table)
5945
start_keyuse= keyuse;
5946
key= keyuse->getKey();
5761
start_keyuse=keyuse;
5947
5763
s->keys.set(key); // QQ: remove this ?
5951
5767
eq_part.reset();
5954
if (keyuse->getVal()->type() != Item::NULL_ITEM &&
5955
! keyuse->getOptimizeFlags())
5770
if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
5957
if (! ((~found_const_table_map) & keyuse->getUsedTables()))
5958
const_ref.set(keyuse->getKeypart());
5772
if (!((~found_const_table_map) & keyuse->used_tables))
5773
const_ref.set(keyuse->keypart);
5960
refs|= keyuse->getUsedTables();
5961
eq_part.set(keyuse->getKeypart());
5775
refs|=keyuse->used_tables;
5776
eq_part.set(keyuse->keypart);
5964
} while (keyuse->getTable() == table && keyuse->getKey() == key);
5779
} while (keyuse->table == table && keyuse->key == key);
5966
5781
if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5967
! table->pos_in_table_list->getEmbedding())
5782
!table->pos_in_table_list->embedding)
5969
5784
if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
6051
5866
add_group_and_distinct_keys(join, s);
6053
5868
if (s->const_keys.any() &&
6054
!s->table->pos_in_table_list->getEmbedding())
5869
!s->table->pos_in_table_list->embedding)
6056
5871
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);
5873
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
5876
records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
6062
5877
s->quick=select->quick;
6063
5878
s->needed_reg=select->needed_reg;
6064
5879
select->quick=0;
6066
5880
if (records == 0 && s->table->reginfo.impossible_range)
6247
6056
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
6058
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
6059
joins counters and join->cur_embedding_map. It is ok to call this
6060
function for the first table in join order (for which
6292
6061
check_interleaving_with_nj has not been called)
6294
6063
@param last join table to remove, it is assumed to be the last in current
6295
6064
partial join order.
6298
6066
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)
6068
TableList *last_emb= last->table->pos_in_table_list->embedding;
6069
JOIN *join= last->join;
6072
if (last_emb->on_expr)
6074
if (!(--last_emb->nested_join->counter_))
6075
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6076
else if (last_emb->nested_join->join_list.elements-1 ==
6077
last_emb->nested_join->counter_)
6078
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6082
last_emb= last_emb->embedding;
6087
Determine if the set is already ordered for order_st BY, so it can
6088
disable join cache because it will change the ordering of the results.
6089
Code handles sort table that is at any location (not only first after
6090
the const tables) despite the fact that it's currently prohibited.
6091
We must disable join cache if the first non-const table alone is
6092
ordered. If there is a temp table the ordering is done as a last
6093
operation and doesn't prevent join cache usage.
6095
static uint32_t make_join_orderinfo(JOIN *join)
6099
return join->tables;
6101
for (i=join->const_tables ; i < join->tables ; i++)
6103
JoinTable *tab= join->join_tab+i;
6104
Table *table= tab->table;
6105
if ((table == join->sort_by_table &&
6106
(!join->order || join->skip_sort_order)) ||
6107
(join->sort_by_table == (Table *) 1 && i != join->const_tables))
6314
join->cur_embedding_map|= nest->nj_map;