35
#include <drizzled/item/cache.h>
36
#include <drizzled/item/cmpfunc.h>
37
#include <drizzled/item/copy_string.h>
38
#include <drizzled/item/uint.h>
39
#include <drizzled/cached_item.h>
40
#include <drizzled/sql_base.h>
41
#include <drizzled/sql_select.h> /* include join.h */
42
#include <drizzled/lock.h>
43
#include <drizzled/nested_join.h>
44
#include <drizzled/join.h>
45
#include <drizzled/join_cache.h>
46
#include <drizzled/show.h>
47
#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>
62
#include <drizzled/session.h>
63
#include <drizzled/select_result.h>
65
#include <drizzled/debug.h>
35
#include "drizzled/item/cache.h"
36
#include "drizzled/item/cmpfunc.h"
37
#include "drizzled/item/copy_string.h"
38
#include "drizzled/item/uint.h"
39
#include "drizzled/cached_item.h"
40
#include "drizzled/sql_base.h"
41
#include "drizzled/sql_select.h" /* include join.h */
42
#include "drizzled/lock.h"
43
#include "drizzled/nested_join.h"
44
#include "drizzled/join.h"
45
#include "drizzled/join_cache.h"
46
#include "drizzled/show.h"
47
#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"
67
62
#include <algorithm>
73
69
extern plugin::StorageEngine *heap_engine;
70
extern std::bitset<12> test_flags;
75
72
/** Declarations of static functions used in this source file. */
76
73
static bool make_group_fields(Join *main_join, Join *curr_join);
77
static void calc_group_buffer(Join *join, Order *group);
78
static bool alloc_group_fields(Join *join, Order *group);
74
static void calc_group_buffer(Join *join,order_st *group);
75
static bool alloc_group_fields(Join *join,order_st *group);
79
76
static uint32_t cache_record_length(Join *join, uint32_t index);
80
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
81
78
static bool get_best_combination(Join *join);
105
102
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
106
103
static bool make_join_readinfo(Join *join);
107
104
static void update_depend_map(Join *join);
108
static void update_depend_map(Join *join, Order *order);
109
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
105
static void update_depend_map(Join *join, order_st *order);
106
static order_st *remove_constants(Join *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
110
107
static int return_zero_rows(Join *join,
111
108
select_result *res,
112
109
TableList *tables,
124
121
List<Item> &fields,
125
122
List<Item> &all_fields,
129
126
bool *hidden_group_fields);
130
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
131
128
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
132
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
129
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
133
130
static void reset_nj_counters(List<TableList> *join_list);
134
static bool test_if_subpart(Order *a,Order *b);
131
static bool test_if_subpart(order_st *a,order_st *b);
135
132
static void restore_prev_nj_state(JoinTable *last);
136
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
137
134
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
139
Join::Join(Session *session_arg,
140
List<Item> &fields_arg,
141
uint64_t select_options_arg,
142
select_result *result_arg) :
154
sort_and_group(false),
158
no_field_update(false),
160
resume_nested_loop(false),
161
no_const_tables(false),
162
select_distinct(false),
163
group_optimized_away(false),
167
skip_sort_order(false),
171
hidden_group_fields(false),
173
found_const_table_map(0),
180
fetch_limit(HA_POS_ERROR),
181
session(session_arg),
182
fields_list(fields_arg),
187
exec_tmp_table1(NULL),
188
exec_tmp_table2(NULL),
193
having_history(NULL),
194
select_options(select_options_arg),
196
lock(session_arg->lock),
198
all_fields(fields_arg),
202
ref_pointer_array(NULL),
207
ref_pointer_array_size(0),
208
zero_result_cause(NULL),
211
join_tab_reexec(NULL)
213
select_distinct= test(select_options & SELECT_DISTINCT);
214
if (&fields_list != &fields_arg) /* only copy if not same*/
215
fields_list= fields_arg;
216
memset(&keyuse, 0, sizeof(keyuse));
217
tmp_table_param.init();
218
tmp_table_param.end_write_records= HA_POS_ERROR;
219
rollup.setState(Rollup::STATE_NONE);
223
* This method is currently only used when a subselect EXPLAIN is performed.
224
* I pulled out the init() method and have simply reset the values to what
225
* was previously in the init() method. See the note about the hack in
228
void Join::reset(Session *session_arg,
229
List<Item> &fields_arg,
230
uint64_t select_options_arg,
231
select_result *result_arg)
244
sort_and_group= false;
248
no_field_update= false;
250
resume_nested_loop= false;
251
no_const_tables= false;
252
select_distinct= false;
253
group_optimized_away= false;
257
skip_sort_order= false;
261
hidden_group_fields= false;
263
found_const_table_map= 0;
270
fetch_limit= HA_POS_ERROR;
271
session= session_arg;
272
fields_list= fields_arg;
277
exec_tmp_table1= NULL;
278
exec_tmp_table2= NULL;
283
having_history= NULL;
284
select_options= select_options_arg;
286
lock= session_arg->lock;
288
all_fields= fields_arg;
292
ref_pointer_array= NULL;
297
ref_pointer_array_size= 0;
298
zero_result_cause= NULL;
301
join_tab_reexec= NULL;
302
select_distinct= test(select_options & SELECT_DISTINCT);
303
if (&fields_list != &fields_arg) /* only copy if not same*/
304
fields_list= fields_arg;
305
memset(&keyuse, 0, sizeof(keyuse));
306
tmp_table_param.init();
307
tmp_table_param.end_write_records= HA_POS_ERROR;
308
rollup.setState(Rollup::STATE_NONE);
311
bool Join::is_top_level_join() const
313
return (unit == &session->getLex()->unit && (unit->fake_select_lex == 0 ||
314
select_lex == unit->fake_select_lex));
318
137
Prepare of whole select (including sub queries in future).
395
nesting_map save_allow_sum_func= session->getLex()->allow_sum_func;
396
session->setWhere("having clause");
397
session->getLex()->allow_sum_func|= 1 << select_lex_arg->nest_level;
211
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
212
session->where="having clause";
213
session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
398
214
select_lex->having_fix_field= 1;
399
215
bool having_fix_rc= (!having->fixed &&
400
216
(having->fix_fields(session, &having) ||
625
443
select_limit= HA_POS_ERROR;
626
444
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
627
445
// Ignore errors of execution if option IGNORE present
628
if (session->getLex()->ignore)
629
session->getLex()->current_select->no_error= 1;
446
if (session->lex->ignore)
447
session->lex->current_select->no_error= 1;
631
449
#ifdef HAVE_REF_TO_FIELDS // Not done yet
632
450
/* Add HAVING to WHERE if possible */
2014
1849
for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2016
1851
Item_subselect *subselect= sl->master_unit()->item;
2017
bool full_local= full && (!subselect ||
2018
(subselect->is_evaluated() &&
2019
!subselect->is_uncacheable()));
1852
bool full_local= full && (!subselect || subselect->is_evaluated());
2021
1854
If this join is evaluated, we can fully clean it up and clean up all
2022
1855
its underlying joins even if they are correlated -- they will not be
2038
1871
if (can_unlock && lock && session->lock &&
2039
1872
!(select_options & SELECT_NO_UNLOCK) &&
2040
1873
!select_lex->subquery_in_having &&
2041
(select_lex == (session->getLex()->unit.fake_select_lex ?
2042
session->getLex()->unit.fake_select_lex : &session->getLex()->select_lex)))
1874
(select_lex == (session->lex->unit.fake_select_lex ?
1875
session->lex->unit.fake_select_lex : &session->lex->select_lex)))
2045
1878
TODO: unlock tables even if the join isn't top level select in the
2048
session->unlockReadTables(lock); // Don't free join->lock
1881
mysql_unlock_read_tables(session, lock); // Don't free join->lock
2228
2054
((Item_sum *)item)->depended_from() == select_lex))
2229
2055
*func++= (Item_sum*) item;
2231
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2057
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2233
rollup.setState(Rollup::STATE_READY);
2059
rollup.state= ROLLUP::STATE_READY;
2234
2060
if (rollup_make_fields(field_list, send_fields, &func))
2235
return true; // Should never happen
2061
return(true); // Should never happen
2237
else if (rollup.getState() == Rollup::STATE_NONE)
2063
else if (rollup.state == ROLLUP::STATE_NONE)
2239
2065
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2240
2066
sum_funcs_end[i]= func;
2242
else if (rollup.getState() == Rollup::STATE_READY)
2068
else if (rollup.state == ROLLUP::STATE_READY)
2243
2069
return(false); // Don't put end marker
2244
2070
*func=0; // End marker
2260
2087
tmp_table_param.group_parts= send_group_parts;
2262
rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
2264
sizeof(List<Item>) +
2265
ref_pointer_array_size)
2266
* send_group_parts ));
2267
if (! rollup.getNullItems())
2089
if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2091
sizeof(List<Item>) +
2092
ref_pointer_array_size)
2093
* send_group_parts )))
2272
rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
2273
rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
2274
ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
2096
rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
2097
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
2098
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2277
2101
Prepare space for field list for the different levels
2278
2102
These will be filled up in rollup_make_fields()
2280
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2104
for (i= 0 ; i < send_group_parts ; i++)
2282
rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2283
List<Item> *rollup_fields= &rollup.getFields()[i];
2284
rollup_fields->clear();
2285
rollup.getRefPointerArrays()[i]= ref_array;
2106
rollup.null_items[i]= new (session->mem_root) Item_null_result();
2107
List<Item> *rollup_fields= &rollup.fields[i];
2108
rollup_fields->empty();
2109
rollup.ref_pointer_arrays[i]= ref_array;
2286
2110
ref_array+= all_fields.elements;
2289
for (uint32_t i= 0 ; i < send_group_parts; i++)
2112
for (i= 0 ; i < send_group_parts; i++)
2291
for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2293
rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2114
for (j=0 ; j < fields_list.elements ; j++)
2115
rollup.fields[i].push_back(rollup.null_items[i]);
2297
List<Item>::iterator it(all_fields.begin());
2117
List_iterator<Item> it(all_fields);
2299
2119
while ((item= it++))
2121
order_st *group_tmp;
2302
2122
bool found_in_group= 0;
2304
2124
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2500
2320
int Join::rollup_send_data(uint32_t idx)
2502
for (uint32_t i= send_group_parts ; i-- > idx ; )
2323
for (i= send_group_parts ; i-- > idx ; )
2504
2325
/* Get reference pointers to sum functions in place */
2505
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2326
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2327
ref_pointer_array_size);
2507
2328
if ((!having || having->val_int()))
2509
if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2330
if (send_records < unit->select_limit_cnt && do_send_rows &&
2331
result->send_data(rollup.fields[i]))
2513
2333
send_records++;
2516
2336
/* Restore ref_pointer_array */
2517
2337
set_items_ref_array(current_ref_pointer_array);
2541
2360
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2543
for (uint32_t i= send_group_parts ; i-- > idx ; )
2363
for (i= send_group_parts ; i-- > idx ; )
2545
2365
/* Get reference pointers to sum functions in place */
2546
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2366
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2547
2367
ref_pointer_array_size);
2548
2368
if ((!having || having->val_int()))
2550
2370
int write_error;
2552
List<Item>::iterator it(rollup.getFields()[i].begin());
2372
List_iterator_fast<Item> it(rollup.fields[i]);
2553
2373
while ((item= it++))
2555
2375
if (item->type() == Item::NULL_ITEM && item->is_result_field())
3099
2915
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3101
2917
init_tmptable_sum_functions(join->sum_funcs);
3102
if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3103
return NESTED_LOOP_ERROR;
2918
copy_funcs(join->tmp_table_param.items_to_copy);
3104
2919
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3106
2921
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3212
3026
case REAL_RESULT:
3213
3027
key_length+= sizeof(double);
3216
3029
case INT_RESULT:
3217
3030
key_length+= sizeof(int64_t);
3220
3032
case DECIMAL_RESULT:
3221
key_length+= class_decimal_get_binary_size(group_item->max_length -
3033
key_length+= my_decimal_get_binary_size(group_item->max_length -
3222
3034
(group_item->decimals ? 1 : 0),
3223
3035
group_item->decimals);
3226
3037
case STRING_RESULT:
3228
enum enum_field_types type= group_item->field_type();
3039
enum enum_field_types type= group_item->field_type();
3041
As items represented as DATE/TIME fields in the group buffer
3042
have STRING_RESULT result type, we increase the length
3043
by 8 as maximum pack length of such fields.
3045
if (type == DRIZZLE_TYPE_DATE ||
3046
type == DRIZZLE_TYPE_DATETIME ||
3047
type == DRIZZLE_TYPE_TIMESTAMP)
3230
As items represented as DATE/TIME fields in the group buffer
3231
have STRING_RESULT result type, we increase the length
3232
by 8 as maximum pack length of such fields.
3054
Group strings are taken as varstrings and require an length field.
3055
A field is not yet created by create_tmp_field()
3056
and the sizes should match up.
3234
if (field::isDateTime(type))
3241
Group strings are taken as varstrings and require an length field.
3242
A field is not yet created by create_tmp_field()
3243
and the sizes should match up.
3245
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3058
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3252
3063
/* This case should never be choosen */
3254
3065
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3260
3069
if (group_item->maybe_null)
3264
3072
join->tmp_table_param.group_length=key_length+null_parts;
3265
3073
join->tmp_table_param.group_parts=parts;
3266
3074
join->tmp_table_param.group_null_parts=null_parts;
5200
4999
Returns new sort order
5202
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
5001
static order_st *remove_constants(Join *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
5204
5003
if (join->tables == join->const_tables)
5205
5004
return change_list ? 0 : first_order; // No need to sort
5207
Order *order,**prev_ptr;
5006
order_st *order,**prev_ptr;
5208
5007
table_map first_table= join->join_tab[join->const_tables].table->map;
5209
5008
table_map not_const_tables= ~join->const_table_map;
5645
5444
List<Item> &fields,
5646
5445
List<Item> &all_fields,
5650
5449
bool *hidden_group_fields)
5653
nesting_map save_allow_sum_func=session->getLex()->allow_sum_func ;
5452
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
5655
session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
5454
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5656
5455
res= session->setup_conds(tables, conds);
5658
session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
5457
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5659
5458
res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
5661
session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
5460
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5662
5461
res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
5663
5462
group, hidden_group_fields);
5664
session->getLex()->allow_sum_func= save_allow_sum_func;
5463
session->lex->allow_sum_func= save_allow_sum_func;
5795
5594
As we use bitmaps to represent the relation the complexity
5796
5595
of the algorithm is O((number of tables)^2).
5798
for (i= 0; i < table_count; i++)
5597
for (i= 0, s= stat ; i < table_count ; i++, s++)
5801
table= stat[i].table;
5803
if (!table->reginfo.join_tab->dependent)
5806
for (j= 0, s= stat; j < table_count; j++, s++)
5599
for (uint32_t j= 0 ; j < table_count ; j++)
5601
table= stat[j].table;
5808
5602
if (s->dependent & table->map)
5810
table_map was_dependent= s->dependent;
5811
5603
s->dependent |= table->reginfo.join_tab->dependent;
5812
if (i > j && s->dependent != was_dependent)
5606
s->table->maybe_null= 1;
5820
5608
/* Catch illegal cross references for outer joins */
5821
5609
for (i= 0, s= stat ; i < table_count ; i++, s++)
6100
5884
if (join->const_tables != join->tables)
6102
5886
optimize_keyuse(join, keyuse_array);
6103
// @note c_str() is not likely to be valid here if dtrace expects it to
6104
// exist for any period of time.
6105
DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->getQueryString()->c_str(), join->session->thread_id);
5887
DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query.c_str(), join->session->thread_id);
6106
5888
bool res= choose_plan(join, all_table_map & ~join->const_table_map);
6107
5889
DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);