70
68
extern std::bitset<12> test_flags;
72
70
/** Declarations of static functions used in this source file. */
73
static bool make_group_fields(Join *main_join, Join *curr_join);
74
static void calc_group_buffer(Join *join, Order *group);
75
static bool alloc_group_fields(Join *join, Order *group);
76
static uint32_t cache_record_length(Join *join, uint32_t index);
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
78
static bool get_best_combination(Join *join);
79
static void set_position(Join *join,
71
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
72
static void calc_group_buffer(JOIN *join,order_st *group);
73
static bool alloc_group_fields(JOIN *join,order_st *group);
74
static uint32_t cache_record_length(JOIN *join, uint32_t index);
75
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
76
static bool get_best_combination(JOIN *join);
77
static void set_position(JOIN *join,
82
80
optimizer::KeyUse *key);
83
static bool choose_plan(Join *join,table_map join_tables);
84
static void best_access_path(Join *join, JoinTable *s,
81
static bool choose_plan(JOIN *join,table_map join_tables);
82
static void best_access_path(JOIN *join, JoinTable *s,
86
84
table_map remaining_tables,
88
86
double record_count,
90
static void optimize_straight_join(Join *join, table_map join_tables);
91
static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
92
static bool best_extension_by_limited_search(Join *join,
88
static void optimize_straight_join(JOIN *join, table_map join_tables);
89
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
90
static bool best_extension_by_limited_search(JOIN *join,
93
91
table_map remaining_tables,
95
93
double record_count,
98
96
uint32_t prune_level);
99
static uint32_t determine_search_depth(Join* join);
100
static bool make_simple_join(Join *join,Table *tmp_table);
101
static void make_outerjoin_info(Join *join);
102
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
103
static bool make_join_readinfo(Join *join);
104
static void update_depend_map(Join *join);
105
static void update_depend_map(Join *join, Order *order);
106
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
107
static int return_zero_rows(Join *join,
97
static uint32_t determine_search_depth(JOIN* join);
98
static bool make_simple_join(JOIN *join,Table *tmp_table);
99
static void make_outerjoin_info(JOIN *join);
100
static bool make_join_select(JOIN *join, optimizer::SqlSelect *select,COND *item);
101
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
102
static void update_depend_map(JOIN *join);
103
static void update_depend_map(JOIN *join, order_st *order);
104
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
105
static int return_zero_rows(JOIN *join,
108
106
select_result *res,
109
107
TableList *tables,
110
108
List<Item> &fields,
121
119
List<Item> &fields,
122
120
List<Item> &all_fields,
126
124
bool *hidden_group_fields);
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
125
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
126
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
129
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
127
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
128
static void reset_nj_counters(List<TableList> *join_list);
131
static bool test_if_subpart(Order *a,Order *b);
129
static bool test_if_subpart(order_st *a,order_st *b);
132
130
static void restore_prev_nj_state(JoinTable *last);
131
static uint32_t make_join_orderinfo(JOIN *join);
133
132
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
133
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
1791
1790
is called after all rows are sent, but before EOF packet is sent.
1793
1792
For a simple SELECT with no subqueries this function performs a full
1794
cleanup of the Join and calls unlockReadTables to free used base
1793
cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1797
If a Join is executed for a subquery or if it has a subquery, we can't
1796
If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1797
do the full cleanup and need to do a partial cleanup only.
1799
- If a Join is not the top level join, we must not unlock the tables
1798
- If a JOIN is not the top level join, we must not unlock the tables
1800
1799
because the outer select may not have been evaluated yet, and we
1801
1800
can't unlock only selected tables of a query.
1802
- Additionally, if this Join corresponds to a correlated subquery, we
1801
- Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1802
should not free quick selects and join buffers because they will be
1804
1803
needed for the next execution of the correlated subquery.
1805
- However, if this is a Join for a [sub]select, which is not
1804
- However, if this is a JOIN for a [sub]select, which is not
1806
1805
a correlated subquery itself, but has subqueries, we can free it
1807
fully and also free Joins of all its subqueries. The exception
1806
fully and also free JOINs of all its subqueries. The exception
1808
1807
is a subquery in SELECT list, e.g: @n
1809
1808
SELECT a, (select cmax(b) from t1) group by c @n
1810
1809
This subquery will not be evaluated at first sweep and its value will
2635
2637
return (*join_tab->next_select)(join, join_tab+1, 0);
2638
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
2640
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2640
2642
enum_nested_loop_state rc= NESTED_LOOP_OK;
2644
2646
join_tab->table->null_row= 0;
2645
2647
if (!join_tab->cache.records)
2647
2648
return NESTED_LOOP_OK; /* Nothing to do */
2652
(void) join_tab->cache.store_record_in_cache(); // Must save this for later
2650
(void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2651
if (join_tab->use_quick == 2)
2658
2653
if (join_tab->select->quick)
2817
2812
if (!end_of_records)
2819
2814
copy_fields(&join->tmp_table_param);
2820
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
return NESTED_LOOP_ERROR;
2815
copy_funcs(join->tmp_table_param.items_to_copy);
2822
2816
if (!join->having || join->having->val_int())
2825
2819
join->found_records++;
2826
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2820
if ((error=table->cursor->ha_write_row(table->record[0])))
2828
2822
if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2830
return NESTED_LOOP_OK;
2833
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2834
return NESTED_LOOP_ERROR; // Table is_full error
2824
if (create_myisam_from_heap(join->session, table,
2825
join->tmp_table_param.start_recinfo,
2826
&join->tmp_table_param.recinfo,
2828
return NESTED_LOOP_ERROR; // Not a table_is_full error
2829
table->s->uniques= 0; // To ensure rows are the same
2836
2831
if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
2873
2868
if (item->maybe_null)
2874
2869
group->buff[-1]= (char) group->field->is_null();
2876
if (!table->cursor->index_read_map(table->getUpdateRecord(),
2871
if (!table->cursor->index_read_map(table->record[1],
2877
2872
join->tmp_table_param.group_buff,
2879
2874
HA_READ_KEY_EXACT))
2880
2875
{ /* Update old record */
2881
2876
table->restoreRecord();
2882
2877
update_tmptable_sum_func(join->sum_funcs,table);
2883
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
table->getInsertRecord())))
2878
if ((error= table->cursor->ha_update_row(table->record[1],
2886
2881
table->print_error(error,MYF(0));
2887
2882
return NESTED_LOOP_ERROR;
2894
2889
We can't copy all data as the key may have different format
2895
2890
as the row data (for example as with VARCHAR keys)
2897
KeyPartInfo *key_part;
2892
KEY_PART_INFO *key_part;
2898
2893
for (group=table->group,key_part=table->key_info[0].key_part;
2900
2895
group=group->next,key_part++)
2902
2897
if (key_part->null_bit)
2903
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
2898
memcpy(table->record[0]+key_part->offset, group->buff, 1);
2905
2900
init_tmptable_sum_functions(join->sum_funcs);
2906
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2907
return NESTED_LOOP_ERROR;
2908
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
2901
copy_funcs(join->tmp_table_param.items_to_copy);
2902
if ((error=table->cursor->ha_write_row(table->record[0])))
2910
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
return NESTED_LOOP_ERROR; // Table is_full error
2904
if (create_myisam_from_heap(join->session, table,
2905
join->tmp_table_param.start_recinfo,
2906
&join->tmp_table_param.recinfo,
2908
return NESTED_LOOP_ERROR; // Not a table_is_full error
2909
/* Change method to update rows */
2910
table->cursor->ha_index_init(0, 0);
2911
join->join_tab[join->tables-1].next_select= end_unique_update;
2913
2913
join->send_records++;
2914
2914
return NESTED_LOOP_OK;
2917
2917
/** Like end_update, but this is done with unique constraints instead of keys. */
2918
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
2918
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2920
2920
Table *table= join->tmp_table;
2923
2923
if (end_of_records)
2924
2924
return NESTED_LOOP_OK;
2925
if (join->session->getKilled()) // Aborted by user
2925
if (join->session->killed) // Aborted by user
2927
2927
join->session->send_kill_message();
2928
2928
return NESTED_LOOP_KILLED;
2942
2941
table->print_error(error,MYF(0));
2943
2942
return NESTED_LOOP_ERROR;
2945
if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
2944
if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
2947
2946
table->print_error(error,MYF(0));
2948
2947
return NESTED_LOOP_ERROR;
2950
2949
table->restoreRecord();
2951
2950
update_tmptable_sum_func(join->sum_funcs,table);
2952
if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
table->getInsertRecord())))
2951
if ((error= table->cursor->ha_update_row(table->record[1],
2955
2954
table->print_error(error,MYF(0));
2956
2955
return NESTED_LOOP_ERROR;
3016
3015
case REAL_RESULT:
3017
3016
key_length+= sizeof(double);
3020
3018
case INT_RESULT:
3021
3019
key_length+= sizeof(int64_t);
3024
3021
case DECIMAL_RESULT:
3025
3022
key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
3023
(group_item->decimals ? 1 : 0),
3027
3024
group_item->decimals);
3030
3026
case STRING_RESULT:
3032
enum enum_field_types type= group_item->field_type();
3028
enum enum_field_types type= group_item->field_type();
3030
As items represented as DATE/TIME fields in the group buffer
3031
have STRING_RESULT result type, we increase the length
3032
by 8 as maximum pack length of such fields.
3034
if (type == DRIZZLE_TYPE_DATE ||
3035
type == DRIZZLE_TYPE_DATETIME ||
3036
type == DRIZZLE_TYPE_TIMESTAMP)
3034
As items represented as DATE/TIME fields in the group buffer
3035
have STRING_RESULT result type, we increase the length
3036
by 8 as maximum pack length of such fields.
3043
Group strings are taken as varstrings and require an length field.
3044
A field is not yet created by create_tmp_field()
3045
and the sizes should match up.
3038
if (type == DRIZZLE_TYPE_DATE ||
3039
type == DRIZZLE_TYPE_DATETIME ||
3040
type == DRIZZLE_TYPE_TIMESTAMP)
3047
Group strings are taken as varstrings and require an length field.
3048
A field is not yet created by create_tmp_field()
3049
and the sizes should match up.
3051
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3047
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3057
3052
/* This case should never be choosen */
3059
3054
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3065
3058
if (group_item->maybe_null)
3069
3061
join->tmp_table_param.group_length=key_length+null_parts;
3070
3062
join->tmp_table_param.group_parts=parts;
3071
3063
join->tmp_table_param.group_null_parts=null_parts;
4902
4891
produce sorted output.
4904
4893
tab->sorted= sorted;
4905
sorted= false; // only first must be sorted
4894
sorted= 0; // only first must be sorted
4907
4895
if (tab->insideout_match_tab)
4909
if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
4897
if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
4915
optimizer::AccessMethodFactory &factory= optimizer::AccessMethodFactory::singleton();
4916
boost::shared_ptr<optimizer::AccessMethod> access_method(factory.createAccessMethod(tab->type));
4918
if (! access_method)
4922
* Is abort() the correct thing to call here? I call this here because it was what was called in
4923
* the default case for the switch statement that used to be here.
4902
switch (tab->type) {
4903
case AM_SYSTEM: // Only happens with left join
4904
table->status=STATUS_NO_RECORD;
4905
tab->read_first_record= join_read_system;
4906
tab->read_record.read_record= join_no_more_records;
4908
case AM_CONST: // Only happens with left join
4909
table->status=STATUS_NO_RECORD;
4910
tab->read_first_record= join_read_const;
4911
tab->read_record.read_record= join_no_more_records;
4912
if (table->covering_keys.test(tab->ref.key) &&
4916
table->cursor->extra(HA_EXTRA_KEYREAD);
4920
table->status=STATUS_NO_RECORD;
4923
delete tab->select->quick;
4924
tab->select->quick=0;
4928
tab->read_first_record= join_read_key;
4929
tab->read_record.read_record= join_no_more_records;
4930
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4933
table->cursor->extra(HA_EXTRA_KEYREAD);
4936
case AM_REF_OR_NULL:
4938
table->status=STATUS_NO_RECORD;
4941
delete tab->select->quick;
4942
tab->select->quick=0;
4946
if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
4949
table->cursor->extra(HA_EXTRA_KEYREAD);
4951
if (tab->type == AM_REF)
4953
tab->read_first_record= join_read_always_key;
4954
tab->read_record.read_record= tab->insideout_match_tab?
4955
join_read_next_same_diff : join_read_next_same;
4959
tab->read_first_record= join_read_always_key_or_null;
4960
tab->read_record.read_record= join_read_next_same_or_null;
4965
If previous table use cache
4966
If the incoming data set is already sorted don't use cache.
4968
table->status=STATUS_NO_RECORD;
4969
using_join_cache= false;
4970
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
4971
tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
4972
!tab->insideout_match_tab)
4974
if ((options & SELECT_DESCRIBE) ||
4975
!join_init_cache(join->session,join->join_tab+join->const_tables,
4976
i-join->const_tables))
4978
using_join_cache= true;
4979
tab[-1].next_select=sub_select_cache; /* Patch previous */
4982
/* These init changes read_record */
4983
if (tab->use_quick == 2)
4985
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
4986
tab->read_first_record= join_init_quick_read_record;
4988
status_var_increment(join->session->status_var.select_range_check_count);
4992
tab->read_first_record= join_init_read_record;
4993
if (i == join->const_tables)
4995
if (tab->select && tab->select->quick)
4998
status_var_increment(join->session->status_var.select_range_count);
5002
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5004
status_var_increment(join->session->status_var.select_scan_count);
5009
if (tab->select && tab->select->quick)
5012
status_var_increment(join->session->status_var.select_full_range_join_count);
5016
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
5018
status_var_increment(join->session->status_var.select_full_join_count);
5021
if (!table->no_keyread)
5023
if (tab->select && tab->select->quick &&
5024
tab->select->quick->index != MAX_KEY && //not index_merge
5025
table->covering_keys.test(tab->select->quick->index))
5028
table->cursor->extra(HA_EXTRA_KEYREAD);
5030
else if (!table->covering_keys.none() &&
5031
!(tab->select && tab->select->quick))
5032
{ // Only read index tree
5033
if (!tab->insideout_match_tab)
5036
See bug #26447: "Using the clustered index for a table scan
5037
is always faster than using a secondary index".
5039
if (table->s->primary_key != MAX_KEY &&
5040
table->cursor->primary_key_is_clustered())
5041
tab->index= table->s->primary_key;
5043
tab->index= table->find_shortest_key(&table->covering_keys);
5045
tab->read_first_record= join_read_first;
5046
tab->type= AM_NEXT; // Read with index_first / index_next
4928
access_method->getStats(table, tab);
4931
join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
5058
join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
4936
5062
/** Update the dependency map for the tables. */
4937
static void update_depend_map(Join *join)
5063
static void update_depend_map(JOIN *join)
4939
5065
JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5319
5445
if (table->on_expr)
5321
table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
if (table->getEmbedding())
5447
table->dep_tables|= table->on_expr->used_tables();
5448
if (table->embedding)
5324
table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
5450
table->dep_tables&= ~table->embedding->nested_join->used_tables;
5326
5452
Embedding table depends on tables used
5327
5453
in embedded on expressions.
5329
table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
5455
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5332
table->setDepTables(table->getDepTables() & ~table->table->map);
5458
table->dep_tables&= ~table->table->map;
5335
5461
if (prev_table)
5337
//If this is straight join, set prev table to be dependent on all tables
5338
//from this nested join, so that correct join order is selected.
5339
if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
5340
prev_table->straight)
5341
prev_table->setDepTables(prev_table->getDepTables() | used_tables);
5463
/* The order of tables is reverse: prev_table follows table */
5464
if (prev_table->straight)
5465
prev_table->dep_tables|= used_tables;
5342
5466
if (prev_table->on_expr)
5344
prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
prev_table->getNestedJoin()->used_tables :
5468
prev_table->dep_tables|= table->on_expr_dep_tables;
5469
table_map prev_used_tables= prev_table->nested_join ?
5470
prev_table->nested_join->used_tables :
5347
5471
prev_table->table->map;
5349
5473
If on expression contains only references to inner tables
5405
5529
join->unit->select_limit_cnt= 1; // Only send first row
5408
Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
5532
Field **first_field=entry->field+entry->s->fields - field_count;
5409
5533
offset= (field_count ?
5410
entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
reclength= entry->getShare()->getRecordLength() - offset;
5534
entry->field[entry->s->fields - field_count]->
5535
offset(entry->record[0]) : 0);
5536
reclength= entry->s->reclength-offset;
5413
5538
entry->free_io_cache(); // Safety
5414
5539
entry->cursor->info(HA_STATUS_VARIABLE);
5415
if (entry->getShare()->db_type() == heap_engine ||
5416
(!entry->getShare()->blob_fields &&
5540
if (entry->s->db_type() == heap_engine ||
5541
(!entry->s->blob_fields &&
5417
5542
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
session->variables.sortbuff_size)))
5543
session->variables.sortbuff_size)))
5420
5544
error= remove_dup_with_hash_index(join->session, entry,
5421
field_count, first_field,
5545
field_count, first_field,
5426
error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5548
error= remove_dup_with_compare(join->session, entry, first_field, offset,
5429
5551
free_blobs(first_field);
5553
5673
outer_join|= table->map;
5554
5674
s->embedding_map.reset();
5555
for (;embedding; embedding= embedding->getEmbedding())
5556
s->embedding_map|= embedding->getNestedJoin()->nj_map;
5675
for (;embedding; embedding= embedding->embedding)
5676
s->embedding_map|= embedding->nested_join->nj_map;
5559
if (embedding && !(false && ! embedding->getEmbedding()))
5679
if (embedding && !(false && ! embedding->embedding))
5561
5681
/* s belongs to a nested join, maybe to several embedded joins */
5562
5682
s->embedding_map.reset();
5565
nested_join_st *nested_join= embedding->getNestedJoin();
5685
nested_join_st *nested_join= embedding->nested_join;
5566
5686
s->embedding_map|= nested_join->nj_map;
5567
s->dependent|= embedding->getDepTables();
5568
embedding= embedding->getEmbedding();
5687
s->dependent|= embedding->dep_tables;
5688
embedding= embedding->embedding;
5569
5689
outer_join|= nested_join->used_tables;
5571
5691
while (embedding);
6026
6144
Nested joins perspective: Remove the last table from the join order.
6028
The algorithm is the reciprocal of check_interleaving_with_nj(), hence
6029
parent join nest nodes are updated only when the last table in its child
6030
node is removed. The ASCII graphic below will clarify.
6032
%A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
6033
represented by the below join nest tree.
6041
t1 x [ (t2 x t3) x (t4 x t5) ]
6044
At the point in time when check_interleaving_with_nj() adds the table t5 to
6045
the query execution plan, QEP, it also directs the node named NJ2 to mark
6046
the table as covered. NJ2 does so by incrementing its @c counter
6047
member. Since all of NJ2's tables are now covered by the QEP, the algorithm
6048
proceeds up the tree to NJ1, incrementing its counter as well. All join
6049
nests are now completely covered by the QEP.
6051
restore_prev_nj_state() does the above in reverse. As seen above, the node
6052
NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
6053
that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
6054
completely covers NJ2. The removal of t5 from the partial plan will first
6055
decrement NJ2's counter to 1. It will then detect that NJ2 went from being
6056
completely to partially covered, and hence the algorithm must continue
6057
upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
6058
will however not influence NJ1 since it did not un-cover the last table in
6062
restore_prev_nj_state()
6063
last join table to remove, it is assumed to be the last in current
6068
6146
Remove the last table from the partial join order and update the nested
6069
joins counters and join->cur_embedding_map. It is ok to call this
6070
function for the first table in join order (for which
6147
joins counters and join->cur_embedding_map. It is ok to call this
6148
function for the first table in join order (for which
6071
6149
check_interleaving_with_nj has not been called)
6073
6151
@param last join table to remove, it is assumed to be the last in current
6074
6152
partial join order.
6077
6154
static void restore_prev_nj_state(JoinTable *last)
6079
TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
6080
Join *join= last->join;
6081
for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6083
nested_join_st *nest= last_emb->getNestedJoin();
6085
bool was_fully_covered= nest->is_fully_covered();
6087
if (--nest->counter_ == 0)
6088
join->cur_embedding_map&= ~nest->nj_map;
6090
if (!was_fully_covered)
6156
TableList *last_emb= last->table->pos_in_table_list->embedding;
6157
JOIN *join= last->join;
6160
if (last_emb->on_expr)
6162
if (!(--last_emb->nested_join->counter_))
6163
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
6164
else if (last_emb->nested_join->join_list.elements-1 ==
6165
last_emb->nested_join->counter_)
6166
join->cur_embedding_map|= last_emb->nested_join->nj_map;
6170
last_emb= last_emb->embedding;
6175
Determine if the set is already ordered for order_st BY, so it can
6176
disable join cache because it will change the ordering of the results.
6177
Code handles sort table that is at any location (not only first after
6178
the const tables) despite the fact that it's currently prohibited.
6179
We must disable join cache if the first non-const table alone is
6180
ordered. If there is a temp table the ordering is done as a last
6181
operation and doesn't prevent join cache usage.
6183
static uint32_t make_join_orderinfo(JOIN *join)
6187
return join->tables;
6189
for (i=join->const_tables ; i < join->tables ; i++)
6191
JoinTable *tab= join->join_tab+i;
6192
Table *table= tab->table;
6193
if ((table == join->sort_by_table &&
6194
(!join->order || join->skip_sort_order)) ||
6195
(join->sort_by_table == (Table *) 1 && i != join->const_tables))
6093
join->cur_embedding_map|= nest->nj_map;