28
28
#include "sj_tmp_table.h"
30
30
#include <mysys/my_bit.h>
31
#include <drizzled/drizzled_error_messages.h>
32
#include <libdrizzle/gettext.h>
31
#include <drizzled/error.h>
32
#include <drizzled/gettext.h>
33
#include <drizzled/util/test.h>
34
#include <drizzled/nested_join.h>
34
36
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
35
37
"MAYBE_REF","ALL","range","index",
42
44
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
43
45
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
44
46
DYNAMIC_ARRAY *keyuse);
45
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
47
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
46
48
JOIN_TAB *join_tab,
47
49
uint32_t tables, COND *conds,
48
50
COND_EQUAL *cond_equal,
54
56
table_map used_tables);
55
57
static bool choose_plan(JOIN *join,table_map join_tables);
57
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
59
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
58
60
table_map remaining_tables, uint32_t idx,
59
61
double record_count, double read_time);
60
62
static void optimize_straight_join(JOIN *join, table_map join_tables);
77
79
static uint32_t cache_record_length(JOIN *join,uint32_t index);
78
80
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
79
81
static bool get_best_combination(JOIN *join);
80
static store_key *get_store_key(THD *thd,
82
static store_key *get_store_key(Session *session,
81
83
KEYUSE *keyuse, table_map used_tables,
82
84
KEY_PART_INFO *key_part, unsigned char *key_buff,
83
85
uint32_t maybe_null);
94
96
List<Item> &fields, bool send_row,
95
97
uint64_t select_options, const char *info,
97
static COND *build_equal_items(THD *thd, COND *cond,
99
static COND *build_equal_items(Session *session, COND *cond,
98
100
COND_EQUAL *inherited,
99
101
List<TableList> *join_list,
100
102
COND_EQUAL **cond_equal_ref);
167
169
bool (*find_func) (Field *, void *), void *data);
168
170
static bool find_field_in_item_list (Field *field, void *data);
169
171
static bool find_field_in_order_list (Field *field, void *data);
170
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
172
static int create_sort_index(Session *session, JOIN *join, order_st *order,
171
173
ha_rows filesort_limit, ha_rows select_limit,
172
174
bool is_order_by);
173
175
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
175
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
177
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
176
178
ulong offset,Item *having);
177
static int remove_dup_with_hash_index(THD *thd,Table *table,
179
static int remove_dup_with_hash_index(Session *session,Table *table,
178
180
uint32_t field_count, Field **first_field,
180
182
ulong key_length,Item *having);
181
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count);
183
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
182
184
static ulong used_blob_length(CACHE_FIELD **ptr);
183
185
static bool store_record_in_cache(JOIN_CACHE *cache);
184
186
static void reset_cache_read(JOIN_CACHE *cache);
185
187
static void reset_cache_write(JOIN_CACHE *cache);
186
188
static void read_cached_record(JOIN_TAB *tab);
187
189
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
188
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
190
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
189
191
order_st *order, List<Item> &fields,
190
192
List<Item> &all_fields,
191
193
bool *all_order_by_fields_used);
195
197
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
196
198
static bool alloc_group_fields(JOIN *join,order_st *group);
197
199
// Create list for using with tempory table
198
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
200
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
199
201
List<Item> &new_list1,
200
202
List<Item> &new_list2,
201
203
uint32_t elements, List<Item> &items);
202
204
// Create list for using with tempory table
203
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
205
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
204
206
List<Item> &new_list1,
205
207
List<Item> &new_list2,
206
208
uint32_t elements, List<Item> &items);
207
209
static void init_tmptable_sum_functions(Item_sum **func);
208
210
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
209
211
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
210
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
211
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
212
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
213
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
212
214
static bool init_sum_functions(Item_sum **func, Item_sum **end);
213
215
static bool update_sum_func(Item_sum **func);
214
216
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
236
238
This handles SELECT with and without UNION.
239
bool handle_select(THD *thd, LEX *lex, select_result *result,
241
bool handle_select(Session *session, LEX *lex, select_result *result,
240
242
ulong setup_tables_done_option)
246
248
if (select_lex->master_unit()->is_union() ||
247
249
select_lex->master_unit()->fake_select_lex)
248
res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
250
res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
251
253
SELECT_LEX_UNIT *unit= &lex->unit;
252
254
unit->set_limit(unit->global_parameters);
255
session->session_marker= 0;
255
257
'options' of mysql_select will be set in JOIN, as far as JOIN for
256
258
every PS/SP execution new, we will not need reset this flag if
257
259
setup_tables_done_option changed for next rexecution
259
res= mysql_select(thd, &select_lex->ref_pointer_array,
261
res= mysql_select(session, &select_lex->ref_pointer_array,
260
262
(TableList*) select_lex->table_list.first,
261
263
select_lex->with_wild, select_lex->item_list,
262
264
select_lex->where,
266
268
(order_st*) select_lex->group_list.first,
267
269
select_lex->having,
268
270
(order_st*) lex->proc_list.first,
269
select_lex->options | thd->options |
271
select_lex->options | session->options |
270
272
setup_tables_done_option,
271
273
result, unit, select_lex);
273
res|= thd->is_error();
275
res|= session->is_error();
274
276
if (unlikely(res))
324
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
326
fix_inner_refs(Session *session, List<Item> &all_fields, SELECT_LEX *select,
325
327
Item **ref_pointer_array)
327
329
Item_outer_ref *ref;
382
384
ref->outer_ref= new_ref;
383
385
ref->ref= &ref->outer_ref;
385
if (!ref->fixed && ref->fix_fields(thd, 0))
387
if (!ref->fixed && ref->fix_fields(session, 0))
387
thd->used_tables|= item->used_tables();
389
session->used_tables|= item->used_tables();
392
#define MAGIC_IN_WHERE_TOP_LEVEL 10
394
395
Function to setup clauses without sum functions.
396
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
397
inline int setup_without_group(Session *session, Item **ref_pointer_array,
397
398
TableList *tables,
398
399
TableList *leaves,
399
400
List<Item> &fields,
403
404
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,
407
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
409
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
410
res= setup_conds(session, tables, leaves, conds);
412
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
413
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,
415
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
416
res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
416
417
group, hidden_group_fields);
417
thd->lex->allow_sum_func= save_allow_sum_func;
418
session->lex->allow_sum_func= save_allow_sum_func;
459
460
join_list= &select_lex->top_join_list;
460
461
union_part= unit_arg->is_union();
462
thd->lex->current_select->is_item_list_lookup= 1;
463
session->lex->current_select->is_item_list_lookup= 1;
464
465
If we have already executed SELECT, then it have not sense to prevent
465
466
its table from update (see unique_table())
467
if (thd->derived_tables_processing)
468
if (session->derived_tables_processing)
468
469
select_lex->exclude_from_table_unique_test= true;
470
471
/* Check that all tables, fields, conds and order are ok */
472
473
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
473
setup_tables_and_check_access(thd, &select_lex->context, join_list,
474
setup_tables_and_check_access(session, &select_lex->context, join_list,
474
475
tables_list, &select_lex->leaf_tables,
481
482
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,
485
if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
486
select_lex->setup_ref_array(session, og_num) ||
487
setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
487
488
&all_fields, 1) ||
488
setup_without_group(thd, (*rref_pointer_array), tables_list,
489
setup_without_group(session, (*rref_pointer_array), tables_list,
489
490
select_lex->leaf_tables, fields_list,
490
491
all_fields, &conds, order, group_list,
491
492
&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;
499
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
500
session->where="having clause";
501
session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
501
502
select_lex->having_fix_field= 1;
502
503
bool having_fix_rc= (!having->fixed &&
503
(having->fix_fields(thd, &having) ||
504
(having->fix_fields(session, &having) ||
504
505
having->check_cols(1)));
505
506
select_lex->having_fix_field= 0;
506
if (having_fix_rc || thd->is_error())
507
if (having_fix_rc || session->is_error())
507
508
return(-1); /* purecov: inspected */
508
thd->lex->allow_sum_func= save_allow_sum_func;
509
session->lex->allow_sum_func= save_allow_sum_func;
518
519
if ((subselect= select_lex->master_unit()->item))
520
bool do_semijoin= !test(thd->variables.optimizer_switch &
521
bool do_semijoin= !test(session->variables.optimizer_switch &
521
522
OPTIMIZER_SWITCH_NO_SEMIJOIN);
522
523
if (subselect->substype() == Item_subselect::IN_SUBS)
523
524
in_subs= (Item_in_subselect*)subselect;
544
545
!select_lex->master_unit()->first_select()->next_select() && // 2
545
546
!select_lex->group_list.elements && !order && // 3
546
547
!having && !select_lex->with_sum_func && // 4
547
thd->thd_marker && // 5
548
session->session_marker && // 5
548
549
select_lex->outer_select()->join && // (*)
549
550
select_lex->master_unit()->first_select()->leaf_tables && // (**)
572
573
/* 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;
574
select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
575
in_subs->expr_join_nest= (TableList*)session->session_marker;
578
bool do_materialize= !test(thd->variables.optimizer_switch &
579
bool do_materialize= !test(session->variables.optimizer_switch &
579
580
OPTIMIZER_SWITCH_NO_MATERIALIZATION);
581
582
Check if the subquery predicate can be executed via materialization.
611
612
!select_lex->master_unit()->first_select()->next_select() && // 2
612
613
select_lex->master_unit()->first_select()->leaf_tables && // 3
613
thd->lex->sql_command == SQLCOM_SELECT) // *
614
session->lex->sql_command == SQLCOM_SELECT) // *
615
616
if (in_subs->is_top_level_item() && // 4
616
617
!in_subs->is_correlated && // 5
636
637
Item *item= *ord->item;
637
638
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
638
item->split_sum_func(thd, ref_pointer_array, all_fields);
639
item->split_sum_func(session, ref_pointer_array, all_fields);
642
643
if (having && having->with_sum_func)
643
having->split_sum_func2(thd, ref_pointer_array, all_fields,
644
having->split_sum_func2(session, ref_pointer_array, all_fields,
645
646
if (select_lex->inner_sum_func_list)
651
652
item_sum= item_sum->next;
652
item_sum->split_sum_func2(thd, ref_pointer_array,
653
item_sum->split_sum_func2(session, ref_pointer_array,
653
654
all_fields, item_sum->ref_by, false);
654
655
} while (item_sum != end);
657
658
if (select_lex->inner_refs_list.elements &&
658
fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
659
fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
1146
1147
SJ_TMP_TABLE *sjtbl;
1147
1148
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)))
1149
if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
1150
!(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
1151
1152
memcpy(sjtbl->tabs, sjtabs, tabs_size);
1152
1153
sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1228
1229
select_limit= HA_POS_ERROR;
1229
1230
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1230
1231
// Ignore errors of execution if option IGNORE present
1231
if (thd->lex->ignore)
1232
thd->lex->current_select->no_error= 1;
1232
if (session->lex->ignore)
1233
session->lex->current_select->no_error= 1;
1234
1235
#ifdef HAVE_REF_TO_FIELDS // Not done yet
1235
1236
/* Add HAVING to WHERE if possible */
1246
1247
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);
1250
conds->fix_fields(session, &conds);
1251
conds->change_ref_to_fields(session, tables_list);
1251
1252
conds->top_level_item();
1329
1330
Preserve conditions for EXPLAIN.
1331
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
1332
if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
1333
1334
COND *table_independent_conds=
1334
1335
make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1345
1346
sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1347
1348
/* Calculate how to do the join */
1348
thd_proc_info(thd, "statistics");
1349
session->set_proc_info("statistics");
1349
1350
if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1350
thd->is_fatal_error)
1351
session->is_fatal_error)
1355
1356
/* Remove distinct if only const tables */
1356
1357
select_distinct= select_distinct && (const_tables != tables);
1357
thd_proc_info(thd, "preparing");
1358
session->set_proc_info("preparing");
1358
1359
if (result->initialize_tables(this))
1360
1361
return(1); // error == -1
1363
1364
!(select_options & SELECT_DESCRIBE) &&
1365
1366
!(conds->used_tables() & RAND_TABLE_BIT) ||
1366
select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
1367
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1368
1369
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 &&
1373
if (!(session->options & OPTION_BIG_SELECTS) &&
1374
best_read > (double) session->variables.max_join_size &&
1374
1375
!(select_options & SELECT_DESCRIBE))
1375
1376
{ /* purecov: inspected */
1376
1377
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1380
if (const_tables && !thd->locked_tables &&
1381
if (const_tables && !session->locked_tables &&
1381
1382
!(select_options & SELECT_NO_UNLOCK))
1382
mysql_unlock_some_tables(thd, table, const_tables);
1383
mysql_unlock_some_tables(session, table, const_tables);
1383
1384
if (!conds && outer_join)
1385
1386
/* Handle the case where we have an OUTER JOIN without a WHERE */
1426
1427
if (conds &&!outer_join && const_table_map != found_const_table_map &&
1427
1428
(select_options & SELECT_DESCRIBE) &&
1428
select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
1429
select_lex->master_unit() == &session->lex->unit) // upper level SELECT
1430
1431
conds=new Item_int((int64_t) 0,1); // Always false
1541
1542
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
1542
1543
&tab->table->keys_in_use_for_order_by);
1543
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
1544
if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
1544
1545
order, fields_list, all_fields,
1545
1546
&all_order_fields_used)))
1806
1807
ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1808
!thd->lex->current_select->with_sum_func) ?
1809
!session->lex->current_select->with_sum_func) ?
1809
1810
select_limit : HA_POS_ERROR;
1811
1812
if (!(exec_tmp_table1=
1812
create_tmp_table(thd, &tmp_table_param, all_fields,
1813
create_tmp_table(session, &tmp_table_param, all_fields,
1814
1815
group_list ? 0 : select_distinct,
1815
1816
group_list && simple_group,
1837
1838
/* if group or order on first table, sort first */
1838
1839
if (group_list && simple_group)
1840
thd_proc_info(thd, "Sorting for group");
1841
if (create_sort_index(thd, this, group_list,
1841
session->set_proc_info("Sorting for group");
1842
if (create_sort_index(session, this, group_list,
1842
1843
HA_POS_ERROR, HA_POS_ERROR, false) ||
1843
1844
alloc_group_fields(this, group_list) ||
1844
1845
make_sum_func_list(all_fields, fields_list, 1) ||
1845
setup_sum_funcs(thd, sum_funcs))
1846
setup_sum_funcs(session, sum_funcs))
1853
1854
if (make_sum_func_list(all_fields, fields_list, 0) ||
1854
setup_sum_funcs(thd, sum_funcs))
1855
setup_sum_funcs(session, sum_funcs))
1859
1860
if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1861
thd_proc_info(thd, "Sorting for order");
1862
if (create_sort_index(thd, this, order,
1862
session->set_proc_info("Sorting for order");
1863
if (create_sort_index(session, this, order,
1863
1864
HA_POS_ERROR, HA_POS_ERROR, true))
2140
2141
curr_tmp_table= exec_tmp_table1;
2142
2143
/* Copy data to the temporary table */
2143
thd_proc_info(thd, "Copying to tmp table");
2144
session->set_proc_info("Copying to tmp table");
2144
2145
if (!curr_join->sort_and_group &&
2145
2146
curr_join->const_tables != curr_join->tables)
2146
2147
curr_join->join_tab[curr_join->const_tables].sorted= 0;
2161
2162
items1= items0 + all_fields.elements;
2162
2163
if (sort_and_group || curr_tmp_table->group)
2164
if (change_to_use_tmp_fields(thd, items1,
2165
if (change_to_use_tmp_fields(session, items1,
2165
2166
tmp_fields_list1, tmp_all_fields1,
2166
2167
fields_list.elements, all_fields))
2171
if (change_refs_to_tmp_fields(thd, items1,
2172
if (change_refs_to_tmp_fields(session, items1,
2172
2173
tmp_fields_list1, tmp_all_fields1,
2173
2174
fields_list.elements, all_fields))
2256
2257
if (curr_join->group_list)
2258
thd_proc_info(thd, "Creating sort index");
2259
session->set_proc_info("Creating sort index");
2259
2260
if (curr_join->join_tab == join_tab && save_join_tab())
2263
if (create_sort_index(thd, curr_join, curr_join->group_list,
2264
if (create_sort_index(session, curr_join, curr_join->group_list,
2264
2265
HA_POS_ERROR, HA_POS_ERROR, false) ||
2265
2266
make_group_fields(this, curr_join))
2292
2293
if (!curr_join->sort_and_group &&
2293
2294
curr_join->const_tables != curr_join->tables)
2294
2295
curr_join->join_tab[curr_join->const_tables].sorted= 0;
2295
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2296
if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2296
2297
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2298
2299
error= tmp_error;
2308
2309
items2= items1 + all_fields.elements;
2309
if (change_to_use_tmp_fields(thd, items2,
2310
if (change_to_use_tmp_fields(session, items2,
2310
2311
tmp_fields_list2, tmp_all_fields2,
2311
2312
fields_list.elements, tmp_all_fields1))
2326
2327
curr_join->join_free(); /* Free quick selects */
2327
2328
if (curr_join->select_distinct && ! curr_join->group_list)
2329
thd_proc_info(thd, "Removing duplicates");
2330
session->set_proc_info("Removing duplicates");
2330
2331
if (curr_join->tmp_having)
2331
2332
curr_join->tmp_having->update_used_tables();
2332
2333
if (remove_duplicates(curr_join, curr_tmp_table,
2356
2357
init_items_ref_array();
2357
2358
items3= ref_pointer_array + (all_fields.elements*4);
2358
setup_copy_fields(thd, &curr_join->tmp_table_param,
2359
setup_copy_fields(session, &curr_join->tmp_table_param,
2359
2360
items3, tmp_fields_list3, tmp_all_fields3,
2360
2361
curr_fields_list->elements, *curr_all_fields);
2361
2362
tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2379
2380
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)
2382
setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2383
session->is_fatal_error)
2385
2386
if (curr_join->group_list || curr_join->order)
2387
thd_proc_info(thd, "Sorting result");
2388
session->set_proc_info("Sorting result");
2388
2389
/* If we have already done the group, add HAVING to sorted table */
2389
2390
if (curr_join->tmp_having && ! curr_join->group_list &&
2390
2391
! curr_join->sort_and_group)
2463
2464
the query. XXX: it's never shown in EXPLAIN!
2464
2465
OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2466
if (create_sort_index(thd, curr_join,
2467
if (create_sort_index(session, curr_join,
2467
2468
curr_join->group_list ?
2468
2469
curr_join->group_list : curr_join->order,
2469
2470
curr_join->select_limit,
2487
/* XXX: When can we have here thd->is_error() not zero? */
2488
if (thd->is_error())
2488
/* XXX: When can we have here session->is_error() not zero? */
2489
if (session->is_error())
2490
error= thd->is_error();
2491
error= session->is_error();
2493
2494
curr_join->having= curr_join->tmp_having;
2494
2495
curr_join->fields= curr_fields_list;
2497
thd_proc_info(thd, "Sending data");
2498
session->set_proc_info("Sending data");
2498
2499
result->send_fields(*curr_fields_list,
2499
2500
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2500
2501
error= do_select(curr_join, curr_fields_list, NULL);
2501
thd->limit_found_rows= curr_join->send_records;
2502
session->limit_found_rows= curr_join->send_records;
2504
2505
/* Accumulate the counts from all join iterations of all join parts. */
2505
thd->examined_row_count+= curr_join->examined_rows;
2506
session->examined_row_count+= curr_join->examined_rows;
2508
2509
With EXPLAIN EXTENDED we have to restore original ref_array
2560
2561
An entry point to single-unit select (a select without UNION).
2562
@param thd thread handler
2563
@param session thread handler
2563
2564
@param rref_pointer_array a reference to ref_pointer_array of
2564
2565
the top-level select_lex for this query
2565
2566
@param tables list of all tables used in this query.
2604
mysql_select(THD *thd, Item ***rref_pointer_array,
2605
mysql_select(Session *session, Item ***rref_pointer_array,
2605
2606
TableList *tables, uint32_t wild_num, List<Item> &fields,
2606
2607
COND *conds, uint32_t og_num, order_st *order, order_st *group,
2607
2608
Item *having, order_st *proc_param, uint64_t select_options,
2649
if (!(join= new JOIN(thd, fields, select_options, result)))
2650
if (!(join= new JOIN(session, fields, select_options, result)))
2651
thd_proc_info(thd, "init");
2652
thd->used_tables=0; // Updated by setup_fields
2652
session->set_proc_info("init");
2653
session->used_tables=0; // Updated by setup_fields
2653
2654
if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2654
2655
conds, og_num, order, group, having, proc_param,
2655
2656
select_lex, unit)) == true)
2674
if (thd->lex->describe & DESCRIBE_EXTENDED)
2675
if (session->lex->describe & DESCRIBE_EXTENDED)
2676
2677
join->conds_history= join->conds;
2677
2678
join->having_history= (join->having?join->having:join->tmp_having);
2680
if (thd->is_error())
2681
if (session->is_error())
2685
if (thd->lex->describe & DESCRIBE_EXTENDED)
2686
if (session->lex->describe & DESCRIBE_EXTENDED)
2687
2688
select_lex->where= join->conds_history;
2688
2689
select_lex->having= join->having_history;
2716
static TableList *alloc_join_nest(THD *thd)
2717
static TableList *alloc_join_nest(Session *session)
2718
2719
TableList *tbl;
2719
if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
2720
if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
2720
2721
sizeof(nested_join_st))))
2722
2723
tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl +
2772
2773
SELECT_LEX *parent_lex= parent_join->select_lex;
2773
2774
TableList *emb_tbl_nest= NULL;
2774
2775
List<TableList> *emb_join_list= &parent_lex->top_join_list;
2775
THD *thd= parent_join->thd;
2776
Session *session= parent_join->session;
2778
2779
1. Find out where to put the predicate into.
2952
2953
Put the subquery's WHERE into semi-join's sj_on_expr
2953
2954
Add the subquery-induced equalities too.
2955
SELECT_LEX *save_lex= thd->lex->current_select;
2956
thd->lex->current_select=subq_lex;
2956
SELECT_LEX *save_lex= session->lex->current_select;
2957
session->lex->current_select=subq_lex;
2957
2958
if (!subq_pred->left_expr->fixed &&
2958
subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
2959
subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
2960
thd->lex->current_select=save_lex;
2961
session->lex->current_select=save_lex;
2962
2963
sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2963
2964
sj_nest->nested_join->sj_depends_on= subq_pred->used_tables() |
3024
3025
emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
3025
3026
sj_nest->sj_on_expr);
3026
emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
3027
emb_tbl_nest->on_expr->fix_fields(parent_join->session, &emb_tbl_nest->on_expr);
3030
3031
/* Inject into the WHERE */
3031
3032
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);
3033
parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
3033
3034
parent_join->select_lex->where= parent_join->conds;
3359
3360
*****************************************************************************/
3362
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
3363
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
3364
3365
const key_map *keys,ha_rows limit)
3367
if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
3368
if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3368
3369
return(0); // Fatal error flag is set
3371
3372
select->head=table;
3372
3373
table->reginfo.impossible_range=0;
3373
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
3374
if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
3374
3375
limit, 0, false)) == 1)
3375
3376
return(select->quick->records);
3376
3377
if (error == -1)
3422
3423
JOIN_TAB *stat_vector[MAX_TABLES+1];
3424
3425
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));
3426
stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
3427
stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3428
table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
3428
3429
if (!stat || !stat_ref || !table_vector)
3429
3430
return(1); // Eom /* purecov: inspected */
3545
3546
if (conds || outer_join)
3546
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
3547
if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
3547
3548
conds, join->cond_equal,
3548
3549
~outer_join, join->select_lex, &sargables))
3771
records= get_quick_record_count(join->thd, select, s->table,
3772
records= get_quick_record_count(join->session, select, s->table,
3772
3773
&s->const_keys, join->row_limit);
3773
3774
s->quick=select->quick;
3774
3775
s->needed_reg=select->needed_reg;
4567
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4568
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4568
4569
uint32_t tables, COND *cond,
4569
4570
COND_EQUAL *cond_equal __attribute__((unused)),
4570
4571
table_map normal_tables, SELECT_LEX *select_lex,
4599
4600
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)))
4601
(((session->lex->current_select->cond_count+1)*2 +
4602
session->lex->current_select->between_count)*m+1);
4603
if (!(key_fields=(KEY_FIELD*) session->alloc(sz)))
4603
4604
return true; /* purecov: inspected */
4605
4606
field= end= key_fields;
4898
4899
@param join pointer to the structure providing all context info
4900
4901
@param s the table to be joined by the function
4901
@param thd thread for the connection that submitted the query
4902
@param session thread for the connection that submitted the query
4902
4903
@param remaining_tables set of tables not included into the partial plan yet
4903
4904
@param idx the length of the partial plan
4904
4905
@param record_count estimate for the number of records returned by the
5164
5165
/* Limit the number of matched rows */
5166
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5167
set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5167
5168
if (table->covering_keys.is_set(key))
5169
5170
/* we can use only index tree */
5330
5331
/* Limit the number of matched rows */
5331
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5332
set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5332
5333
if (table->covering_keys.is_set(key))
5334
5335
/* we can use only index tree */
5458
5459
/* We read the table as many times as join buffer becomes full. */
5459
5460
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5461
(double) thd->variables.join_buff_size));
5462
(double) session->variables.join_buff_size));
5463
5464
We don't make full cartesian product between rows in the scanned
5464
5465
table and existing records because we skip all rows from the
5537
5538
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;
5540
uint32_t search_depth= join->session->variables.optimizer_search_depth;
5541
uint32_t prune_level= join->session->variables.optimizer_prune_level;
5541
5542
bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5543
5544
join->cur_embedding_map= 0;
5585
5586
i.e. they have subqueries, unions or call stored procedures.
5586
5587
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;
5589
if (join->session->lex->is_single_level_stmt())
5590
join->session->status_var.last_query_cost= join->best_read;
5740
5741
/* Find the best access method from 's' to the current partial plan */
5741
5742
advance_sj_state(join_tables, s);
5742
best_access_path(join, s, join->thd, join_tables, idx,
5743
best_access_path(join, s, join->session, join_tables, idx,
5743
5744
record_count, read_time);
5744
5745
/* compute the cost of the new plan extended with 's' */
5745
5746
record_count*= join->positions[idx].records_read;
6057
6058
when the depth is insufficient??)
6059
6060
/* Find the best access method from 's' to the current partial plan */
6060
best_access_path(join, s, thd, remaining_tables, idx,
6061
best_access_path(join, s, session, remaining_tables, idx,
6061
6062
record_count, read_time);
6062
6063
/* Compute the cost of extending the plan with 's' */
6063
6064
current_record_count= record_count * join->positions[idx].records_read;
6183
6184
double records, best;
6184
6185
advance_sj_state(rest_tables, s);
6185
best_access_path(join, s, thd, rest_tables, idx, record_count,
6186
best_access_path(join, s, session, rest_tables, idx, record_count,
6187
6188
records= join->positions[idx].records_read;
6188
6189
best= join->positions[idx].read_time;
6223
6224
Find how much space the prevous read not const tables takes in cache.
6226
static void calc_used_field_length(THD *thd __attribute__((unused)),
6227
static void calc_used_field_length(Session *session __attribute__((unused)),
6227
6228
JOIN_TAB *join_tab)
6229
6230
uint32_t null_fields,blobs,fields,rec_length;
6274
6275
JOIN_TAB *join_tab= *pos;
6275
6276
if (!join_tab->used_fieldlength) /* Not calced yet */
6276
calc_used_field_length(thd, join_tab);
6277
calc_used_field_length(session, join_tab);
6277
6278
length+=join_tab->used_fieldlength;
6464
6465
j->ref.key_parts=keyparts;
6465
6466
j->ref.key_length=length;
6466
6467
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*) *
6468
if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
6469
!(j->ref.key_copy= (store_key**) session->alloc((sizeof(store_key*) *
6469
6470
(keyparts+1)))) ||
6470
!(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
6471
!(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
6471
!(j->ref.items= (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
6472
!(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
6498
6499
if (!keyuse->used_tables &&
6499
6500
!(join->select_options & SELECT_DESCRIBE))
6500
6501
{ // Compare against constant
6501
store_key_item tmp(thd, keyinfo->key_part[i].field,
6502
store_key_item tmp(session, keyinfo->key_part[i].field,
6502
6503
key_buff + maybe_null,
6503
6504
maybe_null ? key_buff : 0,
6504
6505
keyinfo->key_part[i].length, keyuse->val);
6505
if (thd->is_fatal_error)
6506
if (session->is_fatal_error)
6510
*ref_key++= get_store_key(thd,
6511
*ref_key++= get_store_key(session,
6511
6512
keyuse,join->const_table_map,
6512
6513
&keyinfo->key_part[i],
6513
6514
key_buff, maybe_null);
6552
6553
static store_key *
6553
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
6554
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6554
6555
KEY_PART_INFO *key_part, unsigned char *key_buff, uint32_t maybe_null)
6556
6557
if (!((~used_tables) & keyuse->used_tables)) // if const item
6558
return new store_key_const_item(thd,
6559
return new store_key_const_item(session,
6559
6560
key_part->field,
6560
6561
key_buff + maybe_null,
6561
6562
maybe_null ? key_buff : 0,
6568
6569
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6569
6570
Item_ref::DIRECT_REF &&
6570
6571
keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6571
return new store_key_field(thd,
6572
return new store_key_field(session,
6572
6573
key_part->field,
6573
6574
key_buff + maybe_null,
6574
6575
maybe_null ? key_buff : 0,
6575
6576
key_part->length,
6576
6577
((Item_field*) keyuse->val->real_item())->field,
6577
6578
keyuse->val->full_name());
6578
return new store_key_item(thd,
6579
return new store_key_item(session,
6579
6580
key_part->field,
6580
6581
key_buff + maybe_null,
6581
6582
maybe_null ? key_buff : 0,
6597
6598
Table *table= field->table;
6598
THD *thd= table->in_use;
6599
ha_rows cuted_fields=thd->cuted_fields;
6599
Session *session= table->in_use;
6600
ha_rows cuted_fields=session->cuted_fields;
6602
6603
we should restore old value of count_cuted_fields because
6603
6604
store_val_in_field can be called from mysql_insert
6604
6605
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;
6607
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
6608
session->count_cuted_fields= check_flag;
6608
6609
error= item->save_in_field(field, 1);
6609
thd->count_cuted_fields= old_count_cuted_fields;
6610
return error || cuted_fields != thd->cuted_fields;
6610
session->count_cuted_fields= old_count_cuted_fields;
6611
return error || cuted_fields != session->cuted_fields;
6631
6632
if (!join->join_tab_reexec)
6633
6634
if (!(join->join_tab_reexec=
6634
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
6635
(JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
6635
6636
return(true); /* purecov: inspected */
6636
6637
if (join->tmp_join)
6637
6638
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6931
6932
if (join->tables > 1)
6932
6933
cond->update_used_tables(); // Tablenr may have changed
6933
6934
if (join->const_tables == join->tables &&
6934
thd->lex->current_select->master_unit() ==
6935
&thd->lex->unit) // not upper level SELECT
6935
session->lex->current_select->master_unit() ==
6936
&session->lex->unit) // not upper level SELECT
6936
6937
join->const_table_map|=RAND_TABLE_BIT;
6937
6938
{ // Check const tables
6938
6939
COND *const_cond=
7061
7062
/* Push condition to storage engine if this is enabled
7062
7063
and the condition is not guarded */
7063
7064
tab->table->file->pushed_cond= NULL;
7064
if (thd->variables.engine_condition_pushdown)
7065
if (session->variables.engine_condition_pushdown)
7066
7067
COND *push_cond=
7067
7068
make_cond_for_table(tmp, current_map, current_map, 0);
7130
7131
if (sel->cond && !sel->cond->fixed)
7131
7132
sel->cond->quick_fix_field();
7133
if (sel->test_quick_select(thd, tab->keys,
7134
if (sel->test_quick_select(session, tab->keys,
7134
7135
used_tables & ~ current_map,
7135
7136
(join->select_options &
7136
7137
OPTION_FOUND_ROWS ?
7145
7146
sel->cond=orig_cond;
7146
7147
if (!*tab->on_expr_ref ||
7147
sel->test_quick_select(thd, tab->keys,
7148
sel->test_quick_select(session, tab->keys,
7148
7149
used_tables & ~ current_map,
7149
7150
(join->select_options &
7150
7151
OPTION_FOUND_ROWS ?
7186
7187
current_map, 0)))
7188
7189
tab->cache.select=(SQL_SELECT*)
7189
thd->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7190
session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7190
7191
tab->cache.select->cond=tmp;
7191
7192
tab->cache.select->read_tables=join->const_table_map;
7543
7544
Item *idx_cond;
7544
7545
if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7545
tab->join->thd->variables.engine_condition_pushdown)
7546
tab->join->session->variables.engine_condition_pushdown)
7547
7548
idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7548
7549
other_tbls_ok);
7750
7751
!tab->insideout_match_tab)
7752
7753
if ((options & SELECT_DESCRIBE) ||
7753
!join_init_cache(join->thd,join->join_tab+join->const_tables,
7754
!join_init_cache(join->session,join->join_tab+join->const_tables,
7754
7755
i-join->const_tables))
7756
7757
using_join_cache= true;
7760
7761
/* These init changes read_record */
7761
7762
if (tab->use_quick == 2)
7763
join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7764
join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7764
7765
tab->read_first_record= join_init_quick_read_record;
7765
7766
if (statistics)
7766
status_var_increment(join->thd->status_var.select_range_check_count);
7767
status_var_increment(join->session->status_var.select_range_check_count);
7773
7774
if (tab->select && tab->select->quick)
7775
7776
if (statistics)
7776
status_var_increment(join->thd->status_var.select_range_count);
7777
status_var_increment(join->session->status_var.select_range_count);
7780
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7781
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7781
7782
if (statistics)
7782
status_var_increment(join->thd->status_var.select_scan_count);
7783
status_var_increment(join->session->status_var.select_scan_count);
7787
7788
if (tab->select && tab->select->quick)
7789
7790
if (statistics)
7790
status_var_increment(join->thd->status_var.select_full_range_join_count);
7791
status_var_increment(join->session->status_var.select_full_range_join_count);
7794
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7795
join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7795
7796
if (statistics)
7796
status_var_increment(join->thd->status_var.select_full_join_count);
7797
status_var_increment(join->session->status_var.select_full_join_count);
7799
7800
if (!table->no_keyread)
7985
7986
We are not using tables anymore
7986
7987
Unlock all tables. We may be in an INSERT .... SELECT statement.
7988
if (can_unlock && lock && thd->lock &&
7989
if (can_unlock && lock && session->lock &&
7989
7990
!(select_options & SELECT_NO_UNLOCK) &&
7990
7991
!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)))
7992
(select_lex == (session->lex->unit.fake_select_lex ?
7993
session->lex->unit.fake_select_lex : &session->lex->select_lex)))
7995
7996
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
7999
mysql_unlock_read_tables(session, lock); // Don't free join->lock
8706
8707
false otherwise
8709
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
8710
static bool check_row_equality(Session *session, Item *left_row, Item_row *right_row,
8710
8711
COND_EQUAL *cond_equal, List<Item>* eq_list)
8712
8713
uint32_t n= left_row->cols();
8718
8719
if (left_item->type() == Item::ROW_ITEM &&
8719
8720
right_item->type() == Item::ROW_ITEM)
8721
is_converted= check_row_equality(thd,
8722
is_converted= check_row_equality(session,
8722
8723
(Item_row *) left_item,
8723
8724
(Item_row *) right_item,
8724
8725
cond_equal, eq_list);
8725
8726
if (!is_converted)
8726
thd->lex->current_select->cond_count++;
8727
session->lex->current_select->cond_count++;
8730
8731
is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8731
thd->lex->current_select->cond_count++;
8732
session->lex->current_select->cond_count++;
8734
8735
if (!is_converted)
8775
8776
or, if the procedure fails by a fatal error.
8778
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
8779
static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal,
8779
8780
List<Item> *eq_list)
8781
8782
if (item->type() == Item::FUNC_ITEM &&
8787
8788
if (left_item->type() == Item::ROW_ITEM &&
8788
8789
right_item->type() == Item::ROW_ITEM)
8790
thd->lex->current_select->cond_count--;
8791
return check_row_equality(thd,
8791
session->lex->current_select->cond_count--;
8792
return check_row_equality(session,
8792
8793
(Item_row *) left_item,
8793
8794
(Item_row *) right_item,
8794
8795
cond_equal, eq_list);
8819
8820
just an argument of a comparison predicate.
8820
8821
The function also determines the maximum number of members in
8821
8822
equality lists of each Item_cond_and object assigning it to
8822
thd->lex->current_select->max_equal_elems.
8823
session->lex->current_select->max_equal_elems.
8825
8826
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8896
8897
structure here because it's restored before each
8897
8898
re-execution of any prepared statement/stored procedure.
8899
if (check_equality(thd, item, &cond_equal, &eq_list))
8900
if (check_equality(session, item, &cond_equal, &eq_list))
8950
8951
for WHERE a=b AND c=d AND (b=c OR d=5)
8951
8952
b=c is replaced by =(a,b,c,d).
8953
if (check_equality(thd, cond, &cond_equal, &eq_list))
8954
if (check_equality(session, cond, &cond_equal, &eq_list))
8955
8956
int n= cond_equal.current_level.elements + eq_list.elements;
8983
8984
item_equal->fix_length_and_dec();
8984
8985
item_equal->update_used_tables();
8985
set_if_bigger(thd->lex->current_select->max_equal_elems,
8986
set_if_bigger(session->lex->current_select->max_equal_elems,
8986
8987
item_equal->members());
8988
8989
and_cond->cond_equal= cond_equal;
9062
9063
can get more freedom in performing join operations.
9063
9064
Althogh we don't use this property now, it probably makes sense to use
9064
9065
it in the future.
9065
@param thd Thread handler
9066
@param session Thread handler
9066
9067
@param cond condition to build the multiple equalities for
9067
9068
@param inherited path to all inherited multiple equality items
9068
9069
@param join_list list of join tables to which the condition
9074
9075
pointer to the transformed condition containing multiple equalities
9077
static COND *build_equal_items(THD *thd, COND *cond,
9078
static COND *build_equal_items(Session *session, COND *cond,
9078
9079
COND_EQUAL *inherited,
9079
9080
List<TableList> *join_list,
9080
9081
COND_EQUAL **cond_equal_ref)
9086
cond= build_equal_items_for_cond(thd, cond, inherited);
9087
cond= build_equal_items_for_cond(session, cond, inherited);
9087
9088
cond->update_used_tables();
9088
9089
if (cond->type() == Item::COND_ITEM &&
9089
9090
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9117
9118
We can modify table->on_expr because its old value will
9118
9119
be restored before re-execution of PS/SP.
9120
table->on_expr= build_equal_items(thd, table->on_expr, inherited,
9121
table->on_expr= build_equal_items(session, table->on_expr, inherited,
9121
9122
nested_join_list,
9122
9123
&table->cond_equal);
9458
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
9459
change_cond_ref_to_const(Session *session, I_List<COND_CMP> *save_list,
9459
9460
Item *and_father, Item *cond,
9460
9461
Item *field, Item *value)
9466
9467
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9468
9469
while ((item=li++))
9469
change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
9470
change_cond_ref_to_const(session, save_list,and_level ? cond : item, item,
9493
thd->change_item_tree(args + 1, tmp);
9494
session->change_item_tree(args + 1, tmp);
9494
9495
func->update_used_tables();
9495
9496
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9496
9497
&& and_father != cond && !left_item->const_item())
9517
thd->change_item_tree(args, tmp);
9518
session->change_item_tree(args, tmp);
9519
9520
func->update_used_tables();
9520
9521
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9521
9522
&& and_father != cond && !right_item->const_item())
9523
9524
args[0]= args[1]; // For easy check
9524
thd->change_item_tree(args + 1, value);
9525
session->change_item_tree(args + 1, value);
9525
9526
cond->marker=1;
9526
9527
COND_CMP *tmp2;
9527
9528
if ((tmp2=new COND_CMP(and_father,func)))
9568
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
9569
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
9569
9570
COND *and_father, COND *cond)
9571
9572
if (cond->type() == Item::COND_ITEM)
9577
9578
I_List<COND_CMP> save;
9578
9579
while ((item=li++))
9580
propagate_cond_constants(thd, &save,and_level ? cond : item, item);
9581
propagate_cond_constants(session, &save,and_level ? cond : item, item);
9583
9584
{ // Handle other found items
9588
9589
Item **args= cond_cmp->cmp_func->arguments();
9589
9590
if (!args[0]->const_item())
9590
change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
9591
change_cond_ref_to_const(session, &save,cond_cmp->and_level,
9591
9592
cond_cmp->and_level, args[0], args[1]);
9608
9609
if (right_const)
9610
resolve_const_item(thd, &args[1], args[0]);
9611
resolve_const_item(session, &args[1], args[0]);
9611
9612
func->update_used_tables();
9612
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9613
change_cond_ref_to_const(session, save_list, and_father, and_father,
9613
9614
args[0], args[1]);
9615
9616
else if (left_const)
9617
resolve_const_item(thd, &args[0], args[1]);
9618
resolve_const_item(session, &args[0], args[1]);
9618
9619
func->update_used_tables();
9619
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9620
change_cond_ref_to_const(session, save_list, and_father, and_father,
9620
9621
args[1], args[0]);
10223
10224
predicate. Substitute a constant instead of this field if the
10224
10225
multiple equality contains a constant.
10226
conds= build_equal_items(join->thd, conds, NULL, join_list,
10227
conds= build_equal_items(join->session, conds, NULL, join_list,
10227
10228
&join->cond_equal);
10229
10230
/* change field = field to field = const for each found field = const */
10230
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
10231
propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10232
10233
Remove all instances of item == item
10233
10234
Remove all and-levels where CONST item != CONST item
10235
conds= remove_eq_conds(thd, conds, cond_value) ;
10236
conds= remove_eq_conds(session, conds, cond_value) ;
10237
10238
return(conds);
10330
10331
Field *field=((Item_field*) args[0])->field;
10331
10332
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))
10333
(session->options & OPTION_AUTO_IS_NULL) &&
10334
(session->first_successful_insert_id_in_prev_stmt > 0 &&
10335
session->substitute_null_with_insert_id))
10336
10337
COND *new_cond;
10337
10338
if ((new_cond= new Item_func_eq(args[0],
10338
10339
new Item_int("last_insert_id()",
10339
thd->read_first_successful_insert_id_in_prev_stmt(),
10340
session->read_first_successful_insert_id_in_prev_stmt(),
10340
10341
MY_INT64_NUM_DECIMAL_DIGITS))))
10342
10343
cond=new_cond;
10345
10346
cond->fixed, also it do not need tables so we use 0 as second
10348
cond->fix_fields(thd, &cond);
10349
cond->fix_fields(session, &cond);
10351
10352
IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10352
10353
clear for next row
10354
thd->substitute_null_with_insert_id= false;
10355
session->substitute_null_with_insert_id= false;
10356
10357
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10357
10358
else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10697
10698
rc= sub_select(join,join_tab,end_of_records);
10700
if (join->thd->killed) // If aborted by user
10701
if (join->session->killed) // If aborted by user
10702
join->thd->send_kill_message();
10703
join->session->send_kill_message();
10703
10704
return NESTED_LOOP_KILLED; /* purecov: inspected */
10705
10706
if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10877
10878
/* Set first_unmatched for the last inner table of this group */
10878
10879
join_tab->last_inner->first_unmatched= join_tab;
10880
join->thd->row_count= 0;
10881
join->session->row_count= 0;
10882
10883
error= (*join_tab->read_first_record)(join_tab);
10883
10884
rc= evaluate_join_record(join, join_tab, error);
10971
10972
/* create_myisam_from_heap will generate error if needed */
10972
10973
if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10973
create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo,
10974
create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo,
10974
10975
&sjtbl->recinfo, error, 1))
10976
10977
//return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11007
11008
ha_rows found_records=join->found_records;
11008
11009
COND *select_cond= join_tab->select_cond;
11010
if (error > 0 || (join->thd->is_error())) // Fatal error
11011
if (error > 0 || (join->session->is_error())) // Fatal error
11011
11012
return NESTED_LOOP_ERROR;
11012
11013
if (error < 0)
11013
11014
return NESTED_LOOP_NO_MORE_ROWS;
11014
if (join->thd->killed) // Aborted by user
11015
if (join->session->killed) // Aborted by user
11016
join->thd->send_kill_message();
11017
join->session->send_kill_message();
11017
11018
return NESTED_LOOP_KILLED; /* purecov: inspected */
11019
11020
if (!select_cond || select_cond->val_int())
11076
11077
join_tab->found_match= true;
11077
11078
if (join_tab->check_weed_out_table)
11079
int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
11080
int res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table);
11080
11081
if (res == -1)
11081
11082
return NESTED_LOOP_ERROR;
11082
11083
if (res == 1)
11239
11240
info= &join_tab->read_record;
11242
if (join->thd->killed)
11243
if (join->session->killed)
11244
join->thd->send_kill_message();
11245
join->session->send_kill_message();
11245
11246
return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11247
11248
SQL_SELECT *select=join_tab->select;
11259
11260
if (!join_tab->check_weed_out_table ||
11260
!(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
11261
!(res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table)))
11262
11263
rc= (join_tab->next_select)(join,join_tab+1,0);
11263
11264
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11565
11569
if (!table->file->inited)
11566
11570
table->file->ha_index_init(tab->ref.key, tab->sorted);
11567
if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11571
if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11569
11573
if ((error=table->file->index_read_last_map(table->record[0],
11570
11574
tab->ref.key_buff,
11680
11686
delete tab->select->quick;
11681
11687
tab->select->quick=0;
11682
return tab->select->test_quick_select(tab->join->thd, tab->keys,
11688
return tab->select->test_quick_select(tab->join->session, tab->keys,
11683
11689
(table_map) 0, HA_POS_ERROR, 0,
11691
11697
if (tab->select && tab->select->quick && tab->select->quick->reset())
11693
init_read_record(&tab->read_record, tab->join->thd, tab->table,
11699
init_read_record(&tab->read_record, tab->join->session, tab->table,
11694
11700
tab->select,1,1);
11695
11701
return (*tab->read_record.read_record)(&tab->read_record);
11752
11760
if ((error=info->file->index_next(info->record)))
11753
11761
return info->table->report_error(error);
11763
update_virtual_fields_marked_for_write(tab->table);
11755
11764
} while (!key_cmp(tab->table->key_info[tab->index].key_part,
11756
11765
tab->insideout_buf, key->key_length));
11757
11766
tab->insideout_match_tab->found_match= 0;
12035
12050
Table *table=join->tmp_table;
12037
if (join->thd->killed) // Aborted by user
12052
if (join->session->killed) // Aborted by user
12039
join->thd->send_kill_message();
12054
join->session->send_kill_message();
12040
12055
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12042
12057
if (!end_of_records)
12044
12059
copy_fields(&join->tmp_table_param);
12045
12060
copy_funcs(join->tmp_table_param.items_to_copy);
12046
#ifdef TO_BE_DELETED
12047
if (!table->uniques) // If not unique handling
12049
/* Copy null values from group to row */
12051
for (group=table->group ; group ; group=group->next)
12053
Item *item= *group->item;
12054
if (item->maybe_null)
12056
Field *field=item->get_tmp_table_field();
12057
field->ptr[-1]= (unsigned char) (field->is_null() ? 1 : 0);
12062
12061
if (!join->having || join->having->val_int())
12068
12067
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12070
if (create_myisam_from_heap(join->thd, table,
12069
if (create_myisam_from_heap(join->session, table,
12071
12070
join->tmp_table_param.start_recinfo,
12072
12071
&join->tmp_table_param.recinfo,
12152
12151
copy_funcs(join->tmp_table_param.items_to_copy);
12153
12152
if ((error=table->file->ha_write_row(table->record[0])))
12155
if (create_myisam_from_heap(join->thd, table,
12154
if (create_myisam_from_heap(join->session, table,
12156
12155
join->tmp_table_param.start_recinfo,
12157
12156
&join->tmp_table_param.recinfo,
12222
12221
Table *table=join->tmp_table;
12225
if (join->thd->killed)
12224
if (join->session->killed)
12226
12225
{ // Aborted by user
12227
join->thd->send_kill_message();
12226
join->session->send_kill_message();
12228
12227
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12230
12229
if (!join->first_record || end_of_records ||
12245
12244
if (!join->having || join->having->val_int())
12247
12246
int error= table->file->ha_write_row(table->record[0]);
12248
if (error && create_myisam_from_heap(join->thd, table,
12247
if (error && create_myisam_from_heap(join->session, table,
12249
12248
join->tmp_table_param.start_recinfo,
12250
12249
&join->tmp_table_param.recinfo,
12349
12348
@param join The top-level query.
12350
12349
@param old_cond The expression to be replaced.
12351
12350
@param new_cond The expression to be substituted.
12352
@param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
12351
@param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
12353
12352
the new expression.
12354
12353
@return <code>true</code> if there was an error, <code>false</code> if
12981
12980
new_ref_key_map.clear_all(); // Force the creation of quick select
12982
12981
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12984
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
12983
if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
12985
12984
(tab->join->select_options &
12986
12985
OPTION_FOUND_ROWS) ?
12987
12986
HA_POS_ERROR :
13168
13167
map.clear_all(); // Force the creation of quick select
13169
13168
map.set_bit(best_key); // only best_key.
13170
13169
quick_created=
13171
select->test_quick_select(join->thd, map, 0,
13170
select->test_quick_select(join->session, map, 0,
13172
13171
join->select_options & OPTION_FOUND_ROWS ?
13173
13172
HA_POS_ERROR :
13174
13173
join->unit->select_limit_cnt,
13315
create_sort_index(THD *thd, JOIN *join, order_st *order,
13314
create_sort_index(Session *session, JOIN *join, order_st *order,
13316
13315
ha_rows filesort_limit, ha_rows select_limit,
13317
13316
bool is_order_by)
13376
13375
For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13377
13376
field, quick will contain an empty record set.
13379
if (!(select->quick= (get_quick_select_for_ref(thd, table, &tab->ref,
13378
if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref,
13380
13379
tab->found_records))))
13390
13389
if (table->s->tmp_table)
13391
13390
table->file->info(HA_STATUS_VARIABLE); // Get record count
13392
table->sort.found_records=filesort(thd, table,join->sortorder, length,
13391
table->sort.found_records=filesort(session, table,join->sortorder, length,
13393
13392
select, filesort_limit, 0,
13394
13393
&examined_rows);
13395
13394
tab->records= table->sort.found_records; // For SQL_CALC_ROWS
13471
13470
if (entry->s->db_type() == heap_hton ||
13472
13471
(!entry->s->blob_fields &&
13473
13472
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13474
thd->variables.sortbuff_size)))
13475
error=remove_dup_with_hash_index(join->thd, entry,
13473
session->variables.sortbuff_size)))
13474
error=remove_dup_with_hash_index(join->session, entry,
13476
13475
field_count, first_field,
13477
13476
reclength, having);
13479
error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13478
error=remove_dup_with_compare(join->session, entry, first_field, offset,
13482
13481
free_blobs(first_field);
13487
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
13486
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13488
13487
ulong offset, Item *having)
13490
13489
handler *file=table->file;
13726
13725
******************************************************************************/
13729
join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count)
13728
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
13731
13730
register unsigned int i;
13732
13731
unsigned int length, blobs;
13742
13741
for (i=0 ; i < table_count ; i++,join_tab++)
13744
13743
if (!join_tab->used_fieldlength) /* Not calced yet */
13745
calc_used_field_length(thd, join_tab);
13744
calc_used_field_length(session, join_tab);
13746
13745
cache->fields+=join_tab->used_fields;
13747
13746
blobs+=join_tab->used_blobs;
13835
13834
cache->length=length+blobs*sizeof(char*);
13836
13835
cache->blobs=blobs;
13837
13836
*blob_ptr=0; /* End sequentel */
13838
size=cmax(thd->variables.join_buff_size, (ulong)cache->length);
13837
size=cmax(session->variables.join_buff_size, (ulong)cache->length);
13839
13838
if (!(cache->buff=(unsigned char*) my_malloc(size,MYF(0))))
13840
13839
return(1); /* Don't use cache */ /* purecov: inspected */
13841
13840
cache->end=cache->buff+size;
14035
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
14034
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
14037
enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
14038
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
14036
enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
14037
session->count_cuted_fields= CHECK_FIELD_IGNORE;
14039
14038
bool result= 0;
14041
14040
for (store_key **copy=ref->key_copy ; *copy ; copy++)
14072
14071
ref_pointer_array and all_fields are updated.
14074
@param[in] thd Pointer to current thread structure
14073
@param[in] session Pointer to current thread structure
14075
14074
@param[in,out] ref_pointer_array All select, group and order by fields
14076
14075
@param[in] tables List of tables to search in (usually
14092
find_order_in_list(THD *thd, Item **ref_pointer_array, TableList *tables,
14091
find_order_in_list(Session *session, Item **ref_pointer_array, TableList *tables,
14093
14092
order_st *order, List<Item> &fields, List<Item> &all_fields,
14094
14093
bool is_group_field)
14110
14109
if (!count || count > fields.elements)
14112
14111
my_error(ER_BAD_FIELD_ERROR, MYF(0),
14113
order_item->full_name(), thd->where);
14112
order_item->full_name(), session->where);
14116
14115
order->item= ref_pointer_array + count - 1;
14136
14135
for this name (in case if we would perform lookup in all tables).
14138
14137
if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14139
order_item->fix_fields(thd, order->item))
14138
order_item->fix_fields(session, order->item))
14142
14141
/* Lookup the current GROUP field in the FROM clause. */
14145
14144
if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14146
14145
order_item_type == Item::REF_ITEM)
14148
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
14147
from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
14149
14148
NULL, &view_ref, IGNORE_ERRORS, true,
14151
14150
if (!from_field)
14185
14184
warning so the user knows that the field from the FROM clause
14186
14185
overshadows the column reference from the SELECT list.
14188
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14187
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14189
14188
ER(ER_NON_UNIQ_ERROR),
14190
14189
((Item_ident*) order_item)->field_name,
14191
current_thd->where);
14190
current_session->where);
14205
14204
arguments for which fix_fields already was called.
14207
14206
if (!order_item->fixed &&
14208
(order_item->fix_fields(thd, order->item) ||
14207
(order_item->fix_fields(session, order->item) ||
14209
14208
(order_item= *order->item)->check_cols(1) ||
14210
thd->is_fatal_error))
14209
session->is_fatal_error))
14211
14210
return true; /* Wrong field. */
14213
14212
uint32_t el= all_fields.elements;
14225
14224
the field list.
14228
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
14227
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14229
14228
List<Item> &fields, List<Item> &all_fields, order_st *order)
14231
thd->where="order clause";
14230
session->where="order clause";
14232
14231
for (; order; order=order->next)
14234
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
14233
if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
14235
14234
all_fields, false))
14269
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
14268
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
14270
14269
List<Item> &fields, List<Item> &all_fields, order_st *order,
14271
14270
bool *hidden_group_fields)
14279
14278
uint32_t org_fields=all_fields.elements;
14281
thd->where="group statement";
14280
session->where="group statement";
14282
14281
for (ord= order; ord; ord= ord->next)
14284
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
14283
if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
14285
14284
all_fields, true))
14287
14286
(*ord->item)->marker= UNDEF_POS; /* Mark found */
14365
14364
static order_st *
14366
create_distinct_group(THD *thd, Item **ref_pointer_array,
14365
create_distinct_group(Session *session, Item **ref_pointer_array,
14367
14366
order_st *order_list, List<Item> &fields,
14368
14367
List<Item> &all_fields __attribute__((unused)),
14369
14368
bool *all_order_by_fields_used)
14657
14656
for (; group ; group=group->next)
14659
Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
14658
Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
14660
14659
if (!tmp || join->group_fields.push_front(tmp))
14703
14702
Change old item_field to use a new field with points at saved fieldvalue
14704
14703
This function is only called before use of send_fields.
14706
@param thd THD pointer
14705
@param session Session pointer
14707
14706
@param param temporary table parameters
14708
14707
@param ref_pointer_array array of pointers to top elements of filed list
14709
14708
@param res_selected_fields new list of items of select item list
14727
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
14726
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
14728
14727
Item **ref_pointer_array,
14729
14728
List<Item> &res_selected_fields, List<Item> &res_all_fields,
14730
14729
uint32_t elements, List<Item> &all_fields)
14787
14786
field= item->field;
14788
item->result_field=field->new_field(thd->mem_root,field->table, 1);
14787
item->result_field=field->new_field(session->mem_root,field->table, 1);
14790
14789
We need to allocate one extra byte for null handling and
14791
14790
another extra byte to not get warnings from purify in
14980
14979
Change all funcs and sum_funcs to fields in tmp table, and create
14981
14980
new list of all items.
14983
@param thd THD pointer
14982
@param session Session pointer
14984
14983
@param ref_pointer_array array of pointers to top elements of filed list
14985
14984
@param res_selected_fields new list of items of select item list
14986
14985
@param res_all_fields new list of all items
14997
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
14996
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
14998
14997
List<Item> &res_selected_fields,
14999
14998
List<Item> &res_all_fields,
15000
14999
uint32_t elements, List<Item> &all_fields)
15060
15059
Change all sum_func refs to fields to point at fields in tmp table.
15061
15060
Change all funcs to be fields in tmp table.
15063
@param thd THD pointer
15062
@param session Session pointer
15064
15063
@param ref_pointer_array array of pointers to top elements of filed list
15065
15064
@param res_selected_fields new list of items of select item list
15066
15065
@param res_all_fields new list of all items
15077
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
15076
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
15078
15077
List<Item> &res_selected_fields,
15079
15078
List<Item> &res_all_fields, uint32_t elements,
15080
15079
List<Item> &all_fields)
15087
15086
uint32_t i, border= all_fields.elements - elements;
15088
15087
for (i= 0; (item= it++); i++)
15090
res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
15089
res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
15091
15090
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15225
15224
Item *value=join_tab->ref.items[i];
15226
15225
cond->add(new Item_func_equal(new Item_field(field), value));
15228
if (thd->is_fatal_error)
15227
if (session->is_fatal_error)
15229
15228
return(true);
15231
15230
if (!cond->fixed)
15232
cond->fix_fields(thd, (Item**)&cond);
15231
cond->fix_fields(session, (Item**)&cond);
15233
15232
if (join_tab->select)
15235
15234
error=(int) cond->add(join_tab->select->cond);
15247
15246
Free joins of subselect of this select.
15249
@param thd THD pointer
15248
@param session Session pointer
15250
15249
@param select pointer to st_select_lex which subselects joins we will free
15253
void free_underlaid_joins(THD *thd __attribute__((unused)),
15252
void free_underlaid_joins(Session *session __attribute__((unused)),
15254
15253
SELECT_LEX *select)
15256
15255
for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15288
15287
This substitution is needed GROUP BY queries with ROLLUP if
15289
15288
SELECT list contains expressions over group by attributes.
15291
@param thd reference to the context
15290
@param session reference to the context
15292
15291
@param expr expression to make replacement
15293
15292
@param group_list list of references to group by items
15294
15293
@param changed out: returns 1 if item contains a replaced field item
15306
static bool change_group_ref(THD *thd, Item_func *expr, order_st *group_list,
15305
static bool change_group_ref(Session *session, Item_func *expr, order_st *group_list,
15307
15306
bool *changed)
15309
15308
if (expr->arg_count)
15311
Name_resolution_context *context= &thd->lex->current_select->context;
15310
Name_resolution_context *context= &session->lex->current_select->context;
15312
15311
Item **arg,**arg_end;
15313
15312
bool arg_changed= false;
15314
15313
for (arg= expr->arguments(),
15327
15326
if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15328
15327
item->name)))
15329
15328
return 1; // fatal_error is set
15330
thd->change_item_tree(arg, new_item);
15329
session->change_item_tree(arg, new_item);
15331
15330
arg_changed= true;
15335
15334
else if (item->type() == Item::FUNC_ITEM)
15337
if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
15336
if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
15423
15422
Item* new_item= new Item_func_rollup_const(item);
15424
15423
if (!new_item)
15426
new_item->fix_fields(thd, (Item **) 0);
15427
thd->change_item_tree(it.ref(), new_item);
15425
new_item->fix_fields(session, (Item **) 0);
15426
session->change_item_tree(it.ref(), new_item);
15428
15427
for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15430
15429
if (*tmp->item == item)
15431
thd->change_item_tree(tmp->item, new_item);
15430
session->change_item_tree(tmp->item, new_item);
15436
15435
if (item->type() == Item::FUNC_ITEM && !found_in_group)
15438
15437
bool changed= false;
15439
if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
15438
if (change_group_ref(session, (Item_func *) item, group_list, &changed))
15442
15441
We have to prevent creation of a field in a temporary table for
15663
15662
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15664
15663
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15666
if (create_myisam_from_heap(thd, table_arg,
15665
if (create_myisam_from_heap(session, table_arg,
15667
15666
tmp_table_param.start_recinfo,
15668
15667
&tmp_table_param.recinfo,
15669
15668
write_error, 0))
15706
15705
List<Item> field_list;
15707
15706
List<Item> item_list;
15708
THD *thd=join->thd;
15707
Session *session=join->session;
15709
15708
select_result *result=join->result;
15710
15709
Item *item_null= new Item_null();
15711
15710
const CHARSET_INFO * const cs= system_charset_info;
15712
15711
int quick_type;
15713
15712
/* Don't log this into the slow query log */
15714
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15713
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15715
15714
join->unit->offset_limit_cnt= 0;
15718
15717
NOTE: the number/types of items pushed into item_list must be in sync with
15719
EXPLAIN column types as they're "defined" in THD::send_explain_fields()
15718
EXPLAIN column types as they're "defined" in Session::send_explain_fields()
15726
15725
strlen(join->select_lex->type), cs));
15727
15726
for (uint32_t i=0 ; i < 7; i++)
15728
15727
item_list.push_back(item_null);
15729
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15728
if (join->session->lex->describe & DESCRIBE_EXTENDED)
15730
15729
item_list.push_back(item_null);
15732
15731
item_list.push_back(new Item_string(message,strlen(message),cs));
16051
16050
const COND *pushed_cond= tab->table->file->pushed_cond;
16053
if (thd->variables.engine_condition_pushdown && pushed_cond)
16052
if (session->variables.engine_condition_pushdown && pushed_cond)
16055
16054
extra.append(STRING_WITH_LEN("; Using where with pushed "
16056
16055
"condition"));
16057
if (thd->lex->describe & DESCRIBE_EXTENDED)
16056
if (session->lex->describe & DESCRIBE_EXTENDED)
16059
16058
extra.append(STRING_WITH_LEN(": "));
16060
16059
((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16109
16108
need_order=0;
16110
16109
extra.append(STRING_WITH_LEN("; Using filesort"));
16112
if (distinct & test_all_bits(used_tables,thd->used_tables))
16111
if (distinct & test_all_bits(used_tables,session->used_tables))
16113
16112
extra.append(STRING_WITH_LEN("; Distinct"));
16115
16114
if (tab->insideout_match_tab)
16172
16171
unit= unit->next_unit())
16174
if (mysql_explain_union(thd, unit, result))
16173
if (mysql_explain_union(session, unit, result))
16181
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
16180
bool mysql_explain_union(Session *session, SELECT_LEX_UNIT *unit, select_result *result)
16184
16183
SELECT_LEX *first= unit->first_select();
16190
16189
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16191
16190
uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16192
sl->type= (((&thd->lex->select_lex)==sl)?
16191
sl->type= (((&session->lex->select_lex)==sl)?
16193
16192
(sl->first_inner_unit() || sl->next_select() ?
16194
16193
"PRIMARY" : "SIMPLE"):
16195
16194
((sl == first)?
16210
16209
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16211
16210
unit->fake_select_lex->type= "UNION RESULT";
16212
16211
unit->fake_select_lex->options|= SELECT_DESCRIBE;
16213
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16212
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16214
16213
res= unit->exec();
16215
16214
res|= unit->cleanup();
16219
thd->lex->current_select= first;
16218
session->lex->current_select= first;
16220
16219
unit->set_limit(unit->global_parameters);
16221
res= mysql_select(thd, &first->ref_pointer_array,
16220
res= mysql_select(session, &first->ref_pointer_array,
16222
16221
(TableList*) first->table_list.first,
16223
16222
first->with_wild, first->item_list,
16224
16223
first->where,
16227
16226
(order_st*) first->order_list.first,
16228
16227
(order_st*) first->group_list.first,
16229
16228
first->having,
16230
(order_st*) thd->lex->proc_list.first,
16231
first->options | thd->options | SELECT_DESCRIBE,
16229
(order_st*) session->lex->proc_list.first,
16230
first->options | session->options | SELECT_DESCRIBE,
16232
16231
result, unit, first);
16234
return(res || thd->is_error());
16233
return(res || session->is_error());
16238
static void print_table_array(THD *thd, String *str, TableList **table,
16237
static void print_table_array(Session *session, String *str, TableList **table,
16239
16238
TableList **end)
16241
(*table)->print(thd, str, QT_ORDINARY);
16240
(*table)->print(session, str, QT_ORDINARY);
16243
16242
for (TableList **tbl= table + 1; tbl < end; tbl++)
16254
16253
str->append(STRING_WITH_LEN(" semi join "));
16256
16255
str->append(STRING_WITH_LEN(" join "));
16257
curr->print(thd, str, QT_ORDINARY);
16256
curr->print(session, str, QT_ORDINARY);
16258
16257
if (curr->on_expr)
16260
16259
str->append(STRING_WITH_LEN(" on("));
16269
16268
Print joins from the FROM clause.
16270
@param thd thread handler
16269
@param session thread handler
16271
16270
@param str string where table should be printed
16272
16271
@param tables list of tables in join
16273
16272
@query_type type of the query is being generated
16276
static void print_join(THD *thd,
16275
static void print_join(Session *session,
16278
16277
List<TableList> *tables,
16279
16278
enum_query_type query_type __attribute__((unused)))
16281
16280
/* List is reversed => we should reverse it before using */
16282
16281
List_iterator_fast<TableList> ti(*tables);
16283
TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
16282
TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16284
16283
tables->elements);
16285
16284
if (table == 0)
16286
16285
return; // out of memory
16309
16308
assert(tables->elements >= 1);
16310
print_table_array(thd, str, table, table + tables->elements);
16309
print_table_array(session, str, table, table + tables->elements);
16317
16316
@details Prints out the USE|FORCE|IGNORE index hint.
16319
@param thd the current thread
16318
@param session the current thread
16320
16319
@param[out] str appends the index hint here
16321
16320
@param hint what the hint is (as string : "USE INDEX"|
16322
16321
"FORCE INDEX"|"IGNORE INDEX")
16336
16335
str->append (STRING_WITH_LEN(" ("));
16337
16336
if (key_name.length)
16339
if (thd && !my_strnncoll(system_charset_info,
16338
if (session && !my_strnncoll(system_charset_info,
16340
16339
(const unsigned char *)key_name.str, key_name.length,
16341
16340
(const unsigned char *)primary_key_name,
16342
16341
strlen(primary_key_name)))
16343
16342
str->append(primary_key_name);
16345
append_identifier(thd, str, key_name.str, key_name.length);
16344
append_identifier(session, str, key_name.str, key_name.length);
16347
16346
str->append(')');
16354
16353
@param str string where table should be printed
16357
void TableList::print(THD *thd, String *str, enum_query_type query_type)
16356
void TableList::print(Session *session, String *str, enum_query_type query_type)
16359
16358
if (nested_join)
16361
16360
str->append('(');
16362
print_join(thd, str, &nested_join->join_list, query_type);
16361
print_join(session, str, &nested_join->join_list, query_type);
16363
16362
str->append(')');
16378
16377
// A normal table
16380
append_identifier(thd, str, db, db_length);
16379
append_identifier(session, str, db, db_length);
16381
16380
str->append('.');
16383
16382
if (schema_table)
16385
append_identifier(thd, str, schema_table_name,
16384
append_identifier(session, str, schema_table_name,
16386
16385
strlen(schema_table_name));
16387
16386
cmp_name= schema_table_name;
16391
append_identifier(thd, str, table_name, table_name_length);
16390
append_identifier(session, str, table_name, table_name_length);
16392
16391
cmp_name= table_name;
16419
16418
while ((hint= it++))
16421
16420
str->append (STRING_WITH_LEN(" "));
16422
hint->print (thd, str);
16421
hint->print (session, str);
16429
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
16428
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
16431
/* QQ: thd may not be set for sub queries, but this should be fixed */
16430
/* QQ: session may not be set for sub queries, but this should be fixed */
16432
session= current_session;
16435
16434
str->append(STRING_WITH_LEN("select "));
16437
16436
/* First add options */
16438
16437
if (options & SELECT_STRAIGHT_JOIN)
16439
16438
str->append(STRING_WITH_LEN("straight_join "));
16440
if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16441
(this == &thd->lex->select_lex))
16439
if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16440
(this == &session->lex->select_lex))
16442
16441
str->append(STRING_WITH_LEN("high_priority "));
16443
16442
if (options & SELECT_DISTINCT)
16444
16443
str->append(STRING_WITH_LEN("distinct "));
16473
16472
str->append(STRING_WITH_LEN(" from "));
16474
16473
/* go through join tree */
16475
print_join(thd, str, &top_join_list, query_type);
16474
print_join(session, str, &top_join_list, query_type);
16477
16476
else if (where)