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"
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>
64
#include <drizzled/debug.h>
65
#include <drizzled/item/subselect.h>
66
#include <drizzled/my_hash.h>
67
#include <drizzled/sql_lex.h>
68
#include <drizzled/statistics_variables.h>
69
#include <drizzled/system_variables.h>
62
70
#include <algorithm>
64
72
using namespace std;
69
76
extern plugin::StorageEngine *heap_engine;
70
extern std::bitset<12> test_flags;
72
78
/** Declarations of static functions used in this source file. */
73
79
static bool make_group_fields(Join *main_join, Join *curr_join);
133
139
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
140
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
142
Join::Join(Session *session_arg,
143
List<Item> &fields_arg,
144
uint64_t select_options_arg,
145
select_result *result_arg) :
157
sort_and_group(false),
161
no_field_update(false),
163
resume_nested_loop(false),
164
no_const_tables(false),
165
select_distinct(false),
166
group_optimized_away(false),
170
skip_sort_order(false),
174
hidden_group_fields(false),
176
found_const_table_map(0),
183
fetch_limit(HA_POS_ERROR),
184
session(session_arg),
185
fields_list(fields_arg),
190
exec_tmp_table1(NULL),
191
exec_tmp_table2(NULL),
196
having_history(NULL),
197
select_options(select_options_arg),
199
lock(session_arg->lock),
201
all_fields(fields_arg),
205
ref_pointer_array(NULL),
210
ref_pointer_array_size(0),
211
zero_result_cause(NULL),
214
join_tab_reexec(NULL)
216
select_distinct= test(select_options & SELECT_DISTINCT);
217
if (&fields_list != &fields_arg) /* only copy if not same*/
218
fields_list= fields_arg;
219
memset(&keyuse, 0, sizeof(keyuse));
220
tmp_table_param.init();
221
tmp_table_param.end_write_records= HA_POS_ERROR;
222
rollup.setState(Rollup::STATE_NONE);
226
* This method is currently only used when a subselect EXPLAIN is performed.
227
* I pulled out the init() method and have simply reset the values to what
228
* was previously in the init() method. See the note about the hack in
231
void Join::reset(Session *session_arg,
232
List<Item> &fields_arg,
233
uint64_t select_options_arg,
234
select_result *result_arg)
247
sort_and_group= false;
251
no_field_update= false;
253
resume_nested_loop= false;
254
no_const_tables= false;
255
select_distinct= false;
256
group_optimized_away= false;
260
skip_sort_order= false;
264
hidden_group_fields= false;
266
found_const_table_map= 0;
273
fetch_limit= HA_POS_ERROR;
274
session= session_arg;
275
fields_list= fields_arg;
280
exec_tmp_table1= NULL;
281
exec_tmp_table2= NULL;
286
having_history= NULL;
287
select_options= select_options_arg;
289
lock= session_arg->lock;
291
all_fields= fields_arg;
295
ref_pointer_array= NULL;
300
ref_pointer_array_size= 0;
301
zero_result_cause= NULL;
304
join_tab_reexec= NULL;
305
select_distinct= test(select_options & SELECT_DISTINCT);
306
if (&fields_list != &fields_arg) /* only copy if not same*/
307
fields_list= fields_arg;
308
memset(&keyuse, 0, sizeof(keyuse));
309
tmp_table_param.init();
310
tmp_table_param.end_write_records= HA_POS_ERROR;
311
rollup.setState(Rollup::STATE_NONE);
314
bool Join::is_top_level_join() const
316
return (unit == &session->lex().unit && (unit->fake_select_lex == 0 ||
317
select_lex == unit->fake_select_lex));
137
321
Prepare of whole select (including sub queries in future).
214
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
215
session->where="having clause";
216
session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
398
nesting_map save_allow_sum_func= session->lex().allow_sum_func;
399
session->setWhere("having clause");
400
session->lex().allow_sum_func|= 1 << select_lex_arg->nest_level;
217
401
select_lex->having_fix_field= 1;
218
402
bool having_fix_rc= (!having->fixed &&
219
403
(having->fix_fields(session, &having) ||
1348
1530
curr_join->all_fields= *curr_all_fields;
1351
items1= items0 + all_fields.elements;
1533
items1= items0 + all_fields.size();
1352
1534
if (sort_and_group || curr_tmp_table->group)
1354
1536
if (change_to_use_tmp_fields(session, items1,
1355
1537
tmp_fields_list1, tmp_all_fields1,
1356
fields_list.elements, all_fields))
1538
fields_list.size(), all_fields))
1361
1543
if (change_refs_to_tmp_fields(session, items1,
1362
1544
tmp_fields_list1, tmp_all_fields1,
1363
fields_list.elements, all_fields))
1545
fields_list.size(), all_fields))
1366
1548
curr_join->tmp_all_fields1= tmp_all_fields1;
1497
1679
// No sum funcs anymore
1500
items2= items1 + all_fields.elements;
1682
items2= items1 + all_fields.size();
1501
1683
if (change_to_use_tmp_fields(session, items2,
1502
1684
tmp_fields_list2, tmp_all_fields2,
1503
fields_list.elements, tmp_all_fields1))
1685
fields_list.size(), tmp_all_fields1))
1505
1687
curr_join->tmp_fields_list2= tmp_fields_list2;
1506
1688
curr_join->tmp_all_fields2= tmp_all_fields2;
1547
1729
init_items_ref_array();
1548
items3= ref_pointer_array + (all_fields.elements*4);
1730
items3= ref_pointer_array + (all_fields.size() * 4);
1549
1731
setup_copy_fields(session, &curr_join->tmp_table_param,
1550
1732
items3, tmp_fields_list3, tmp_all_fields3,
1551
curr_fields_list->elements, *curr_all_fields);
1733
curr_fields_list->size(), *curr_all_fields);
1552
1734
tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
1553
1735
tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
1554
1736
tmp_table_param.save_copy_field_end= curr_join->tmp_table_param.copy_field_end;
2039
2230
((Item_sum *)item)->depended_from() == select_lex))
2040
2231
*func++= (Item_sum*) item;
2042
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2233
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2044
rollup.state= ROLLUP::STATE_READY;
2235
rollup.setState(Rollup::STATE_READY);
2045
2236
if (rollup_make_fields(field_list, send_fields, &func))
2046
return(true); // Should never happen
2237
return true; // Should never happen
2048
else if (rollup.state == ROLLUP::STATE_NONE)
2239
else if (rollup.getState() == Rollup::STATE_NONE)
2050
2241
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2051
2242
sum_funcs_end[i]= func;
2053
else if (rollup.state == ROLLUP::STATE_READY)
2244
else if (rollup.getState() == Rollup::STATE_READY)
2054
2245
return(false); // Don't put end marker
2055
2246
*func=0; // End marker
2072
2262
tmp_table_param.group_parts= send_group_parts;
2074
if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2076
sizeof(List<Item>) +
2077
ref_pointer_array_size)
2078
* send_group_parts )))
2264
rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
2266
sizeof(List<Item>) +
2267
ref_pointer_array_size)
2268
* send_group_parts ));
2269
if (! rollup.getNullItems())
2081
rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
2082
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
2083
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2274
rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
2275
rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
2276
ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
2086
2279
Prepare space for field list for the different levels
2087
2280
These will be filled up in rollup_make_fields()
2089
for (i= 0 ; i < send_group_parts ; i++)
2091
rollup.null_items[i]= new (session->mem_root) Item_null_result();
2092
List<Item> *rollup_fields= &rollup.fields[i];
2093
rollup_fields->empty();
2094
rollup.ref_pointer_arrays[i]= ref_array;
2095
ref_array+= all_fields.elements;
2097
for (i= 0 ; i < send_group_parts; i++)
2099
for (j=0 ; j < fields_list.elements ; j++)
2100
rollup.fields[i].push_back(rollup.null_items[i]);
2102
List_iterator<Item> it(all_fields);
2282
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2284
rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2285
List<Item> *rollup_fields= &rollup.getFields()[i];
2286
rollup_fields->clear();
2287
rollup.getRefPointerArrays()[i]= ref_array;
2288
ref_array+= all_fields.size();
2291
for (uint32_t i= 0 ; i < send_group_parts; i++)
2293
for (uint32_t j= 0 ; j < fields_list.size() ; j++)
2295
rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2299
List<Item>::iterator it(all_fields.begin());
2104
2301
while ((item= it++))
2205
2402
uint32_t pos= send_group_parts - level -1;
2206
2403
bool real_fields= 0;
2208
List_iterator<Item> new_it(rollup.fields[pos]);
2209
Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2405
List<Item>::iterator new_it(rollup.getFields()[pos].begin());
2406
Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2210
2407
Order *start_group;
2212
2409
/* Point to first hidden field */
2213
Item **ref_array= ref_array_start + fields_arg.elements-1;
2410
Item **ref_array= ref_array_start + fields_arg.size()-1;
2215
2412
/* Remember where the sum functions ends for the previous level */
2216
2413
sum_funcs_end[pos+1]= *func;
2305
2502
int Join::rollup_send_data(uint32_t idx)
2308
for (i= send_group_parts ; i-- > idx ; )
2504
for (uint32_t i= send_group_parts ; i-- > idx ; )
2310
2506
/* Get reference pointers to sum functions in place */
2311
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2312
ref_pointer_array_size);
2507
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2313
2509
if ((!having || having->val_int()))
2315
if (send_records < unit->select_limit_cnt && do_send_rows &&
2316
result->send_data(rollup.fields[i]))
2511
if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2318
2515
send_records++;
2321
2518
/* Restore ref_pointer_array */
2322
2519
set_items_ref_array(current_ref_pointer_array);
2345
2543
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2348
for (i= send_group_parts ; i-- > idx ; )
2545
for (uint32_t i= send_group_parts ; i-- > idx ; )
2350
2547
/* Get reference pointers to sum functions in place */
2351
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2548
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2352
2549
ref_pointer_array_size);
2353
2550
if ((!having || having->val_int()))
2355
2552
int write_error;
2357
List_iterator_fast<Item> it(rollup.fields[i]);
2554
List<Item>::iterator it(rollup.getFields()[i].begin());
2358
2555
while ((item= it++))
2360
2557
if (item->type() == Item::NULL_ITEM && item->is_result_field())
4523
4724
if (join->tables > 1)
4524
4725
cond->update_used_tables(); // Tablenr may have changed
4525
4726
if (join->const_tables == join->tables &&
4526
session->lex->current_select->master_unit() ==
4527
&session->lex->unit) // not upper level SELECT
4727
session->lex().current_select->master_unit() ==
4728
&session->lex().unit) // not upper level SELECT
4528
4729
join->const_table_map|=RAND_TABLE_BIT;
4529
4730
{ // Check const tables
4530
4731
COND *const_cond=
4531
4732
make_cond_for_table(cond,
4532
4733
join->const_table_map,
4534
4735
for (JoinTable *tab= join->join_tab+join->const_tables;
4535
4736
tab < join->join_tab+join->tables ; tab++)
5446
5653
bool *hidden_group_fields)
5449
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
5656
nesting_map save_allow_sum_func=session->lex().allow_sum_func ;
5451
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5658
session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
5452
5659
res= session->setup_conds(tables, conds);
5454
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5661
session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
5455
5662
res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
5457
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5664
session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
5458
5665
res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
5459
5666
group, hidden_group_fields);
5460
session->lex->allow_sum_func= save_allow_sum_func;
5667
session->lex().allow_sum_func= save_allow_sum_func;
5591
5798
As we use bitmaps to represent the relation the complexity
5592
5799
of the algorithm is O((number of tables)^2).
5594
for (i= 0, s= stat ; i < table_count ; i++, s++)
5801
for (i= 0; i < table_count; i++)
5596
for (uint32_t j= 0 ; j < table_count ; j++)
5804
table= stat[i].table;
5806
if (!table->reginfo.join_tab->dependent)
5809
for (j= 0, s= stat; j < table_count; j++, s++)
5598
table= stat[j].table;
5599
5811
if (s->dependent & table->map)
5813
table_map was_dependent= s->dependent;
5600
5814
s->dependent |= table->reginfo.join_tab->dependent;
5815
if (i > j && s->dependent != was_dependent)
5603
s->table->maybe_null= 1;
5605
5823
/* Catch illegal cross references for outer joins */
5606
5824
for (i= 0, s= stat ; i < table_count ; i++, s++)
5785
6006
if (const_count && ! sargables.empty())
5787
vector<optimizer::SargableParam>::iterator iter= sargables.begin();
5788
while (iter != sargables.end())
6008
BOOST_FOREACH(vector<optimizer::SargableParam>::reference iter, sargables)
5790
Field *field= (*iter).getField();
5791
JoinTable *join_tab= field->getTable()->reginfo.join_tab;
5792
key_map possible_keys= field->key_start;
5793
possible_keys&= field->getTable()->keys_in_use_for_query;
6010
Field& field= *iter.getField();
6011
JoinTable *join_tab= field.getTable()->reginfo.join_tab;
6012
key_map possible_keys= field.key_start & field.getTable()->keys_in_use_for_query;
5794
6013
bool is_const= true;
5795
for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
is_const&= (*iter).isConstItem(j);
6014
for (uint32_t j= 0; j < iter.getNumValues(); j++)
6015
is_const&= iter.isConstItem(j);
5798
6017
join_tab[0].const_keys|= possible_keys;
6121
6339
if (!cond->fixed)
6122
6340
cond->fix_fields(session, (Item**)&cond);
6123
6342
if (join_tab->select)
6125
error=(int) cond->add(join_tab->select->cond);
6344
cond->add(join_tab->select->cond);
6126
6345
join_tab->select_cond=join_tab->select->cond=cond;
6128
else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6347
else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0, &error)))
6130
6348
join_tab->select_cond=cond;
6132
return(error ? true : false);
6135
6353
static void free_blobs(Field **ptr)