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/open_tables_state.h>
49
#include <drizzled/optimizer/position.h>
50
#include <drizzled/optimizer/sargable_param.h>
51
#include <drizzled/optimizer/key_use.h>
52
#include <drizzled/optimizer/range.h>
53
#include <drizzled/optimizer/sum.h>
54
#include <drizzled/optimizer/explain_plan.h>
55
#include <drizzled/optimizer/access_method_factory.h>
56
#include <drizzled/optimizer/access_method.h>
57
#include <drizzled/records.h>
58
#include <drizzled/probes.h>
59
#include <drizzled/internal/my_bit.h>
60
#include <drizzled/internal/my_sys.h>
61
#include <drizzled/internal/iocache.h>
62
#include <drizzled/plugin/storage_engine.h>
63
#include <drizzled/session.h>
64
#include <drizzled/select_result.h>
65
#include <drizzled/debug.h>
66
#include <drizzled/item/subselect.h>
67
#include <drizzled/my_hash.h>
68
#include <drizzled/sql_lex.h>
69
#include <drizzled/statistics_variables.h>
70
#include <drizzled/system_variables.h>
62
71
#include <algorithm>
64
73
using namespace std;
69
77
extern plugin::StorageEngine *heap_engine;
70
extern std::bitset<12> test_flags;
72
79
/** Declarations of static functions used in this source file. */
73
80
static bool make_group_fields(Join *main_join, Join *curr_join);
133
140
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
141
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
143
Join::Join(Session *session_arg,
144
List<Item> &fields_arg,
145
uint64_t select_options_arg,
146
select_result *result_arg) :
158
sort_and_group(false),
162
no_field_update(false),
164
resume_nested_loop(false),
165
no_const_tables(false),
166
select_distinct(false),
167
group_optimized_away(false),
171
skip_sort_order(false),
175
hidden_group_fields(false),
177
found_const_table_map(0),
184
fetch_limit(HA_POS_ERROR),
185
session(session_arg),
186
fields_list(fields_arg),
191
exec_tmp_table1(NULL),
192
exec_tmp_table2(NULL),
197
having_history(NULL),
198
select_options(select_options_arg),
200
lock(session_arg->open_tables.lock),
202
all_fields(fields_arg),
206
ref_pointer_array(NULL),
211
ref_pointer_array_size(0),
212
zero_result_cause(NULL),
215
join_tab_reexec(NULL)
217
select_distinct= test(select_options & SELECT_DISTINCT);
218
if (&fields_list != &fields_arg) /* only copy if not same*/
219
fields_list= fields_arg;
220
memset(&keyuse, 0, sizeof(keyuse));
221
tmp_table_param.init();
222
tmp_table_param.end_write_records= HA_POS_ERROR;
223
rollup.setState(Rollup::STATE_NONE);
227
* This method is currently only used when a subselect EXPLAIN is performed.
228
* I pulled out the init() method and have simply reset the values to what
229
* was previously in the init() method. See the note about the hack in
232
void Join::reset(Session *session_arg,
233
List<Item> &fields_arg,
234
uint64_t select_options_arg,
235
select_result *result_arg)
248
sort_and_group= false;
252
no_field_update= false;
254
resume_nested_loop= false;
255
no_const_tables= false;
256
select_distinct= false;
257
group_optimized_away= false;
261
skip_sort_order= false;
265
hidden_group_fields= false;
267
found_const_table_map= 0;
274
fetch_limit= HA_POS_ERROR;
275
session= session_arg;
276
fields_list= fields_arg;
281
exec_tmp_table1= NULL;
282
exec_tmp_table2= NULL;
287
having_history= NULL;
288
select_options= select_options_arg;
290
lock= session_arg->open_tables.lock;
292
all_fields= fields_arg;
296
ref_pointer_array= NULL;
301
ref_pointer_array_size= 0;
302
zero_result_cause= NULL;
305
join_tab_reexec= NULL;
306
select_distinct= test(select_options & SELECT_DISTINCT);
307
if (&fields_list != &fields_arg) /* only copy if not same*/
308
fields_list= fields_arg;
309
memset(&keyuse, 0, sizeof(keyuse));
310
tmp_table_param.init();
311
tmp_table_param.end_write_records= HA_POS_ERROR;
312
rollup.setState(Rollup::STATE_NONE);
315
bool Join::is_top_level_join() const
317
return (unit == &session->lex().unit && (unit->fake_select_lex == 0 ||
318
select_lex == unit->fake_select_lex));
137
322
Prepare of whole select (including sub queries in future).
1348
1531
curr_join->all_fields= *curr_all_fields;
1351
items1= items0 + all_fields.elements;
1534
items1= items0 + all_fields.size();
1352
1535
if (sort_and_group || curr_tmp_table->group)
1354
1537
if (change_to_use_tmp_fields(session, items1,
1355
1538
tmp_fields_list1, tmp_all_fields1,
1356
fields_list.elements, all_fields))
1539
fields_list.size(), all_fields))
1361
1544
if (change_refs_to_tmp_fields(session, items1,
1362
1545
tmp_fields_list1, tmp_all_fields1,
1363
fields_list.elements, all_fields))
1546
fields_list.size(), all_fields))
1366
1549
curr_join->tmp_all_fields1= tmp_all_fields1;
1497
1680
// No sum funcs anymore
1500
items2= items1 + all_fields.elements;
1683
items2= items1 + all_fields.size();
1501
1684
if (change_to_use_tmp_fields(session, items2,
1502
1685
tmp_fields_list2, tmp_all_fields2,
1503
fields_list.elements, tmp_all_fields1))
1686
fields_list.size(), tmp_all_fields1))
1505
1688
curr_join->tmp_fields_list2= tmp_fields_list2;
1506
1689
curr_join->tmp_all_fields2= tmp_all_fields2;
1547
1730
init_items_ref_array();
1548
items3= ref_pointer_array + (all_fields.elements*4);
1731
items3= ref_pointer_array + (all_fields.size() * 4);
1549
1732
setup_copy_fields(session, &curr_join->tmp_table_param,
1550
1733
items3, tmp_fields_list3, tmp_all_fields3,
1551
curr_fields_list->elements, *curr_all_fields);
1734
curr_fields_list->size(), *curr_all_fields);
1552
1735
tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
1553
1736
tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
1554
1737
tmp_table_param.save_copy_field_end= curr_join->tmp_table_param.copy_field_end;
1853
2038
We are not using tables anymore
1854
2039
Unlock all tables. We may be in an INSERT .... SELECT statement.
1856
if (can_unlock && lock && session->lock &&
2041
if (can_unlock && lock && session->open_tables.lock &&
1857
2042
!(select_options & SELECT_NO_UNLOCK) &&
1858
2043
!select_lex->subquery_in_having &&
1859
(select_lex == (session->lex->unit.fake_select_lex ?
1860
session->lex->unit.fake_select_lex : &session->lex->select_lex)))
2044
(select_lex == (session->lex().unit.fake_select_lex ?
2045
session->lex().unit.fake_select_lex : &session->lex().select_lex)))
1863
2048
TODO: unlock tables even if the join isn't top level select in the
2039
2231
((Item_sum *)item)->depended_from() == select_lex))
2040
2232
*func++= (Item_sum*) item;
2042
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2234
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2044
rollup.state= ROLLUP::STATE_READY;
2236
rollup.setState(Rollup::STATE_READY);
2045
2237
if (rollup_make_fields(field_list, send_fields, &func))
2046
return(true); // Should never happen
2238
return true; // Should never happen
2048
else if (rollup.state == ROLLUP::STATE_NONE)
2240
else if (rollup.getState() == Rollup::STATE_NONE)
2050
2242
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2051
2243
sum_funcs_end[i]= func;
2053
else if (rollup.state == ROLLUP::STATE_READY)
2245
else if (rollup.getState() == Rollup::STATE_READY)
2054
2246
return(false); // Don't put end marker
2055
2247
*func=0; // End marker
2072
2263
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 )))
2265
rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
2267
sizeof(List<Item>) +
2268
ref_pointer_array_size)
2269
* send_group_parts ));
2270
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);
2275
rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
2276
rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
2277
ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
2086
2280
Prepare space for field list for the different levels
2087
2281
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);
2283
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2285
rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2286
List<Item> *rollup_fields= &rollup.getFields()[i];
2287
rollup_fields->clear();
2288
rollup.getRefPointerArrays()[i]= ref_array;
2289
ref_array+= all_fields.size();
2292
for (uint32_t i= 0 ; i < send_group_parts; i++)
2294
for (uint32_t j= 0 ; j < fields_list.size() ; j++)
2296
rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2300
List<Item>::iterator it(all_fields.begin());
2104
2302
while ((item= it++))
2205
2403
uint32_t pos= send_group_parts - level -1;
2206
2404
bool real_fields= 0;
2208
List_iterator<Item> new_it(rollup.fields[pos]);
2209
Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2406
List<Item>::iterator new_it(rollup.getFields()[pos].begin());
2407
Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2210
2408
Order *start_group;
2212
2410
/* Point to first hidden field */
2213
Item **ref_array= ref_array_start + fields_arg.elements-1;
2411
Item **ref_array= ref_array_start + fields_arg.size()-1;
2215
2413
/* Remember where the sum functions ends for the previous level */
2216
2414
sum_funcs_end[pos+1]= *func;
2305
2503
int Join::rollup_send_data(uint32_t idx)
2308
for (i= send_group_parts ; i-- > idx ; )
2505
for (uint32_t i= send_group_parts ; i-- > idx ; )
2310
2507
/* Get reference pointers to sum functions in place */
2311
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2312
ref_pointer_array_size);
2508
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2313
2510
if ((!having || having->val_int()))
2315
if (send_records < unit->select_limit_cnt && do_send_rows &&
2316
result->send_data(rollup.fields[i]))
2512
if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2318
2516
send_records++;
2321
2519
/* Restore ref_pointer_array */
2322
2520
set_items_ref_array(current_ref_pointer_array);
2345
2544
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2348
for (i= send_group_parts ; i-- > idx ; )
2546
for (uint32_t i= send_group_parts ; i-- > idx ; )
2350
2548
/* Get reference pointers to sum functions in place */
2351
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2549
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2352
2550
ref_pointer_array_size);
2353
2551
if ((!having || having->val_int()))
2355
2553
int write_error;
2357
List_iterator_fast<Item> it(rollup.fields[i]);
2555
List<Item>::iterator it(rollup.getFields()[i].begin());
2358
2556
while ((item= it++))
2360
2558
if (item->type() == Item::NULL_ITEM && item->is_result_field())
4523
4725
if (join->tables > 1)
4524
4726
cond->update_used_tables(); // Tablenr may have changed
4525
4727
if (join->const_tables == join->tables &&
4526
session->lex->current_select->master_unit() ==
4527
&session->lex->unit) // not upper level SELECT
4728
session->lex().current_select->master_unit() ==
4729
&session->lex().unit) // not upper level SELECT
4528
4730
join->const_table_map|=RAND_TABLE_BIT;
4529
4731
{ // Check const tables
4530
4732
COND *const_cond=
4531
4733
make_cond_for_table(cond,
4532
4734
join->const_table_map,
4534
4736
for (JoinTable *tab= join->join_tab+join->const_tables;
4535
4737
tab < join->join_tab+join->tables ; tab++)
5446
5654
bool *hidden_group_fields)
5449
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
5657
nesting_map save_allow_sum_func=session->lex().allow_sum_func ;
5451
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5659
session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
5452
5660
res= session->setup_conds(tables, conds);
5454
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5662
session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
5455
5663
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);
5665
session->lex().allow_sum_func&= ~(1 << session->lex().current_select->nest_level);
5458
5666
res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
5459
5667
group, hidden_group_fields);
5460
session->lex->allow_sum_func= save_allow_sum_func;
5668
session->lex().allow_sum_func= save_allow_sum_func;
5591
5799
As we use bitmaps to represent the relation the complexity
5592
5800
of the algorithm is O((number of tables)^2).
5594
for (i= 0, s= stat ; i < table_count ; i++, s++)
5802
for (i= 0; i < table_count; i++)
5596
for (uint32_t j= 0 ; j < table_count ; j++)
5805
table= stat[i].table;
5807
if (!table->reginfo.join_tab->dependent)
5810
for (j= 0, s= stat; j < table_count; j++, s++)
5598
table= stat[j].table;
5599
5812
if (s->dependent & table->map)
5814
table_map was_dependent= s->dependent;
5600
5815
s->dependent |= table->reginfo.join_tab->dependent;
5816
if (i > j && s->dependent != was_dependent)
5603
s->table->maybe_null= 1;
5605
5824
/* Catch illegal cross references for outer joins */
5606
5825
for (i= 0, s= stat ; i < table_count ; i++, s++)
5785
6007
if (const_count && ! sargables.empty())
5787
vector<optimizer::SargableParam>::iterator iter= sargables.begin();
5788
while (iter != sargables.end())
6009
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;
6011
Field& field= *iter.getField();
6012
JoinTable *join_tab= field.getTable()->reginfo.join_tab;
6013
key_map possible_keys= field.key_start & field.getTable()->keys_in_use_for_query;
5794
6014
bool is_const= true;
5795
for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
is_const&= (*iter).isConstItem(j);
6015
for (uint32_t j= 0; j < iter.getNumValues(); j++)
6016
is_const&= iter.isConstItem(j);
5798
6018
join_tab[0].const_keys|= possible_keys;
6121
6340
if (!cond->fixed)
6122
6341
cond->fix_fields(session, (Item**)&cond);
6123
6343
if (join_tab->select)
6125
error=(int) cond->add(join_tab->select->cond);
6345
cond->add(join_tab->select->cond);
6126
6346
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,
6348
else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0, &error)))
6130
6349
join_tab->select_cond=cond;
6132
return(error ? true : false);
6135
6354
static void free_blobs(Field **ptr)