71
69
extern plugin::StorageEngine *heap_engine;
70
extern std::bitset<12> test_flags;
73
72
/** Declarations of static functions used in this source file. */
74
73
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);
74
static void calc_group_buffer(Join *join,order_st *group);
75
static bool alloc_group_fields(Join *join,order_st *group);
77
76
static uint32_t cache_record_length(Join *join, uint32_t index);
78
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
79
78
static bool get_best_combination(Join *join);
103
102
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
104
103
static bool make_join_readinfo(Join *join);
105
104
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);
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);
108
107
static int return_zero_rows(Join *join,
109
108
select_result *res,
110
109
TableList *tables,
122
121
List<Item> &fields,
123
122
List<Item> &all_fields,
127
126
bool *hidden_group_fields);
128
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
129
128
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);
129
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
131
130
static void reset_nj_counters(List<TableList> *join_list);
132
static bool test_if_subpart(Order *a,Order *b);
131
static bool test_if_subpart(order_st *a,order_st *b);
133
132
static void restore_prev_nj_state(JoinTable *last);
134
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
135
134
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
137
Prepare of whole select (including sub queries in future).
2012
1849
for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2014
1851
Item_subselect *subselect= sl->master_unit()->item;
2015
bool full_local= full && (!subselect ||
2016
(subselect->is_evaluated() &&
2017
!subselect->is_uncacheable()));
1852
bool full_local= full && (!subselect || subselect->is_evaluated());
2019
1854
If this join is evaluated, we can fully clean it up and clean up all
2020
1855
its underlying joins even if they are correlated -- they will not be
2226
2054
((Item_sum *)item)->depended_from() == select_lex))
2227
2055
*func++= (Item_sum*) item;
2229
if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2057
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2231
rollup.setState(Rollup::STATE_READY);
2059
rollup.state= ROLLUP::STATE_READY;
2232
2060
if (rollup_make_fields(field_list, send_fields, &func))
2233
return true; // Should never happen
2061
return(true); // Should never happen
2235
else if (rollup.getState() == Rollup::STATE_NONE)
2063
else if (rollup.state == ROLLUP::STATE_NONE)
2237
2065
for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2066
sum_funcs_end[i]= func;
2240
else if (rollup.getState() == Rollup::STATE_READY)
2068
else if (rollup.state == ROLLUP::STATE_READY)
2241
2069
return(false); // Don't put end marker
2242
2070
*func=0; // End marker
2258
2087
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())
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 )))
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);
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);
2275
2101
Prepare space for field list for the different levels
2276
2102
These will be filled up in rollup_make_fields()
2278
for (uint32_t i= 0 ; i < send_group_parts ; i++)
2104
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];
2106
rollup.null_items[i]= new (session->mem_root) Item_null_result();
2107
List<Item> *rollup_fields= &rollup.fields[i];
2282
2108
rollup_fields->empty();
2283
rollup.getRefPointerArrays()[i]= ref_array;
2109
rollup.ref_pointer_arrays[i]= ref_array;
2284
2110
ref_array+= all_fields.elements;
2287
for (uint32_t i= 0 ; i < send_group_parts; i++)
2112
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]);
2114
for (j=0 ; j < fields_list.elements ; j++)
2115
rollup.fields[i].push_back(rollup.null_items[i]);
2295
2117
List_iterator<Item> it(all_fields);
2297
2119
while ((item= it++))
2121
order_st *group_tmp;
2300
2122
bool found_in_group= 0;
2302
2124
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2498
2320
int Join::rollup_send_data(uint32_t idx)
2500
for (uint32_t i= send_group_parts ; i-- > idx ; )
2323
for (i= send_group_parts ; i-- > idx ; )
2502
2325
/* Get reference pointers to sum functions in place */
2503
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);
2505
2328
if ((!having || having->val_int()))
2507
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]))
2511
2333
send_records++;
2514
2336
/* Restore ref_pointer_array */
2515
2337
set_items_ref_array(current_ref_pointer_array);
2539
2360
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2541
for (uint32_t i= send_group_parts ; i-- > idx ; )
2363
for (i= send_group_parts ; i-- > idx ; )
2543
2365
/* Get reference pointers to sum functions in place */
2544
memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2366
memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2545
2367
ref_pointer_array_size);
2546
2368
if ((!having || having->val_int()))
2548
2370
int write_error;
2550
List_iterator_fast<Item> it(rollup.getFields()[i]);
2372
List_iterator_fast<Item> it(rollup.fields[i]);
2551
2373
while ((item= it++))
2553
2375
if (item->type() == Item::NULL_ITEM && item->is_result_field())
3097
2915
memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3099
2917
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;
2918
copy_funcs(join->tmp_table_param.items_to_copy);
3102
2919
if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3104
2921
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3210
3026
case REAL_RESULT:
3211
3027
key_length+= sizeof(double);
3214
3029
case INT_RESULT:
3215
3030
key_length+= sizeof(int64_t);
3218
3032
case DECIMAL_RESULT:
3219
key_length+= class_decimal_get_binary_size(group_item->max_length -
3033
key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
3034
(group_item->decimals ? 1 : 0),
3221
3035
group_item->decimals);
3224
3037
case STRING_RESULT:
3226
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)
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.
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.
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;
3058
key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3254
3063
/* This case should never be choosen */
3256
3065
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3262
3069
if (group_item->maybe_null)
3266
3072
join->tmp_table_param.group_length=key_length+null_parts;
3267
3073
join->tmp_table_param.group_parts=parts;
3268
3074
join->tmp_table_param.group_null_parts=null_parts;
5202
4999
Returns new sort order
5204
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)
5206
5003
if (join->tables == join->const_tables)
5207
5004
return change_list ? 0 : first_order; // No need to sort
5209
Order *order,**prev_ptr;
5006
order_st *order,**prev_ptr;
5210
5007
table_map first_table= join->join_tab[join->const_tables].table->map;
5211
5008
table_map not_const_tables= ~join->const_table_map;
5797
5594
As we use bitmaps to represent the relation the complexity
5798
5595
of the algorithm is O((number of tables)^2).
5800
for (i= 0; i < table_count; i++)
5597
for (i= 0, s= stat ; i < table_count ; i++, s++)
5803
table= stat[i].table;
5805
if (!table->reginfo.join_tab->dependent)
5808
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;
5810
5602
if (s->dependent & table->map)
5812
table_map was_dependent= s->dependent;
5813
5603
s->dependent |= table->reginfo.join_tab->dependent;
5814
if (i > j && s->dependent != was_dependent)
5606
s->table->maybe_null= 1;
5822
5608
/* Catch illegal cross references for outer joins */
5823
5609
for (i= 0, s= stat ; i < table_count ; i++, s++)
6102
5884
if (join->const_tables != join->tables)
6104
5886
optimize_keyuse(join, keyuse_array);
6105
// @note c_str() is not likely to be valid here if dtrace expects it to
6106
// exist for any period of time.
6107
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);
6108
5888
bool res= choose_plan(join, all_table_map & ~join->const_table_map);
6109
5889
DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);