43
43
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
44
44
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
45
45
DYNAMIC_ARRAY *keyuse);
46
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
46
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
47
47
JOIN_TAB *join_tab,
48
48
uint32_t tables, COND *conds,
49
49
COND_EQUAL *cond_equal,
55
55
table_map used_tables);
56
56
static bool choose_plan(JOIN *join,table_map join_tables);
58
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
58
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
59
59
table_map remaining_tables, uint32_t idx,
60
60
double record_count, double read_time);
61
61
static void optimize_straight_join(JOIN *join, table_map join_tables);
78
78
static uint32_t cache_record_length(JOIN *join,uint32_t index);
79
79
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
80
80
static bool get_best_combination(JOIN *join);
81
static store_key *get_store_key(THD *thd,
81
static store_key *get_store_key(Session *session,
82
82
KEYUSE *keyuse, table_map used_tables,
83
83
KEY_PART_INFO *key_part, unsigned char *key_buff,
84
84
uint32_t maybe_null);
95
95
List<Item> &fields, bool send_row,
96
96
uint64_t select_options, const char *info,
98
static COND *build_equal_items(THD *thd, COND *cond,
98
static COND *build_equal_items(Session *session, COND *cond,
99
99
COND_EQUAL *inherited,
100
100
List<TableList> *join_list,
101
101
COND_EQUAL **cond_equal_ref);
168
168
bool (*find_func) (Field *, void *), void *data);
169
169
static bool find_field_in_item_list (Field *field, void *data);
170
170
static bool find_field_in_order_list (Field *field, void *data);
171
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
171
static int create_sort_index(Session *session, JOIN *join, order_st *order,
172
172
ha_rows filesort_limit, ha_rows select_limit,
173
173
bool is_order_by);
174
174
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
176
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
176
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
177
177
ulong offset,Item *having);
178
static int remove_dup_with_hash_index(THD *thd,Table *table,
178
static int remove_dup_with_hash_index(Session *session,Table *table,
179
179
uint32_t field_count, Field **first_field,
181
181
ulong key_length,Item *having);
182
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count);
182
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
183
183
static ulong used_blob_length(CACHE_FIELD **ptr);
184
184
static bool store_record_in_cache(JOIN_CACHE *cache);
185
185
static void reset_cache_read(JOIN_CACHE *cache);
186
186
static void reset_cache_write(JOIN_CACHE *cache);
187
187
static void read_cached_record(JOIN_TAB *tab);
188
188
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
189
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
189
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
190
190
order_st *order, List<Item> &fields,
191
191
List<Item> &all_fields,
192
192
bool *all_order_by_fields_used);
196
196
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
197
197
static bool alloc_group_fields(JOIN *join,order_st *group);
198
198
// Create list for using with tempory table
199
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
199
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
200
200
List<Item> &new_list1,
201
201
List<Item> &new_list2,
202
202
uint32_t elements, List<Item> &items);
203
203
// Create list for using with tempory table
204
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
204
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
205
205
List<Item> &new_list1,
206
206
List<Item> &new_list2,
207
207
uint32_t elements, List<Item> &items);
208
208
static void init_tmptable_sum_functions(Item_sum **func);
209
209
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
210
210
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
211
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
212
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
211
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
212
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
213
213
static bool init_sum_functions(Item_sum **func, Item_sum **end);
214
214
static bool update_sum_func(Item_sum **func);
215
215
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
237
237
This handles SELECT with and without UNION.
240
bool handle_select(THD *thd, LEX *lex, select_result *result,
240
bool handle_select(Session *session, LEX *lex, select_result *result,
241
241
ulong setup_tables_done_option)
247
247
if (select_lex->master_unit()->is_union() ||
248
248
select_lex->master_unit()->fake_select_lex)
249
res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
249
res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
252
252
SELECT_LEX_UNIT *unit= &lex->unit;
253
253
unit->set_limit(unit->global_parameters);
254
session->session_marker= 0;
256
256
'options' of mysql_select will be set in JOIN, as far as JOIN for
257
257
every PS/SP execution new, we will not need reset this flag if
258
258
setup_tables_done_option changed for next rexecution
260
res= mysql_select(thd, &select_lex->ref_pointer_array,
260
res= mysql_select(session, &select_lex->ref_pointer_array,
261
261
(TableList*) select_lex->table_list.first,
262
262
select_lex->with_wild, select_lex->item_list,
263
263
select_lex->where,
267
267
(order_st*) select_lex->group_list.first,
268
268
select_lex->having,
269
269
(order_st*) lex->proc_list.first,
270
select_lex->options | thd->options |
270
select_lex->options | session->options |
271
271
setup_tables_done_option,
272
272
result, unit, select_lex);
274
res|= thd->is_error();
274
res|= session->is_error();
275
275
if (unlikely(res))
325
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
325
fix_inner_refs(Session *session, List<Item> &all_fields, SELECT_LEX *select,
326
326
Item **ref_pointer_array)
328
328
Item_outer_ref *ref;
383
383
ref->outer_ref= new_ref;
384
384
ref->ref= &ref->outer_ref;
386
if (!ref->fixed && ref->fix_fields(thd, 0))
386
if (!ref->fixed && ref->fix_fields(session, 0))
388
thd->used_tables|= item->used_tables();
388
session->used_tables|= item->used_tables();
403
403
order_st *group, bool *hidden_group_fields)
406
nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
408
thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
409
res= setup_conds(thd, tables, leaves, conds);
411
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
412
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
406
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
408
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
409
res= setup_conds(session, tables, leaves, conds);
411
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
412
res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
414
thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
415
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
414
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
415
res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
416
416
group, hidden_group_fields);
417
thd->lex->allow_sum_func= save_allow_sum_func;
417
session->lex->allow_sum_func= save_allow_sum_func;
459
459
join_list= &select_lex->top_join_list;
460
460
union_part= unit_arg->is_union();
462
thd->lex->current_select->is_item_list_lookup= 1;
462
session->lex->current_select->is_item_list_lookup= 1;
464
464
If we have already executed SELECT, then it have not sense to prevent
465
465
its table from update (see unique_table())
467
if (thd->derived_tables_processing)
467
if (session->derived_tables_processing)
468
468
select_lex->exclude_from_table_unique_test= true;
470
470
/* Check that all tables, fields, conds and order are ok */
472
472
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
473
setup_tables_and_check_access(thd, &select_lex->context, join_list,
473
setup_tables_and_check_access(session, &select_lex->context, join_list,
474
474
tables_list, &select_lex->leaf_tables,
481
481
table_ptr= table_ptr->next_leaf)
484
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
485
select_lex->setup_ref_array(thd, og_num) ||
486
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
484
if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
485
select_lex->setup_ref_array(session, og_num) ||
486
setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
487
487
&all_fields, 1) ||
488
setup_without_group(thd, (*rref_pointer_array), tables_list,
488
setup_without_group(session, (*rref_pointer_array), tables_list,
489
489
select_lex->leaf_tables, fields_list,
490
490
all_fields, &conds, order, group_list,
491
491
&hidden_group_fields))
498
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
499
thd->where="having clause";
500
thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
498
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
499
session->where="having clause";
500
session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
501
501
select_lex->having_fix_field= 1;
502
502
bool having_fix_rc= (!having->fixed &&
503
(having->fix_fields(thd, &having) ||
503
(having->fix_fields(session, &having) ||
504
504
having->check_cols(1)));
505
505
select_lex->having_fix_field= 0;
506
if (having_fix_rc || thd->is_error())
506
if (having_fix_rc || session->is_error())
507
507
return(-1); /* purecov: inspected */
508
thd->lex->allow_sum_func= save_allow_sum_func;
508
session->lex->allow_sum_func= save_allow_sum_func;
518
518
if ((subselect= select_lex->master_unit()->item))
520
bool do_semijoin= !test(thd->variables.optimizer_switch &
520
bool do_semijoin= !test(session->variables.optimizer_switch &
521
521
OPTIMIZER_SWITCH_NO_SEMIJOIN);
522
522
if (subselect->substype() == Item_subselect::IN_SUBS)
523
523
in_subs= (Item_in_subselect*)subselect;
544
544
!select_lex->master_unit()->first_select()->next_select() && // 2
545
545
!select_lex->group_list.elements && !order && // 3
546
546
!having && !select_lex->with_sum_func && // 4
547
thd->thd_marker && // 5
547
session->session_marker && // 5
548
548
select_lex->outer_select()->join && // (*)
549
549
select_lex->master_unit()->first_select()->leaf_tables && // (**)
572
572
/* Register the subquery for further processing */
573
select_lex->outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
574
in_subs->expr_join_nest= (TableList*)thd->thd_marker;
573
select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
574
in_subs->expr_join_nest= (TableList*)session->session_marker;
578
bool do_materialize= !test(thd->variables.optimizer_switch &
578
bool do_materialize= !test(session->variables.optimizer_switch &
579
579
OPTIMIZER_SWITCH_NO_MATERIALIZATION);
581
581
Check if the subquery predicate can be executed via materialization.
611
611
!select_lex->master_unit()->first_select()->next_select() && // 2
612
612
select_lex->master_unit()->first_select()->leaf_tables && // 3
613
thd->lex->sql_command == SQLCOM_SELECT) // *
613
session->lex->sql_command == SQLCOM_SELECT) // *
615
615
if (in_subs->is_top_level_item() && // 4
616
616
!in_subs->is_correlated && // 5
636
636
Item *item= *ord->item;
637
637
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
638
item->split_sum_func(thd, ref_pointer_array, all_fields);
638
item->split_sum_func(session, ref_pointer_array, all_fields);
642
642
if (having && having->with_sum_func)
643
having->split_sum_func2(thd, ref_pointer_array, all_fields,
643
having->split_sum_func2(session, ref_pointer_array, all_fields,
645
645
if (select_lex->inner_sum_func_list)
651
651
item_sum= item_sum->next;
652
item_sum->split_sum_func2(thd, ref_pointer_array,
652
item_sum->split_sum_func2(session, ref_pointer_array,
653
653
all_fields, item_sum->ref_by, false);
654
654
} while (item_sum != end);
657
657
if (select_lex->inner_refs_list.elements &&
658
fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
658
fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
1146
1146
SJ_TMP_TABLE *sjtbl;
1147
1147
uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
1148
if (!(sjtbl= (SJ_TMP_TABLE*)thd->alloc(sizeof(SJ_TMP_TABLE))) ||
1149
!(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) thd->alloc(tabs_size)))
1148
if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
1149
!(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
1151
1151
memcpy(sjtbl->tabs, sjtabs, tabs_size);
1152
1152
sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1228
1228
select_limit= HA_POS_ERROR;
1229
1229
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1230
1230
// Ignore errors of execution if option IGNORE present
1231
if (thd->lex->ignore)
1232
thd->lex->current_select->no_error= 1;
1231
if (session->lex->ignore)
1232
session->lex->current_select->no_error= 1;
1234
1234
#ifdef HAVE_REF_TO_FIELDS // Not done yet
1235
1235
/* Add HAVING to WHERE if possible */
1246
1246
Item_cond_and can't be fixed after creation, so we do not check
1249
conds->fix_fields(thd, &conds);
1250
conds->change_ref_to_fields(thd, tables_list);
1249
conds->fix_fields(session, &conds);
1250
conds->change_ref_to_fields(session, tables_list);
1251
1251
conds->top_level_item();
1329
1329
Preserve conditions for EXPLAIN.
1331
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
1331
if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
1333
1333
COND *table_independent_conds=
1334
1334
make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1345
1345
sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1347
1347
/* Calculate how to do the join */
1348
thd->set_proc_info("statistics");
1348
session->set_proc_info("statistics");
1349
1349
if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1350
thd->is_fatal_error)
1350
session->is_fatal_error)
1355
1355
/* Remove distinct if only const tables */
1356
1356
select_distinct= select_distinct && (const_tables != tables);
1357
thd->set_proc_info("preparing");
1357
session->set_proc_info("preparing");
1358
1358
if (result->initialize_tables(this))
1360
1360
return(1); // error == -1
1363
1363
!(select_options & SELECT_DESCRIBE) &&
1365
1365
!(conds->used_tables() & RAND_TABLE_BIT) ||
1366
select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
1366
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1368
1368
zero_result_cause= "no matching row in const table";
1372
if (!(thd->options & OPTION_BIG_SELECTS) &&
1373
best_read > (double) thd->variables.max_join_size &&
1372
if (!(session->options & OPTION_BIG_SELECTS) &&
1373
best_read > (double) session->variables.max_join_size &&
1374
1374
!(select_options & SELECT_DESCRIBE))
1375
1375
{ /* purecov: inspected */
1376
1376
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1380
if (const_tables && !thd->locked_tables &&
1380
if (const_tables && !session->locked_tables &&
1381
1381
!(select_options & SELECT_NO_UNLOCK))
1382
mysql_unlock_some_tables(thd, table, const_tables);
1382
mysql_unlock_some_tables(session, table, const_tables);
1383
1383
if (!conds && outer_join)
1385
1385
/* Handle the case where we have an OUTER JOIN without a WHERE */
1426
1426
if (conds &&!outer_join && const_table_map != found_const_table_map &&
1427
1427
(select_options & SELECT_DESCRIBE) &&
1428
select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
1428
select_lex->master_unit() == &session->lex->unit) // upper level SELECT
1430
1430
conds=new Item_int((int64_t) 0,1); // Always false
1541
1541
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
1542
1542
&tab->table->keys_in_use_for_order_by);
1543
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
1543
if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
1544
1544
order, fields_list, all_fields,
1545
1545
&all_order_fields_used)))
1806
1806
ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1808
!thd->lex->current_select->with_sum_func) ?
1808
!session->lex->current_select->with_sum_func) ?
1809
1809
select_limit : HA_POS_ERROR;
1811
1811
if (!(exec_tmp_table1=
1812
create_tmp_table(thd, &tmp_table_param, all_fields,
1812
create_tmp_table(session, &tmp_table_param, all_fields,
1814
1814
group_list ? 0 : select_distinct,
1815
1815
group_list && simple_group,
1837
1837
/* if group or order on first table, sort first */
1838
1838
if (group_list && simple_group)
1840
thd->set_proc_info("Sorting for group");
1841
if (create_sort_index(thd, this, group_list,
1840
session->set_proc_info("Sorting for group");
1841
if (create_sort_index(session, this, group_list,
1842
1842
HA_POS_ERROR, HA_POS_ERROR, false) ||
1843
1843
alloc_group_fields(this, group_list) ||
1844
1844
make_sum_func_list(all_fields, fields_list, 1) ||
1845
setup_sum_funcs(thd, sum_funcs))
1845
setup_sum_funcs(session, sum_funcs))
1853
1853
if (make_sum_func_list(all_fields, fields_list, 0) ||
1854
setup_sum_funcs(thd, sum_funcs))
1854
setup_sum_funcs(session, sum_funcs))
1859
1859
if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1861
thd->set_proc_info("Sorting for order");
1862
if (create_sort_index(thd, this, order,
1861
session->set_proc_info("Sorting for order");
1862
if (create_sort_index(session, this, order,
1863
1863
HA_POS_ERROR, HA_POS_ERROR, true))
2140
2140
curr_tmp_table= exec_tmp_table1;
2142
2142
/* Copy data to the temporary table */
2143
thd->set_proc_info("Copying to tmp table");
2143
session->set_proc_info("Copying to tmp table");
2144
2144
if (!curr_join->sort_and_group &&
2145
2145
curr_join->const_tables != curr_join->tables)
2146
2146
curr_join->join_tab[curr_join->const_tables].sorted= 0;
2161
2161
items1= items0 + all_fields.elements;
2162
2162
if (sort_and_group || curr_tmp_table->group)
2164
if (change_to_use_tmp_fields(thd, items1,
2164
if (change_to_use_tmp_fields(session, items1,
2165
2165
tmp_fields_list1, tmp_all_fields1,
2166
2166
fields_list.elements, all_fields))
2171
if (change_refs_to_tmp_fields(thd, items1,
2171
if (change_refs_to_tmp_fields(session, items1,
2172
2172
tmp_fields_list1, tmp_all_fields1,
2173
2173
fields_list.elements, all_fields))
2256
2256
if (curr_join->group_list)
2258
thd->set_proc_info("Creating sort index");
2258
session->set_proc_info("Creating sort index");
2259
2259
if (curr_join->join_tab == join_tab && save_join_tab())
2263
if (create_sort_index(thd, curr_join, curr_join->group_list,
2263
if (create_sort_index(session, curr_join, curr_join->group_list,
2264
2264
HA_POS_ERROR, HA_POS_ERROR, false) ||
2265
2265
make_group_fields(this, curr_join))
2292
2292
if (!curr_join->sort_and_group &&
2293
2293
curr_join->const_tables != curr_join->tables)
2294
2294
curr_join->join_tab[curr_join->const_tables].sorted= 0;
2295
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2295
if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2296
2296
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2298
2298
error= tmp_error;
2308
2308
items2= items1 + all_fields.elements;
2309
if (change_to_use_tmp_fields(thd, items2,
2309
if (change_to_use_tmp_fields(session, items2,
2310
2310
tmp_fields_list2, tmp_all_fields2,
2311
2311
fields_list.elements, tmp_all_fields1))
2326
2326
curr_join->join_free(); /* Free quick selects */
2327
2327
if (curr_join->select_distinct && ! curr_join->group_list)
2329
thd->set_proc_info("Removing duplicates");
2329
session->set_proc_info("Removing duplicates");
2330
2330
if (curr_join->tmp_having)
2331
2331
curr_join->tmp_having->update_used_tables();
2332
2332
if (remove_duplicates(curr_join, curr_tmp_table,
2356
2356
init_items_ref_array();
2357
2357
items3= ref_pointer_array + (all_fields.elements*4);
2358
setup_copy_fields(thd, &curr_join->tmp_table_param,
2358
setup_copy_fields(session, &curr_join->tmp_table_param,
2359
2359
items3, tmp_fields_list3, tmp_all_fields3,
2360
2360
curr_fields_list->elements, *curr_all_fields);
2361
2361
tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2379
2379
if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
2381
setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2382
thd->is_fatal_error)
2381
setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2382
session->is_fatal_error)
2385
2385
if (curr_join->group_list || curr_join->order)
2387
thd->set_proc_info("Sorting result");
2387
session->set_proc_info("Sorting result");
2388
2388
/* If we have already done the group, add HAVING to sorted table */
2389
2389
if (curr_join->tmp_having && ! curr_join->group_list &&
2390
2390
! curr_join->sort_and_group)
2463
2463
the query. XXX: it's never shown in EXPLAIN!
2464
2464
OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2466
if (create_sort_index(thd, curr_join,
2466
if (create_sort_index(session, curr_join,
2467
2467
curr_join->group_list ?
2468
2468
curr_join->group_list : curr_join->order,
2469
2469
curr_join->select_limit,
2487
/* XXX: When can we have here thd->is_error() not zero? */
2488
if (thd->is_error())
2487
/* XXX: When can we have here session->is_error() not zero? */
2488
if (session->is_error())
2490
error= thd->is_error();
2490
error= session->is_error();
2493
2493
curr_join->having= curr_join->tmp_having;
2494
2494
curr_join->fields= curr_fields_list;
2497
thd->set_proc_info("Sending data");
2497
session->set_proc_info("Sending data");
2498
2498
result->send_fields(*curr_fields_list,
2499
2499
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2500
2500
error= do_select(curr_join, curr_fields_list, NULL);
2501
thd->limit_found_rows= curr_join->send_records;
2501
session->limit_found_rows= curr_join->send_records;
2504
2504
/* Accumulate the counts from all join iterations of all join parts. */
2505
thd->examined_row_count+= curr_join->examined_rows;
2505
session->examined_row_count+= curr_join->examined_rows;
2508
2508
With EXPLAIN EXTENDED we have to restore original ref_array
2560
2560
An entry point to single-unit select (a select without UNION).
2562
@param thd thread handler
2562
@param session thread handler
2563
2563
@param rref_pointer_array a reference to ref_pointer_array of
2564
2564
the top-level select_lex for this query
2565
2565
@param tables list of all tables used in this query.
2604
mysql_select(THD *thd, Item ***rref_pointer_array,
2604
mysql_select(Session *session, Item ***rref_pointer_array,
2605
2605
TableList *tables, uint32_t wild_num, List<Item> &fields,
2606
2606
COND *conds, uint32_t og_num, order_st *order, order_st *group,
2607
2607
Item *having, order_st *proc_param, uint64_t select_options,
2649
if (!(join= new JOIN(thd, fields, select_options, result)))
2649
if (!(join= new JOIN(session, fields, select_options, result)))
2651
thd->set_proc_info("init");
2652
thd->used_tables=0; // Updated by setup_fields
2651
session->set_proc_info("init");
2652
session->used_tables=0; // Updated by setup_fields
2653
2653
if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2654
2654
conds, og_num, order, group, having, proc_param,
2655
2655
select_lex, unit)) == true)
2674
if (thd->lex->describe & DESCRIBE_EXTENDED)
2674
if (session->lex->describe & DESCRIBE_EXTENDED)
2676
2676
join->conds_history= join->conds;
2677
2677
join->having_history= (join->having?join->having:join->tmp_having);
2680
if (thd->is_error())
2680
if (session->is_error())
2685
if (thd->lex->describe & DESCRIBE_EXTENDED)
2685
if (session->lex->describe & DESCRIBE_EXTENDED)
2687
2687
select_lex->where= join->conds_history;
2688
2688
select_lex->having= join->having_history;
2716
static TableList *alloc_join_nest(THD *thd)
2716
static TableList *alloc_join_nest(Session *session)
2718
2718
TableList *tbl;
2719
if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
2719
if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
2720
2720
sizeof(nested_join_st))))
2722
2722
tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl +
2772
2772
SELECT_LEX *parent_lex= parent_join->select_lex;
2773
2773
TableList *emb_tbl_nest= NULL;
2774
2774
List<TableList> *emb_join_list= &parent_lex->top_join_list;
2775
THD *thd= parent_join->thd;
2775
Session *session= parent_join->session;
2778
2778
1. Find out where to put the predicate into.
2952
2952
Put the subquery's WHERE into semi-join's sj_on_expr
2953
2953
Add the subquery-induced equalities too.
2955
SELECT_LEX *save_lex= thd->lex->current_select;
2956
thd->lex->current_select=subq_lex;
2955
SELECT_LEX *save_lex= session->lex->current_select;
2956
session->lex->current_select=subq_lex;
2957
2957
if (!subq_pred->left_expr->fixed &&
2958
subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
2958
subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
2960
thd->lex->current_select=save_lex;
2960
session->lex->current_select=save_lex;
2962
2962
sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2963
2963
sj_nest->nested_join->sj_depends_on= subq_pred->used_tables() |
3024
3024
emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
3025
3025
sj_nest->sj_on_expr);
3026
emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
3026
emb_tbl_nest->on_expr->fix_fields(parent_join->session, &emb_tbl_nest->on_expr);
3030
3030
/* Inject into the WHERE */
3031
3031
parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
3032
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
3032
parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
3033
3033
parent_join->select_lex->where= parent_join->conds;
3359
3359
*****************************************************************************/
3362
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
3362
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
3364
3364
const key_map *keys,ha_rows limit)
3367
if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
3367
if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3368
3368
return(0); // Fatal error flag is set
3371
3371
select->head=table;
3372
3372
table->reginfo.impossible_range=0;
3373
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
3373
if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
3374
3374
limit, 0, false)) == 1)
3375
3375
return(select->quick->records);
3376
3376
if (error == -1)
3422
3422
JOIN_TAB *stat_vector[MAX_TABLES+1];
3424
3424
table_count=join->tables;
3425
stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
3426
stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3427
table_vector=(Table**) join->thd->alloc(sizeof(Table*)*(table_count*2));
3425
stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
3426
stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3427
table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
3428
3428
if (!stat || !stat_ref || !table_vector)
3429
3429
return(1); // Eom /* purecov: inspected */
3545
3545
if (conds || outer_join)
3546
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
3546
if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
3547
3547
conds, join->cond_equal,
3548
3548
~outer_join, join->select_lex, &sargables))
3771
records= get_quick_record_count(join->thd, select, s->table,
3771
records= get_quick_record_count(join->session, select, s->table,
3772
3772
&s->const_keys, join->row_limit);
3773
3773
s->quick=select->quick;
3774
3774
s->needed_reg=select->needed_reg;
4567
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4567
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4568
4568
uint32_t tables, COND *cond,
4569
4569
COND_EQUAL *cond_equal __attribute__((unused)),
4570
4570
table_map normal_tables, SELECT_LEX *select_lex,
4599
4599
sz= cmax(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
4600
(((thd->lex->current_select->cond_count+1)*2 +
4601
thd->lex->current_select->between_count)*m+1);
4602
if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
4600
(((session->lex->current_select->cond_count+1)*2 +
4601
session->lex->current_select->between_count)*m+1);
4602
if (!(key_fields=(KEY_FIELD*) session->alloc(sz)))
4603
4603
return true; /* purecov: inspected */
4605
4605
field= end= key_fields;
4898
4898
@param join pointer to the structure providing all context info
4900
4900
@param s the table to be joined by the function
4901
@param thd thread for the connection that submitted the query
4901
@param session thread for the connection that submitted the query
4902
4902
@param remaining_tables set of tables not included into the partial plan yet
4903
4903
@param idx the length of the partial plan
4904
4904
@param record_count estimate for the number of records returned by the
5164
5164
/* Limit the number of matched rows */
5166
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5166
set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5167
5167
if (table->covering_keys.is_set(key))
5169
5169
/* we can use only index tree */
5330
5330
/* Limit the number of matched rows */
5331
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5331
set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5332
5332
if (table->covering_keys.is_set(key))
5334
5334
/* we can use only index tree */
5458
5458
/* We read the table as many times as join buffer becomes full. */
5459
5459
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5461
(double) thd->variables.join_buff_size));
5461
(double) session->variables.join_buff_size));
5463
5463
We don't make full cartesian product between rows in the scanned
5464
5464
table and existing records because we skip all rows from the
5537
5537
choose_plan(JOIN *join, table_map join_tables)
5539
uint32_t search_depth= join->thd->variables.optimizer_search_depth;
5540
uint32_t prune_level= join->thd->variables.optimizer_prune_level;
5539
uint32_t search_depth= join->session->variables.optimizer_search_depth;
5540
uint32_t prune_level= join->session->variables.optimizer_prune_level;
5541
5541
bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5543
5543
join->cur_embedding_map= 0;
5585
5585
i.e. they have subqueries, unions or call stored procedures.
5586
5586
TODO: calculate a correct cost for a query with subqueries and UNIONs.
5588
if (join->thd->lex->is_single_level_stmt())
5589
join->thd->status_var.last_query_cost= join->best_read;
5588
if (join->session->lex->is_single_level_stmt())
5589
join->session->status_var.last_query_cost= join->best_read;
5740
5740
/* Find the best access method from 's' to the current partial plan */
5741
5741
advance_sj_state(join_tables, s);
5742
best_access_path(join, s, join->thd, join_tables, idx,
5742
best_access_path(join, s, join->session, join_tables, idx,
5743
5743
record_count, read_time);
5744
5744
/* compute the cost of the new plan extended with 's' */
5745
5745
record_count*= join->positions[idx].records_read;
6057
6057
when the depth is insufficient??)
6059
6059
/* Find the best access method from 's' to the current partial plan */
6060
best_access_path(join, s, thd, remaining_tables, idx,
6060
best_access_path(join, s, session, remaining_tables, idx,
6061
6061
record_count, read_time);
6062
6062
/* Compute the cost of extending the plan with 's' */
6063
6063
current_record_count= record_count * join->positions[idx].records_read;
6183
6183
double records, best;
6184
6184
advance_sj_state(rest_tables, s);
6185
best_access_path(join, s, thd, rest_tables, idx, record_count,
6185
best_access_path(join, s, session, rest_tables, idx, record_count,
6187
6187
records= join->positions[idx].records_read;
6188
6188
best= join->positions[idx].read_time;
6223
6223
Find how much space the prevous read not const tables takes in cache.
6226
static void calc_used_field_length(THD *thd __attribute__((unused)),
6226
static void calc_used_field_length(Session *session __attribute__((unused)),
6227
6227
JOIN_TAB *join_tab)
6229
6229
uint32_t null_fields,blobs,fields,rec_length;
6274
6274
JOIN_TAB *join_tab= *pos;
6275
6275
if (!join_tab->used_fieldlength) /* Not calced yet */
6276
calc_used_field_length(thd, join_tab);
6276
calc_used_field_length(session, join_tab);
6277
6277
length+=join_tab->used_fieldlength;
6464
6464
j->ref.key_parts=keyparts;
6465
6465
j->ref.key_length=length;
6466
6466
j->ref.key=(int) key;
6467
if (!(j->ref.key_buff= (unsigned char*) thd->calloc(ALIGN_SIZE(length)*2)) ||
6468
!(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
6467
if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
6468
!(j->ref.key_copy= (store_key**) session->alloc((sizeof(store_key*) *
6469
6469
(keyparts+1)))) ||
6470
!(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
6471
!(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
6470
!(j->ref.items= (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
6471
!(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
6498
6498
if (!keyuse->used_tables &&
6499
6499
!(join->select_options & SELECT_DESCRIBE))
6500
6500
{ // Compare against constant
6501
store_key_item tmp(thd, keyinfo->key_part[i].field,
6501
store_key_item tmp(session, keyinfo->key_part[i].field,
6502
6502
key_buff + maybe_null,
6503
6503
maybe_null ? key_buff : 0,
6504
6504
keyinfo->key_part[i].length, keyuse->val);
6505
if (thd->is_fatal_error)
6505
if (session->is_fatal_error)
6510
*ref_key++= get_store_key(thd,
6510
*ref_key++= get_store_key(session,
6511
6511
keyuse,join->const_table_map,
6512
6512
&keyinfo->key_part[i],
6513
6513
key_buff, maybe_null);
6552
6552
static store_key *
6553
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
6553
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6554
6554
KEY_PART_INFO *key_part, unsigned char *key_buff, uint32_t maybe_null)
6556
6556
if (!((~used_tables) & keyuse->used_tables)) // if const item
6558
return new store_key_const_item(thd,
6558
return new store_key_const_item(session,
6559
6559
key_part->field,
6560
6560
key_buff + maybe_null,
6561
6561
maybe_null ? key_buff : 0,
6568
6568
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6569
6569
Item_ref::DIRECT_REF &&
6570
6570
keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6571
return new store_key_field(thd,
6571
return new store_key_field(session,
6572
6572
key_part->field,
6573
6573
key_buff + maybe_null,
6574
6574
maybe_null ? key_buff : 0,
6575
6575
key_part->length,
6576
6576
((Item_field*) keyuse->val->real_item())->field,
6577
6577
keyuse->val->full_name());
6578
return new store_key_item(thd,
6578
return new store_key_item(session,
6579
6579
key_part->field,
6580
6580
key_buff + maybe_null,
6581
6581
maybe_null ? key_buff : 0,
6597
6597
Table *table= field->table;
6598
THD *thd= table->in_use;
6599
ha_rows cuted_fields=thd->cuted_fields;
6598
Session *session= table->in_use;
6599
ha_rows cuted_fields=session->cuted_fields;
6602
6602
we should restore old value of count_cuted_fields because
6603
6603
store_val_in_field can be called from mysql_insert
6604
6604
with select_insert, which make count_cuted_fields= 1
6606
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
6607
thd->count_cuted_fields= check_flag;
6606
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
6607
session->count_cuted_fields= check_flag;
6608
6608
error= item->save_in_field(field, 1);
6609
thd->count_cuted_fields= old_count_cuted_fields;
6610
return error || cuted_fields != thd->cuted_fields;
6609
session->count_cuted_fields= old_count_cuted_fields;
6610
return error || cuted_fields != session->cuted_fields;
6631
6631
if (!join->join_tab_reexec)
6633
6633
if (!(join->join_tab_reexec=
6634
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
6634
(JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
6635
6635
return(true); /* purecov: inspected */
6636
6636
if (join->tmp_join)
6637
6637
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6931
6931
if (join->tables > 1)
6932
6932
cond->update_used_tables(); // Tablenr may have changed
6933
6933
if (join->const_tables == join->tables &&
6934
thd->lex->current_select->master_unit() ==
6935
&thd->lex->unit) // not upper level SELECT
6934
session->lex->current_select->master_unit() ==
6935
&session->lex->unit) // not upper level SELECT
6936
6936
join->const_table_map|=RAND_TABLE_BIT;
6937
6937
{ // Check const tables
6938
6938
COND *const_cond=
7061
7061
/* Push condition to storage engine if this is enabled
7062
7062
and the condition is not guarded */
7063
7063
tab->table->file->pushed_cond= NULL;
7064
if (thd->variables.engine_condition_pushdown)
7064
if (session->variables.engine_condition_pushdown)
7066
7066
COND *push_cond=
7067
7067
make_cond_for_table(tmp, current_map, current_map, 0);
7130
7130
if (sel->cond && !sel->cond->fixed)
7131
7131
sel->cond->quick_fix_field();
7133
if (sel->test_quick_select(thd, tab->keys,
7133
if (sel->test_quick_select(session, tab->keys,
7134
7134
used_tables & ~ current_map,
7135
7135
(join->select_options &
7136
7136
OPTION_FOUND_ROWS ?
7145
7145
sel->cond=orig_cond;
7146
7146
if (!*tab->on_expr_ref ||
7147
sel->test_quick_select(thd, tab->keys,
7147
sel->test_quick_select(session, tab->keys,
7148
7148
used_tables & ~ current_map,
7149
7149
(join->select_options &
7150
7150
OPTION_FOUND_ROWS ?
7186
7186
current_map, 0)))
7188
7188
tab->cache.select=(SQL_SELECT*)
7189
thd->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7189
session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7190
7190
tab->cache.select->cond=tmp;
7191
7191
tab->cache.select->read_tables=join->const_table_map;
7543
7543
Item *idx_cond;
7544
7544
if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7545
tab->join->thd->variables.engine_condition_pushdown)
7545
tab->join->session->variables.engine_condition_pushdown)
7547
7547
idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7548
7548
other_tbls_ok);
7750
7750
!tab->insideout_match_tab)
7752
7752
if ((options & SELECT_DESCRIBE) ||
7753
!join_init_cache(join->thd,join->join_tab+join->const_tables,
7753
!join_init_cache(join->session,join->join_tab+join->const_tables,
7754
7754
i-join->const_tables))
7756
7756
using_join_cache= true;
7760
7760
/* These init changes read_record */
7761
7761
if (tab->use_quick == 2)
7763
join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7763
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7764
7764
tab->read_first_record= join_init_quick_read_record;
7765
7765
if (statistics)
7766
status_var_increment(join->thd->status_var.select_range_check_count);
7766
status_var_increment(join->session->status_var.select_range_check_count);
7773
7773
if (tab->select && tab->select->quick)
7775
7775
if (statistics)
7776
status_var_increment(join->thd->status_var.select_range_count);
7776
status_var_increment(join->session->status_var.select_range_count);
7780
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7780
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7781
7781
if (statistics)
7782
status_var_increment(join->thd->status_var.select_scan_count);
7782
status_var_increment(join->session->status_var.select_scan_count);
7787
7787
if (tab->select && tab->select->quick)
7789
7789
if (statistics)
7790
status_var_increment(join->thd->status_var.select_full_range_join_count);
7790
status_var_increment(join->session->status_var.select_full_range_join_count);
7794
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7794
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7795
7795
if (statistics)
7796
status_var_increment(join->thd->status_var.select_full_join_count);
7796
status_var_increment(join->session->status_var.select_full_join_count);
7799
7799
if (!table->no_keyread)
7985
7985
We are not using tables anymore
7986
7986
Unlock all tables. We may be in an INSERT .... SELECT statement.
7988
if (can_unlock && lock && thd->lock &&
7988
if (can_unlock && lock && session->lock &&
7989
7989
!(select_options & SELECT_NO_UNLOCK) &&
7990
7990
!select_lex->subquery_in_having &&
7991
(select_lex == (thd->lex->unit.fake_select_lex ?
7992
thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
7991
(select_lex == (session->lex->unit.fake_select_lex ?
7992
session->lex->unit.fake_select_lex : &session->lex->select_lex)))
7995
7995
TODO: unlock tables even if the join isn't top level select in the
7998
mysql_unlock_read_tables(thd, lock); // Don't free join->lock
7998
mysql_unlock_read_tables(session, lock); // Don't free join->lock
8706
8706
false otherwise
8709
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
8709
static bool check_row_equality(Session *session, Item *left_row, Item_row *right_row,
8710
8710
COND_EQUAL *cond_equal, List<Item>* eq_list)
8712
8712
uint32_t n= left_row->cols();
8718
8718
if (left_item->type() == Item::ROW_ITEM &&
8719
8719
right_item->type() == Item::ROW_ITEM)
8721
is_converted= check_row_equality(thd,
8721
is_converted= check_row_equality(session,
8722
8722
(Item_row *) left_item,
8723
8723
(Item_row *) right_item,
8724
8724
cond_equal, eq_list);
8725
8725
if (!is_converted)
8726
thd->lex->current_select->cond_count++;
8726
session->lex->current_select->cond_count++;
8730
8730
is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8731
thd->lex->current_select->cond_count++;
8731
session->lex->current_select->cond_count++;
8734
8734
if (!is_converted)
8775
8775
or, if the procedure fails by a fatal error.
8778
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
8778
static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal,
8779
8779
List<Item> *eq_list)
8781
8781
if (item->type() == Item::FUNC_ITEM &&
8787
8787
if (left_item->type() == Item::ROW_ITEM &&
8788
8788
right_item->type() == Item::ROW_ITEM)
8790
thd->lex->current_select->cond_count--;
8791
return check_row_equality(thd,
8790
session->lex->current_select->cond_count--;
8791
return check_row_equality(session,
8792
8792
(Item_row *) left_item,
8793
8793
(Item_row *) right_item,
8794
8794
cond_equal, eq_list);
8819
8819
just an argument of a comparison predicate.
8820
8820
The function also determines the maximum number of members in
8821
8821
equality lists of each Item_cond_and object assigning it to
8822
thd->lex->current_select->max_equal_elems.
8822
session->lex->current_select->max_equal_elems.
8825
8825
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8896
8896
structure here because it's restored before each
8897
8897
re-execution of any prepared statement/stored procedure.
8899
if (check_equality(thd, item, &cond_equal, &eq_list))
8899
if (check_equality(session, item, &cond_equal, &eq_list))
8950
8950
for WHERE a=b AND c=d AND (b=c OR d=5)
8951
8951
b=c is replaced by =(a,b,c,d).
8953
if (check_equality(thd, cond, &cond_equal, &eq_list))
8953
if (check_equality(session, cond, &cond_equal, &eq_list))
8955
8955
int n= cond_equal.current_level.elements + eq_list.elements;
8983
8983
item_equal->fix_length_and_dec();
8984
8984
item_equal->update_used_tables();
8985
set_if_bigger(thd->lex->current_select->max_equal_elems,
8985
set_if_bigger(session->lex->current_select->max_equal_elems,
8986
8986
item_equal->members());
8988
8988
and_cond->cond_equal= cond_equal;
9062
9062
can get more freedom in performing join operations.
9063
9063
Althogh we don't use this property now, it probably makes sense to use
9064
9064
it in the future.
9065
@param thd Thread handler
9065
@param session Thread handler
9066
9066
@param cond condition to build the multiple equalities for
9067
9067
@param inherited path to all inherited multiple equality items
9068
9068
@param join_list list of join tables to which the condition
9074
9074
pointer to the transformed condition containing multiple equalities
9077
static COND *build_equal_items(THD *thd, COND *cond,
9077
static COND *build_equal_items(Session *session, COND *cond,
9078
9078
COND_EQUAL *inherited,
9079
9079
List<TableList> *join_list,
9080
9080
COND_EQUAL **cond_equal_ref)
9086
cond= build_equal_items_for_cond(thd, cond, inherited);
9086
cond= build_equal_items_for_cond(session, cond, inherited);
9087
9087
cond->update_used_tables();
9088
9088
if (cond->type() == Item::COND_ITEM &&
9089
9089
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9117
9117
We can modify table->on_expr because its old value will
9118
9118
be restored before re-execution of PS/SP.
9120
table->on_expr= build_equal_items(thd, table->on_expr, inherited,
9120
table->on_expr= build_equal_items(session, table->on_expr, inherited,
9121
9121
nested_join_list,
9122
9122
&table->cond_equal);
9458
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
9458
change_cond_ref_to_const(Session *session, I_List<COND_CMP> *save_list,
9459
9459
Item *and_father, Item *cond,
9460
9460
Item *field, Item *value)
9466
9466
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9468
9468
while ((item=li++))
9469
change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
9469
change_cond_ref_to_const(session, save_list,and_level ? cond : item, item,
9493
thd->change_item_tree(args + 1, tmp);
9493
session->change_item_tree(args + 1, tmp);
9494
9494
func->update_used_tables();
9495
9495
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9496
9496
&& and_father != cond && !left_item->const_item())
9517
thd->change_item_tree(args, tmp);
9517
session->change_item_tree(args, tmp);
9519
9519
func->update_used_tables();
9520
9520
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9521
9521
&& and_father != cond && !right_item->const_item())
9523
9523
args[0]= args[1]; // For easy check
9524
thd->change_item_tree(args + 1, value);
9524
session->change_item_tree(args + 1, value);
9525
9525
cond->marker=1;
9526
9526
COND_CMP *tmp2;
9527
9527
if ((tmp2=new COND_CMP(and_father,func)))
9568
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
9568
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
9569
9569
COND *and_father, COND *cond)
9571
9571
if (cond->type() == Item::COND_ITEM)
9577
9577
I_List<COND_CMP> save;
9578
9578
while ((item=li++))
9580
propagate_cond_constants(thd, &save,and_level ? cond : item, item);
9580
propagate_cond_constants(session, &save,and_level ? cond : item, item);
9583
9583
{ // Handle other found items
9588
9588
Item **args= cond_cmp->cmp_func->arguments();
9589
9589
if (!args[0]->const_item())
9590
change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
9590
change_cond_ref_to_const(session, &save,cond_cmp->and_level,
9591
9591
cond_cmp->and_level, args[0], args[1]);
9608
9608
if (right_const)
9610
resolve_const_item(thd, &args[1], args[0]);
9610
resolve_const_item(session, &args[1], args[0]);
9611
9611
func->update_used_tables();
9612
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9612
change_cond_ref_to_const(session, save_list, and_father, and_father,
9613
9613
args[0], args[1]);
9615
9615
else if (left_const)
9617
resolve_const_item(thd, &args[0], args[1]);
9617
resolve_const_item(session, &args[0], args[1]);
9618
9618
func->update_used_tables();
9619
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9619
change_cond_ref_to_const(session, save_list, and_father, and_father,
9620
9620
args[1], args[0]);
10223
10223
predicate. Substitute a constant instead of this field if the
10224
10224
multiple equality contains a constant.
10226
conds= build_equal_items(join->thd, conds, NULL, join_list,
10226
conds= build_equal_items(join->session, conds, NULL, join_list,
10227
10227
&join->cond_equal);
10229
10229
/* change field = field to field = const for each found field = const */
10230
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
10230
propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10232
10232
Remove all instances of item == item
10233
10233
Remove all and-levels where CONST item != CONST item
10235
conds= remove_eq_conds(thd, conds, cond_value) ;
10235
conds= remove_eq_conds(session, conds, cond_value) ;
10237
10237
return(conds);
10330
10330
Field *field=((Item_field*) args[0])->field;
10331
10331
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
10332
(thd->options & OPTION_AUTO_IS_NULL) &&
10333
(thd->first_successful_insert_id_in_prev_stmt > 0 &&
10334
thd->substitute_null_with_insert_id))
10332
(session->options & OPTION_AUTO_IS_NULL) &&
10333
(session->first_successful_insert_id_in_prev_stmt > 0 &&
10334
session->substitute_null_with_insert_id))
10336
10336
COND *new_cond;
10337
10337
if ((new_cond= new Item_func_eq(args[0],
10338
10338
new Item_int("last_insert_id()",
10339
thd->read_first_successful_insert_id_in_prev_stmt(),
10339
session->read_first_successful_insert_id_in_prev_stmt(),
10340
10340
MY_INT64_NUM_DECIMAL_DIGITS))))
10342
10342
cond=new_cond;
10345
10345
cond->fixed, also it do not need tables so we use 0 as second
10348
cond->fix_fields(thd, &cond);
10348
cond->fix_fields(session, &cond);
10351
10351
IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10352
10352
clear for next row
10354
thd->substitute_null_with_insert_id= false;
10354
session->substitute_null_with_insert_id= false;
10356
10356
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10357
10357
else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10697
10697
rc= sub_select(join,join_tab,end_of_records);
10700
if (join->thd->killed) // If aborted by user
10700
if (join->session->killed) // If aborted by user
10702
join->thd->send_kill_message();
10702
join->session->send_kill_message();
10703
10703
return NESTED_LOOP_KILLED; /* purecov: inspected */
10705
10705
if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10877
10877
/* Set first_unmatched for the last inner table of this group */
10878
10878
join_tab->last_inner->first_unmatched= join_tab;
10880
join->thd->row_count= 0;
10880
join->session->row_count= 0;
10882
10882
error= (*join_tab->read_first_record)(join_tab);
10883
10883
rc= evaluate_join_record(join, join_tab, error);
10971
10971
/* create_myisam_from_heap will generate error if needed */
10972
10972
if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10973
create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo,
10973
create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo,
10974
10974
&sjtbl->recinfo, error, 1))
10976
10976
//return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11007
11007
ha_rows found_records=join->found_records;
11008
11008
COND *select_cond= join_tab->select_cond;
11010
if (error > 0 || (join->thd->is_error())) // Fatal error
11010
if (error > 0 || (join->session->is_error())) // Fatal error
11011
11011
return NESTED_LOOP_ERROR;
11012
11012
if (error < 0)
11013
11013
return NESTED_LOOP_NO_MORE_ROWS;
11014
if (join->thd->killed) // Aborted by user
11014
if (join->session->killed) // Aborted by user
11016
join->thd->send_kill_message();
11016
join->session->send_kill_message();
11017
11017
return NESTED_LOOP_KILLED; /* purecov: inspected */
11019
11019
if (!select_cond || select_cond->val_int())
11076
11076
join_tab->found_match= true;
11077
11077
if (join_tab->check_weed_out_table)
11079
int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
11079
int res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table);
11080
11080
if (res == -1)
11081
11081
return NESTED_LOOP_ERROR;
11082
11082
if (res == 1)
11239
11239
info= &join_tab->read_record;
11242
if (join->thd->killed)
11242
if (join->session->killed)
11244
join->thd->send_kill_message();
11244
join->session->send_kill_message();
11245
11245
return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11247
11247
SQL_SELECT *select=join_tab->select;
11259
11259
if (!join_tab->check_weed_out_table ||
11260
!(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
11260
!(res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table)))
11262
11262
rc= (join_tab->next_select)(join,join_tab+1,0);
11263
11263
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11568
11568
if (!table->file->inited)
11569
11569
table->file->ha_index_init(tab->ref.key, tab->sorted);
11570
if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11570
if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11572
11572
if ((error=table->file->index_read_last_map(table->record[0],
11573
11573
tab->ref.key_buff,
11685
11685
delete tab->select->quick;
11686
11686
tab->select->quick=0;
11687
return tab->select->test_quick_select(tab->join->thd, tab->keys,
11687
return tab->select->test_quick_select(tab->join->session, tab->keys,
11688
11688
(table_map) 0, HA_POS_ERROR, 0,
11696
11696
if (tab->select && tab->select->quick && tab->select->quick->reset())
11698
init_read_record(&tab->read_record, tab->join->thd, tab->table,
11698
init_read_record(&tab->read_record, tab->join->session, tab->table,
11699
11699
tab->select,1,1);
11700
11700
return (*tab->read_record.read_record)(&tab->read_record);
12049
12049
Table *table=join->tmp_table;
12051
if (join->thd->killed) // Aborted by user
12051
if (join->session->killed) // Aborted by user
12053
join->thd->send_kill_message();
12053
join->session->send_kill_message();
12054
12054
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12056
12056
if (!end_of_records)
12058
12058
copy_fields(&join->tmp_table_param);
12059
12059
copy_funcs(join->tmp_table_param.items_to_copy);
12060
#ifdef TO_BE_DELETED
12061
if (!table->uniques) // If not unique handling
12063
/* Copy null values from group to row */
12065
for (group=table->group ; group ; group=group->next)
12067
Item *item= *group->item;
12068
if (item->maybe_null)
12070
Field *field=item->get_tmp_table_field();
12071
field->ptr[-1]= (unsigned char) (field->is_null() ? 1 : 0);
12076
12060
if (!join->having || join->having->val_int())
12082
12066
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12084
if (create_myisam_from_heap(join->thd, table,
12068
if (create_myisam_from_heap(join->session, table,
12085
12069
join->tmp_table_param.start_recinfo,
12086
12070
&join->tmp_table_param.recinfo,
12166
12150
copy_funcs(join->tmp_table_param.items_to_copy);
12167
12151
if ((error=table->file->ha_write_row(table->record[0])))
12169
if (create_myisam_from_heap(join->thd, table,
12153
if (create_myisam_from_heap(join->session, table,
12170
12154
join->tmp_table_param.start_recinfo,
12171
12155
&join->tmp_table_param.recinfo,
12236
12220
Table *table=join->tmp_table;
12239
if (join->thd->killed)
12223
if (join->session->killed)
12240
12224
{ // Aborted by user
12241
join->thd->send_kill_message();
12225
join->session->send_kill_message();
12242
12226
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12244
12228
if (!join->first_record || end_of_records ||
12259
12243
if (!join->having || join->having->val_int())
12261
12245
int error= table->file->ha_write_row(table->record[0]);
12262
if (error && create_myisam_from_heap(join->thd, table,
12246
if (error && create_myisam_from_heap(join->session, table,
12263
12247
join->tmp_table_param.start_recinfo,
12264
12248
&join->tmp_table_param.recinfo,
12363
12347
@param join The top-level query.
12364
12348
@param old_cond The expression to be replaced.
12365
12349
@param new_cond The expression to be substituted.
12366
@param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
12350
@param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
12367
12351
the new expression.
12368
12352
@return <code>true</code> if there was an error, <code>false</code> if
12995
12979
new_ref_key_map.clear_all(); // Force the creation of quick select
12996
12980
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12998
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
12982
if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
12999
12983
(tab->join->select_options &
13000
12984
OPTION_FOUND_ROWS) ?
13001
12985
HA_POS_ERROR :
13182
13166
map.clear_all(); // Force the creation of quick select
13183
13167
map.set_bit(best_key); // only best_key.
13184
13168
quick_created=
13185
select->test_quick_select(join->thd, map, 0,
13169
select->test_quick_select(join->session, map, 0,
13186
13170
join->select_options & OPTION_FOUND_ROWS ?
13187
13171
HA_POS_ERROR :
13188
13172
join->unit->select_limit_cnt,
13329
create_sort_index(THD *thd, JOIN *join, order_st *order,
13313
create_sort_index(Session *session, JOIN *join, order_st *order,
13330
13314
ha_rows filesort_limit, ha_rows select_limit,
13331
13315
bool is_order_by)
13390
13374
For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13391
13375
field, quick will contain an empty record set.
13393
if (!(select->quick= (get_quick_select_for_ref(thd, table, &tab->ref,
13377
if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref,
13394
13378
tab->found_records))))
13404
13388
if (table->s->tmp_table)
13405
13389
table->file->info(HA_STATUS_VARIABLE); // Get record count
13406
table->sort.found_records=filesort(thd, table,join->sortorder, length,
13390
table->sort.found_records=filesort(session, table,join->sortorder, length,
13407
13391
select, filesort_limit, 0,
13408
13392
&examined_rows);
13409
13393
tab->records= table->sort.found_records; // For SQL_CALC_ROWS
13485
13469
if (entry->s->db_type() == heap_hton ||
13486
13470
(!entry->s->blob_fields &&
13487
13471
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13488
thd->variables.sortbuff_size)))
13489
error=remove_dup_with_hash_index(join->thd, entry,
13472
session->variables.sortbuff_size)))
13473
error=remove_dup_with_hash_index(join->session, entry,
13490
13474
field_count, first_field,
13491
13475
reclength, having);
13493
error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13477
error=remove_dup_with_compare(join->session, entry, first_field, offset,
13496
13480
free_blobs(first_field);
13501
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
13485
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13502
13486
ulong offset, Item *having)
13504
13488
handler *file=table->file;
13740
13724
******************************************************************************/
13743
join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count)
13727
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
13745
13729
register unsigned int i;
13746
13730
unsigned int length, blobs;
13756
13740
for (i=0 ; i < table_count ; i++,join_tab++)
13758
13742
if (!join_tab->used_fieldlength) /* Not calced yet */
13759
calc_used_field_length(thd, join_tab);
13743
calc_used_field_length(session, join_tab);
13760
13744
cache->fields+=join_tab->used_fields;
13761
13745
blobs+=join_tab->used_blobs;
13849
13833
cache->length=length+blobs*sizeof(char*);
13850
13834
cache->blobs=blobs;
13851
13835
*blob_ptr=0; /* End sequentel */
13852
size=cmax(thd->variables.join_buff_size, (ulong)cache->length);
13836
size=cmax(session->variables.join_buff_size, (ulong)cache->length);
13853
13837
if (!(cache->buff=(unsigned char*) my_malloc(size,MYF(0))))
13854
13838
return(1); /* Don't use cache */ /* purecov: inspected */
13855
13839
cache->end=cache->buff+size;
14049
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
14033
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
14051
enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
14052
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
14035
enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
14036
session->count_cuted_fields= CHECK_FIELD_IGNORE;
14053
14037
bool result= 0;
14055
14039
for (store_key **copy=ref->key_copy ; *copy ; copy++)
14086
14070
ref_pointer_array and all_fields are updated.
14088
@param[in] thd Pointer to current thread structure
14072
@param[in] session Pointer to current thread structure
14089
14073
@param[in,out] ref_pointer_array All select, group and order by fields
14090
14074
@param[in] tables List of tables to search in (usually
14106
find_order_in_list(THD *thd, Item **ref_pointer_array, TableList *tables,
14090
find_order_in_list(Session *session, Item **ref_pointer_array, TableList *tables,
14107
14091
order_st *order, List<Item> &fields, List<Item> &all_fields,
14108
14092
bool is_group_field)
14124
14108
if (!count || count > fields.elements)
14126
14110
my_error(ER_BAD_FIELD_ERROR, MYF(0),
14127
order_item->full_name(), thd->where);
14111
order_item->full_name(), session->where);
14130
14114
order->item= ref_pointer_array + count - 1;
14150
14134
for this name (in case if we would perform lookup in all tables).
14152
14136
if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14153
order_item->fix_fields(thd, order->item))
14137
order_item->fix_fields(session, order->item))
14156
14140
/* Lookup the current GROUP field in the FROM clause. */
14159
14143
if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14160
14144
order_item_type == Item::REF_ITEM)
14162
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
14146
from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
14163
14147
NULL, &view_ref, IGNORE_ERRORS, true,
14165
14149
if (!from_field)
14199
14183
warning so the user knows that the field from the FROM clause
14200
14184
overshadows the column reference from the SELECT list.
14202
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14186
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14203
14187
ER(ER_NON_UNIQ_ERROR),
14204
14188
((Item_ident*) order_item)->field_name,
14205
current_thd->where);
14189
current_session->where);
14219
14203
arguments for which fix_fields already was called.
14221
14205
if (!order_item->fixed &&
14222
(order_item->fix_fields(thd, order->item) ||
14206
(order_item->fix_fields(session, order->item) ||
14223
14207
(order_item= *order->item)->check_cols(1) ||
14224
thd->is_fatal_error))
14208
session->is_fatal_error))
14225
14209
return true; /* Wrong field. */
14227
14211
uint32_t el= all_fields.elements;
14239
14223
the field list.
14242
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
14226
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14243
14227
List<Item> &fields, List<Item> &all_fields, order_st *order)
14245
thd->where="order clause";
14229
session->where="order clause";
14246
14230
for (; order; order=order->next)
14248
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
14232
if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
14249
14233
all_fields, false))
14283
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
14267
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
14284
14268
List<Item> &fields, List<Item> &all_fields, order_st *order,
14285
14269
bool *hidden_group_fields)
14293
14277
uint32_t org_fields=all_fields.elements;
14295
thd->where="group statement";
14279
session->where="group statement";
14296
14280
for (ord= order; ord; ord= ord->next)
14298
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
14282
if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
14299
14283
all_fields, true))
14301
14285
(*ord->item)->marker= UNDEF_POS; /* Mark found */
14379
14363
static order_st *
14380
create_distinct_group(THD *thd, Item **ref_pointer_array,
14364
create_distinct_group(Session *session, Item **ref_pointer_array,
14381
14365
order_st *order_list, List<Item> &fields,
14382
14366
List<Item> &all_fields __attribute__((unused)),
14383
14367
bool *all_order_by_fields_used)
14671
14655
for (; group ; group=group->next)
14673
Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
14657
Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
14674
14658
if (!tmp || join->group_fields.push_front(tmp))
14717
14701
Change old item_field to use a new field with points at saved fieldvalue
14718
14702
This function is only called before use of send_fields.
14720
@param thd THD pointer
14704
@param session Session pointer
14721
14705
@param param temporary table parameters
14722
14706
@param ref_pointer_array array of pointers to top elements of filed list
14723
14707
@param res_selected_fields new list of items of select item list
14741
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
14725
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
14742
14726
Item **ref_pointer_array,
14743
14727
List<Item> &res_selected_fields, List<Item> &res_all_fields,
14744
14728
uint32_t elements, List<Item> &all_fields)
14801
14785
field= item->field;
14802
item->result_field=field->new_field(thd->mem_root,field->table, 1);
14786
item->result_field=field->new_field(session->mem_root,field->table, 1);
14804
14788
We need to allocate one extra byte for null handling and
14805
14789
another extra byte to not get warnings from purify in
14994
14978
Change all funcs and sum_funcs to fields in tmp table, and create
14995
14979
new list of all items.
14997
@param thd THD pointer
14981
@param session Session pointer
14998
14982
@param ref_pointer_array array of pointers to top elements of filed list
14999
14983
@param res_selected_fields new list of items of select item list
15000
14984
@param res_all_fields new list of all items
15011
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
14995
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
15012
14996
List<Item> &res_selected_fields,
15013
14997
List<Item> &res_all_fields,
15014
14998
uint32_t elements, List<Item> &all_fields)
15074
15058
Change all sum_func refs to fields to point at fields in tmp table.
15075
15059
Change all funcs to be fields in tmp table.
15077
@param thd THD pointer
15061
@param session Session pointer
15078
15062
@param ref_pointer_array array of pointers to top elements of filed list
15079
15063
@param res_selected_fields new list of items of select item list
15080
15064
@param res_all_fields new list of all items
15091
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
15075
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
15092
15076
List<Item> &res_selected_fields,
15093
15077
List<Item> &res_all_fields, uint32_t elements,
15094
15078
List<Item> &all_fields)
15101
15085
uint32_t i, border= all_fields.elements - elements;
15102
15086
for (i= 0; (item= it++); i++)
15104
res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
15088
res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
15105
15089
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15239
15223
Item *value=join_tab->ref.items[i];
15240
15224
cond->add(new Item_func_equal(new Item_field(field), value));
15242
if (thd->is_fatal_error)
15226
if (session->is_fatal_error)
15243
15227
return(true);
15245
15229
if (!cond->fixed)
15246
cond->fix_fields(thd, (Item**)&cond);
15230
cond->fix_fields(session, (Item**)&cond);
15247
15231
if (join_tab->select)
15249
15233
error=(int) cond->add(join_tab->select->cond);
15261
15245
Free joins of subselect of this select.
15263
@param thd THD pointer
15247
@param session Session pointer
15264
15248
@param select pointer to st_select_lex which subselects joins we will free
15267
void free_underlaid_joins(THD *thd __attribute__((unused)),
15251
void free_underlaid_joins(Session *session __attribute__((unused)),
15268
15252
SELECT_LEX *select)
15270
15254
for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15302
15286
This substitution is needed GROUP BY queries with ROLLUP if
15303
15287
SELECT list contains expressions over group by attributes.
15305
@param thd reference to the context
15289
@param session reference to the context
15306
15290
@param expr expression to make replacement
15307
15291
@param group_list list of references to group by items
15308
15292
@param changed out: returns 1 if item contains a replaced field item
15320
static bool change_group_ref(THD *thd, Item_func *expr, order_st *group_list,
15304
static bool change_group_ref(Session *session, Item_func *expr, order_st *group_list,
15321
15305
bool *changed)
15323
15307
if (expr->arg_count)
15325
Name_resolution_context *context= &thd->lex->current_select->context;
15309
Name_resolution_context *context= &session->lex->current_select->context;
15326
15310
Item **arg,**arg_end;
15327
15311
bool arg_changed= false;
15328
15312
for (arg= expr->arguments(),
15341
15325
if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15342
15326
item->name)))
15343
15327
return 1; // fatal_error is set
15344
thd->change_item_tree(arg, new_item);
15328
session->change_item_tree(arg, new_item);
15345
15329
arg_changed= true;
15349
15333
else if (item->type() == Item::FUNC_ITEM)
15351
if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
15335
if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
15437
15421
Item* new_item= new Item_func_rollup_const(item);
15438
15422
if (!new_item)
15440
new_item->fix_fields(thd, (Item **) 0);
15441
thd->change_item_tree(it.ref(), new_item);
15424
new_item->fix_fields(session, (Item **) 0);
15425
session->change_item_tree(it.ref(), new_item);
15442
15426
for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15444
15428
if (*tmp->item == item)
15445
thd->change_item_tree(tmp->item, new_item);
15429
session->change_item_tree(tmp->item, new_item);
15450
15434
if (item->type() == Item::FUNC_ITEM && !found_in_group)
15452
15436
bool changed= false;
15453
if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
15437
if (change_group_ref(session, (Item_func *) item, group_list, &changed))
15456
15440
We have to prevent creation of a field in a temporary table for
15677
15661
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15678
15662
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15680
if (create_myisam_from_heap(thd, table_arg,
15664
if (create_myisam_from_heap(session, table_arg,
15681
15665
tmp_table_param.start_recinfo,
15682
15666
&tmp_table_param.recinfo,
15683
15667
write_error, 0))
15720
15704
List<Item> field_list;
15721
15705
List<Item> item_list;
15722
THD *thd=join->thd;
15706
Session *session=join->session;
15723
15707
select_result *result=join->result;
15724
15708
Item *item_null= new Item_null();
15725
15709
const CHARSET_INFO * const cs= system_charset_info;
15726
15710
int quick_type;
15727
15711
/* Don't log this into the slow query log */
15728
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15712
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15729
15713
join->unit->offset_limit_cnt= 0;
15732
15716
NOTE: the number/types of items pushed into item_list must be in sync with
15733
EXPLAIN column types as they're "defined" in THD::send_explain_fields()
15717
EXPLAIN column types as they're "defined" in Session::send_explain_fields()
15740
15724
strlen(join->select_lex->type), cs));
15741
15725
for (uint32_t i=0 ; i < 7; i++)
15742
15726
item_list.push_back(item_null);
15743
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15727
if (join->session->lex->describe & DESCRIBE_EXTENDED)
15744
15728
item_list.push_back(item_null);
15746
15730
item_list.push_back(new Item_string(message,strlen(message),cs));
16065
16049
const COND *pushed_cond= tab->table->file->pushed_cond;
16067
if (thd->variables.engine_condition_pushdown && pushed_cond)
16051
if (session->variables.engine_condition_pushdown && pushed_cond)
16069
16053
extra.append(STRING_WITH_LEN("; Using where with pushed "
16070
16054
"condition"));
16071
if (thd->lex->describe & DESCRIBE_EXTENDED)
16055
if (session->lex->describe & DESCRIBE_EXTENDED)
16073
16057
extra.append(STRING_WITH_LEN(": "));
16074
16058
((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16123
16107
need_order=0;
16124
16108
extra.append(STRING_WITH_LEN("; Using filesort"));
16126
if (distinct & test_all_bits(used_tables,thd->used_tables))
16110
if (distinct & test_all_bits(used_tables,session->used_tables))
16127
16111
extra.append(STRING_WITH_LEN("; Distinct"));
16129
16113
if (tab->insideout_match_tab)
16186
16170
unit= unit->next_unit())
16188
if (mysql_explain_union(thd, unit, result))
16172
if (mysql_explain_union(session, unit, result))
16195
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
16179
bool mysql_explain_union(Session *session, SELECT_LEX_UNIT *unit, select_result *result)
16198
16182
SELECT_LEX *first= unit->first_select();
16204
16188
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16205
16189
uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16206
sl->type= (((&thd->lex->select_lex)==sl)?
16190
sl->type= (((&session->lex->select_lex)==sl)?
16207
16191
(sl->first_inner_unit() || sl->next_select() ?
16208
16192
"PRIMARY" : "SIMPLE"):
16209
16193
((sl == first)?
16224
16208
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16225
16209
unit->fake_select_lex->type= "UNION RESULT";
16226
16210
unit->fake_select_lex->options|= SELECT_DESCRIBE;
16227
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16211
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16228
16212
res= unit->exec();
16229
16213
res|= unit->cleanup();
16233
thd->lex->current_select= first;
16217
session->lex->current_select= first;
16234
16218
unit->set_limit(unit->global_parameters);
16235
res= mysql_select(thd, &first->ref_pointer_array,
16219
res= mysql_select(session, &first->ref_pointer_array,
16236
16220
(TableList*) first->table_list.first,
16237
16221
first->with_wild, first->item_list,
16238
16222
first->where,
16241
16225
(order_st*) first->order_list.first,
16242
16226
(order_st*) first->group_list.first,
16243
16227
first->having,
16244
(order_st*) thd->lex->proc_list.first,
16245
first->options | thd->options | SELECT_DESCRIBE,
16228
(order_st*) session->lex->proc_list.first,
16229
first->options | session->options | SELECT_DESCRIBE,
16246
16230
result, unit, first);
16248
return(res || thd->is_error());
16232
return(res || session->is_error());
16252
static void print_table_array(THD *thd, String *str, TableList **table,
16236
static void print_table_array(Session *session, String *str, TableList **table,
16253
16237
TableList **end)
16255
(*table)->print(thd, str, QT_ORDINARY);
16239
(*table)->print(session, str, QT_ORDINARY);
16257
16241
for (TableList **tbl= table + 1; tbl < end; tbl++)
16268
16252
str->append(STRING_WITH_LEN(" semi join "));
16270
16254
str->append(STRING_WITH_LEN(" join "));
16271
curr->print(thd, str, QT_ORDINARY);
16255
curr->print(session, str, QT_ORDINARY);
16272
16256
if (curr->on_expr)
16274
16258
str->append(STRING_WITH_LEN(" on("));
16283
16267
Print joins from the FROM clause.
16284
@param thd thread handler
16268
@param session thread handler
16285
16269
@param str string where table should be printed
16286
16270
@param tables list of tables in join
16287
16271
@query_type type of the query is being generated
16290
static void print_join(THD *thd,
16274
static void print_join(Session *session,
16292
16276
List<TableList> *tables,
16293
16277
enum_query_type query_type __attribute__((unused)))
16295
16279
/* List is reversed => we should reverse it before using */
16296
16280
List_iterator_fast<TableList> ti(*tables);
16297
TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
16281
TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16298
16282
tables->elements);
16299
16283
if (table == 0)
16300
16284
return; // out of memory
16323
16307
assert(tables->elements >= 1);
16324
print_table_array(thd, str, table, table + tables->elements);
16308
print_table_array(session, str, table, table + tables->elements);
16331
16315
@details Prints out the USE|FORCE|IGNORE index hint.
16333
@param thd the current thread
16317
@param session the current thread
16334
16318
@param[out] str appends the index hint here
16335
16319
@param hint what the hint is (as string : "USE INDEX"|
16336
16320
"FORCE INDEX"|"IGNORE INDEX")
16350
16334
str->append (STRING_WITH_LEN(" ("));
16351
16335
if (key_name.length)
16353
if (thd && !my_strnncoll(system_charset_info,
16337
if (session && !my_strnncoll(system_charset_info,
16354
16338
(const unsigned char *)key_name.str, key_name.length,
16355
16339
(const unsigned char *)primary_key_name,
16356
16340
strlen(primary_key_name)))
16357
16341
str->append(primary_key_name);
16359
append_identifier(thd, str, key_name.str, key_name.length);
16343
append_identifier(session, str, key_name.str, key_name.length);
16361
16345
str->append(')');
16368
16352
@param str string where table should be printed
16371
void TableList::print(THD *thd, String *str, enum_query_type query_type)
16355
void TableList::print(Session *session, String *str, enum_query_type query_type)
16373
16357
if (nested_join)
16375
16359
str->append('(');
16376
print_join(thd, str, &nested_join->join_list, query_type);
16360
print_join(session, str, &nested_join->join_list, query_type);
16377
16361
str->append(')');
16392
16376
// A normal table
16394
append_identifier(thd, str, db, db_length);
16378
append_identifier(session, str, db, db_length);
16395
16379
str->append('.');
16397
16381
if (schema_table)
16399
append_identifier(thd, str, schema_table_name,
16383
append_identifier(session, str, schema_table_name,
16400
16384
strlen(schema_table_name));
16401
16385
cmp_name= schema_table_name;
16405
append_identifier(thd, str, table_name, table_name_length);
16389
append_identifier(session, str, table_name, table_name_length);
16406
16390
cmp_name= table_name;
16433
16417
while ((hint= it++))
16435
16419
str->append (STRING_WITH_LEN(" "));
16436
hint->print (thd, str);
16420
hint->print (session, str);
16443
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
16427
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
16445
/* QQ: thd may not be set for sub queries, but this should be fixed */
16429
/* QQ: session may not be set for sub queries, but this should be fixed */
16431
session= current_session;
16449
16433
str->append(STRING_WITH_LEN("select "));
16451
16435
/* First add options */
16452
16436
if (options & SELECT_STRAIGHT_JOIN)
16453
16437
str->append(STRING_WITH_LEN("straight_join "));
16454
if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16455
(this == &thd->lex->select_lex))
16438
if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16439
(this == &session->lex->select_lex))
16456
16440
str->append(STRING_WITH_LEN("high_priority "));
16457
16441
if (options & SELECT_DISTINCT)
16458
16442
str->append(STRING_WITH_LEN("distinct "));
16487
16471
str->append(STRING_WITH_LEN(" from "));
16488
16472
/* go through join tree */
16489
print_join(thd, str, &top_join_list, query_type);
16473
print_join(session, str, &top_join_list, query_type);
16491
16475
else if (where)