26
26
#include <drizzled/server_includes.h>
27
27
#include <drizzled/sql_select.h>
28
#include <drizzled/sj_tmp_table.h>
29
#include <drizzled/table_map_iterator.h>
28
#include "sj_tmp_table.h"
31
30
#include <mysys/my_bit.h>
32
#include <drizzled/error.h>
33
#include <drizzled/gettext.h>
34
#include <drizzled/util/test.h>
35
#include <drizzled/name_resolution_context_state.h>
36
#include <drizzled/nested_join.h>
37
#include <drizzled/probes.h>
38
#include <drizzled/show.h>
39
#include <drizzled/item/cmpfunc.h>
40
#include <drizzled/cached_item.h>
41
#include <drizzled/sql_base.h>
42
#include <drizzled/field/blob.h>
46
#if defined(CMATH_NAMESPACE)
47
using namespace CMATH_NAMESPACE;
31
#include <drizzled/drizzled_error_messages.h>
32
#include <libdrizzle/gettext.h>
50
34
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
51
35
"MAYBE_REF","ALL","range","index",
58
42
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
59
43
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
60
44
DYNAMIC_ARRAY *keyuse);
61
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
45
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
62
46
JOIN_TAB *join_tab,
63
uint32_t tables, COND *conds,
47
uint tables, COND *conds,
64
48
COND_EQUAL *cond_equal,
65
49
table_map table_map, SELECT_LEX *select_lex,
66
50
st_sargable_param **sargables);
67
51
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
68
static void set_position(JOIN *join,uint32_t index,JOIN_TAB *table,KEYUSE *key);
52
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
69
53
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
70
54
table_map used_tables);
71
55
static bool choose_plan(JOIN *join,table_map join_tables);
73
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
74
table_map remaining_tables, uint32_t idx,
57
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
58
table_map remaining_tables, uint idx,
75
59
double record_count, double read_time);
76
60
static void optimize_straight_join(JOIN *join, table_map join_tables);
77
61
static bool greedy_search(JOIN *join, table_map remaining_tables,
78
uint32_t depth, uint32_t prune_level);
62
uint depth, uint prune_level);
79
63
static bool best_extension_by_limited_search(JOIN *join,
80
64
table_map remaining_tables,
81
uint32_t idx, double record_count,
82
double read_time, uint32_t depth,
83
uint32_t prune_level);
84
static uint32_t determine_search_depth(JOIN* join);
65
uint idx, double record_count,
66
double read_time, uint depth,
68
static uint determine_search_depth(JOIN* join);
85
69
static int join_tab_cmp(const void* ptr1, const void* ptr2);
86
70
static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
88
72
TODO: 'find_best' is here only temporarily until 'greedy_search' is
89
73
tested and approved.
91
static bool find_best(JOIN *join,table_map rest_tables,uint32_t index,
75
static bool find_best(JOIN *join,table_map rest_tables,uint index,
92
76
double record_count,double read_time);
93
static uint32_t cache_record_length(JOIN *join,uint32_t index);
94
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
77
static uint cache_record_length(JOIN *join,uint index);
78
static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
95
79
static bool get_best_combination(JOIN *join);
96
static store_key *get_store_key(Session *session,
80
static store_key *get_store_key(THD *thd,
97
81
KEYUSE *keyuse, table_map used_tables,
98
KEY_PART_INFO *key_part, unsigned char *key_buff,
82
KEY_PART_INFO *key_part, uchar *key_buff,
100
84
static bool make_simple_join(JOIN *join,Table *tmp_table);
101
85
static void make_outerjoin_info(JOIN *join);
102
86
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
103
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
87
static bool make_join_readinfo(JOIN *join, uint64_t options, uint no_jbuf_after);
104
88
static bool only_eq_ref_tables(JOIN *join, order_st *order, table_map tables);
105
89
static void update_depend_map(JOIN *join);
106
90
static void update_depend_map(JOIN *join, order_st *order);
183
167
bool (*find_func) (Field *, void *), void *data);
184
168
static bool find_field_in_item_list (Field *field, void *data);
185
169
static bool find_field_in_order_list (Field *field, void *data);
186
static int create_sort_index(Session *session, JOIN *join, order_st *order,
170
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
187
171
ha_rows filesort_limit, ha_rows select_limit,
188
172
bool is_order_by);
189
173
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
191
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
192
uint32_t offset, Item *having);
193
static int remove_dup_with_hash_index(Session *session,Table *table,
194
uint32_t field_count, Field **first_field,
195
uint32_t key_length, Item *having);
196
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
197
static uint32_t used_blob_length(CACHE_FIELD **ptr);
175
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
176
ulong offset,Item *having);
177
static int remove_dup_with_hash_index(THD *thd,Table *table,
178
uint field_count, Field **first_field,
180
ulong key_length,Item *having);
181
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
182
static ulong used_blob_length(CACHE_FIELD **ptr);
198
183
static bool store_record_in_cache(JOIN_CACHE *cache);
199
184
static void reset_cache_read(JOIN_CACHE *cache);
200
185
static void reset_cache_write(JOIN_CACHE *cache);
201
186
static void read_cached_record(JOIN_TAB *tab);
202
187
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
203
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
188
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
204
189
order_st *order, List<Item> &fields,
205
190
List<Item> &all_fields,
206
191
bool *all_order_by_fields_used);
210
195
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
211
196
static bool alloc_group_fields(JOIN *join,order_st *group);
212
197
// Create list for using with tempory table
213
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
198
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
214
199
List<Item> &new_list1,
215
200
List<Item> &new_list2,
216
uint32_t elements, List<Item> &items);
201
uint elements, List<Item> &items);
217
202
// Create list for using with tempory table
218
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
203
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
219
204
List<Item> &new_list1,
220
205
List<Item> &new_list2,
221
uint32_t elements, List<Item> &items);
206
uint elements, List<Item> &items);
222
207
static void init_tmptable_sum_functions(Item_sum **func);
223
208
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
224
209
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
225
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
226
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
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);
227
212
static bool init_sum_functions(Item_sum **func, Item_sum **end);
228
213
static bool update_sum_func(Item_sum **func);
229
214
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
230
bool distinct, const char *message=NULL);
215
bool distinct, const char *message=NullS);
231
216
static Item *remove_additional_cond(Item* conds);
232
217
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
233
218
static bool test_if_ref(Item_field *left_item,Item *right_item);
261
246
if (select_lex->master_unit()->is_union() ||
262
247
select_lex->master_unit()->fake_select_lex)
263
res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
248
res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
266
251
SELECT_LEX_UNIT *unit= &lex->unit;
267
252
unit->set_limit(unit->global_parameters);
268
session->session_marker= 0;
270
255
'options' of mysql_select will be set in JOIN, as far as JOIN for
271
256
every PS/SP execution new, we will not need reset this flag if
272
257
setup_tables_done_option changed for next rexecution
274
res= mysql_select(session, &select_lex->ref_pointer_array,
259
res= mysql_select(thd, &select_lex->ref_pointer_array,
275
260
(TableList*) select_lex->table_list.first,
276
261
select_lex->with_wild, select_lex->item_list,
277
262
select_lex->where,
397
382
ref->outer_ref= new_ref;
398
383
ref->ref= &ref->outer_ref;
400
if (!ref->fixed && ref->fix_fields(session, 0))
385
if (!ref->fixed && ref->fix_fields(thd, 0))
402
session->used_tables|= item->used_tables();
387
thd->used_tables|= item->used_tables();
392
#define MAGIC_IN_WHERE_TOP_LEVEL 10
408
394
Function to setup clauses without sum functions.
410
inline int setup_without_group(Session *session, Item **ref_pointer_array,
414
List<Item> &all_fields,
417
order_st *group, bool *hidden_group_fields)
396
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
400
List<Item> &all_fields,
403
order_st *group, bool *hidden_group_fields)
420
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
422
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
423
res= setup_conds(session, tables, leaves, conds);
425
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
426
res= res || setup_order(session, ref_pointer_array, tables, fields, all_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,
428
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
429
res= res || setup_group(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,
430
416
group, hidden_group_fields);
431
session->lex->allow_sum_func= save_allow_sum_func;
417
thd->lex->allow_sum_func= save_allow_sum_func;
473
459
join_list= &select_lex->top_join_list;
474
460
union_part= unit_arg->is_union();
476
session->lex->current_select->is_item_list_lookup= 1;
462
thd->lex->current_select->is_item_list_lookup= 1;
478
464
If we have already executed SELECT, then it have not sense to prevent
479
465
its table from update (see unique_table())
481
if (session->derived_tables_processing)
467
if (thd->derived_tables_processing)
482
468
select_lex->exclude_from_table_unique_test= true;
484
470
/* Check that all tables, fields, conds and order are ok */
486
472
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
487
setup_tables_and_check_access(session, &select_lex->context, join_list,
473
setup_tables_and_check_access(thd, &select_lex->context, join_list,
488
474
tables_list, &select_lex->leaf_tables,
495
481
table_ptr= table_ptr->next_leaf)
498
if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
499
select_lex->setup_ref_array(session, og_num) ||
500
setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
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,
501
487
&all_fields, 1) ||
502
setup_without_group(session, (*rref_pointer_array), tables_list,
488
setup_without_group(thd, (*rref_pointer_array), tables_list,
503
489
select_lex->leaf_tables, fields_list,
504
490
all_fields, &conds, order, group_list,
505
491
&hidden_group_fields))
512
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
513
session->where="having clause";
514
session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
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;
515
501
select_lex->having_fix_field= 1;
516
502
bool having_fix_rc= (!having->fixed &&
517
(having->fix_fields(session, &having) ||
503
(having->fix_fields(thd, &having) ||
518
504
having->check_cols(1)));
519
505
select_lex->having_fix_field= 0;
520
if (having_fix_rc || session->is_error())
506
if (having_fix_rc || thd->is_error())
521
507
return(-1); /* purecov: inspected */
522
session->lex->allow_sum_func= save_allow_sum_func;
508
thd->lex->allow_sum_func= save_allow_sum_func;
1260
1246
Item_cond_and can't be fixed after creation, so we do not check
1263
conds->fix_fields(session, &conds);
1264
conds->change_ref_to_fields(session, tables_list);
1249
conds->fix_fields(thd, &conds);
1250
conds->change_ref_to_fields(thd, tables_list);
1265
1251
conds->top_level_item();
1256
SELECT_LEX *sel= thd->lex->current_select;
1257
if (sel->first_cond_optimization)
1260
The following code will allocate the new items in a permanent
1261
MEMROOT for prepared statements and stored procedures.
1263
sel->first_cond_optimization= 0;
1271
/* Convert all outer joins to inner joins if possible */
1272
conds= simplify_joins(this, join_list, conds, true, false);
1273
build_bitmap_for_nested_joins(join_list, 0);
1265
/* Convert all outer joins to inner joins if possible */
1266
conds= simplify_joins(this, join_list, conds, true, false);
1267
build_bitmap_for_nested_joins(join_list, 0);
1275
1270
conds= optimize_cond(this, conds, join_list, &cond_value);
1276
if (session->is_error())
1271
if (thd->is_error())
1377
1372
!(select_options & SELECT_DESCRIBE) &&
1379
1374
!(conds->used_tables() & RAND_TABLE_BIT) ||
1380
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1375
select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
1382
1377
zero_result_cause= "no matching row in const table";
1386
if (!(session->options & OPTION_BIG_SELECTS) &&
1387
best_read > (double) session->variables.max_join_size &&
1381
if (!(thd->options & OPTION_BIG_SELECTS) &&
1382
best_read > (double) thd->variables.max_join_size &&
1388
1383
!(select_options & SELECT_DESCRIBE))
1389
1384
{ /* purecov: inspected */
1390
1385
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1394
if (const_tables && !session->locked_tables &&
1389
if (const_tables && !thd->locked_tables &&
1395
1390
!(select_options & SELECT_NO_UNLOCK))
1396
mysql_unlock_some_tables(session, table, const_tables);
1391
mysql_unlock_some_tables(thd, table, const_tables);
1397
1392
if (!conds && outer_join)
1399
1394
/* Handle the case where we have an OUTER JOIN without a WHERE */
1851
1846
/* if group or order on first table, sort first */
1852
1847
if (group_list && simple_group)
1854
session->set_proc_info("Sorting for group");
1855
if (create_sort_index(session, this, group_list,
1849
thd_proc_info(thd, "Sorting for group");
1850
if (create_sort_index(thd, this, group_list,
1856
1851
HA_POS_ERROR, HA_POS_ERROR, false) ||
1857
1852
alloc_group_fields(this, group_list) ||
1858
1853
make_sum_func_list(all_fields, fields_list, 1) ||
1859
setup_sum_funcs(session, sum_funcs))
1854
setup_sum_funcs(thd, sum_funcs))
2175
2170
items1= items0 + all_fields.elements;
2176
2171
if (sort_and_group || curr_tmp_table->group)
2178
if (change_to_use_tmp_fields(session, items1,
2173
if (change_to_use_tmp_fields(thd, items1,
2179
2174
tmp_fields_list1, tmp_all_fields1,
2180
2175
fields_list.elements, all_fields))
2185
if (change_refs_to_tmp_fields(session, items1,
2180
if (change_refs_to_tmp_fields(thd, items1,
2186
2181
tmp_fields_list1, tmp_all_fields1,
2187
2182
fields_list.elements, all_fields))
2501
/* XXX: When can we have here session->is_error() not zero? */
2502
if (session->is_error())
2496
/* XXX: When can we have here thd->is_error() not zero? */
2497
if (thd->is_error())
2504
error= session->is_error();
2499
error= thd->is_error();
2507
2502
curr_join->having= curr_join->tmp_having;
2508
2503
curr_join->fields= curr_fields_list;
2511
session->set_proc_info("Sending data");
2506
thd_proc_info(thd, "Sending data");
2512
2507
result->send_fields(*curr_fields_list,
2513
2508
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2514
2509
error= do_select(curr_join, curr_fields_list, NULL);
2515
session->limit_found_rows= curr_join->send_records;
2510
thd->limit_found_rows= curr_join->send_records;
2518
2513
/* Accumulate the counts from all join iterations of all join parts. */
2519
session->examined_row_count+= curr_join->examined_rows;
2514
thd->examined_row_count+= curr_join->examined_rows;
2522
2517
With EXPLAIN EXTENDED we have to restore original ref_array
2618
mysql_select(Session *session, Item ***rref_pointer_array,
2619
TableList *tables, uint32_t wild_num, List<Item> &fields,
2620
COND *conds, uint32_t og_num, order_st *order, order_st *group,
2613
mysql_select(THD *thd, Item ***rref_pointer_array,
2614
TableList *tables, uint wild_num, List<Item> &fields,
2615
COND *conds, uint og_num, order_st *order, order_st *group,
2621
2616
Item *having, order_st *proc_param, uint64_t select_options,
2622
2617
select_result *result, SELECT_LEX_UNIT *unit,
2623
2618
SELECT_LEX *select_lex)
2663
if (!(join= new JOIN(session, fields, select_options, result)))
2658
if (!(join= new JOIN(thd, fields, select_options, result)))
2665
session->set_proc_info("init");
2666
session->used_tables=0; // Updated by setup_fields
2660
thd_proc_info(thd, "init");
2661
thd->used_tables=0; // Updated by setup_fields
2667
2662
if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2668
2663
conds, og_num, order, group, having, proc_param,
2669
2664
select_lex, unit)) == true)
3373
3368
*****************************************************************************/
3376
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
3371
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
3378
3373
const key_map *keys,ha_rows limit)
3381
if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3376
if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
3382
3377
return(0); // Fatal error flag is set
3385
3380
select->head=table;
3386
3381
table->reginfo.impossible_range=0;
3387
if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
3382
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
3388
3383
limit, 0, false)) == 1)
3389
3384
return(select->quick->records);
3390
3385
if (error == -1)
4581
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4582
uint32_t tables, COND *cond, COND_EQUAL *,
4576
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4577
uint tables, COND *cond,
4578
COND_EQUAL *cond_equal __attribute__((unused)),
4583
4579
table_map normal_tables, SELECT_LEX *select_lex,
4584
4580
SARGABLE_PARAM **sargables)
4586
4582
uint and_level,i,found_eq_constant;
4587
4583
KEY_FIELD *key_fields, *end, *field;
4589
uint32_t m= cmax(select_lex->max_equal_elems,(uint32_t)1);
4585
uint m= max(select_lex->max_equal_elems,(uint32_t)1);
4592
4588
We use the same piece of memory to store both KEY_FIELD
6609
6606
Table *table= field->table;
6610
Session *session= table->in_use;
6611
ha_rows cuted_fields=session->cuted_fields;
6607
THD *thd= table->in_use;
6608
ha_rows cuted_fields=thd->cuted_fields;
6614
6611
we should restore old value of count_cuted_fields because
6615
6612
store_val_in_field can be called from mysql_insert
6616
6613
with select_insert, which make count_cuted_fields= 1
6618
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
6619
session->count_cuted_fields= check_flag;
6615
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
6616
thd->count_cuted_fields= check_flag;
6620
6617
error= item->save_in_field(field, 1);
6621
session->count_cuted_fields= old_count_cuted_fields;
6622
return error || cuted_fields != session->cuted_fields;
6618
thd->count_cuted_fields= old_count_cuted_fields;
6619
return error || cuted_fields != thd->cuted_fields;
9619
9616
if (right_const)
9621
resolve_const_item(session, &args[1], args[0]);
9618
resolve_const_item(thd, &args[1], args[0]);
9622
9619
func->update_used_tables();
9623
change_cond_ref_to_const(session, save_list, and_father, and_father,
9620
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9624
9621
args[0], args[1]);
9626
9623
else if (left_const)
9628
resolve_const_item(session, &args[0], args[1]);
9625
resolve_const_item(thd, &args[0], args[1]);
9629
9626
func->update_used_tables();
9630
change_cond_ref_to_const(session, save_list, and_father, and_father,
9627
change_cond_ref_to_const(thd, save_list, and_father, and_father,
9631
9628
args[1], args[0]);
10234
10231
predicate. Substitute a constant instead of this field if the
10235
10232
multiple equality contains a constant.
10237
conds= build_equal_items(join->session, conds, NULL, join_list,
10234
conds= build_equal_items(join->thd, conds, NULL, join_list,
10238
10235
&join->cond_equal);
10240
10237
/* change field = field to field = const for each found field = const */
10241
propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10238
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
10243
10240
Remove all instances of item == item
10244
10241
Remove all and-levels where CONST item != CONST item
10246
conds= remove_eq_conds(session, conds, cond_value) ;
10243
conds= remove_eq_conds(thd, conds, cond_value) ;
10248
10245
return(conds);
12055
12039
enum_nested_loop_state
12056
end_write(JOIN *join, JOIN_TAB *,
12057
bool end_of_records)
12040
end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
12041
bool end_of_records)
12059
12043
Table *table=join->tmp_table;
12061
if (join->session->killed) // Aborted by user
12045
if (join->thd->killed) // Aborted by user
12063
join->session->send_kill_message();
12047
join->thd->send_kill_message();
12064
12048
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12066
12050
if (!end_of_records)
12068
12052
copy_fields(&join->tmp_table_param);
12069
12053
copy_funcs(join->tmp_table_param.items_to_copy);
12054
#ifdef TO_BE_DELETED
12055
if (!table->uniques) // If not unique handling
12057
/* Copy null values from group to row */
12059
for (group=table->group ; group ; group=group->next)
12061
Item *item= *group->item;
12062
if (item->maybe_null)
12064
Field *field=item->get_tmp_table_field();
12065
field->ptr[-1]= (uchar) (field->is_null() ? 1 : 0);
12070
12070
if (!join->having || join->having->val_int())
13472
13472
offset= (field_count ?
13473
13473
entry->field[entry->s->fields - field_count]->
13474
13474
offset(entry->record[0]) : 0);
13475
reclength= entry->s->reclength-offset;
13475
reclength=entry->s->reclength-offset;
13477
13477
free_io_cache(entry); // Safety
13478
13478
entry->file->info(HA_STATUS_VARIABLE);
13479
13479
if (entry->s->db_type() == heap_hton ||
13480
13480
(!entry->s->blob_fields &&
13481
13481
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13482
session->variables.sortbuff_size)))
13483
error= remove_dup_with_hash_index(join->session, entry,
13482
thd->variables.sortbuff_size)))
13483
error=remove_dup_with_hash_index(join->thd, entry,
13484
13484
field_count, first_field,
13485
13485
reclength, having);
13487
error= remove_dup_with_compare(join->session, entry, first_field, offset,
13487
error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13490
13490
free_blobs(first_field);
13583
13583
Note that this will not work on tables with blobs!
13586
static int remove_dup_with_hash_index(Session *session, Table *table,
13587
uint32_t field_count,
13586
static int remove_dup_with_hash_index(THD *thd, Table *table,
13588
13588
Field **first_field,
13589
uint32_t key_length,
13590
13590
Item *having)
13592
unsigned char *key_buffer, *key_pos, *record=table->record[0];
13592
uchar *key_buffer, *key_pos, *record=table->record[0];
13594
13594
handler *file= table->file;
13595
uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
13596
uint32_t *field_lengths,*field_length;
13595
ulong extra_length= ALIGN_SIZE(key_length)-key_length;
13596
uint *field_lengths,*field_length;
13599
13599
if (!my_multi_malloc(MYF(MY_WME),
14232
14233
the field list.
14235
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14236
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
14236
14237
List<Item> &fields, List<Item> &all_fields, order_st *order)
14238
session->where="order clause";
14239
thd->where="order clause";
14239
14240
for (; order; order=order->next)
14241
if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
14242
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
14242
14243
all_fields, false))
16214
16218
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16215
16219
unit->fake_select_lex->type= "UNION RESULT";
16216
16220
unit->fake_select_lex->options|= SELECT_DESCRIBE;
16217
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16221
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16218
16222
res= unit->exec();
16219
16223
res|= unit->cleanup();
16223
session->lex->current_select= first;
16227
thd->lex->current_select= first;
16224
16228
unit->set_limit(unit->global_parameters);
16225
res= mysql_select(session, &first->ref_pointer_array,
16229
res= mysql_select(thd, &first->ref_pointer_array,
16226
16230
(TableList*) first->table_list.first,
16227
16231
first->with_wild, first->item_list,
16228
16232
first->where,
16231
16235
(order_st*) first->order_list.first,
16232
16236
(order_st*) first->group_list.first,
16233
16237
first->having,
16234
(order_st*) session->lex->proc_list.first,
16235
first->options | session->options | SELECT_DESCRIBE,
16238
(order_st*) thd->lex->proc_list.first,
16239
first->options | thd->options | SELECT_DESCRIBE,
16236
16240
result, unit, first);
16238
return(res || session->is_error());
16242
return(res || thd->is_error());
16242
static void print_table_array(Session *session, String *str, TableList **table,
16246
static void print_table_array(THD *thd, String *str, TableList **table,
16243
16247
TableList **end)
16245
(*table)->print(session, str, QT_ORDINARY);
16249
(*table)->print(thd, str, QT_ORDINARY);
16247
16251
for (TableList **tbl= table + 1; tbl < end; tbl++)
16273
16277
Print joins from the FROM clause.
16274
@param session thread handler
16278
@param thd thread handler
16275
16279
@param str string where table should be printed
16276
16280
@param tables list of tables in join
16277
16281
@query_type type of the query is being generated
16280
static void print_join(Session *session, String *str,
16281
List<TableList> *tables, enum_query_type)
16284
static void print_join(THD *thd,
16286
List<TableList> *tables,
16287
enum_query_type query_type __attribute__((unused)))
16283
16289
/* List is reversed => we should reverse it before using */
16284
16290
List_iterator_fast<TableList> ti(*tables);
16285
TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16291
TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
16286
16292
tables->elements);
16287
16293
if (table == 0)
16288
16294
return; // out of memory
16377
16386
// A normal table
16379
append_identifier(session, str, db, db_length);
16388
append_identifier(thd, str, db, db_length);
16380
16389
str->append('.');
16382
16391
if (schema_table)
16384
append_identifier(session, str, schema_table_name,
16393
append_identifier(thd, str, schema_table_name,
16385
16394
strlen(schema_table_name));
16386
16395
cmp_name= schema_table_name;
16390
append_identifier(session, str, table_name, table_name_length);
16399
append_identifier(thd, str, table_name, table_name_length);
16391
16400
cmp_name= table_name;
16418
16427
while ((hint= it++))
16420
16429
str->append (STRING_WITH_LEN(" "));
16421
hint->print (session, str);
16430
hint->print (thd, str);
16428
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
16437
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
16430
/* QQ: session may not be set for sub queries, but this should be fixed */
16432
session= current_session;
16439
/* QQ: thd may not be set for sub queries, but this should be fixed */
16434
16443
str->append(STRING_WITH_LEN("select "));
16436
16445
/* First add options */
16437
16446
if (options & SELECT_STRAIGHT_JOIN)
16438
16447
str->append(STRING_WITH_LEN("straight_join "));
16439
if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16440
(this == &session->lex->select_lex))
16448
if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16449
(this == &thd->lex->select_lex))
16441
16450
str->append(STRING_WITH_LEN("high_priority "));
16442
16451
if (options & SELECT_DISTINCT)
16443
16452
str->append(STRING_WITH_LEN("distinct "));