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/nested_join.h>
36
#include <drizzled/probes.h>
39
#if defined(CMATH_NAMESPACE)
40
using namespace CMATH_NAMESPACE;
31
#include <drizzled/drizzled_error_messages.h>
32
#include <libdrizzle/gettext.h>
43
34
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
44
35
"MAYBE_REF","ALL","range","index",
51
42
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
52
43
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
53
44
DYNAMIC_ARRAY *keyuse);
54
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
45
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
55
46
JOIN_TAB *join_tab,
56
uint32_t tables, COND *conds,
47
uint tables, COND *conds,
57
48
COND_EQUAL *cond_equal,
58
49
table_map table_map, SELECT_LEX *select_lex,
59
50
st_sargable_param **sargables);
60
51
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
61
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);
62
53
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
63
54
table_map used_tables);
64
55
static bool choose_plan(JOIN *join,table_map join_tables);
66
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
67
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,
68
59
double record_count, double read_time);
69
60
static void optimize_straight_join(JOIN *join, table_map join_tables);
70
61
static bool greedy_search(JOIN *join, table_map remaining_tables,
71
uint32_t depth, uint32_t prune_level);
62
uint depth, uint prune_level);
72
63
static bool best_extension_by_limited_search(JOIN *join,
73
64
table_map remaining_tables,
74
uint32_t idx, double record_count,
75
double read_time, uint32_t depth,
76
uint32_t prune_level);
77
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);
78
69
static int join_tab_cmp(const void* ptr1, const void* ptr2);
79
70
static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
81
72
TODO: 'find_best' is here only temporarily until 'greedy_search' is
82
73
tested and approved.
84
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,
85
76
double record_count,double read_time);
86
static uint32_t cache_record_length(JOIN *join,uint32_t index);
87
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);
88
79
static bool get_best_combination(JOIN *join);
89
static store_key *get_store_key(Session *session,
80
static store_key *get_store_key(THD *thd,
90
81
KEYUSE *keyuse, table_map used_tables,
91
KEY_PART_INFO *key_part, unsigned char *key_buff,
82
KEY_PART_INFO *key_part, uchar *key_buff,
93
84
static bool make_simple_join(JOIN *join,Table *tmp_table);
94
85
static void make_outerjoin_info(JOIN *join);
95
86
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
96
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);
97
88
static bool only_eq_ref_tables(JOIN *join, order_st *order, table_map tables);
98
89
static void update_depend_map(JOIN *join);
99
90
static void update_depend_map(JOIN *join, order_st *order);
176
167
bool (*find_func) (Field *, void *), void *data);
177
168
static bool find_field_in_item_list (Field *field, void *data);
178
169
static bool find_field_in_order_list (Field *field, void *data);
179
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,
180
171
ha_rows filesort_limit, ha_rows select_limit,
181
172
bool is_order_by);
182
173
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
184
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
185
uint32_t offset, Item *having);
186
static int remove_dup_with_hash_index(Session *session,Table *table,
187
uint32_t field_count, Field **first_field,
188
uint32_t key_length, Item *having);
189
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
190
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);
191
183
static bool store_record_in_cache(JOIN_CACHE *cache);
192
184
static void reset_cache_read(JOIN_CACHE *cache);
193
185
static void reset_cache_write(JOIN_CACHE *cache);
194
186
static void read_cached_record(JOIN_TAB *tab);
195
187
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
196
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,
197
189
order_st *order, List<Item> &fields,
198
190
List<Item> &all_fields,
199
191
bool *all_order_by_fields_used);
203
195
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
204
196
static bool alloc_group_fields(JOIN *join,order_st *group);
205
197
// Create list for using with tempory table
206
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,
207
199
List<Item> &new_list1,
208
200
List<Item> &new_list2,
209
uint32_t elements, List<Item> &items);
201
uint elements, List<Item> &items);
210
202
// Create list for using with tempory table
211
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,
212
204
List<Item> &new_list1,
213
205
List<Item> &new_list2,
214
uint32_t elements, List<Item> &items);
206
uint elements, List<Item> &items);
215
207
static void init_tmptable_sum_functions(Item_sum **func);
216
208
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
217
209
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
218
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
219
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);
220
212
static bool init_sum_functions(Item_sum **func, Item_sum **end);
221
213
static bool update_sum_func(Item_sum **func);
222
214
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
223
bool distinct, const char *message=NULL);
215
bool distinct, const char *message=NullS);
224
216
static Item *remove_additional_cond(Item* conds);
225
217
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
226
218
static bool test_if_ref(Item_field *left_item,Item *right_item);
254
246
if (select_lex->master_unit()->is_union() ||
255
247
select_lex->master_unit()->fake_select_lex)
256
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);
259
251
SELECT_LEX_UNIT *unit= &lex->unit;
260
252
unit->set_limit(unit->global_parameters);
261
session->session_marker= 0;
263
255
'options' of mysql_select will be set in JOIN, as far as JOIN for
264
256
every PS/SP execution new, we will not need reset this flag if
265
257
setup_tables_done_option changed for next rexecution
267
res= mysql_select(session, &select_lex->ref_pointer_array,
259
res= mysql_select(thd, &select_lex->ref_pointer_array,
268
260
(TableList*) select_lex->table_list.first,
269
261
select_lex->with_wild, select_lex->item_list,
270
262
select_lex->where,
410
403
order_st *group, bool *hidden_group_fields)
413
nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
415
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
416
res= setup_conds(session, tables, leaves, conds);
418
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
419
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,
421
session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
422
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,
423
416
group, hidden_group_fields);
424
session->lex->allow_sum_func= save_allow_sum_func;
417
thd->lex->allow_sum_func= save_allow_sum_func;
466
459
join_list= &select_lex->top_join_list;
467
460
union_part= unit_arg->is_union();
469
session->lex->current_select->is_item_list_lookup= 1;
462
thd->lex->current_select->is_item_list_lookup= 1;
471
464
If we have already executed SELECT, then it have not sense to prevent
472
465
its table from update (see unique_table())
474
if (session->derived_tables_processing)
467
if (thd->derived_tables_processing)
475
468
select_lex->exclude_from_table_unique_test= true;
477
470
/* Check that all tables, fields, conds and order are ok */
479
472
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
480
setup_tables_and_check_access(session, &select_lex->context, join_list,
473
setup_tables_and_check_access(thd, &select_lex->context, join_list,
481
474
tables_list, &select_lex->leaf_tables,
488
481
table_ptr= table_ptr->next_leaf)
491
if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
492
select_lex->setup_ref_array(session, og_num) ||
493
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,
494
487
&all_fields, 1) ||
495
setup_without_group(session, (*rref_pointer_array), tables_list,
488
setup_without_group(thd, (*rref_pointer_array), tables_list,
496
489
select_lex->leaf_tables, fields_list,
497
490
all_fields, &conds, order, group_list,
498
491
&hidden_group_fields))
505
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
506
session->where="having clause";
507
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;
508
501
select_lex->having_fix_field= 1;
509
502
bool having_fix_rc= (!having->fixed &&
510
(having->fix_fields(session, &having) ||
503
(having->fix_fields(thd, &having) ||
511
504
having->check_cols(1)));
512
505
select_lex->having_fix_field= 0;
513
if (having_fix_rc || session->is_error())
506
if (having_fix_rc || thd->is_error())
514
507
return(-1); /* purecov: inspected */
515
session->lex->allow_sum_func= save_allow_sum_func;
508
thd->lex->allow_sum_func= save_allow_sum_func;
1253
1246
Item_cond_and can't be fixed after creation, so we do not check
1256
conds->fix_fields(session, &conds);
1257
conds->change_ref_to_fields(session, tables_list);
1249
conds->fix_fields(thd, &conds);
1250
conds->change_ref_to_fields(thd, tables_list);
1258
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;
1264
/* Convert all outer joins to inner joins if possible */
1265
conds= simplify_joins(this, join_list, conds, true, false);
1266
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);
1268
1270
conds= optimize_cond(this, conds, join_list, &cond_value);
1269
if (session->is_error())
1271
if (thd->is_error())
1370
1372
!(select_options & SELECT_DESCRIBE) &&
1372
1374
!(conds->used_tables() & RAND_TABLE_BIT) ||
1373
select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1375
select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
1375
1377
zero_result_cause= "no matching row in const table";
1379
if (!(session->options & OPTION_BIG_SELECTS) &&
1380
best_read > (double) session->variables.max_join_size &&
1381
if (!(thd->options & OPTION_BIG_SELECTS) &&
1382
best_read > (double) thd->variables.max_join_size &&
1381
1383
!(select_options & SELECT_DESCRIBE))
1382
1384
{ /* purecov: inspected */
1383
1385
my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1387
if (const_tables && !session->locked_tables &&
1389
if (const_tables && !thd->locked_tables &&
1388
1390
!(select_options & SELECT_NO_UNLOCK))
1389
mysql_unlock_some_tables(session, table, const_tables);
1391
mysql_unlock_some_tables(thd, table, const_tables);
1390
1392
if (!conds && outer_join)
1392
1394
/* Handle the case where we have an OUTER JOIN without a WHERE */
1844
1846
/* if group or order on first table, sort first */
1845
1847
if (group_list && simple_group)
1847
session->set_proc_info("Sorting for group");
1848
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,
1849
1851
HA_POS_ERROR, HA_POS_ERROR, false) ||
1850
1852
alloc_group_fields(this, group_list) ||
1851
1853
make_sum_func_list(all_fields, fields_list, 1) ||
1852
setup_sum_funcs(session, sum_funcs))
1854
setup_sum_funcs(thd, sum_funcs))
2168
2170
items1= items0 + all_fields.elements;
2169
2171
if (sort_and_group || curr_tmp_table->group)
2171
if (change_to_use_tmp_fields(session, items1,
2173
if (change_to_use_tmp_fields(thd, items1,
2172
2174
tmp_fields_list1, tmp_all_fields1,
2173
2175
fields_list.elements, all_fields))
2178
if (change_refs_to_tmp_fields(session, items1,
2180
if (change_refs_to_tmp_fields(thd, items1,
2179
2181
tmp_fields_list1, tmp_all_fields1,
2180
2182
fields_list.elements, all_fields))
2494
/* XXX: When can we have here session->is_error() not zero? */
2495
if (session->is_error())
2496
/* XXX: When can we have here thd->is_error() not zero? */
2497
if (thd->is_error())
2497
error= session->is_error();
2499
error= thd->is_error();
2500
2502
curr_join->having= curr_join->tmp_having;
2501
2503
curr_join->fields= curr_fields_list;
2504
session->set_proc_info("Sending data");
2506
thd_proc_info(thd, "Sending data");
2505
2507
result->send_fields(*curr_fields_list,
2506
2508
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2507
2509
error= do_select(curr_join, curr_fields_list, NULL);
2508
session->limit_found_rows= curr_join->send_records;
2510
thd->limit_found_rows= curr_join->send_records;
2511
2513
/* Accumulate the counts from all join iterations of all join parts. */
2512
session->examined_row_count+= curr_join->examined_rows;
2514
thd->examined_row_count+= curr_join->examined_rows;
2515
2517
With EXPLAIN EXTENDED we have to restore original ref_array
2611
mysql_select(Session *session, Item ***rref_pointer_array,
2612
TableList *tables, uint32_t wild_num, List<Item> &fields,
2613
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,
2614
2616
Item *having, order_st *proc_param, uint64_t select_options,
2615
2617
select_result *result, SELECT_LEX_UNIT *unit,
2616
2618
SELECT_LEX *select_lex)
2656
if (!(join= new JOIN(session, fields, select_options, result)))
2658
if (!(join= new JOIN(thd, fields, select_options, result)))
2658
session->set_proc_info("init");
2659
session->used_tables=0; // Updated by setup_fields
2660
thd_proc_info(thd, "init");
2661
thd->used_tables=0; // Updated by setup_fields
2660
2662
if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2661
2663
conds, og_num, order, group, having, proc_param,
2662
2664
select_lex, unit)) == true)
3366
3368
*****************************************************************************/
3369
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,
3371
3373
const key_map *keys,ha_rows limit)
3374
if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3376
if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
3375
3377
return(0); // Fatal error flag is set
3378
3380
select->head=table;
3379
3381
table->reginfo.impossible_range=0;
3380
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,
3381
3383
limit, 0, false)) == 1)
3382
3384
return(select->quick->records);
3383
3385
if (error == -1)
4574
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4575
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)),
4576
4579
table_map normal_tables, SELECT_LEX *select_lex,
4577
4580
SARGABLE_PARAM **sargables)
4579
4582
uint and_level,i,found_eq_constant;
4580
4583
KEY_FIELD *key_fields, *end, *field;
4582
uint32_t m= cmax(select_lex->max_equal_elems,(uint32_t)1);
4585
uint m= max(select_lex->max_equal_elems,(uint32_t)1);
4585
4588
We use the same piece of memory to store both KEY_FIELD
6602
6606
Table *table= field->table;
6603
Session *session= table->in_use;
6604
ha_rows cuted_fields=session->cuted_fields;
6607
THD *thd= table->in_use;
6608
ha_rows cuted_fields=thd->cuted_fields;
6607
6611
we should restore old value of count_cuted_fields because
6608
6612
store_val_in_field can be called from mysql_insert
6609
6613
with select_insert, which make count_cuted_fields= 1
6611
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
6612
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;
6613
6617
error= item->save_in_field(field, 1);
6614
session->count_cuted_fields= old_count_cuted_fields;
6615
return error || cuted_fields != session->cuted_fields;
6618
thd->count_cuted_fields= old_count_cuted_fields;
6619
return error || cuted_fields != thd->cuted_fields;
9612
9616
if (right_const)
9614
resolve_const_item(session, &args[1], args[0]);
9618
resolve_const_item(thd, &args[1], args[0]);
9615
9619
func->update_used_tables();
9616
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,
9617
9621
args[0], args[1]);
9619
9623
else if (left_const)
9621
resolve_const_item(session, &args[0], args[1]);
9625
resolve_const_item(thd, &args[0], args[1]);
9622
9626
func->update_used_tables();
9623
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,
9624
9628
args[1], args[0]);
10227
10231
predicate. Substitute a constant instead of this field if the
10228
10232
multiple equality contains a constant.
10230
conds= build_equal_items(join->session, conds, NULL, join_list,
10234
conds= build_equal_items(join->thd, conds, NULL, join_list,
10231
10235
&join->cond_equal);
10233
10237
/* change field = field to field = const for each found field = const */
10234
propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10238
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
10236
10240
Remove all instances of item == item
10237
10241
Remove all and-levels where CONST item != CONST item
10239
conds= remove_eq_conds(session, conds, cond_value) ;
10243
conds= remove_eq_conds(thd, conds, cond_value) ;
10241
10245
return(conds);
12048
12039
enum_nested_loop_state
12049
end_write(JOIN *join, JOIN_TAB *,
12050
bool end_of_records)
12040
end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
12041
bool end_of_records)
12052
12043
Table *table=join->tmp_table;
12054
if (join->session->killed) // Aborted by user
12045
if (join->thd->killed) // Aborted by user
12056
join->session->send_kill_message();
12047
join->thd->send_kill_message();
12057
12048
return(NESTED_LOOP_KILLED); /* purecov: inspected */
12059
12050
if (!end_of_records)
12061
12052
copy_fields(&join->tmp_table_param);
12062
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);
12063
12070
if (!join->having || join->having->val_int())
13465
13472
offset= (field_count ?
13466
13473
entry->field[entry->s->fields - field_count]->
13467
13474
offset(entry->record[0]) : 0);
13468
reclength= entry->s->reclength-offset;
13475
reclength=entry->s->reclength-offset;
13470
13477
free_io_cache(entry); // Safety
13471
13478
entry->file->info(HA_STATUS_VARIABLE);
13472
13479
if (entry->s->db_type() == heap_hton ||
13473
13480
(!entry->s->blob_fields &&
13474
13481
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13475
session->variables.sortbuff_size)))
13476
error= remove_dup_with_hash_index(join->session, entry,
13482
thd->variables.sortbuff_size)))
13483
error=remove_dup_with_hash_index(join->thd, entry,
13477
13484
field_count, first_field,
13478
13485
reclength, having);
13480
error= remove_dup_with_compare(join->session, entry, first_field, offset,
13487
error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13483
13490
free_blobs(first_field);
13576
13583
Note that this will not work on tables with blobs!
13579
static int remove_dup_with_hash_index(Session *session, Table *table,
13580
uint32_t field_count,
13586
static int remove_dup_with_hash_index(THD *thd, Table *table,
13581
13588
Field **first_field,
13582
uint32_t key_length,
13583
13590
Item *having)
13585
unsigned char *key_buffer, *key_pos, *record=table->record[0];
13592
uchar *key_buffer, *key_pos, *record=table->record[0];
13587
13594
handler *file= table->file;
13588
uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
13589
uint32_t *field_lengths,*field_length;
13595
ulong extra_length= ALIGN_SIZE(key_length)-key_length;
13596
uint *field_lengths,*field_length;
13592
13599
if (!my_multi_malloc(MYF(MY_WME),
14225
14233
the field list.
14228
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14236
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
14229
14237
List<Item> &fields, List<Item> &all_fields, order_st *order)
14231
session->where="order clause";
14239
thd->where="order clause";
14232
14240
for (; order; order=order->next)
14234
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,
14235
14243
all_fields, false))
16207
16218
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16208
16219
unit->fake_select_lex->type= "UNION RESULT";
16209
16220
unit->fake_select_lex->options|= SELECT_DESCRIBE;
16210
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16221
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16211
16222
res= unit->exec();
16212
16223
res|= unit->cleanup();
16216
session->lex->current_select= first;
16227
thd->lex->current_select= first;
16217
16228
unit->set_limit(unit->global_parameters);
16218
res= mysql_select(session, &first->ref_pointer_array,
16229
res= mysql_select(thd, &first->ref_pointer_array,
16219
16230
(TableList*) first->table_list.first,
16220
16231
first->with_wild, first->item_list,
16221
16232
first->where,
16224
16235
(order_st*) first->order_list.first,
16225
16236
(order_st*) first->group_list.first,
16226
16237
first->having,
16227
(order_st*) session->lex->proc_list.first,
16228
first->options | session->options | SELECT_DESCRIBE,
16238
(order_st*) thd->lex->proc_list.first,
16239
first->options | thd->options | SELECT_DESCRIBE,
16229
16240
result, unit, first);
16231
return(res || session->is_error());
16242
return(res || thd->is_error());
16235
static void print_table_array(Session *session, String *str, TableList **table,
16246
static void print_table_array(THD *thd, String *str, TableList **table,
16236
16247
TableList **end)
16238
(*table)->print(session, str, QT_ORDINARY);
16249
(*table)->print(thd, str, QT_ORDINARY);
16240
16251
for (TableList **tbl= table + 1; tbl < end; tbl++)
16266
16277
Print joins from the FROM clause.
16267
@param session thread handler
16278
@param thd thread handler
16268
16279
@param str string where table should be printed
16269
16280
@param tables list of tables in join
16270
16281
@query_type type of the query is being generated
16273
static void print_join(Session *session, String *str,
16274
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)))
16276
16289
/* List is reversed => we should reverse it before using */
16277
16290
List_iterator_fast<TableList> ti(*tables);
16278
TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16291
TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
16279
16292
tables->elements);
16280
16293
if (table == 0)
16281
16294
return; // out of memory
16331
16344
str->append (STRING_WITH_LEN(" ("));
16332
16345
if (key_name.length)
16334
if (session && !my_strnncoll(system_charset_info,
16335
(const unsigned char *)key_name.str, key_name.length,
16336
(const unsigned char *)primary_key_name,
16347
if (thd && !my_strnncoll(system_charset_info,
16348
(const uchar *)key_name.str, key_name.length,
16349
(const uchar *)primary_key_name,
16337
16350
strlen(primary_key_name)))
16338
16351
str->append(primary_key_name);
16340
append_identifier(session, str, key_name.str, key_name.length);
16353
append_identifier(thd, str, key_name.str, key_name.length);
16342
16355
str->append(')');
16373
16386
// A normal table
16375
append_identifier(session, str, db, db_length);
16388
append_identifier(thd, str, db, db_length);
16376
16389
str->append('.');
16378
16391
if (schema_table)
16380
append_identifier(session, str, schema_table_name,
16393
append_identifier(thd, str, schema_table_name,
16381
16394
strlen(schema_table_name));
16382
16395
cmp_name= schema_table_name;
16386
append_identifier(session, str, table_name, table_name_length);
16399
append_identifier(thd, str, table_name, table_name_length);
16387
16400
cmp_name= table_name;
16414
16427
while ((hint= it++))
16416
16429
str->append (STRING_WITH_LEN(" "));
16417
hint->print (session, str);
16430
hint->print (thd, str);
16424
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)
16426
/* QQ: session may not be set for sub queries, but this should be fixed */
16428
session= current_session;
16439
/* QQ: thd may not be set for sub queries, but this should be fixed */
16430
16443
str->append(STRING_WITH_LEN("select "));
16432
16445
/* First add options */
16433
16446
if (options & SELECT_STRAIGHT_JOIN)
16434
16447
str->append(STRING_WITH_LEN("straight_join "));
16435
if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16436
(this == &session->lex->select_lex))
16448
if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16449
(this == &thd->lex->select_lex))
16437
16450
str->append(STRING_WITH_LEN("high_priority "));
16438
16451
if (options & SELECT_DISTINCT)
16439
16452
str->append(STRING_WITH_LEN("distinct "));