~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Jay Pipes
  • Date: 2008-09-09 20:10:57 UTC
  • mto: (383.2.4 fix-failing-tests)
  • mto: This revision was merged to the branch mainline in revision 386.
  • Revision ID: jay@mysql.com-20080909201057-3qkgcxqaps2s58y9
Re-enabled a number of passing tests from trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
*/
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"
30
29
 
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>
43
 
 
44
 
#include CMATH_H
45
 
 
46
 
#if defined(CMATH_NAMESPACE)
47
 
using namespace CMATH_NAMESPACE;
48
 
#endif
 
31
#include <drizzled/drizzled_error_messages.h>
 
32
#include <libdrizzle/gettext.h>
49
33
 
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);
72
56
 
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,
 
67
                                             uint prune_level);
 
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);
87
71
/*
88
72
  TODO: 'find_best' is here only temporarily until 'greedy_search' is
89
73
  tested and approved.
90
74
*/
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,
99
 
                                uint32_t maybe_null);
 
82
                                KEY_PART_INFO *key_part, uchar *key_buff,
 
83
                                uint maybe_null);
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);
110
94
                            List<Item> &fields, bool send_row,
111
95
                            uint64_t select_options, const char *info,
112
96
                            Item *having);
113
 
static COND *build_equal_items(Session *session, COND *cond,
 
97
static COND *build_equal_items(THD *thd, COND *cond,
114
98
                               COND_EQUAL *inherited,
115
99
                               List<TableList> *join_list,
116
100
                               COND_EQUAL **cond_equal_ref);
122
106
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
123
107
static void restore_prev_nj_state(JOIN_TAB *last);
124
108
static void reset_nj_counters(List<TableList> *join_list);
125
 
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list,
126
 
                                          uint32_t first_unused);
 
109
static uint build_bitmap_for_nested_joins(List<TableList> *join_list,
 
110
                                          uint first_unused);
127
111
 
128
112
static 
129
113
void advance_sj_state(const table_map remaining_tables, const JOIN_TAB *tab);
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,
190
174
                             Item *having);
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,
 
179
 
 
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);
251
236
  This handles SELECT with and without UNION.
252
237
*/
253
238
 
254
 
bool handle_select(Session *session, LEX *lex, select_result *result,
 
239
bool handle_select(THD *thd, LEX *lex, select_result *result,
255
240
                   ulong setup_tables_done_option)
256
241
{
257
242
  bool res;
260
245
 
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);
264
249
  else
265
250
  {
266
251
    SELECT_LEX_UNIT *unit= &lex->unit;
267
252
    unit->set_limit(unit->global_parameters);
268
 
    session->session_marker= 0;
 
253
    thd->thd_marker= 0;
269
254
    /*
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
273
258
    */
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,
281
266
                      (order_st*) select_lex->group_list.first,
282
267
                      select_lex->having,
283
268
                      (order_st*) lex->proc_list.first,
284
 
                      select_lex->options | session->options |
 
269
                      select_lex->options | thd->options |
285
270
                      setup_tables_done_option,
286
271
                      result, unit, select_lex);
287
272
  }
288
 
  res|= session->is_error();
 
273
  res|= thd->is_error();
289
274
  if (unlikely(res))
290
275
    result->abort();
291
276
 
299
284
 
300
285
  SYNOPSIS
301
286
    fix_inner_refs()
302
 
    session               Thread handle
 
287
    thd               Thread handle
303
288
    all_fields        List of all fields used in select
304
289
    select            Current select
305
290
    ref_pointer_array Array of references to Items used in current select
336
321
*/
337
322
 
338
323
bool
339
 
fix_inner_refs(Session *session, List<Item> &all_fields, SELECT_LEX *select,
 
324
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
340
325
                 Item **ref_pointer_array)
341
326
{
342
327
  Item_outer_ref *ref;
397
382
    ref->outer_ref= new_ref;
398
383
    ref->ref= &ref->outer_ref;
399
384
 
400
 
    if (!ref->fixed && ref->fix_fields(session, 0))
 
385
    if (!ref->fixed && ref->fix_fields(thd, 0))
401
386
      return true;
402
 
    session->used_tables|= item->used_tables();
 
387
    thd->used_tables|= item->used_tables();
403
388
  }
404
389
  return res;
405
390
}
406
391
 
 
392
#define MAGIC_IN_WHERE_TOP_LEVEL 10
407
393
/**
408
394
  Function to setup clauses without sum functions.
409
395
*/
410
 
inline int setup_without_group(Session *session, Item **ref_pointer_array,
411
 
                               TableList *tables,
412
 
                               TableList *leaves,
413
 
                               List<Item> &fields,
414
 
                               List<Item> &all_fields,
415
 
                               COND **conds,
416
 
                               order_st *order,
417
 
                               order_st *group, bool *hidden_group_fields)
 
396
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
 
397
                               TableList *tables,
 
398
                               TableList *leaves,
 
399
                               List<Item> &fields,
 
400
                               List<Item> &all_fields,
 
401
                               COND **conds,
 
402
                               order_st *order,
 
403
                               order_st *group, bool *hidden_group_fields)
418
404
{
419
405
  int res;
420
 
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
421
 
 
422
 
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
423
 
  res= setup_conds(session, tables, leaves, conds);
424
 
 
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 ;
 
407
 
 
408
  thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
 
409
  res= setup_conds(thd, tables, leaves, conds);
 
410
 
 
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,
427
413
                          order);
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;
432
418
  return(res);
433
419
}
434
420
 
452
438
int
453
439
JOIN::prepare(Item ***rref_pointer_array,
454
440
              TableList *tables_init,
455
 
              uint32_t wild_num, COND *conds_init, uint32_t og_num,
 
441
              uint wild_num, COND *conds_init, uint og_num,
456
442
              order_st *order_init, order_st *group_init,
457
443
              Item *having_init,
458
444
              order_st *proc_param_init, SELECT_LEX *select_lex_arg,
473
459
  join_list= &select_lex->top_join_list;
474
460
  union_part= unit_arg->is_union();
475
461
 
476
 
  session->lex->current_select->is_item_list_lookup= 1;
 
462
  thd->lex->current_select->is_item_list_lookup= 1;
477
463
  /*
478
464
    If we have already executed SELECT, then it have not sense to prevent
479
465
    its table from update (see unique_table())
480
466
  */
481
 
  if (session->derived_tables_processing)
 
467
  if (thd->derived_tables_processing)
482
468
    select_lex->exclude_from_table_unique_test= true;
483
469
 
484
470
  /* Check that all tables, fields, conds and order are ok */
485
471
 
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,
489
475
                                    false))
490
476
      return(-1);
495
481
       table_ptr= table_ptr->next_leaf)
496
482
    tables++;
497
483
 
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))
509
495
  
510
496
  if (having)
511
497
  {
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;
523
509
  }
524
510
 
525
511
  {
531
517
    */
532
518
    if ((subselect= select_lex->master_unit()->item))
533
519
    {
534
 
      bool do_semijoin= !test(session->variables.optimizer_switch &
 
520
      bool do_semijoin= !test(thd->variables.optimizer_switch &
535
521
                              OPTIMIZER_SWITCH_NO_SEMIJOIN);
536
522
      if (subselect->substype() == Item_subselect::IN_SUBS)
537
523
        in_subs= (Item_in_subselect*)subselect;
558
544
          !select_lex->master_unit()->first_select()->next_select() &&  // 2
559
545
          !select_lex->group_list.elements && !order &&                 // 3
560
546
          !having && !select_lex->with_sum_func &&                      // 4
561
 
          session->session_marker &&                                            // 5
 
547
          thd->thd_marker &&                                            // 5
562
548
          select_lex->outer_select()->join &&                           // (*)
563
549
          select_lex->master_unit()->first_select()->leaf_tables &&     // (**) 
564
550
          do_semijoin &&
566
552
      {
567
553
        {
568
554
          if (!in_subs->left_expr->fixed &&
569
 
               in_subs->left_expr->fix_fields(session, &in_subs->left_expr))
 
555
               in_subs->left_expr->fix_fields(thd, &in_subs->left_expr))
570
556
          {
571
557
            return(-1);
572
558
          }
584
570
        }
585
571
 
586
572
        /* Register the subquery for further processing */
587
 
        select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
588
 
        in_subs->expr_join_nest= (TableList*)session->session_marker;
 
573
        select_lex->outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
 
574
        in_subs->expr_join_nest= (TableList*)thd->thd_marker;
589
575
      }
590
576
      else
591
577
      {
592
 
        bool do_materialize= !test(session->variables.optimizer_switch &
 
578
        bool do_materialize= !test(thd->variables.optimizer_switch &
593
579
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
594
580
        /*
595
581
          Check if the subquery predicate can be executed via materialization.
624
610
            in_subs  &&                                                   // 1
625
611
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
626
612
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
627
 
            session->lex->sql_command == SQLCOM_SELECT)                       // *
 
613
            thd->lex->sql_command == SQLCOM_SELECT)                       // *
628
614
        {
629
615
          if (in_subs->is_top_level_item() &&                             // 4
630
616
              !in_subs->is_correlated &&                                  // 5
649
635
    {
650
636
      Item *item= *ord->item;
651
637
      if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
652
 
        item->split_sum_func(session, ref_pointer_array, all_fields);
 
638
        item->split_sum_func(thd, ref_pointer_array, all_fields);
653
639
    }
654
640
  }
655
641
 
656
642
  if (having && having->with_sum_func)
657
 
    having->split_sum_func(session, ref_pointer_array, all_fields,
658
 
                           &having, true);
 
643
    having->split_sum_func2(thd, ref_pointer_array, all_fields,
 
644
                            &having, true);
659
645
  if (select_lex->inner_sum_func_list)
660
646
  {
661
647
    Item_sum *end=select_lex->inner_sum_func_list;
663
649
    do
664
650
    { 
665
651
      item_sum= item_sum->next;
666
 
      item_sum->split_sum_func(session, ref_pointer_array,
667
 
                               all_fields, item_sum->ref_by, false);
 
652
      item_sum->split_sum_func2(thd, ref_pointer_array,
 
653
                                all_fields, item_sum->ref_by, false);
668
654
    } while (item_sum != end);
669
655
  }
670
656
 
671
657
  if (select_lex->inner_refs_list.elements &&
672
 
      fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
 
658
      fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
673
659
    return(-1);
674
660
 
675
661
  /*
793
779
    join_tab->packed_info |= TAB_INFO_USING_INDEX;
794
780
  if (where)
795
781
    join_tab->packed_info |= TAB_INFO_USING_WHERE;
796
 
  for (uint32_t i = 0; i < join_tab->ref.key_parts; i++)
 
782
  for (uint i = 0; i < join_tab->ref.key_parts; i++)
797
783
  {
798
784
    if (join_tab->ref.cond_guards[i])
799
785
    {
843
829
  if (join_tab->type == JT_EQ_REF)
844
830
  {
845
831
    Table_map_iterator it(join_tab->ref.depend_map & ~PSEUDO_TABLE_BITS);
846
 
    uint32_t idx;
 
832
    uint idx;
847
833
    while ((idx= it.next_bit())!=Table_map_iterator::BITMAP_END)
848
834
    {
849
835
      JOIN_TAB *ref_tab= join->join_tab + idx;
955
941
*/
956
942
 
957
943
static
958
 
int setup_semijoin_dups_elimination(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
 
944
int setup_semijoin_dups_elimination(JOIN *join, uint64_t options, uint no_jbuf_after)
959
945
{
960
946
  table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
961
947
  struct {
965
951
      2 - Temptable (maybe confluent),
966
952
      3 - Temptable with join buffering
967
953
    */
968
 
    uint32_t strategy;
969
 
    uint32_t start_idx; /* Left range bound */
970
 
    uint32_t end_idx;   /* Right range bound */
 
954
    uint strategy;
 
955
    uint start_idx; /* Left range bound */
 
956
    uint end_idx;   /* Right range bound */
971
957
    /* 
972
958
      For Temptable strategy: Bitmap of all outer and correlated tables from 
973
959
      all involved join nests.
982
968
  table_map range_start_map= 0; /* table_map at current range start */
983
969
  bool dealing_with_jbuf= false; /* true <=> table within cur range uses join buf */
984
970
  int cur_range= 0;
985
 
  uint32_t i;
 
971
  uint i;
986
972
 
987
973
  /*
988
974
    First pass: locate the duplicate-generating ranges and pick the strategies.
1105
1091
    }
1106
1092
  }
1107
1093
 
1108
 
  Session *session= join->session;
 
1094
  THD *thd= join->thd;
1109
1095
  SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
1110
1096
  /*
1111
1097
    Second pass: setup the chosen strategies    
1123
1109
    {
1124
1110
      SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
1125
1111
      table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
1126
 
      uint32_t jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
1127
 
      uint32_t jt_null_bits= 0;    // # null bits in tuple bytes
 
1112
      uint jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
 
1113
      uint jt_null_bits= 0;    // # null bits in tuple bytes
1128
1114
      SJ_TMP_TABLE::TAB *last_tab= sjtabs;
1129
 
      uint32_t rowid_keep_flags= JOIN_TAB::CALL_POSITION | JOIN_TAB::KEEP_ROWID;
 
1115
      uint rowid_keep_flags= JOIN_TAB::CALL_POSITION | JOIN_TAB::KEEP_ROWID;
1130
1116
      JOIN_TAB *last_outer_tab= tab - 1;
1131
1117
      /*
1132
1118
        Walk through the range and remember
1158
1144
      if (jt_rowid_offset) /* Temptable has at least one rowid */
1159
1145
      {
1160
1146
        SJ_TMP_TABLE *sjtbl;
1161
 
        uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
1162
 
        if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
1163
 
            !(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
 
1147
        uint 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)))
1164
1150
          return(true);
1165
1151
        memcpy(sjtbl->tabs, sjtabs, tabs_size);
1166
1152
        sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1173
1159
        sjtbl->next= NULL;
1174
1160
 
1175
1161
        sjtbl->tmp_table= 
1176
 
          create_duplicate_weedout_tmp_table(session, 
 
1162
          create_duplicate_weedout_tmp_table(thd, 
1177
1163
                                             sjtbl->rowid_len + 
1178
1164
                                             sjtbl->null_bytes,
1179
1165
                                             sjtbl);
1205
1191
  {
1206
1192
    if (sj_tbl->tmp_table)
1207
1193
    {
1208
 
      sj_tbl->tmp_table->free_tmp_table(join->session);
 
1194
      sj_tbl->tmp_table->free_tmp_table(join->thd);
1209
1195
    }
1210
1196
  }
1211
1197
  join->sj_tmp_tables= NULL;
1212
1198
}
1213
1199
 
1214
 
uint32_t make_join_orderinfo(JOIN *join);
 
1200
uint make_join_orderinfo(JOIN *join);
1215
1201
 
1216
1202
/**
1217
1203
  global select optimisation.
1233
1219
    return(0);
1234
1220
  optimized= 1;
1235
1221
 
1236
 
  session->set_proc_info("optimizing");
 
1222
  thd_proc_info(thd, "optimizing");
1237
1223
  row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
1238
1224
              unit->select_limit_cnt);
1239
1225
  /* select_limit is used to decide if we are likely to scan the whole table */
1242
1228
    select_limit= HA_POS_ERROR;
1243
1229
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1244
1230
  // Ignore errors of execution if option IGNORE present
1245
 
  if (session->lex->ignore)
1246
 
    session->lex->current_select->no_error= 1;
 
1231
  if (thd->lex->ignore)
 
1232
    thd->lex->current_select->no_error= 1;
1247
1233
 
1248
1234
#ifdef HAVE_REF_TO_FIELDS                       // Not done yet
1249
1235
  /* Add HAVING to WHERE if possible */
1260
1246
        Item_cond_and can't be fixed after creation, so we do not check
1261
1247
        conds->fixed
1262
1248
      */
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();
1266
1252
      having= 0;
1267
1253
    }
1268
1254
  }
1269
1255
#endif
 
1256
  SELECT_LEX *sel= thd->lex->current_select;
 
1257
  if (sel->first_cond_optimization)
 
1258
  {
 
1259
    /*
 
1260
      The following code will allocate the new items in a permanent
 
1261
      MEMROOT for prepared statements and stored procedures.
 
1262
    */
 
1263
    sel->first_cond_optimization= 0;
1270
1264
 
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);
 
1268
  }
1274
1269
 
1275
1270
  conds= optimize_cond(this, conds, join_list, &cond_value);   
1276
 
  if (session->is_error())
 
1271
  if (thd->is_error())
1277
1272
  {
1278
1273
    error= 1;
1279
1274
    return(1);
1281
1276
 
1282
1277
  {
1283
1278
    having= optimize_cond(this, having, join_list, &having_value);
1284
 
    if (session->is_error())
 
1279
    if (thd->is_error())
1285
1280
    {
1286
1281
      error= 1;
1287
1282
      return(1);
1301
1296
    }
1302
1297
  }
1303
1298
 
1304
 
  /* Optimize count(*), cmin() and cmax() */
 
1299
  /* Optimize count(*), min() and max() */
1305
1300
  if (tables_list && tmp_table_param.sum_func_count && ! group_list)
1306
1301
  {
1307
1302
    int res;
1342
1337
        conjunctions.
1343
1338
        Preserve conditions for EXPLAIN.
1344
1339
      */
1345
 
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
 
1340
      if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
1346
1341
      {
1347
1342
        COND *table_independent_conds=
1348
1343
          make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1359
1354
  sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1360
1355
 
1361
1356
  /* Calculate how to do the join */
1362
 
  session->set_proc_info("statistics");
 
1357
  thd_proc_info(thd, "statistics");
1363
1358
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1364
 
      session->is_fatal_error)
 
1359
      thd->is_fatal_error)
1365
1360
  {
1366
1361
    return(1);
1367
1362
  }
1368
1363
 
1369
1364
  /* Remove distinct if only const tables */
1370
1365
  select_distinct= select_distinct && (const_tables != tables);
1371
 
  session->set_proc_info("preparing");
 
1366
  thd_proc_info(thd, "preparing");
1372
1367
  if (result->initialize_tables(this))
1373
1368
  {
1374
1369
    return(1);                          // error == -1
1377
1372
      !(select_options & SELECT_DESCRIBE) &&
1378
1373
      (!conds ||
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
1381
1376
  {
1382
1377
    zero_result_cause= "no matching row in const table";
1383
1378
    error= 0;
1384
1379
    return(0);
1385
1380
  }
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));
1391
1386
    error= -1;
1392
1387
    return(1);
1393
1388
  }
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)
1398
1393
  {
1399
1394
    /* Handle the case where we have an OUTER JOIN without a WHERE */
1439
1434
 
1440
1435
  if (conds &&!outer_join && const_table_map != found_const_table_map && 
1441
1436
      (select_options & SELECT_DESCRIBE) &&
1442
 
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
 
1437
      select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
1443
1438
  {
1444
1439
    conds=new Item_int((int64_t) 0,1);  // Always false
1445
1440
  }
1456
1451
  {
1457
1452
    order_st *org_order= order;
1458
1453
    order=remove_const(this, order,conds,1, &simple_order);
1459
 
    if (session->is_error())
 
1454
    if (thd->is_error())
1460
1455
    {
1461
1456
      error= 1;
1462
1457
      return(1);
1554
1549
    if (order)
1555
1550
      skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1, 
1556
1551
        &tab->table->keys_in_use_for_order_by);
1557
 
    if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
 
1552
    if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
1558
1553
                                          order, fields_list, all_fields,
1559
1554
                                          &all_order_fields_used)))
1560
1555
    {
1586
1581
      else
1587
1582
        group_list= 0;
1588
1583
    }
1589
 
    else if (session->is_fatal_error)                   // End of memory
 
1584
    else if (thd->is_fatal_error)                       // End of memory
1590
1585
      return(1);
1591
1586
  }
1592
1587
  simple_group= 0;
1595
1590
    group_list= remove_const(this, (old_group_list= group_list), conds,
1596
1591
                             rollup.state == ROLLUP::STATE_NONE,
1597
1592
                             &simple_group);
1598
 
    if (session->is_error())
 
1593
    if (thd->is_error())
1599
1594
    {
1600
1595
      error= 1;
1601
1596
      return(1);
1641
1636
              (group_list && order) ||
1642
1637
              test(select_options & OPTION_BUFFER_RESULT)));
1643
1638
 
1644
 
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
1639
  uint no_jbuf_after= make_join_orderinfo(this);
1645
1640
  uint64_t select_opts_for_readinfo= 
1646
1641
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
1647
1642
 
1678
1673
        error= 0;
1679
1674
        return(unit->item->
1680
1675
                    change_engine(new
1681
 
                                  subselect_uniquesubquery_engine(session,
 
1676
                                  subselect_uniquesubquery_engine(thd,
1682
1677
                                                                  join_tab,
1683
1678
                                                                  unit->item,
1684
1679
                                                                  where)));
1692
1687
        error= 0;
1693
1688
        return(unit->item->
1694
1689
                    change_engine(new
1695
 
                                  subselect_indexsubquery_engine(session,
 
1690
                                  subselect_indexsubquery_engine(thd,
1696
1691
                                                                 join_tab,
1697
1692
                                                                 unit->item,
1698
1693
                                                                 where,
1708
1703
      conds= remove_additional_cond(conds);
1709
1704
      save_index_subquery_explain_info(join_tab, conds);
1710
1705
      return(unit->item->
1711
 
                  change_engine(new subselect_indexsubquery_engine(session,
 
1706
                  change_engine(new subselect_indexsubquery_engine(thd,
1712
1707
                                                                   join_tab,
1713
1708
                                                                   unit->item,
1714
1709
                                                                   conds,
1725
1720
  */
1726
1721
  if (need_tmp || select_distinct || group_list || order)
1727
1722
  {
1728
 
    for (uint32_t i = const_tables; i < tables; i++)
 
1723
    for (uint i = const_tables; i < tables; i++)
1729
1724
      join_tab[i].table->prepare_for_position();
1730
1725
  }
1731
1726
 
1742
1737
        (join_tab[const_tables].type != JT_REF_OR_NULL) &&
1743
1738
        ((order && simple_order) || (group_list && simple_group)))
1744
1739
    {
1745
 
      if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
 
1740
      if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
1746
1741
        return(1);
1747
1742
      }
1748
1743
    }
1803
1798
  /* Create a tmp table if distinct or if the sort is too complicated */
1804
1799
  if (need_tmp)
1805
1800
  {
1806
 
    session->set_proc_info("Creating tmp table");
 
1801
    thd_proc_info(thd, "Creating tmp table");
1807
1802
 
1808
1803
    init_items_ref_array();
1809
1804
 
1819
1814
    */
1820
1815
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1821
1816
                             !tmp_group &&
1822
 
                             !session->lex->current_select->with_sum_func) ?
 
1817
                             !thd->lex->current_select->with_sum_func) ?
1823
1818
                            select_limit : HA_POS_ERROR;
1824
1819
 
1825
1820
    if (!(exec_tmp_table1=
1826
 
          create_tmp_table(session, &tmp_table_param, all_fields,
 
1821
          create_tmp_table(thd, &tmp_table_param, all_fields,
1827
1822
                           tmp_group,
1828
1823
                           group_list ? 0 : select_distinct,
1829
1824
                           group_list && simple_group,
1851
1846
    /* if group or order on first table, sort first */
1852
1847
    if (group_list && simple_group)
1853
1848
    {
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))
1860
1855
      {
1861
1856
        return(1);
1862
1857
      }
1865
1860
    else
1866
1861
    {
1867
1862
      if (make_sum_func_list(all_fields, fields_list, 0) ||
1868
 
          setup_sum_funcs(session, sum_funcs))
 
1863
          setup_sum_funcs(thd, sum_funcs))
1869
1864
      {
1870
1865
        return(1);
1871
1866
      }
1872
1867
 
1873
1868
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1874
1869
      {
1875
 
        session->set_proc_info("Sorting for order");
1876
 
        if (create_sort_index(session, this, order,
 
1870
        thd_proc_info(thd, "Sorting for order");
 
1871
        if (create_sort_index(thd, this, order,
1877
1872
                              HA_POS_ERROR, HA_POS_ERROR, true))
1878
1873
        {
1879
1874
          return(1);
1890
1885
 
1891
1886
    if (exec_tmp_table1->distinct)
1892
1887
    {
1893
 
      table_map used_tables= session->used_tables;
 
1888
      table_map used_tables= thd->used_tables;
1894
1889
      JOIN_TAB *last_join_tab= join_tab+tables-1;
1895
1890
      do
1896
1891
      {
1938
1933
{
1939
1934
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1940
1935
                                    select_lex->offset_limit->val_uint() :
1941
 
                                    0UL);
 
1936
                                    0ULL);
1942
1937
 
1943
1938
  first_record= 0;
1944
1939
 
1990
1985
bool
1991
1986
JOIN::init_save_join_tab()
1992
1987
{
1993
 
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1988
  if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
1994
1989
    return 1;                                  /* purecov: inspected */
1995
1990
  error= 0;                                    // Ensure that tmp_join.error= 0
1996
1991
  restore_tmp();
2003
1998
{
2004
1999
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
2005
2000
  {
2006
 
    if (!(join_tab_save= (JOIN_TAB*)session->memdup((unsigned char*) join_tab,
 
2001
    if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab,
2007
2002
                                                sizeof(JOIN_TAB) * tables)))
2008
2003
      return 1;
2009
2004
  }
2020
2015
    the query.  It's never shown in EXPLAIN!
2021
2016
 
2022
2017
  @todo
2023
 
    When can we have here session->net.report_error not zero?
 
2018
    When can we have here thd->net.report_error not zero?
2024
2019
*/
2025
2020
void
2026
2021
JOIN::exec()
2028
2023
  List<Item> *columns_list= &fields_list;
2029
2024
  int      tmp_error;
2030
2025
 
2031
 
  session->set_proc_info("executing");
 
2026
  thd_proc_info(thd, "executing");
2032
2027
  error= 0;
2033
2028
  (void) result->prepare2(); // Currently, this cannot fail.
2034
2029
 
2056
2051
        {
2057
2052
          error= (int) result->send_eof();
2058
2053
          send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
2059
 
                         session->sent_row_count);
 
2054
                         thd->sent_row_count);
2060
2055
        }
2061
2056
      }
2062
2057
      else
2066
2061
      }
2067
2062
    }
2068
2063
    /* Single select (without union) always returns 0 or 1 row */
2069
 
    session->limit_found_rows= send_records;
2070
 
    session->examined_row_count= 0;
 
2064
    thd->limit_found_rows= send_records;
 
2065
    thd->examined_row_count= 0;
2071
2066
    return;
2072
2067
  }
2073
2068
  /*
2076
2071
    It must be accumulated from all join iterations of all join parts.
2077
2072
  */
2078
2073
  if (tables)
2079
 
    session->limit_found_rows= 0;
 
2074
    thd->limit_found_rows= 0;
2080
2075
 
2081
2076
  if (zero_result_cause)
2082
2077
  {
2123
2118
    select_describe(this, need_tmp,
2124
2119
                    order != 0 && !skip_sort_order,
2125
2120
                    select_distinct,
2126
 
                    !tables ? "No tables used" : NULL);
 
2121
                    !tables ? "No tables used" : NullS);
2127
2122
    return;
2128
2123
  }
2129
2124
 
2154
2149
    curr_tmp_table= exec_tmp_table1;
2155
2150
 
2156
2151
    /* Copy data to the temporary table */
2157
 
    session->set_proc_info("Copying to tmp table");
 
2152
    thd_proc_info(thd, "Copying to tmp table");
2158
2153
    if (!curr_join->sort_and_group &&
2159
2154
        curr_join->const_tables != curr_join->tables)
2160
2155
      curr_join->join_tab[curr_join->const_tables].sorted= 0;
2175
2170
      items1= items0 + all_fields.elements;
2176
2171
      if (sort_and_group || curr_tmp_table->group)
2177
2172
      {
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))
2181
2176
          return;
2182
2177
      }
2183
2178
      else
2184
2179
      {
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))
2188
2183
          return;
2255
2250
          curr_join->tmp_table_param.precomputed_group_by= true;
2256
2251
 
2257
2252
        if (!(curr_tmp_table=
2258
 
              exec_tmp_table2= create_tmp_table(session,
 
2253
              exec_tmp_table2= create_tmp_table(thd,
2259
2254
                                                &curr_join->tmp_table_param,
2260
2255
                                                *curr_all_fields,
2261
2256
                                                (order_st*) 0,
2269
2264
      }
2270
2265
      if (curr_join->group_list)
2271
2266
      {
2272
 
        session->set_proc_info("Creating sort index");
 
2267
        thd_proc_info(thd, "Creating sort index");
2273
2268
        if (curr_join->join_tab == join_tab && save_join_tab())
2274
2269
        {
2275
2270
          return;
2276
2271
        }
2277
 
        if (create_sort_index(session, curr_join, curr_join->group_list,
 
2272
        if (create_sort_index(thd, curr_join, curr_join->group_list,
2278
2273
                              HA_POS_ERROR, HA_POS_ERROR, false) ||
2279
2274
            make_group_fields(this, curr_join))
2280
2275
        {
2283
2278
        sortorder= curr_join->sortorder;
2284
2279
      }
2285
2280
      
2286
 
      session->set_proc_info("Copying to group table");
 
2281
      thd_proc_info(thd, "Copying to group table");
2287
2282
      tmp_error= -1;
2288
2283
      if (curr_join != this)
2289
2284
      {
2306
2301
      if (!curr_join->sort_and_group &&
2307
2302
          curr_join->const_tables != curr_join->tables)
2308
2303
        curr_join->join_tab[curr_join->const_tables].sorted= 0;
2309
 
      if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
 
2304
      if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2310
2305
          (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2311
2306
      {
2312
2307
        error= tmp_error;
2320
2315
      if (!items2)
2321
2316
      {
2322
2317
        items2= items1 + all_fields.elements;
2323
 
        if (change_to_use_tmp_fields(session, items2,
 
2318
        if (change_to_use_tmp_fields(thd, items2,
2324
2319
                                     tmp_fields_list2, tmp_all_fields2, 
2325
2320
                                     fields_list.elements, tmp_all_fields1))
2326
2321
          return;
2340
2335
    curr_join->join_free();                     /* Free quick selects */
2341
2336
    if (curr_join->select_distinct && ! curr_join->group_list)
2342
2337
    {
2343
 
      session->set_proc_info("Removing duplicates");
 
2338
      thd_proc_info(thd, "Removing duplicates");
2344
2339
      if (curr_join->tmp_having)
2345
2340
        curr_join->tmp_having->update_used_tables();
2346
2341
      if (remove_duplicates(curr_join, curr_tmp_table,
2369
2364
      if (!items0)
2370
2365
        init_items_ref_array();
2371
2366
      items3= ref_pointer_array + (all_fields.elements*4);
2372
 
      setup_copy_fields(session, &curr_join->tmp_table_param,
 
2367
      setup_copy_fields(thd, &curr_join->tmp_table_param,
2373
2368
                        items3, tmp_fields_list3, tmp_all_fields3,
2374
2369
                        curr_fields_list->elements, *curr_all_fields);
2375
2370
      tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2392
2387
 
2393
2388
    if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
2394
2389
                                      1, true) || 
2395
 
        setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2396
 
        session->is_fatal_error)
 
2390
        setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
 
2391
        thd->is_fatal_error)
2397
2392
      return;
2398
2393
  }
2399
2394
  if (curr_join->group_list || curr_join->order)
2400
2395
  {
2401
 
    session->set_proc_info("Sorting result");
 
2396
    thd_proc_info(thd, "Sorting result");
2402
2397
    /* If we have already done the group, add HAVING to sorted table */
2403
2398
    if (curr_join->tmp_having && ! curr_join->group_list && 
2404
2399
        ! curr_join->sort_and_group)
2444
2439
      else
2445
2440
      {
2446
2441
        /*
2447
 
          We can abort sorting after session->select_limit rows if we there is no
 
2442
          We can abort sorting after thd->select_limit rows if we there is no
2448
2443
          WHERE clause for any tables after the sorted one.
2449
2444
        */
2450
2445
        JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
2477
2472
        the query. XXX: it's never shown in EXPLAIN!
2478
2473
        OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2479
2474
      */
2480
 
      if (create_sort_index(session, curr_join,
 
2475
      if (create_sort_index(thd, curr_join,
2481
2476
                            curr_join->group_list ? 
2482
2477
                            curr_join->group_list : curr_join->order,
2483
2478
                            curr_join->select_limit,
2498
2493
      }
2499
2494
    }
2500
2495
  }
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())
2503
2498
  {
2504
 
    error= session->is_error();
 
2499
    error= thd->is_error();
2505
2500
    return;
2506
2501
  }
2507
2502
  curr_join->having= curr_join->tmp_having;
2508
2503
  curr_join->fields= curr_fields_list;
2509
2504
 
2510
2505
  {
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;
2516
2511
  }
2517
2512
 
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;
2520
2515
 
2521
2516
  /* 
2522
2517
    With EXPLAIN EXTENDED we have to restore original ref_array
2524
2519
    Otherwise we would not be able to print the query  correctly.
2525
2520
  */ 
2526
2521
  if (items0 &&
2527
 
      (session->lex->describe & DESCRIBE_EXTENDED) &&
 
2522
      (thd->lex->describe & DESCRIBE_EXTENDED) &&
2528
2523
      select_lex->linkage == DERIVED_TABLE_TYPE)      
2529
2524
    set_items_ref_array(items0);
2530
2525
 
2560
2555
 
2561
2556
  cleanup(1);
2562
2557
  if (exec_tmp_table1)
2563
 
    exec_tmp_table1->free_tmp_table(session);
 
2558
    exec_tmp_table1->free_tmp_table(thd);
2564
2559
  if (exec_tmp_table2)
2565
 
    exec_tmp_table2->free_tmp_table(session);
 
2560
    exec_tmp_table2->free_tmp_table(thd);
2566
2561
  delete select;
2567
2562
  delete_dynamic(&keyuse);
2568
2563
  return(error);
2573
2568
/**
2574
2569
  An entry point to single-unit select (a select without UNION).
2575
2570
 
2576
 
  @param session                  thread handler
 
2571
  @param thd                  thread handler
2577
2572
  @param rref_pointer_array   a reference to ref_pointer_array of
2578
2573
                              the top-level select_lex for this query
2579
2574
  @param tables               list of all tables used in this query.
2615
2610
*/
2616
2611
 
2617
2612
bool
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)
2660
2655
  }
2661
2656
  else
2662
2657
  {
2663
 
    if (!(join= new JOIN(session, fields, select_options, result)))
 
2658
    if (!(join= new JOIN(thd, fields, select_options, result)))
2664
2659
        return(true);
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)
2685
2680
    goto err;                                   // 1
2686
2681
  }
2687
2682
 
2688
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
2683
  if (thd->lex->describe & DESCRIBE_EXTENDED)
2689
2684
  {
2690
2685
    join->conds_history= join->conds;
2691
2686
    join->having_history= (join->having?join->having:join->tmp_having);
2692
2687
  }
2693
2688
 
2694
 
  if (session->is_error())
 
2689
  if (thd->is_error())
2695
2690
    goto err;
2696
2691
 
2697
2692
  join->exec();
2698
2693
 
2699
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
2694
  if (thd->lex->describe & DESCRIBE_EXTENDED)
2700
2695
  {
2701
2696
    select_lex->where= join->conds_history;
2702
2697
    select_lex->having= join->having_history;
2705
2700
err:
2706
2701
  if (free_join)
2707
2702
  {
2708
 
    session->set_proc_info("end");
 
2703
    thd_proc_info(thd, "end");
2709
2704
    err|= select_lex->cleanup();
2710
 
    return(err || session->is_error());
 
2705
    return(err || thd->is_error());
2711
2706
  }
2712
2707
  return(join->error);
2713
2708
}
2727
2722
}
2728
2723
 
2729
2724
 
2730
 
static TableList *alloc_join_nest(Session *session)
 
2725
static TableList *alloc_join_nest(THD *thd)
2731
2726
{
2732
2727
  TableList *tbl;
2733
 
  if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
 
2728
  if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
2734
2729
                                       sizeof(nested_join_st))))
2735
2730
    return NULL;
2736
 
  tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl + 
 
2731
  tbl->nested_join= (nested_join_st*) ((uchar*)tbl + 
2737
2732
                                    ALIGN_SIZE(sizeof(TableList)));
2738
2733
  return tbl;
2739
2734
}
2786
2781
  SELECT_LEX *parent_lex= parent_join->select_lex;
2787
2782
  TableList *emb_tbl_nest= NULL;
2788
2783
  List<TableList> *emb_join_list= &parent_lex->top_join_list;
2789
 
  Session *session= parent_join->session;
 
2784
  THD *thd= parent_join->thd;
2790
2785
 
2791
2786
  /*
2792
2787
    1. Find out where to put the predicate into.
2843
2838
        A3: changes in the TableList::outer_join will make everything work
2844
2839
            automatically.
2845
2840
      */
2846
 
      if (!(wrap_nest= alloc_join_nest(parent_join->session)))
 
2841
      if (!(wrap_nest= alloc_join_nest(parent_join->thd)))
2847
2842
      {
2848
2843
        return(true);
2849
2844
      }
2888
2883
 
2889
2884
  TableList *sj_nest;
2890
2885
  nested_join_st *nested_join;
2891
 
  if (!(sj_nest= alloc_join_nest(parent_join->session)))
 
2886
  if (!(sj_nest= alloc_join_nest(parent_join->thd)))
2892
2887
  {
2893
2888
    return(true);
2894
2889
  }
2949
2944
  /*TODO: also reset the 'with_subselect' there. */
2950
2945
 
2951
2946
  /* n. Adjust the parent_join->tables counter */
2952
 
  uint32_t table_no= parent_join->tables;
 
2947
  uint table_no= parent_join->tables;
2953
2948
  /* n. Walk through child's tables and adjust table->map */
2954
2949
  for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
2955
2950
  {
2966
2961
    Put the subquery's WHERE into semi-join's sj_on_expr
2967
2962
    Add the subquery-induced equalities too.
2968
2963
  */
2969
 
  SELECT_LEX *save_lex= session->lex->current_select;
2970
 
  session->lex->current_select=subq_lex;
 
2964
  SELECT_LEX *save_lex= thd->lex->current_select;
 
2965
  thd->lex->current_select=subq_lex;
2971
2966
  if (!subq_pred->left_expr->fixed &&
2972
 
       subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
 
2967
       subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
2973
2968
    return(true);
2974
 
  session->lex->current_select=save_lex;
 
2969
  thd->lex->current_select=save_lex;
2975
2970
 
2976
2971
  sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2977
2972
  sj_nest->nested_join->sj_depends_on=  subq_pred->used_tables() |
3007
3002
  }
3008
3003
  else
3009
3004
  {
3010
 
    for (uint32_t i= 0; i < subq_pred->left_expr->cols(); i++)
 
3005
    for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
3011
3006
    {
3012
3007
      nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->
3013
3008
                                                element_index(i));
3019
3014
    }
3020
3015
  }
3021
3016
  /* Fix the created equality and AND */
3022
 
  sj_nest->sj_on_expr->fix_fields(parent_join->session, &sj_nest->sj_on_expr);
 
3017
  sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
3023
3018
 
3024
3019
  /*
3025
3020
    Walk through sj nest's WHERE and ON expressions and call
3037
3032
  {
3038
3033
    emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr, 
3039
3034
                                     sj_nest->sj_on_expr);
3040
 
    emb_tbl_nest->on_expr->fix_fields(parent_join->session, &emb_tbl_nest->on_expr);
 
3035
    emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
3041
3036
  }
3042
3037
  else
3043
3038
  {
3044
3039
    /* Inject into the WHERE */
3045
3040
    parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
3046
 
    parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
 
3041
    parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
3047
3042
    parent_join->select_lex->where= parent_join->conds;
3048
3043
  }
3049
3044
 
3132
3127
    if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
3133
3128
      return(true);
3134
3129
 
3135
 
    //if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
 
3130
    //if ((*in_subq)->fix_fields(thd, (*in_subq)->ref_ptr))
3136
3131
    //  return(true);
3137
3132
  }
3138
3133
  sj_subselects.clear();
3209
3204
bool find_eq_ref_candidate(Table *table, table_map sj_inner_tables)
3210
3205
{
3211
3206
  KEYUSE *keyuse= table->reginfo.join_tab->keyuse;
3212
 
  uint32_t key;
 
3207
  uint key;
3213
3208
 
3214
3209
  if (keyuse)
3215
3210
  {
3373
3368
*****************************************************************************/
3374
3369
 
3375
3370
 
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,
3377
3372
                                      Table *table,
3378
3373
                                      const key_map *keys,ha_rows limit)
3379
3374
{
3380
3375
  int error;
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
3383
3378
  if (select)
3384
3379
  {
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)
3407
3402
{
3408
3403
  Field *field;              /* field against which to check sargability */
3409
3404
  Item **arg_value;          /* values of potential keys for lookups     */
3410
 
  uint32_t num_values;           /* number of values in the above array      */
 
3405
  uint num_values;           /* number of values in the above array      */
3411
3406
} SARGABLE_PARAM;  
3412
3407
 
3413
3408
/**
3425
3420
{
3426
3421
  int error;
3427
3422
  Table *table;
3428
 
  uint32_t i,table_count,const_count,key;
 
3423
  uint i,table_count,const_count,key;
3429
3424
  table_map found_const_table_map, all_table_map, found_ref, refs;
3430
3425
  key_map const_ref, eq_part;
3431
3426
  Table **table_vector;
3436
3431
  JOIN_TAB *stat_vector[MAX_TABLES+1];
3437
3432
 
3438
3433
  table_count=join->tables;
3439
 
  stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
3440
 
  stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3441
 
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
 
3434
  stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
 
3435
  stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
 
3436
  table_vector=(Table**) join->thd->alloc(sizeof(Table*)*(table_count*2));
3442
3437
  if (!stat || !stat_ref || !table_vector)
3443
3438
    return(1);                          // Eom /* purecov: inspected */
3444
3439
 
3534
3529
    */
3535
3530
    for (i= 0, s= stat ; i < table_count ; i++, s++)
3536
3531
    {
3537
 
      for (uint32_t j= 0 ; j < table_count ; j++)
 
3532
      for (uint j= 0 ; j < table_count ; j++)
3538
3533
      {
3539
3534
        table= stat[j].table;
3540
3535
        if (s->dependent & table->map)
3557
3552
  }
3558
3553
 
3559
3554
  if (conds || outer_join)
3560
 
    if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
 
3555
    if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
3561
3556
                            conds, join->cond_equal,
3562
3557
                            ~outer_join, join->select_lex, &sargables))
3563
3558
      return(1);
3731
3726
      key_map possible_keys= field->key_start;
3732
3727
      possible_keys.intersect(field->table->keys_in_use_for_query);
3733
3728
      bool is_const= 1;
3734
 
      for (uint32_t j=0; j < sargables->num_values; j++)
 
3729
      for (uint j=0; j < sargables->num_values; j++)
3735
3730
        is_const&= sargables->arg_value[j]->const_item();
3736
3731
      if (is_const)
3737
3732
        join_tab[0].const_keys.merge(possible_keys);
3760
3755
      This is can't be to high as otherwise we are likely to use
3761
3756
      table scan.
3762
3757
    */
3763
 
    s->worst_seeks= cmin((double) s->found_records / 10,
 
3758
    s->worst_seeks= min((double) s->found_records / 10,
3764
3759
                        (double) s->read_time*3);
3765
3760
    if (s->worst_seeks < 2.0)                   // Fix for small tables
3766
3761
      s->worst_seeks=2.0;
3782
3777
                          1, &error);
3783
3778
      if (!select)
3784
3779
        return(1);
3785
 
      records= get_quick_record_count(join->session, select, s->table,
 
3780
      records= get_quick_record_count(join->thd, select, s->table,
3786
3781
                                      &s->const_keys, join->row_limit);
3787
3782
      s->quick=select->quick;
3788
3783
      s->needed_reg=select->needed_reg;
3836
3831
    join->best_read=1.0;
3837
3832
  }
3838
3833
  /* Generate an execution plan from the found optimal join order. */
3839
 
  return(join->session->killed || get_best_combination(join));
 
3834
  return(join->thd->killed || get_best_combination(join));
3840
3835
}
3841
3836
 
3842
3837
 
3861
3856
  */
3862
3857
  bool          null_rejecting; 
3863
3858
  bool          *cond_guard; /* See KEYUSE::cond_guard */
3864
 
  uint32_t          sj_pred_no; /* See KEYUSE::sj_pred_no */
 
3859
  uint          sj_pred_no; /* See KEYUSE::sj_pred_no */
3865
3860
} KEY_FIELD;
3866
3861
 
3867
3862
/**
3890
3885
 
3891
3886
static KEY_FIELD *
3892
3887
merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
3893
 
                 uint32_t and_level)
 
3888
                 uint and_level)
3894
3889
{
3895
3890
  if (start == new_fields)
3896
3891
    return start;                               // Impossible or
4017
4012
*/
4018
4013
 
4019
4014
static void
4020
 
add_key_field(KEY_FIELD **key_fields,uint32_t and_level, Item_func *cond,
4021
 
              Field *field, bool eq_func, Item **value, uint32_t num_values,
 
4015
add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
 
4016
              Field *field, bool eq_func, Item **value, uint num_values,
4022
4017
              table_map usable_tables, SARGABLE_PARAM **sargables)
4023
4018
{
4024
 
  uint32_t exists_optimize= 0;
 
4019
  uint exists_optimize= 0;
4025
4020
  if (!(field->flags & PART_KEY_FLAG))
4026
4021
  {
4027
4022
    // Don't remove column IS NULL on a LEFT JOIN table
4035
4030
  {
4036
4031
    table_map used_tables=0;
4037
4032
    bool optimizable=0;
4038
 
    for (uint32_t i=0; i<num_values; i++)
 
4033
    for (uint i=0; i<num_values; i++)
4039
4034
    {
4040
4035
      used_tables|=(value[i])->used_tables();
4041
4036
      if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
4071
4066
      stat[0].key_dependent|=used_tables;
4072
4067
 
4073
4068
      bool is_const=1;
4074
 
      for (uint32_t i=0; i<num_values; i++)
 
4069
      for (uint i=0; i<num_values; i++)
4075
4070
      {
4076
4071
        if (!(is_const&= value[i]->const_item()))
4077
4072
          break;
4189
4184
*/
4190
4185
 
4191
4186
static void
4192
 
add_key_equal_fields(KEY_FIELD **key_fields, uint32_t and_level,
 
4187
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
4193
4188
                     Item_func *cond, Item_field *field_item,
4194
4189
                     bool eq_func, Item **val,
4195
 
                     uint32_t num_values, table_map usable_tables,
 
4190
                     uint num_values, table_map usable_tables,
4196
4191
                     SARGABLE_PARAM **sargables)
4197
4192
{
4198
4193
  Field *field= field_item->field;
4220
4215
}
4221
4216
 
4222
4217
static void
4223
 
add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint32_t *and_level,
 
4218
add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
4224
4219
               COND *cond, table_map usable_tables,
4225
4220
               SARGABLE_PARAM **sargables)
4226
4221
{
4313
4308
    if (cond_func->functype() == Item_func::BETWEEN)
4314
4309
    {
4315
4310
      values= cond_func->arguments();
4316
 
      for (uint32_t i= 1 ; i < cond_func->argument_count() ; i++)
 
4311
      for (uint i= 1 ; i < cond_func->argument_count() ; i++)
4317
4312
      {
4318
4313
        Item_field *field_item;
4319
4314
        if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM
4424
4419
static uint
4425
4420
max_part_bit(key_part_map bits)
4426
4421
{
4427
 
  uint32_t found;
 
4422
  uint found;
4428
4423
  for (found=0; bits & 1 ; found++,bits>>=1) ;
4429
4424
  return found;
4430
4425
}
4438
4433
 
4439
4434
  if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
4440
4435
  {
4441
 
    for (uint32_t key= 0 ; key < form->sizeKeys() ; key++)
 
4436
    for (uint key= 0 ; key < form->sizeKeys() ; key++)
4442
4437
    {
4443
4438
      if (!(form->keys_in_use_for_query.is_set(key)))
4444
4439
        continue;
4445
4440
 
4446
 
      uint32_t key_parts= (uint) form->key_info[key].key_parts;
4447
 
      for (uint32_t part=0 ; part <  key_parts ; part++)
 
4441
      uint key_parts= (uint) form->key_info[key].key_parts;
 
4442
      for (uint part=0 ; part <  key_parts ; part++)
4448
4443
      {
4449
4444
        if (field->eq(form->key_info[key].key_part[part].field))
4450
4445
        {
4458
4453
          keyuse.null_rejecting= key_field->null_rejecting;
4459
4454
          keyuse.cond_guard= key_field->cond_guard;
4460
4455
          keyuse.sj_pred_no= key_field->sj_pred_no;
4461
 
          insert_dynamic(keyuse_array,(unsigned char*) &keyuse);
 
4456
          VOID(insert_dynamic(keyuse_array,(uchar*) &keyuse));
4462
4457
        }
4463
4458
      }
4464
4459
    }
4521
4516
*/
4522
4517
 
4523
4518
static void add_key_fields_for_nj(JOIN *join, TableList *nested_join_table,
4524
 
                                  KEY_FIELD **end, uint32_t *and_level,
 
4519
                                  KEY_FIELD **end, uint *and_level,
4525
4520
                                  SARGABLE_PARAM **sargables)
4526
4521
{
4527
4522
  List_iterator<TableList> li(nested_join_table->nested_join->join_list);
4559
4554
/**
4560
4555
  Update keyuse array with all possible keys we can use to fetch rows.
4561
4556
  
4562
 
  @param       session 
 
4557
  @param       thd 
4563
4558
  @param[out]  keyuse         Put here ordered array of KEYUSE structures
4564
4559
  @param       join_tab       Array in tablenr_order
4565
4560
  @param       tables         Number of tables in join
4578
4573
*/
4579
4574
 
4580
4575
static bool
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)
4585
4581
{
4586
4582
  uint  and_level,i,found_eq_constant;
4587
4583
  KEY_FIELD *key_fields, *end, *field;
4588
 
  uint32_t sz;
4589
 
  uint32_t m= cmax(select_lex->max_equal_elems,(uint32_t)1);
 
4584
  uint sz;
 
4585
  uint m= max(select_lex->max_equal_elems,(uint32_t)1);
4590
4586
  
4591
4587
  /* 
4592
4588
    We use the same piece of memory to store both  KEY_FIELD 
4609
4605
    can be not more than select_lex->max_equal_elems such 
4610
4606
    substitutions.
4611
4607
  */ 
4612
 
  sz= cmax(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
4613
 
      (((session->lex->current_select->cond_count+1)*2 +
4614
 
        session->lex->current_select->between_count)*m+1);
4615
 
  if (!(key_fields=(KEY_FIELD*) session->alloc(sz)))
 
4608
  sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
 
4609
      (((thd->lex->current_select->cond_count+1)*2 +
 
4610
        thd->lex->current_select->between_count)*m+1);
 
4611
  if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
4616
4612
    return true; /* purecov: inspected */
4617
4613
  and_level= 0;
4618
4614
  field= end= key_fields;
4686
4682
          (qsort_cmp) sort_keyuse);
4687
4683
 
4688
4684
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
4689
 
    insert_dynamic(keyuse,(unsigned char*) &key_end);
 
4685
    VOID(insert_dynamic(keyuse,(uchar*) &key_end));
4690
4686
 
4691
4687
    use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
4692
4688
    prev= &key_end;
4719
4715
      save_pos++;
4720
4716
    }
4721
4717
    i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
4722
 
    set_dynamic(keyuse,(unsigned char*) &key_end,i);
 
4718
    VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
4723
4719
    keyuse->elements=i;
4724
4720
  }
4725
4721
  return false;
4749
4745
        (map= (keyuse->used_tables & ~join->const_table_map &
4750
4746
               ~OUTER_REF_TABLE_BIT)))
4751
4747
    {
4752
 
      uint32_t tablenr;
 
4748
      uint tablenr;
4753
4749
      for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
4754
4750
      if (map == 1)                     // Only one table
4755
4751
      {
4756
4752
        Table *tmp_table=join->all_tables[tablenr];
4757
 
        keyuse->ref_table_rows= cmax(tmp_table->file->stats.records, (ha_rows)100);
 
4753
        keyuse->ref_table_rows= max(tmp_table->file->stats.records, (ha_rows)100);
4758
4754
      }
4759
4755
    }
4760
4756
    /*
4798
4794
  { /* Collect all query fields referenced in the GROUP clause. */
4799
4795
    for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
4800
4796
      (*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
4801
 
                               (unsigned char*) &indexed_fields);
 
4797
                               (uchar*) &indexed_fields);
4802
4798
  }
4803
4799
  else if (join->select_distinct)
4804
4800
  { /* Collect all query fields referenced in the SELECT clause. */
4807
4803
    Item *item;
4808
4804
    while ((item= select_items_it++))
4809
4805
      item->walk(&Item::collect_item_field_processor, 0,
4810
 
                 (unsigned char*) &indexed_fields);
 
4806
                 (uchar*) &indexed_fields);
4811
4807
  }
4812
4808
  else
4813
4809
    return;
4836
4832
/** Save const tables first as used tables. */
4837
4833
 
4838
4834
static void
4839
 
set_position(JOIN *join,uint32_t idx,JOIN_TAB *table,KEYUSE *key)
 
4835
set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
4840
4836
{
4841
4837
  join->positions[idx].table= table;
4842
4838
  join->positions[idx].key=key;
4878
4874
{
4879
4875
  List_iterator<Item> li(sj_nest->nested_join->sj_outer_expr_list);
4880
4876
  Item *item;
4881
 
  uint32_t i= 0;
 
4877
  uint i= 0;
4882
4878
  uint64_t res= 0;
4883
4879
  while ((item= li++))
4884
4880
  {
4890
4886
    */
4891
4887
    if (!(item->used_tables() & remaining_tables))
4892
4888
    {
4893
 
      res |= 1UL < i;
 
4889
      res |= 1ULL < i;
4894
4890
    }
4895
4891
  }
4896
4892
  return res;
4911
4907
  @param join             pointer to the structure providing all context info
4912
4908
                          for the query
4913
4909
  @param s                the table to be joined by the function
4914
 
  @param session              thread for the connection that submitted the query
 
4910
  @param thd              thread for the connection that submitted the query
4915
4911
  @param remaining_tables set of tables not included into the partial plan yet
4916
4912
  @param idx              the length of the partial plan
4917
4913
  @param record_count     estimate for the number of records returned by the
4925
4921
static void
4926
4922
best_access_path(JOIN      *join,
4927
4923
                 JOIN_TAB  *s,
4928
 
                 Session       *session,
 
4924
                 THD       *thd,
4929
4925
                 table_map remaining_tables,
4930
 
                 uint32_t      idx,
 
4926
                 uint      idx,
4931
4927
                 double    record_count,
4932
 
                 double)
 
4928
                 double    read_time __attribute__((unused)))
4933
4929
{
4934
4930
  KEYUSE *best_key=         0;
4935
 
  uint32_t best_max_key_part=   0;
 
4931
  uint best_max_key_part=   0;
4936
4932
  bool found_constraint= 0;
4937
4933
  double best=              DBL_MAX;
4938
4934
  double best_time=         DBL_MAX;
4940
4936
  table_map best_ref_depends_map= 0;
4941
4937
  double tmp;
4942
4938
  ha_rows rec;
4943
 
  uint32_t best_is_sj_inside_out=    0;
 
4939
  uint best_is_sj_inside_out=    0;
4944
4940
 
4945
4941
  if (s->keyuse)
4946
4942
  {                                            /* Use key if possible */
4978
4974
    {
4979
4975
      key_part_map found_part= 0;
4980
4976
      table_map found_ref= 0;
4981
 
      uint32_t key= keyuse->key;
 
4977
      uint key= keyuse->key;
4982
4978
      KEY *keyinfo= table->key_info+key;
4983
4979
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
4984
4980
      key_part_map const_part= 0;
4992
4988
 
4993
4989
      do /* For each keypart */
4994
4990
      {
4995
 
        uint32_t keypart= keyuse->keypart;
 
4991
        uint keypart= keyuse->keypart;
4996
4992
        table_map best_part_found_ref= 0;
4997
4993
        double best_prev_record_reads= DBL_MAX;
4998
4994
        
5031
5027
          if (try_sj_inside_out && keyuse->sj_pred_no != UINT_MAX)
5032
5028
          {
5033
5029
            if (!(remaining_tables & keyuse->used_tables))
5034
 
              bound_sj_equalities |= 1UL << keyuse->sj_pred_no;
 
5030
              bound_sj_equalities |= 1ULL << keyuse->sj_pred_no;
5035
5031
            else
5036
5032
            {
5037
 
              handled_sj_equalities |= 1UL << keyuse->sj_pred_no;
 
5033
              handled_sj_equalities |= 1ULL << keyuse->sj_pred_no;
5038
5034
              sj_insideout_map |= ((key_part_map)1) << keyuse->keypart;
5039
5035
            }
5040
5036
          }
5068
5064
            (handled_sj_equalities | bound_sj_equalities) ==     // (1)
5069
5065
            PREV_BITS(uint64_t, s->emb_sj_nest->sj_in_exprs)) // (1)
5070
5066
        {
5071
 
          uint32_t n_fixed_parts= max_part_bit(found_part);
 
5067
          uint n_fixed_parts= max_part_bit(found_part);
5072
5068
          if (n_fixed_parts != keyinfo->key_parts &&
5073
5069
              (PREV_BITS(uint, n_fixed_parts) | sj_insideout_map) ==
5074
5070
               PREV_BITS(uint, keyinfo->key_parts))
5176
5172
            }
5177
5173
            /* Limit the number of matched rows */
5178
5174
            tmp= records;
5179
 
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
 
5175
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5180
5176
            if (table->covering_keys.is_set(key))
5181
5177
            {
5182
5178
              /* we can use only index tree */
5183
5179
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5184
5180
            }
5185
5181
            else
5186
 
              tmp= record_count*cmin(tmp,s->worst_seeks);
 
5182
              tmp= record_count*min(tmp,s->worst_seeks);
5187
5183
          }
5188
5184
        }
5189
5185
        else
5239
5235
            */
5240
5236
            if (table->quick_keys.is_set(key) && !found_ref &&          //(C1)
5241
5237
                table->quick_key_parts[key] == max_key_part &&          //(C2)
5242
 
                table->quick_n_ranges[key] == 1+((ref_or_null_part)?1:0)) //(C3)
 
5238
                table->quick_n_ranges[key] == 1+test(ref_or_null_part)) //(C3)
5243
5239
            {
5244
5240
              tmp= records= (double) table->quick_rows[key];
5245
5241
            }
5307
5303
                    tmp= a;
5308
5304
                  set_if_bigger(tmp,1.0);
5309
5305
                }
5310
 
                records = (uint32_t) tmp;
 
5306
                records = (ulong) tmp;
5311
5307
              }
5312
5308
 
5313
5309
              if (ref_or_null_part)
5332
5328
              if (table->quick_keys.is_set(key) &&
5333
5329
                  table->quick_key_parts[key] <= max_key_part &&
5334
5330
                  const_part & (1 << table->quick_key_parts[key]) &&
5335
 
                  table->quick_n_ranges[key] == 1 + ((ref_or_null_part &
5336
 
                                                     const_part) ? 1 : 0) &&
 
5331
                  table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
 
5332
                                                         const_part) &&
5337
5333
                  records > (double) table->quick_rows[key])
5338
5334
              {
5339
5335
                tmp= records= (double) table->quick_rows[key];
5341
5337
            }
5342
5338
 
5343
5339
            /* Limit the number of matched rows */
5344
 
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
 
5340
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5345
5341
            if (table->covering_keys.is_set(key))
5346
5342
            {
5347
5343
              /* we can use only index tree */
5348
5344
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5349
5345
            }
5350
5346
            else
5351
 
              tmp= record_count * cmin(tmp,s->worst_seeks);
 
5347
              tmp= record_count * min(tmp,s->worst_seeks);
5352
5348
          }
5353
5349
          else
5354
5350
            tmp= best_time;                    // Do nothing
5471
5467
        /* We read the table as many times as join buffer becomes full. */
5472
5468
        tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5473
5469
                           record_count /
5474
 
                           (double) session->variables.join_buff_size));
 
5470
                           (double) thd->variables.join_buff_size));
5475
5471
        /* 
5476
5472
            We don't make full cartesian product between rows in the scanned
5477
5473
           table and existing records because we skip all rows from the
5549
5545
static bool
5550
5546
choose_plan(JOIN *join, table_map join_tables)
5551
5547
{
5552
 
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
5553
 
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
 
5548
  uint search_depth= join->thd->variables.optimizer_search_depth;
 
5549
  uint prune_level=  join->thd->variables.optimizer_prune_level;
5554
5550
  bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5555
5551
 
5556
5552
  join->cur_embedding_map= 0;
5598
5594
    i.e. they have subqueries, unions or call stored procedures.
5599
5595
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
5600
5596
  */
5601
 
  if (join->session->lex->is_single_level_stmt())
5602
 
    join->session->status_var.last_query_cost= join->best_read;
 
5597
  if (join->thd->lex->is_single_level_stmt())
 
5598
    join->thd->status_var.last_query_cost= join->best_read;
5603
5599
  return(false);
5604
5600
}
5605
5601
 
5684
5680
 
5685
5681
  @todo
5686
5682
    this value should be determined dynamically, based on statistics:
5687
 
    uint32_t max_tables_for_exhaustive_opt= 7;
 
5683
    uint max_tables_for_exhaustive_opt= 7;
5688
5684
 
5689
5685
  @todo
5690
5686
    this value could be determined by some mapping of the form:
5699
5695
static uint
5700
5696
determine_search_depth(JOIN *join)
5701
5697
{
5702
 
  uint32_t table_count=  join->tables - join->const_tables;
5703
 
  uint32_t search_depth;
 
5698
  uint table_count=  join->tables - join->const_tables;
 
5699
  uint search_depth;
5704
5700
  /* TODO: this value should be determined dynamically, based on statistics: */
5705
 
  uint32_t max_tables_for_exhaustive_opt= 7;
 
5701
  uint max_tables_for_exhaustive_opt= 7;
5706
5702
 
5707
5703
  if (table_count <= max_tables_for_exhaustive_opt)
5708
5704
    search_depth= table_count+1; // use exhaustive for small number of tables
5744
5740
optimize_straight_join(JOIN *join, table_map join_tables)
5745
5741
{
5746
5742
  JOIN_TAB *s;
5747
 
  uint32_t idx= join->const_tables;
 
5743
  uint idx= join->const_tables;
5748
5744
  double    record_count= 1.0;
5749
5745
  double    read_time=    0.0;
5750
5746
 
5752
5748
  {
5753
5749
    /* Find the best access method from 's' to the current partial plan */
5754
5750
    advance_sj_state(join_tables, s);
5755
 
    best_access_path(join, s, join->session, join_tables, idx,
 
5751
    best_access_path(join, s, join->thd, join_tables, idx,
5756
5752
                     record_count, read_time);
5757
5753
    /* compute the cost of the new plan extended with 's' */
5758
5754
    record_count*= join->positions[idx].records_read;
5854
5850
static bool
5855
5851
greedy_search(JOIN      *join,
5856
5852
              table_map remaining_tables,
5857
 
              uint32_t      search_depth,
5858
 
              uint32_t      prune_level)
 
5853
              uint      search_depth,
 
5854
              uint      prune_level)
5859
5855
{
5860
5856
  double    record_count= 1.0;
5861
5857
  double    read_time=    0.0;
5862
 
  uint32_t      idx= join->const_tables; // index into 'join->best_ref'
5863
 
  uint32_t      best_idx;
5864
 
  uint32_t      size_remain;    // cardinality of remaining_tables
 
5858
  uint      idx= join->const_tables; // index into 'join->best_ref'
 
5859
  uint      best_idx;
 
5860
  uint      size_remain;    // cardinality of remaining_tables
5865
5861
  POSITION  best_pos;
5866
5862
  JOIN_TAB  *best_table; // the next plan node to be added to the curr QEP
5867
5863
 
6034
6030
static bool
6035
6031
best_extension_by_limited_search(JOIN      *join,
6036
6032
                                 table_map remaining_tables,
6037
 
                                 uint32_t      idx,
 
6033
                                 uint      idx,
6038
6034
                                 double    record_count,
6039
6035
                                 double    read_time,
6040
 
                                 uint32_t      search_depth,
6041
 
                                 uint32_t      prune_level)
 
6036
                                 uint      search_depth,
 
6037
                                 uint      prune_level)
6042
6038
{
6043
 
  Session *session= join->session;
6044
 
  if (session->killed)  // Abort
 
6039
  THD *thd= join->thd;
 
6040
  if (thd->killed)  // Abort
6045
6041
    return(true);
6046
6042
 
6047
6043
  /* 
6070
6066
          when the depth is insufficient??)
6071
6067
      */
6072
6068
      /* Find the best access method from 's' to the current partial plan */
6073
 
      best_access_path(join, s, session, remaining_tables, idx,
 
6069
      best_access_path(join, s, thd, remaining_tables, idx,
6074
6070
                       record_count, read_time);
6075
6071
      /* Compute the cost of extending the plan with 's' */
6076
6072
      current_record_count= record_count * join->positions[idx].records_read;
6162
6158
    true        Fatal error
6163
6159
*/
6164
6160
static bool
6165
 
find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count,
 
6161
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
6166
6162
          double read_time)
6167
6163
{
6168
 
  Session *session= join->session;
6169
 
  if (session->killed)
 
6164
  THD *thd= join->thd;
 
6165
  if (thd->killed)
6170
6166
    return(true);
6171
6167
  if (!rest_tables)
6172
6168
  {
6195
6191
    {
6196
6192
      double records, best;
6197
6193
      advance_sj_state(rest_tables, s);
6198
 
      best_access_path(join, s, session, rest_tables, idx, record_count, 
 
6194
      best_access_path(join, s, thd, rest_tables, idx, record_count, 
6199
6195
                       read_time);
6200
6196
      records= join->positions[idx].records_read;
6201
6197
      best= join->positions[idx].read_time;
6236
6232
  Find how much space the prevous read not const tables takes in cache.
6237
6233
*/
6238
6234
 
6239
 
static void calc_used_field_length(Session *, JOIN_TAB *join_tab)
 
6235
static void calc_used_field_length(THD *thd __attribute__((unused)),
 
6236
                                   JOIN_TAB *join_tab)
6240
6237
{
6241
 
  uint32_t null_fields,blobs,fields,rec_length;
 
6238
  uint null_fields,blobs,fields,rec_length;
6242
6239
  Field **f_ptr,*field;
6243
6240
  MY_BITMAP *read_set= join_tab->table->read_set;;
6244
6241
 
6247
6244
  {
6248
6245
    if (bitmap_is_set(read_set, field->field_index))
6249
6246
    {
6250
 
      uint32_t flags=field->flags;
 
6247
      uint flags=field->flags;
6251
6248
      fields++;
6252
6249
      rec_length+=field->pack_length();
6253
6250
      if (flags & BLOB_FLAG)
6262
6259
    rec_length+=sizeof(bool);
6263
6260
  if (blobs)
6264
6261
  {
6265
 
    uint32_t blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
 
6262
    uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
6266
6263
                             (join_tab->table->getRecordLength()- rec_length));
6267
 
    rec_length+=(uint) cmax((uint)4,blob_length);
 
6264
    rec_length+=(uint) max((uint)4,blob_length);
6268
6265
  }
6269
6266
  join_tab->used_fields=fields;
6270
6267
  join_tab->used_fieldlength=rec_length;
6273
6270
 
6274
6271
 
6275
6272
static uint
6276
 
cache_record_length(JOIN *join,uint32_t idx)
 
6273
cache_record_length(JOIN *join,uint idx)
6277
6274
{
6278
 
  uint32_t length=0;
 
6275
  uint length=0;
6279
6276
  JOIN_TAB **pos,**end;
6280
 
  Session *session=join->session;
 
6277
  THD *thd=join->thd;
6281
6278
 
6282
6279
  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
6283
6280
       pos != end ;
6285
6282
  {
6286
6283
    JOIN_TAB *join_tab= *pos;
6287
6284
    if (!join_tab->used_fieldlength)            /* Not calced yet */
6288
 
      calc_used_field_length(session, join_tab);
 
6285
      calc_used_field_length(thd, join_tab);
6289
6286
    length+=join_tab->used_fieldlength;
6290
6287
  }
6291
6288
  return length;
6344
6341
*/
6345
6342
 
6346
6343
static double
6347
 
prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
 
6344
prev_record_reads(JOIN *join, uint idx, table_map found_ref)
6348
6345
{
6349
6346
  double found=1.0;
6350
6347
  POSITION *pos_end= join->positions - 1;
6384
6381
static bool
6385
6382
get_best_combination(JOIN *join)
6386
6383
{
6387
 
  uint32_t i,tablenr;
 
6384
  uint i,tablenr;
6388
6385
  table_map used_tables;
6389
6386
  JOIN_TAB *join_tab,*j;
6390
6387
  KEYUSE *keyuse;
6391
 
  uint32_t table_count;
6392
 
  Session *session=join->session;
 
6388
  uint table_count;
 
6389
  THD *thd=join->thd;
6393
6390
 
6394
6391
  table_count=join->tables;
6395
6392
  if (!(join->join_tab=join_tab=
6396
 
        (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB)*table_count)))
 
6393
        (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
6397
6394
    return(true);
6398
6395
 
6399
6396
  join->full_join=0;
6437
6434
                               table_map used_tables)
6438
6435
{
6439
6436
  KEYUSE *keyuse=org_keyuse;
6440
 
  Session  *session= join->session;
6441
 
  uint32_t keyparts,length,key;
 
6437
  THD  *thd= join->thd;
 
6438
  uint keyparts,length,key;
6442
6439
  Table *table;
6443
6440
  KEY *keyinfo;
6444
6441
 
6449
6446
 
6450
6447
  {
6451
6448
    keyparts=length=0;
6452
 
    uint32_t found_part_ref_or_null= 0;
 
6449
    uint found_part_ref_or_null= 0;
6453
6450
    /*
6454
6451
      Calculate length for the used key
6455
6452
      Stop if there is a missing key part or when we find second key_part
6476
6473
  j->ref.key_parts=keyparts;
6477
6474
  j->ref.key_length=length;
6478
6475
  j->ref.key=(int) key;
6479
 
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
6480
 
      !(j->ref.key_copy= (store_key**) session->alloc((sizeof(store_key*) *
 
6476
  if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) ||
 
6477
      !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
6481
6478
                                                   (keyparts+1)))) ||
6482
 
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
6483
 
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
 
6479
      !(j->ref.items=    (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
 
6480
      !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
6484
6481
  {
6485
6482
    return(true);
6486
6483
  }
6491
6488
  keyuse=org_keyuse;
6492
6489
 
6493
6490
  store_key **ref_key= j->ref.key_copy;
6494
 
  unsigned char *key_buff=j->ref.key_buff, *null_ref_key= 0;
 
6491
  uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
6495
6492
  bool keyuse_uses_no_tables= true;
6496
6493
  {
6497
 
    uint32_t i;
 
6494
    uint i;
6498
6495
    for (i=0 ; i < keyparts ; keyuse++,i++)
6499
6496
    {
6500
6497
      while (keyuse->keypart != i ||
6501
6498
             ((~used_tables) & keyuse->used_tables))
6502
6499
        keyuse++;                               /* Skip other parts */
6503
6500
 
6504
 
      uint32_t maybe_null= test(keyinfo->key_part[i].null_bit);
 
6501
      uint maybe_null= test(keyinfo->key_part[i].null_bit);
6505
6502
      j->ref.items[i]=keyuse->val;              // Save for cond removal
6506
6503
      j->ref.cond_guards[i]= keyuse->cond_guard;
6507
6504
      if (keyuse->null_rejecting) 
6510
6507
      if (!keyuse->used_tables &&
6511
6508
          !(join->select_options & SELECT_DESCRIBE))
6512
6509
      {                                 // Compare against constant
6513
 
        store_key_item tmp(session, keyinfo->key_part[i].field,
 
6510
        store_key_item tmp(thd, keyinfo->key_part[i].field,
6514
6511
                           key_buff + maybe_null,
6515
6512
                           maybe_null ?  key_buff : 0,
6516
6513
                           keyinfo->key_part[i].length, keyuse->val);
6517
 
        if (session->is_fatal_error)
 
6514
        if (thd->is_fatal_error)
6518
6515
          return(true);
6519
6516
        tmp.copy();
6520
6517
      }
6521
6518
      else
6522
 
        *ref_key++= get_store_key(session,
 
6519
        *ref_key++= get_store_key(thd,
6523
6520
                                  keyuse,join->const_table_map,
6524
6521
                                  &keyinfo->key_part[i],
6525
6522
                                  key_buff, maybe_null);
6562
6559
 
6563
6560
 
6564
6561
static store_key *
6565
 
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6566
 
              KEY_PART_INFO *key_part, unsigned char *key_buff, uint32_t maybe_null)
 
6562
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
 
6563
              KEY_PART_INFO *key_part, uchar *key_buff, uint maybe_null)
6567
6564
{
6568
6565
  if (!((~used_tables) & keyuse->used_tables))          // if const item
6569
6566
  {
6570
 
    return new store_key_const_item(session,
 
6567
    return new store_key_const_item(thd,
6571
6568
                                    key_part->field,
6572
6569
                                    key_buff + maybe_null,
6573
6570
                                    maybe_null ? key_buff : 0,
6580
6577
            (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6581
6578
             Item_ref::DIRECT_REF && 
6582
6579
            keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6583
 
    return new store_key_field(session,
 
6580
    return new store_key_field(thd,
6584
6581
                               key_part->field,
6585
6582
                               key_buff + maybe_null,
6586
6583
                               maybe_null ? key_buff : 0,
6587
6584
                               key_part->length,
6588
6585
                               ((Item_field*) keyuse->val->real_item())->field,
6589
6586
                               keyuse->val->full_name());
6590
 
  return new store_key_item(session,
 
6587
  return new store_key_item(thd,
6591
6588
                            key_part->field,
6592
6589
                            key_buff + maybe_null,
6593
6590
                            maybe_null ? key_buff : 0,
6607
6604
{
6608
6605
  bool error;
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;
6612
6609
 
6613
6610
  /*
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
6617
6614
   */
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;
6623
6620
}
6624
6621
 
6625
6622
 
6635
6632
  */
6636
6633
  if (!join->table_reexec)
6637
6634
  {
6638
 
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
 
6635
    if (!(join->table_reexec= (Table**) join->thd->alloc(sizeof(Table*))))
6639
6636
      return(true);                        /* purecov: inspected */
6640
6637
    if (join->tmp_join)
6641
6638
      join->tmp_join->table_reexec= join->table_reexec;
6643
6640
  if (!join->join_tab_reexec)
6644
6641
  {
6645
6642
    if (!(join->join_tab_reexec=
6646
 
          (JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
 
6643
          (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
6647
6644
      return(true);                        /* purecov: inspected */
6648
6645
    if (join->tmp_join)
6649
6646
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6760
6757
 
6761
6758
static void add_not_null_conds(JOIN *join)
6762
6759
{
6763
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6760
  for (uint i=join->const_tables ; i < join->tables ; i++)
6764
6761
  {
6765
6762
    JOIN_TAB *tab=join->join_tab+i;
6766
6763
    if ((tab->type == JT_REF || tab->type == JT_EQ_REF || 
6767
6764
         tab->type == JT_REF_OR_NULL) &&
6768
6765
        !tab->table->maybe_null)
6769
6766
    {
6770
 
      for (uint32_t keypart= 0; keypart < tab->ref.key_parts; keypart++)
 
6767
      for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
6771
6768
      {
6772
6769
        if (tab->ref.null_rejecting & (1 << keypart))
6773
6770
        {
6791
6788
            when it is called from make_join_select after this function is 
6792
6789
            called.
6793
6790
          */
6794
 
          if (notnull->fix_fields(join->session, &notnull))
 
6791
          if (notnull->fix_fields(join->thd, &notnull))
6795
6792
            return;
6796
6793
          add_cond_and_fix(&referred_tab->select_cond, notnull);
6797
6794
        }
6880
6877
static void
6881
6878
make_outerjoin_info(JOIN *join)
6882
6879
{
6883
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6880
  for (uint i=join->const_tables ; i < join->tables ; i++)
6884
6881
  {
6885
6882
    JOIN_TAB *tab=join->join_tab+i;
6886
6883
    Table *table=tab->table;
6933
6930
static bool
6934
6931
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
6935
6932
{
6936
 
  Session *session= join->session;
 
6933
  THD *thd= join->thd;
6937
6934
  if (select)
6938
6935
  {
6939
6936
    add_not_null_conds(join);
6943
6940
      if (join->tables > 1)
6944
6941
        cond->update_used_tables();             // Tablenr may have changed
6945
6942
      if (join->const_tables == join->tables &&
6946
 
          session->lex->current_select->master_unit() ==
6947
 
          &session->lex->unit)          // not upper level SELECT
 
6943
          thd->lex->current_select->master_unit() ==
 
6944
          &thd->lex->unit)              // not upper level SELECT
6948
6945
        join->const_table_map|=RAND_TABLE_BIT;
6949
6946
      {                                         // Check const tables
6950
6947
        COND *const_cond=
6982
6979
    }
6983
6980
    used_tables=((select->const_tables=join->const_table_map) |
6984
6981
                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
6985
 
    for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6982
    for (uint i=join->const_tables ; i < join->tables ; i++)
6986
6983
    {
6987
6984
      JOIN_TAB *tab=join->join_tab+i;
6988
6985
      /*
7051
7048
          tab->type == JT_EQ_REF)
7052
7049
      {
7053
7050
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
7054
 
                                       session->memdup((unsigned char*) select,
 
7051
                                       thd->memdup((uchar*) select,
7055
7052
                                                   sizeof(*select)));
7056
7053
        if (!sel)
7057
7054
          return(1);                    // End of memory
7073
7070
          /* Push condition to storage engine if this is enabled
7074
7071
             and the condition is not guarded */
7075
7072
          tab->table->file->pushed_cond= NULL;
7076
 
          if (session->variables.engine_condition_pushdown)
 
7073
          if (thd->variables.engine_condition_pushdown)
7077
7074
          {
7078
7075
            COND *push_cond= 
7079
7076
              make_cond_for_table(tmp, current_map, current_map, 0);
7106
7103
          }
7107
7104
          tab->quick=0;
7108
7105
        }
7109
 
        uint32_t ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
 
7106
        uint ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
7110
7107
        if (i == join->const_tables && ref_key)
7111
7108
        {
7112
7109
          if (!tab->const_keys.is_clear_all() &&
7142
7139
            if (sel->cond && !sel->cond->fixed)
7143
7140
              sel->cond->quick_fix_field();
7144
7141
 
7145
 
            if (sel->test_quick_select(session, tab->keys,
 
7142
            if (sel->test_quick_select(thd, tab->keys,
7146
7143
                                       used_tables & ~ current_map,
7147
7144
                                       (join->select_options &
7148
7145
                                        OPTION_FOUND_ROWS ?
7156
7153
              */
7157
7154
              sel->cond=orig_cond;
7158
7155
              if (!*tab->on_expr_ref ||
7159
 
                  sel->test_quick_select(session, tab->keys,
 
7156
                  sel->test_quick_select(thd, tab->keys,
7160
7157
                                         used_tables & ~ current_map,
7161
7158
                                         (join->select_options &
7162
7159
                                          OPTION_FOUND_ROWS ?
7198
7195
                                         current_map, 0)))
7199
7196
            {
7200
7197
              tab->cache.select=(SQL_SELECT*)
7201
 
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
7198
                thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
7202
7199
              tab->cache.select->cond=tmp;
7203
7200
              tab->cache.select->read_tables=join->const_table_map;
7204
7201
            }
7316
7313
    false  No
7317
7314
*/
7318
7315
 
7319
 
bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, 
 
7316
bool uses_index_fields_only(Item *item, Table *tbl, uint keyno, 
7320
7317
                            bool other_tbls_ok)
7321
7318
{
7322
7319
  if (item->const_item())
7411
7408
    Index condition, or NULL if no condition could be inferred.
7412
7409
*/
7413
7410
 
7414
 
Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno,
 
7411
Item *make_cond_for_index(Item *cond, Table *table, uint keyno,
7415
7412
                          bool other_tbls_ok)
7416
7413
{
7417
7414
  if (!cond)
7418
7415
    return NULL;
7419
7416
  if (cond->type() == Item::COND_ITEM)
7420
7417
  {
7421
 
    uint32_t n_marked= 0;
 
7418
    uint n_marked= 0;
7422
7419
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
7423
7420
    {
7424
7421
      Item_cond_and *new_cond=new Item_cond_and;
7550
7547
    Try to extract and push the index condition down to table handler
7551
7548
*/
7552
7549
 
7553
 
static void push_index_cond(JOIN_TAB *tab, uint32_t keyno, bool other_tbls_ok)
 
7550
static void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok)
7554
7551
{
7555
7552
  Item *idx_cond;
7556
7553
  if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7557
 
      tab->join->session->variables.engine_condition_pushdown)
 
7554
      tab->join->thd->variables.engine_condition_pushdown)
7558
7555
  {
7559
7556
    idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7560
7557
                                  other_tbls_ok);
7612
7609
      ordered. If there is a temp table the ordering is done as a last
7613
7610
      operation and doesn't prevent join cache usage.
7614
7611
    */
7615
 
uint32_t make_join_orderinfo(JOIN *join)
 
7612
uint make_join_orderinfo(JOIN *join)
7616
7613
{
7617
 
  uint32_t i;
 
7614
  uint i;
7618
7615
  if (join->need_tmp)
7619
7616
    return join->tables;
7620
7617
 
7656
7653
*/
7657
7654
 
7658
7655
static bool
7659
 
make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
 
7656
make_join_readinfo(JOIN *join, uint64_t options, uint no_jbuf_after)
7660
7657
{
7661
 
  uint32_t i;
 
7658
  uint i;
7662
7659
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
7663
7660
  bool sorted= 1;
7664
7661
 
7678
7675
    sorted= 0;                                  // only first must be sorted
7679
7676
    if (tab->insideout_match_tab)
7680
7677
    {
7681
 
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
7678
      if (!(tab->insideout_buf= (uchar*)join->thd->alloc(tab->table->key_info
7682
7679
                                                         [tab->index].
7683
7680
                                                         key_length)))
7684
7681
        return true;
7762
7759
          !tab->insideout_match_tab)
7763
7760
      {
7764
7761
        if ((options & SELECT_DESCRIBE) ||
7765
 
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
7762
            !join_init_cache(join->thd,join->join_tab+join->const_tables,
7766
7763
                             i-join->const_tables))
7767
7764
        {
7768
7765
          using_join_cache= true;
7772
7769
      /* These init changes read_record */
7773
7770
      if (tab->use_quick == 2)
7774
7771
      {
7775
 
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
7772
        join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7776
7773
        tab->read_first_record= join_init_quick_read_record;
7777
7774
        if (statistics)
7778
 
          status_var_increment(join->session->status_var.select_range_check_count);
 
7775
          status_var_increment(join->thd->status_var.select_range_check_count);
7779
7776
      }
7780
7777
      else
7781
7778
      {
7785
7782
          if (tab->select && tab->select->quick)
7786
7783
          {
7787
7784
            if (statistics)
7788
 
              status_var_increment(join->session->status_var.select_range_count);
 
7785
              status_var_increment(join->thd->status_var.select_range_count);
7789
7786
          }
7790
7787
          else
7791
7788
          {
7792
 
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7789
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7793
7790
            if (statistics)
7794
 
              status_var_increment(join->session->status_var.select_scan_count);
 
7791
              status_var_increment(join->thd->status_var.select_scan_count);
7795
7792
          }
7796
7793
        }
7797
7794
        else
7799
7796
          if (tab->select && tab->select->quick)
7800
7797
          {
7801
7798
            if (statistics)
7802
 
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
7799
              status_var_increment(join->thd->status_var.select_full_range_join_count);
7803
7800
          }
7804
7801
          else
7805
7802
          {
7806
 
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7803
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7807
7804
            if (statistics)
7808
 
              status_var_increment(join->session->status_var.select_full_join_count);
 
7805
              status_var_increment(join->thd->status_var.select_full_join_count);
7809
7806
          }
7810
7807
        }
7811
7808
        if (!table->no_keyread)
7894
7891
  select= 0;
7895
7892
  delete quick;
7896
7893
  quick= 0;
7897
 
  if (cache.buff)
7898
 
    free(cache.buff);
 
7894
  x_free(cache.buff);
7899
7895
  cache.buff= 0;
7900
7896
  limit= 0;
7901
7897
  if (table)
7949
7945
    a correlated subquery itself, but has subqueries, we can free it
7950
7946
    fully and also free JOINs of all its subqueries. The exception
7951
7947
    is a subquery in SELECT list, e.g: @n
7952
 
    SELECT a, (select cmax(b) from t1) group by c @n
 
7948
    SELECT a, (select max(b) from t1) group by c @n
7953
7949
    This subquery will not be evaluated at first sweep and its value will
7954
7950
    not be inserted into the temporary table. Instead, it's evaluated
7955
7951
    when selecting from the temporary table. Therefore, it can't be freed
7967
7963
    Optimization: if not EXPLAIN and we are done with the JOIN,
7968
7964
    free all tables.
7969
7965
  */
7970
 
  bool full= (!select_lex->uncacheable && !session->lex->describe);
 
7966
  bool full= (!select_lex->uncacheable && !thd->lex->describe);
7971
7967
  bool can_unlock= full;
7972
7968
 
7973
7969
  cleanup(full);
7997
7993
    We are not using tables anymore
7998
7994
    Unlock all tables. We may be in an INSERT .... SELECT statement.
7999
7995
  */
8000
 
  if (can_unlock && lock && session->lock &&
 
7996
  if (can_unlock && lock && thd->lock &&
8001
7997
      !(select_options & SELECT_NO_UNLOCK) &&
8002
7998
      !select_lex->subquery_in_having &&
8003
 
      (select_lex == (session->lex->unit.fake_select_lex ?
8004
 
                      session->lex->unit.fake_select_lex : &session->lex->select_lex)))
 
7999
      (select_lex == (thd->lex->unit.fake_select_lex ?
 
8000
                      thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
8005
8001
  {
8006
8002
    /*
8007
8003
      TODO: unlock tables even if the join isn't top level select in the
8008
8004
      tree.
8009
8005
    */
8010
 
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
 
8006
    mysql_unlock_read_tables(thd, lock);           // Don't free join->lock
8011
8007
    lock= 0;
8012
8008
  }
8013
8009
 
8125
8121
    return (tab->eq_ref_table=0);               // We must use this
8126
8122
  Item **ref_item=tab->ref.items;
8127
8123
  Item **end=ref_item+tab->ref.key_parts;
8128
 
  uint32_t found=0;
 
8124
  uint found=0;
8129
8125
  table_map map=tab->table->map;
8130
8126
 
8131
8127
  for (; ref_item != end ; ref_item++)
8187
8183
    TABLE_REF *ref= &join_tab->ref;
8188
8184
    table_map depend_map=0;
8189
8185
    Item **item=ref->items;
8190
 
    uint32_t i;
 
8186
    uint i;
8191
8187
    for (i=0 ; i < ref->key_parts ; i++,item++)
8192
8188
      depend_map|=(*item)->used_tables();
8193
8189
    ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
8344
8340
    result->send_eof();                         // Should be safe
8345
8341
  }
8346
8342
  /* Update results for FOUND_ROWS */
8347
 
  join->session->limit_found_rows= join->session->examined_row_count= 0;
 
8343
  join->thd->limit_found_rows= join->thd->examined_row_count= 0;
8348
8344
  return(0);
8349
8345
}
8350
8346
 
8357
8353
    must clear only the non-const tables, as const tables
8358
8354
    are not re-calculated.
8359
8355
  */
8360
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
8356
  for (uint i=join->const_tables ; i < join->tables ; i++)
8361
8357
    mark_as_null_row(join->table[i]);           // All fields are NULL
8362
8358
}
8363
8359
 
8376
8372
  {
8377
8373
    return (void*) sql_alloc((uint) size);
8378
8374
  }
8379
 
  static void operator delete(void *, size_t)
 
8375
  static void operator delete(void *ptr __attribute__((unused)),
 
8376
                              size_t size __attribute__((unused)))
8380
8377
  { TRASH(ptr, size); }
8381
8378
 
8382
8379
  Item *and_level;
8703
8700
    simple equality nor a row equality the item for this predicate is added
8704
8701
    to eq_list.
8705
8702
 
8706
 
  @param session        thread handle
 
8703
  @param thd        thread handle
8707
8704
  @param left_row   left term of the row equality to be processed
8708
8705
  @param right_row  right term of the row equality to be processed
8709
8706
  @param cond_equal multiple equalities that must hold together with the
8717
8714
    false   otherwise
8718
8715
*/
8719
8716
 
8720
 
static bool check_row_equality(Session *session, Item *left_row, Item_row *right_row,
 
8717
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
8721
8718
                               COND_EQUAL *cond_equal, List<Item>* eq_list)
8722
8719
8723
 
  uint32_t n= left_row->cols();
8724
 
  for (uint32_t i= 0 ; i < n; i++)
 
8720
  uint n= left_row->cols();
 
8721
  for (uint i= 0 ; i < n; i++)
8725
8722
  {
8726
8723
    bool is_converted;
8727
8724
    Item *left_item= left_row->element_index(i);
8729
8726
    if (left_item->type() == Item::ROW_ITEM &&
8730
8727
        right_item->type() == Item::ROW_ITEM)
8731
8728
    {
8732
 
      is_converted= check_row_equality(session, 
 
8729
      is_converted= check_row_equality(thd, 
8733
8730
                                       (Item_row *) left_item,
8734
8731
                                       (Item_row *) right_item,
8735
8732
                                       cond_equal, eq_list);
8736
8733
      if (!is_converted)
8737
 
        session->lex->current_select->cond_count++;      
 
8734
        thd->lex->current_select->cond_count++;      
8738
8735
    }
8739
8736
    else
8740
8737
    { 
8741
8738
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8742
 
      session->lex->current_select->cond_count++;
 
8739
      thd->lex->current_select->cond_count++;
8743
8740
    }  
8744
8741
 
8745
8742
    if (!is_converted)
8770
8767
    equalities which are treated in the same way as original equality
8771
8768
    predicates.
8772
8769
 
8773
 
  @param session        thread handle
 
8770
  @param thd        thread handle
8774
8771
  @param item       predicate to process
8775
8772
  @param cond_equal multiple equalities that must hold together with the
8776
8773
                    predicate
8786
8783
           or, if the procedure fails by a fatal error.
8787
8784
*/
8788
8785
 
8789
 
static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal,
 
8786
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
8790
8787
                           List<Item> *eq_list)
8791
8788
{
8792
8789
  if (item->type() == Item::FUNC_ITEM &&
8798
8795
    if (left_item->type() == Item::ROW_ITEM &&
8799
8796
        right_item->type() == Item::ROW_ITEM)
8800
8797
    {
8801
 
      session->lex->current_select->cond_count--;
8802
 
      return check_row_equality(session,
 
8798
      thd->lex->current_select->cond_count--;
 
8799
      return check_row_equality(thd,
8803
8800
                                (Item_row *) left_item,
8804
8801
                                (Item_row *) right_item,
8805
8802
                                cond_equal, eq_list);
8830
8827
    just an argument of a comparison predicate.
8831
8828
    The function also determines the maximum number of members in 
8832
8829
    equality lists of each Item_cond_and object assigning it to
8833
 
    session->lex->current_select->max_equal_elems.
 
8830
    thd->lex->current_select->max_equal_elems.
8834
8831
 
8835
8832
  @note
8836
8833
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8867
8864
    We need to do things in this order as lower AND levels need to know about
8868
8865
    all possible Item_equal objects in upper levels.
8869
8866
 
8870
 
  @param session        thread handle
 
8867
  @param thd        thread handle
8871
8868
  @param cond       condition(expression) where to make replacement
8872
8869
  @param inherited  path to all inherited multiple equality items
8873
8870
 
8875
8872
    pointer to the transformed condition
8876
8873
*/
8877
8874
 
8878
 
static COND *build_equal_items_for_cond(Session *session, COND *cond,
 
8875
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
8879
8876
                                        COND_EQUAL *inherited)
8880
8877
{
8881
8878
  Item_equal *item_equal;
8907
8904
          structure here because it's restored before each
8908
8905
          re-execution of any prepared statement/stored procedure.
8909
8906
        */
8910
 
        if (check_equality(session, item, &cond_equal, &eq_list))
 
8907
        if (check_equality(thd, item, &cond_equal, &eq_list))
8911
8908
          li.remove();
8912
8909
      }
8913
8910
 
8916
8913
      {
8917
8914
        item_equal->fix_length_and_dec();
8918
8915
        item_equal->update_used_tables();
8919
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
8916
        set_if_bigger(thd->lex->current_select->max_equal_elems,
8920
8917
                      item_equal->members());  
8921
8918
      }
8922
8919
 
8931
8928
    while ((item= li++))
8932
8929
    { 
8933
8930
      Item *new_item;
8934
 
      if ((new_item= build_equal_items_for_cond(session, item, inherited)) != item)
 
8931
      if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
8935
8932
      {
8936
8933
        /* This replacement happens only for standalone equalities */
8937
8934
        /*
8961
8958
      for WHERE a=b AND c=d AND (b=c OR d=5)
8962
8959
      b=c is replaced by =(a,b,c,d).  
8963
8960
     */
8964
 
    if (check_equality(session, cond, &cond_equal, &eq_list))
 
8961
    if (check_equality(thd, cond, &cond_equal, &eq_list))
8965
8962
    {
8966
8963
      int n= cond_equal.current_level.elements + eq_list.elements;
8967
8964
      if (n == 0)
8975
8972
        }
8976
8973
        else
8977
8974
          item_equal= (Item_equal *) eq_list.pop();
8978
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
8975
        set_if_bigger(thd->lex->current_select->max_equal_elems,
8979
8976
                      item_equal->members());  
8980
8977
        return item_equal;
8981
8978
      }
8993
8990
        {
8994
8991
          item_equal->fix_length_and_dec();
8995
8992
          item_equal->update_used_tables();
8996
 
          set_if_bigger(session->lex->current_select->max_equal_elems,
 
8993
          set_if_bigger(thd->lex->current_select->max_equal_elems,
8997
8994
                        item_equal->members());  
8998
8995
        }
8999
8996
        and_cond->cond_equal= cond_equal;
9008
9005
      as soon the field is not of a string type or the field reference is
9009
9006
      an argument of a comparison predicate. 
9010
9007
    */ 
9011
 
    unsigned char *is_subst_valid= (unsigned char *) 1;
 
9008
    uchar *is_subst_valid= (uchar *) 1;
9012
9009
    cond= cond->compile(&Item::subst_argument_checker,
9013
9010
                        &is_subst_valid, 
9014
9011
                        &Item::equal_fields_propagator,
9015
 
                        (unsigned char *) inherited);
 
9012
                        (uchar *) inherited);
9016
9013
    cond->update_used_tables();
9017
9014
  }
9018
9015
  return cond;
9073
9070
    can get more freedom in performing join operations.
9074
9071
    Althogh we don't use this property now, it probably makes sense to use 
9075
9072
    it in the future.    
9076
 
  @param session                      Thread handler
 
9073
  @param thd                  Thread handler
9077
9074
  @param cond                condition to build the multiple equalities for
9078
9075
  @param inherited           path to all inherited multiple equality items
9079
9076
  @param join_list           list of join tables to which the condition
9085
9082
    pointer to the transformed condition containing multiple equalities
9086
9083
*/
9087
9084
   
9088
 
static COND *build_equal_items(Session *session, COND *cond,
 
9085
static COND *build_equal_items(THD *thd, COND *cond,
9089
9086
                               COND_EQUAL *inherited,
9090
9087
                               List<TableList> *join_list,
9091
9088
                               COND_EQUAL **cond_equal_ref)
9094
9091
 
9095
9092
  if (cond) 
9096
9093
  {
9097
 
    cond= build_equal_items_for_cond(session, cond, inherited);
 
9094
    cond= build_equal_items_for_cond(thd, cond, inherited);
9098
9095
    cond->update_used_tables();
9099
9096
    if (cond->type() == Item::COND_ITEM &&
9100
9097
        ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9128
9125
          We can modify table->on_expr because its old value will
9129
9126
          be restored before re-execution of PS/SP.
9130
9127
        */
9131
 
        table->on_expr= build_equal_items(session, table->on_expr, inherited,
 
9128
        table->on_expr= build_equal_items(thd, table->on_expr, inherited,
9132
9129
                                          nested_join_list,
9133
9130
                                          &table->cond_equal);
9134
9131
      }
9466
9463
*/
9467
9464
 
9468
9465
static void
9469
 
change_cond_ref_to_const(Session *session, I_List<COND_CMP> *save_list,
 
9466
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
9470
9467
                         Item *and_father, Item *cond,
9471
9468
                         Item *field, Item *value)
9472
9469
{
9477
9474
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9478
9475
    Item *item;
9479
9476
    while ((item=li++))
9480
 
      change_cond_ref_to_const(session, save_list,and_level ? cond : item, item,
 
9477
      change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
9481
9478
                               field, value);
9482
9479
    return;
9483
9480
  }
9501
9498
    
9502
9499
    if (tmp)
9503
9500
    {
9504
 
      session->change_item_tree(args + 1, tmp);
 
9501
      thd->change_item_tree(args + 1, tmp);
9505
9502
      func->update_used_tables();
9506
9503
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9507
9504
          && and_father != cond && !left_item->const_item())
9525
9522
    
9526
9523
    if (tmp)
9527
9524
    {
9528
 
      session->change_item_tree(args, tmp);
 
9525
      thd->change_item_tree(args, tmp);
9529
9526
      value= tmp;
9530
9527
      func->update_used_tables();
9531
9528
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9532
9529
          && and_father != cond && !right_item->const_item())
9533
9530
      {
9534
9531
        args[0]= args[1];                       // For easy check
9535
 
        session->change_item_tree(args + 1, value);
 
9532
        thd->change_item_tree(args + 1, value);
9536
9533
        cond->marker=1;
9537
9534
        COND_CMP *tmp2;
9538
9535
        if ((tmp2=new COND_CMP(and_father,func)))
9576
9573
}
9577
9574
 
9578
9575
static void
9579
 
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
 
9576
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
9580
9577
                         COND *and_father, COND *cond)
9581
9578
{
9582
9579
  if (cond->type() == Item::COND_ITEM)
9588
9585
    I_List<COND_CMP> save;
9589
9586
    while ((item=li++))
9590
9587
    {
9591
 
      propagate_cond_constants(session, &save,and_level ? cond : item, item);
 
9588
      propagate_cond_constants(thd, &save,and_level ? cond : item, item);
9592
9589
    }
9593
9590
    if (and_level)
9594
9591
    {                                           // Handle other found items
9598
9595
      {
9599
9596
        Item **args= cond_cmp->cmp_func->arguments();
9600
9597
        if (!args[0]->const_item())
9601
 
          change_cond_ref_to_const(session, &save,cond_cmp->and_level,
 
9598
          change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
9602
9599
                                   cond_cmp->and_level, args[0], args[1]);
9603
9600
      }
9604
9601
    }
9618
9615
      {
9619
9616
        if (right_const)
9620
9617
        {
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]);
9625
9622
        }
9626
9623
        else if (left_const)
9627
9624
        {
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]);
9632
9629
        }
9633
9630
      }
9800
9797
          assert(expr);
9801
9798
 
9802
9799
          table->on_expr= expr;
9803
 
          table->prep_on_expr= expr->copy_andor_structure(join->session);
 
9800
          table->prep_on_expr= expr->copy_andor_structure(join->thd);
9804
9801
        }
9805
9802
      }
9806
9803
      nested_join->used_tables= (table_map) 0;
9841
9838
          conds->top_level_item();
9842
9839
          /* conds is always a new item as both cond and on_expr existed */
9843
9840
          assert(!conds->fixed);
9844
 
          conds->fix_fields(join->session, &conds);
 
9841
          conds->fix_fields(join->thd, &conds);
9845
9842
        }
9846
9843
        else
9847
9844
          conds= table->on_expr; 
9948
9945
    First unused bit in nested_join_map after the call.
9949
9946
*/
9950
9947
 
9951
 
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, 
9952
 
                                          uint32_t first_unused)
 
9948
static uint build_bitmap_for_nested_joins(List<TableList> *join_list, 
 
9949
                                          uint first_unused)
9953
9950
{
9954
9951
  List_iterator<TableList> li(*join_list);
9955
9952
  TableList *table;
10220
10217
optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list,
10221
10218
              Item::cond_result *cond_value)
10222
10219
{
10223
 
  Session *session= join->session;
 
10220
  THD *thd= join->thd;
10224
10221
 
10225
10222
  if (!conds)
10226
10223
    *cond_value= Item::COND_TRUE;
10234
10231
      predicate. Substitute a constant instead of this field if the
10235
10232
      multiple equality contains a constant.
10236
10233
    */ 
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);
10239
10236
 
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);
10242
10239
    /*
10243
10240
      Remove all instances of item == item
10244
10241
      Remove all and-levels where CONST item != CONST item
10245
10242
    */
10246
 
    conds= remove_eq_conds(session, conds, cond_value) ;
 
10243
    conds= remove_eq_conds(thd, conds, cond_value) ;
10247
10244
  }
10248
10245
  return(conds);
10249
10246
}
10261
10258
*/
10262
10259
 
10263
10260
COND *
10264
 
remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value)
 
10261
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
10265
10262
{
10266
10263
  if (cond->type() == Item::COND_ITEM)
10267
10264
  {
10275
10272
    Item *item;
10276
10273
    while ((item=li++))
10277
10274
    {
10278
 
      Item *new_item=remove_eq_conds(session, item, &tmp_cond_value);
 
10275
      Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
10279
10276
      if (!new_item)
10280
10277
        li.remove();
10281
10278
      else if (item != new_item)
10282
10279
      {
10283
 
        li.replace(new_item);
 
10280
        VOID(li.replace(new_item));
10284
10281
        should_fix_fields=1;
10285
10282
      }
10286
10283
      if (*cond_value == Item::COND_UNDEF)
10340
10337
    {
10341
10338
      Field *field=((Item_field*) args[0])->field;
10342
10339
      if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
10343
 
          (session->options & OPTION_AUTO_IS_NULL) &&
10344
 
          (session->first_successful_insert_id_in_prev_stmt > 0 &&
10345
 
           session->substitute_null_with_insert_id))
 
10340
          (thd->options & OPTION_AUTO_IS_NULL) &&
 
10341
          (thd->first_successful_insert_id_in_prev_stmt > 0 &&
 
10342
           thd->substitute_null_with_insert_id))
10346
10343
      {
10347
10344
        COND *new_cond;
10348
10345
        if ((new_cond= new Item_func_eq(args[0],
10349
10346
                                        new Item_int("last_insert_id()",
10350
 
                                                     session->read_first_successful_insert_id_in_prev_stmt(),
 
10347
                                                     thd->read_first_successful_insert_id_in_prev_stmt(),
10351
10348
                                                     MY_INT64_NUM_DECIMAL_DIGITS))))
10352
10349
        {
10353
10350
          cond=new_cond;
10356
10353
            cond->fixed, also it do not need tables so we use 0 as second
10357
10354
            argument.
10358
10355
          */
10359
 
          cond->fix_fields(session, &cond);
 
10356
          cond->fix_fields(thd, &cond);
10360
10357
        }
10361
10358
        /*
10362
10359
          IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10363
10360
          clear for next row
10364
10361
        */
10365
 
        session->substitute_null_with_insert_id= false;
 
10362
        thd->substitute_null_with_insert_id= false;
10366
10363
      }
10367
10364
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10368
 
      else if (((field->type() == DRIZZLE_TYPE_DATE) ||
 
10365
      else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10369
10366
                (field->type() == DRIZZLE_TYPE_DATETIME)) &&
10370
10367
                (field->flags & NOT_NULL_FLAG) &&
10371
10368
               !field->table->maybe_null)
10379
10376
            cond->fixed, also it do not need tables so we use 0 as second
10380
10377
            argument.
10381
10378
          */
10382
 
          cond->fix_fields(session, &cond);
 
10379
          cond->fix_fields(thd, &cond);
10383
10380
        }
10384
10381
      }
10385
10382
    }
10605
10602
 
10606
10603
  if (table)
10607
10604
  {
10608
 
    table->file->extra(HA_EXTRA_WRITE_CACHE);
 
10605
    VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
10609
10606
    empty_record(table);
10610
10607
    if (table->group && join->tmp_table_param.sum_func_count &&
10611
10608
        table->s->keys && !table->file->inited)
10638
10635
        so we don't touch it here.
10639
10636
      */
10640
10637
      join->examined_rows++;
10641
 
      join->session->row_count++;
 
10638
      join->thd->row_count++;
10642
10639
      assert(join->examined_rows <= 1);
10643
10640
    }
10644
10641
    else if (join->send_row_on_empty_set())
10692
10689
    if (new_errno)
10693
10690
      table->file->print_error(new_errno,MYF(0));
10694
10691
  }
10695
 
  return(join->session->is_error() ? -1 : rc);
 
10692
  return(join->thd->is_error() ? -1 : rc);
10696
10693
}
10697
10694
 
10698
10695
 
10708
10705
      rc= sub_select(join,join_tab,end_of_records);
10709
10706
    return rc;
10710
10707
  }
10711
 
  if (join->session->killed)            // If aborted by user
 
10708
  if (join->thd->killed)                // If aborted by user
10712
10709
  {
10713
 
    join->session->send_kill_message();
 
10710
    join->thd->send_kill_message();
10714
10711
    return NESTED_LOOP_KILLED;                   /* purecov: inspected */
10715
10712
  }
10716
10713
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10888
10885
      /* Set first_unmatched for the last inner table of this group */
10889
10886
      join_tab->last_inner->first_unmatched= join_tab;
10890
10887
    }
10891
 
    join->session->row_count= 0;
 
10888
    join->thd->row_count= 0;
10892
10889
 
10893
10890
    error= (*join_tab->read_first_record)(join_tab);
10894
10891
    rc= evaluate_join_record(join, join_tab, error);
10928
10925
    0   The row combination is not a duplicate (continue)
10929
10926
*/
10930
10927
 
10931
 
int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl) 
 
10928
int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl) 
10932
10929
{
10933
10930
  int error;
10934
10931
  SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
10935
10932
  SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
10936
 
  unsigned char *ptr= sjtbl->tmp_table->record[0] + 1;
10937
 
  unsigned char *nulls_ptr= ptr;
 
10933
  uchar *ptr= sjtbl->tmp_table->record[0] + 1;
 
10934
  uchar *nulls_ptr= ptr;
10938
10935
  
10939
10936
  /* Put the the rowids tuple into table->record[0]: */
10940
10937
 
10941
10938
  // 1. Store the length 
10942
10939
  if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
10943
10940
  {
10944
 
    *ptr= (unsigned char)(sjtbl->rowid_len + sjtbl->null_bytes);
 
10941
    *ptr= (uchar)(sjtbl->rowid_len + sjtbl->null_bytes);
10945
10942
    ptr++;
10946
10943
  }
10947
10944
  else
10958
10955
  }
10959
10956
 
10960
10957
  // 3. Put the rowids
10961
 
  for (uint32_t i=0; tab != tab_end; tab++, i++)
 
10958
  for (uint i=0; tab != tab_end; tab++, i++)
10962
10959
  {
10963
10960
    handler *h= tab->join_tab->table->file;
10964
10961
    if (tab->join_tab->table->maybe_null && tab->join_tab->table->null_row)
10981
10978
  {
10982
10979
    /* create_myisam_from_heap will generate error if needed */
10983
10980
    if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10984
 
        create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo, 
 
10981
        create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo, 
10985
10982
                                &sjtbl->recinfo, error, 1))
10986
10983
      return -1;
10987
10984
    //return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11018
11015
  ha_rows found_records=join->found_records;
11019
11016
  COND *select_cond= join_tab->select_cond;
11020
11017
 
11021
 
  if (error > 0 || (join->session->is_error()))     // Fatal error
 
11018
  if (error > 0 || (join->thd->is_error()))     // Fatal error
11022
11019
    return NESTED_LOOP_ERROR;
11023
11020
  if (error < 0)
11024
11021
    return NESTED_LOOP_NO_MORE_ROWS;
11025
 
  if (join->session->killed)                    // Aborted by user
 
11022
  if (join->thd->killed)                        // Aborted by user
11026
11023
  {
11027
 
    join->session->send_kill_message();
 
11024
    join->thd->send_kill_message();
11028
11025
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
11029
11026
  }
11030
11027
  if (!select_cond || select_cond->val_int())
11087
11084
    join_tab->found_match= true;
11088
11085
    if (join_tab->check_weed_out_table)
11089
11086
    {
11090
 
      int res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table);
 
11087
      int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
11091
11088
      if (res == -1)
11092
11089
        return NESTED_LOOP_ERROR;
11093
11090
      if (res == 1)
11108
11105
      (See above join->return_tab= tab).
11109
11106
    */
11110
11107
    join->examined_rows++;
11111
 
    join->session->row_count++;
 
11108
    join->thd->row_count++;
11112
11109
 
11113
11110
    if (found)
11114
11111
    {
11140
11137
      with the beginning coinciding with the current partial join.
11141
11138
    */
11142
11139
    join->examined_rows++;
11143
 
    join->session->row_count++;
 
11140
    join->thd->row_count++;
11144
11141
    join_tab->read_record.file->unlock_row();
11145
11142
  }
11146
11143
  return NESTED_LOOP_OK;
11250
11247
  info= &join_tab->read_record;
11251
11248
  do
11252
11249
  {
11253
 
    if (join->session->killed)
 
11250
    if (join->thd->killed)
11254
11251
    {
11255
 
      join->session->send_kill_message();
 
11252
      join->thd->send_kill_message();
11256
11253
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11257
11254
    }
11258
11255
    SQL_SELECT *select=join_tab->select;
11259
11256
    if (rc == NESTED_LOOP_OK &&
11260
11257
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
11261
11258
    {
11262
 
      uint32_t i;
 
11259
      uint i;
11263
11260
      reset_cache_read(&join_tab->cache);
11264
11261
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
11265
11262
      {
11268
11265
        {
11269
11266
          int res= 0;
11270
11267
          if (!join_tab->check_weed_out_table || 
11271
 
              !(res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table)))
 
11268
              !(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
11272
11269
          {
11273
11270
            rc= (join_tab->next_select)(join,join_tab+1,0);
11274
11271
            if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11402
11399
      empty_record(table);                      // Make empty record
11403
11400
      return -1;
11404
11401
    }
11405
 
    update_virtual_fields_marked_for_write(table);
11406
11402
    store_record(table,record[1]);
11407
11403
  }
11408
11404
  else if (!table->status)                      // Only happens with left join
11433
11429
  if (table->status & STATUS_GARBAGE)           // If first read
11434
11430
  {
11435
11431
    table->status= 0;
11436
 
    if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11432
    if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11437
11433
      error=HA_ERR_KEY_NOT_FOUND;
11438
11434
    else
11439
11435
    {
11440
11436
      error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
11441
 
                                            (unsigned char*) tab->ref.key_buff,
 
11437
                                            (uchar*) tab->ref.key_buff,
11442
11438
                                            make_prev_keypart_map(tab->ref.key_parts),
11443
11439
                                            HA_READ_KEY_EXACT);
11444
11440
    }
11451
11447
        return table->report_error(error);
11452
11448
      return -1;
11453
11449
    }
11454
 
    update_virtual_fields_marked_for_write(table);
11455
11450
    store_record(table,record[1]);
11456
11451
  }
11457
11452
  else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
11543
11538
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11544
11539
 
11545
11540
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
11546
 
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
 
11541
  for (uint i= 0 ; i < tab->ref.key_parts ; i++)
11547
11542
  {
11548
11543
    if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
11549
11544
        return -1;
11550
11545
  }
11551
11546
 
11552
 
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11547
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11553
11548
    return -1;
11554
11549
  if ((error=table->file->index_read_map(table->record[0],
11555
11550
                                         tab->ref.key_buff,
11560
11555
      return table->report_error(error);
11561
11556
    return -1; /* purecov: inspected */
11562
11557
  }
11563
 
  update_virtual_fields_marked_for_write(table);
11564
11558
  return 0;
11565
11559
}
11566
11560
 
11578
11572
 
11579
11573
  if (!table->file->inited)
11580
11574
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11581
 
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11575
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11582
11576
    return -1;
11583
11577
  if ((error=table->file->index_read_last_map(table->record[0],
11584
11578
                                              tab->ref.key_buff,
11594
11588
 
11595
11589
        /* ARGSUSED */
11596
11590
static int
11597
 
join_no_more_records(READ_RECORD *)
 
11591
join_no_more_records(READ_RECORD *info __attribute__((unused)))
11598
11592
{
11599
11593
  return -1;
11600
11594
}
11647
11641
    table->status= STATUS_GARBAGE;
11648
11642
    return -1;
11649
11643
  }
11650
 
  update_virtual_fields_marked_for_write(table);
11651
11644
  return 0;
11652
11645
}
11653
11646
 
11667
11660
    table->status=STATUS_NOT_FOUND;
11668
11661
    error= -1;
11669
11662
  }
11670
 
  update_virtual_fields_marked_for_write(table);
11671
11663
  return error;
11672
11664
}
11673
11665
 
11695
11687
{
11696
11688
  delete tab->select->quick;
11697
11689
  tab->select->quick=0;
11698
 
  return tab->select->test_quick_select(tab->join->session, tab->keys,
 
11690
  return tab->select->test_quick_select(tab->join->thd, tab->keys,
11699
11691
                                        (table_map) 0, HA_POS_ERROR, 0,
11700
11692
                                        false);
11701
11693
}
11706
11698
{
11707
11699
  if (tab->select && tab->select->quick && tab->select->quick->reset())
11708
11700
    return 1;
11709
 
  init_read_record(&tab->read_record, tab->join->session, tab->table,
 
11701
  init_read_record(&tab->read_record, tab->join->thd, tab->table,
11710
11702
                   tab->select,1,1);
11711
11703
  return (*tab->read_record.read_record)(&tab->read_record);
11712
11704
}
11748
11740
      table->report_error(error);
11749
11741
    return -1;
11750
11742
  }
11751
 
  if (not error)
11752
 
    update_virtual_fields_marked_for_write(tab->table);
11753
11743
  return 0;
11754
11744
}
11755
11745
 
11769
11759
 
11770
11760
      if ((error=info->file->index_next(info->record)))
11771
11761
        return info->table->report_error(error);
11772
 
      if (not error)
11773
 
        update_virtual_fields_marked_for_write(tab->table);
 
11762
      
11774
11763
    } while (!key_cmp(tab->table->key_info[tab->index].key_part, 
11775
11764
                      tab->insideout_buf, key->key_length));
11776
11765
    tab->insideout_match_tab->found_match= 0;
11787
11776
  int error;
11788
11777
  if ((error=info->file->index_next(info->record)))
11789
11778
    return info->table->report_error(error);
11790
 
  if (not error)
11791
 
    update_virtual_fields_marked_for_write(info->table);
11792
11779
  return 0;
11793
11780
}
11794
11781
 
11814
11801
    table->file->ha_index_init(tab->index, 1);
11815
11802
  if ((error= tab->table->file->index_last(tab->table->record[0])))
11816
11803
    return table->report_error(error);
11817
 
  if (not error)
11818
 
    update_virtual_fields_marked_for_write(tab->table);
11819
11804
  return 0;
11820
11805
}
11821
11806
 
11826
11811
  int error;
11827
11812
  if ((error= info->file->index_prev(info->record)))
11828
11813
    return info->table->report_error(error);
11829
 
  if (not error)
11830
 
    update_virtual_fields_marked_for_write(info->table);
11831
11814
  return 0;
11832
11815
}
11833
11816
 
11894
11877
 
11895
11878
/* ARGSUSED */
11896
11879
static enum_nested_loop_state
11897
 
end_send(JOIN *join, JOIN_TAB *,
11898
 
         bool end_of_records)
 
11880
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
11881
         bool end_of_records)
11899
11882
{
11900
11883
  if (!end_of_records)
11901
11884
  {
11959
11942
}
11960
11943
 
11961
11944
 
11962
 
/* ARGSUSED */
 
11945
        /* ARGSUSED */
11963
11946
enum_nested_loop_state
11964
 
end_send_group(JOIN *join, JOIN_TAB *, bool end_of_records)
 
11947
end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
11948
               bool end_of_records)
11965
11949
{
11966
11950
  int idx= -1;
11967
11951
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
11969
11953
  if (!join->first_record || end_of_records ||
11970
11954
      (idx=test_if_item_cache_changed(join->group_fields)) >= 0)
11971
11955
  {
11972
 
    if (join->first_record ||
 
11956
    if (join->first_record || 
11973
11957
        (end_of_records && !join->group && !join->group_optimized_away))
11974
11958
    {
11975
11959
      if (idx < (int) join->send_group_parts)
12031
12015
      if (end_of_records)
12032
12016
        return(NESTED_LOOP_OK);
12033
12017
      join->first_record=1;
12034
 
      test_if_item_cache_changed(join->group_fields);
 
12018
      VOID(test_if_item_cache_changed(join->group_fields));
12035
12019
    }
12036
12020
    if (idx < (int) join->send_group_parts)
12037
12021
    {
12051
12035
}
12052
12036
 
12053
12037
 
12054
 
/* ARGSUSED */
 
12038
        /* ARGSUSED */
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)
12058
12042
{
12059
12043
  Table *table=join->tmp_table;
12060
12044
 
12061
 
  if (join->session->killed)                    // Aborted by user
 
12045
  if (join->thd->killed)                        // Aborted by user
12062
12046
  {
12063
 
    join->session->send_kill_message();
 
12047
    join->thd->send_kill_message();
12064
12048
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12065
12049
  }
12066
12050
  if (!end_of_records)
12067
12051
  {
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
 
12056
    {
 
12057
      /* Copy null values from group to row */
 
12058
      order_st   *group;
 
12059
      for (group=table->group ; group ; group=group->next)
 
12060
      {
 
12061
        Item *item= *group->item;
 
12062
        if (item->maybe_null)
 
12063
        {
 
12064
          Field *field=item->get_tmp_table_field();
 
12065
          field->ptr[-1]= (uchar) (field->is_null() ? 1 : 0);
 
12066
        }
 
12067
      }
 
12068
    }
 
12069
#endif
12070
12070
    if (!join->having || join->having->val_int())
12071
12071
    {
12072
12072
      int error;
12075
12075
      {
12076
12076
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12077
12077
          goto end;
12078
 
        if (create_myisam_from_heap(join->session, table,
 
12078
        if (create_myisam_from_heap(join->thd, table,
12079
12079
                                    join->tmp_table_param.start_recinfo,
12080
12080
                                    &join->tmp_table_param.recinfo,
12081
12081
                                    error, 1))
12101
12101
/** Group by searching after group record and updating it if possible. */
12102
12102
 
12103
12103
static enum_nested_loop_state
12104
 
end_update(JOIN *join, JOIN_TAB *,
12105
 
           bool end_of_records)
 
12104
end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12105
           bool end_of_records)
12106
12106
{
12107
12107
  Table *table=join->tmp_table;
12108
12108
  order_st   *group;
12110
12110
 
12111
12111
  if (end_of_records)
12112
12112
    return(NESTED_LOOP_OK);
12113
 
  if (join->session->killed)                    // Aborted by user
 
12113
  if (join->thd->killed)                        // Aborted by user
12114
12114
  {
12115
 
    join->session->send_kill_message();
 
12115
    join->thd->send_kill_message();
12116
12116
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12117
12117
  }
12118
12118
 
12160
12160
  copy_funcs(join->tmp_table_param.items_to_copy);
12161
12161
  if ((error=table->file->ha_write_row(table->record[0])))
12162
12162
  {
12163
 
    if (create_myisam_from_heap(join->session, table,
 
12163
    if (create_myisam_from_heap(join->thd, table,
12164
12164
                                join->tmp_table_param.start_recinfo,
12165
12165
                                &join->tmp_table_param.recinfo,
12166
12166
                                error, 0))
12177
12177
/** Like end_update, but this is done with unique constraints instead of keys.  */
12178
12178
 
12179
12179
static enum_nested_loop_state
12180
 
end_unique_update(JOIN *join, JOIN_TAB *,
12181
 
                  bool end_of_records)
 
12180
end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12181
                  bool end_of_records)
12182
12182
{
12183
12183
  Table *table=join->tmp_table;
12184
12184
  int     error;
12185
12185
 
12186
12186
  if (end_of_records)
12187
12187
    return(NESTED_LOOP_OK);
12188
 
  if (join->session->killed)                    // Aborted by user
 
12188
  if (join->thd->killed)                        // Aborted by user
12189
12189
  {
12190
 
    join->session->send_kill_message();
 
12190
    join->thd->send_kill_message();
12191
12191
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12192
12192
  }
12193
12193
 
12222
12222
}
12223
12223
 
12224
12224
 
12225
 
/* ARGSUSED */
 
12225
        /* ARGSUSED */
12226
12226
enum_nested_loop_state
12227
 
end_write_group(JOIN *join, JOIN_TAB *,
12228
 
                bool end_of_records)
 
12227
end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12228
                bool end_of_records)
12229
12229
{
12230
12230
  Table *table=join->tmp_table;
12231
12231
  int     idx= -1;
12232
12232
 
12233
 
  if (join->session->killed)
 
12233
  if (join->thd->killed)
12234
12234
  {                                             // Aborted by user
12235
 
    join->session->send_kill_message();
 
12235
    join->thd->send_kill_message();
12236
12236
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12237
12237
  }
12238
12238
  if (!join->first_record || end_of_records ||
12253
12253
        if (!join->having || join->having->val_int())
12254
12254
        {
12255
12255
          int error= table->file->ha_write_row(table->record[0]);
12256
 
          if (error && create_myisam_from_heap(join->session, table,
 
12256
          if (error && create_myisam_from_heap(join->thd, table,
12257
12257
                                               join->tmp_table_param.start_recinfo,
12258
12258
                                                &join->tmp_table_param.recinfo,
12259
12259
                                               error, 0))
12273
12273
      if (end_of_records)
12274
12274
        return(NESTED_LOOP_OK);
12275
12275
      join->first_record=1;
12276
 
      test_if_item_cache_changed(join->group_fields);
 
12276
      VOID(test_if_item_cache_changed(join->group_fields));
12277
12277
    }
12278
12278
    if (idx < (int) join->send_group_parts)
12279
12279
    {
12357
12357
   @param join The top-level query.
12358
12358
   @param old_cond The expression to be replaced.
12359
12359
   @param new_cond The expression to be substituted.
12360
 
   @param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
 
12360
   @param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
12361
12361
   the new expression.
12362
12362
   @return <code>true</code> if there was an error, <code>false</code> if
12363
12363
   successful.
12368
12368
  if (join->conds == old_cond) {
12369
12369
    join->conds= new_cond;
12370
12370
    if (do_fix_fields)
12371
 
      new_cond->fix_fields(join->session, &join->conds);
 
12371
      new_cond->fix_fields(join->thd, &join->conds);
12372
12372
    return false;
12373
12373
  }
12374
12374
  
12380
12380
      {
12381
12381
        li.replace(new_cond);
12382
12382
        if (do_fix_fields)
12383
 
          new_cond->fix_fields(join->session, li.ref());
 
12383
          new_cond->fix_fields(join->thd, li.ref());
12384
12384
        return false;
12385
12385
      }
12386
12386
  }
12540
12540
  if (!table->reginfo.join_tab)
12541
12541
    return (Item*) 0;             // field from outer non-select (UPDATE,...)
12542
12542
 
12543
 
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
 
12543
  uint ref_parts=table->reginfo.join_tab->ref.key_parts;
12544
12544
  if (ref_parts)
12545
12545
  {
12546
12546
    KEY_PART_INFO *key_part=
12547
12547
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
12548
 
    uint32_t part;
 
12548
    uint part;
12549
12549
 
12550
12550
    for (part=0 ; part < ref_parts ; part++)
12551
12551
    {
12693
12693
*/
12694
12694
 
12695
12695
static uint
12696
 
test_if_subkey(order_st *order, Table *table, uint32_t ref, uint32_t ref_key_parts,
 
12696
test_if_subkey(order_st *order, Table *table, uint ref, uint ref_key_parts,
12697
12697
               const key_map *usable_keys)
12698
12698
{
12699
12699
  uint32_t nr;
12756
12756
list_contains_unique_index(Table *table,
12757
12757
                          bool (*find_func) (Field *, void *), void *data)
12758
12758
{
12759
 
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
 
12759
  for (uint keynr= 0; keynr < table->s->keys; keynr++)
12760
12760
  {
12761
12761
    if (keynr == table->s->primary_key ||
12762
12762
         (table->key_info[keynr].flags & HA_NOSAME))
12880
12880
                        bool no_changes, const key_map *map)
12881
12881
{
12882
12882
  int32_t ref_key;
12883
 
  uint32_t ref_key_parts;
 
12883
  uint ref_key_parts;
12884
12884
  int order_direction;
12885
12885
  uint32_t used_key_parts;
12886
12886
  Table *table=tab->table;
12944
12944
      /*
12945
12945
        We come here when ref_key is not among usable_keys
12946
12946
      */
12947
 
      uint32_t new_ref_key;
 
12947
      uint new_ref_key;
12948
12948
      /*
12949
12949
        If using index only read, only consider other possible index only
12950
12950
        keys
12989
12989
          new_ref_key_map.clear_all();  // Force the creation of quick select
12990
12990
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12991
12991
 
12992
 
          if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
 
12992
          if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
12993
12993
                                        (tab->join->select_options &
12994
12994
                                         OPTION_FOUND_ROWS) ?
12995
12995
                                        HA_POS_ERROR :
13014
13014
      or a table scan.
13015
13015
      It may be the case if order_st/GROUP BY is used with LIMIT.
13016
13016
    */
13017
 
    uint32_t nr;
 
13017
    uint nr;
13018
13018
    key_map keys;
13019
 
    uint32_t best_key_parts= 0;
 
13019
    uint best_key_parts= 0;
13020
13020
    int best_key_direction= 0;
13021
13021
    ha_rows best_records= 0;
13022
13022
    double read_time;
13024
13024
    bool is_best_covering= false;
13025
13025
    double fanout= 1;
13026
13026
    JOIN *join= tab->join;
13027
 
    uint32_t tablenr= tab - join->join_tab;
 
13027
    uint tablenr= tab - join->join_tab;
13028
13028
    ha_rows table_records= table->file->stats.records;
13029
13029
    bool group= join->group && order == join->group_list;
13030
13030
 
13058
13058
      keys= usable_keys;
13059
13059
 
13060
13060
    read_time= join->best_positions[tablenr].read_time;
13061
 
    for (uint32_t i= tablenr+1; i < join->tables; i++)
 
13061
    for (uint i= tablenr+1; i < join->tables; i++)
13062
13062
      fanout*= join->best_positions[i].records_read; // fanout is always >= 1
13063
13063
 
13064
13064
    for (nr=0; nr < table->s->keys ; nr++)
13143
13143
            index entry.
13144
13144
          */
13145
13145
          index_scan_time= select_limit/rec_per_key *
13146
 
                           cmin(rec_per_key, table->file->scan_time());
 
13146
                           min(rec_per_key, table->file->scan_time());
13147
13147
          if (is_covering || (ref_key < 0 && (group || table->force_index)) ||
13148
13148
              index_scan_time < read_time)
13149
13149
          {
13153
13153
            if (table->quick_keys.is_set(nr))
13154
13154
              quick_records= table->quick_rows[nr];
13155
13155
            if (best_key < 0 ||
13156
 
                (select_limit <= cmin(quick_records,best_records) ?
 
13156
                (select_limit <= min(quick_records,best_records) ?
13157
13157
                 keyinfo->key_parts < best_key_parts :
13158
13158
                 quick_records < best_records))
13159
13159
            {
13176
13176
        map.clear_all();       // Force the creation of quick select
13177
13177
        map.set_bit(best_key); // only best_key.
13178
13178
        quick_created=         
13179
 
          select->test_quick_select(join->session, map, 0,
 
13179
          select->test_quick_select(join->thd, map, 0,
13180
13180
                                    join->select_options & OPTION_FOUND_ROWS ?
13181
13181
                                    HA_POS_ERROR :
13182
13182
                                    join->unit->select_limit_cnt,
13295
13295
 
13296
13296
  SYNOPSIS
13297
13297
   create_sort_index()
13298
 
     session            Thread handler
 
13298
     thd                Thread handler
13299
13299
     tab                Table to sort (in join structure)
13300
13300
     order              How table should be sorted
13301
13301
     filesort_limit     Max number of rows that needs to be sorted
13320
13320
*/
13321
13321
 
13322
13322
static int
13323
 
create_sort_index(Session *session, JOIN *join, order_st *order,
 
13323
create_sort_index(THD *thd, JOIN *join, order_st *order,
13324
13324
                  ha_rows filesort_limit, ha_rows select_limit,
13325
13325
                  bool is_order_by)
13326
13326
{
13327
 
  uint32_t length= 0;
 
13327
  uint length= 0;
13328
13328
  ha_rows examined_rows;
13329
13329
  Table *table;
13330
13330
  SQL_SELECT *select;
13384
13384
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13385
13385
        field, quick will contain an empty record set.
13386
13386
      */
13387
 
      if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref, 
 
13387
      if (!(select->quick= (get_quick_select_for_ref(thd, table, &tab->ref, 
13388
13388
                                                     tab->found_records))))
13389
13389
        goto err;
13390
13390
    }
13397
13397
 
13398
13398
  if (table->s->tmp_table)
13399
13399
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
13400
 
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
13400
  table->sort.found_records=filesort(thd, table,join->sortorder, length,
13401
13401
                                     select, filesort_limit, 0,
13402
13402
                                     &examined_rows);
13403
13403
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
13447
13447
remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
13448
13448
{
13449
13449
  int error;
13450
 
  uint32_t reclength,offset;
13451
 
  uint32_t field_count;
13452
 
  Session *session= join->session;
 
13450
  ulong reclength,offset;
 
13451
  uint field_count;
 
13452
  THD *thd= join->thd;
13453
13453
 
13454
13454
  entry->reginfo.lock_type=TL_WRITE;
13455
13455
 
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;
13476
13476
 
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);
13486
13486
  else
13487
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
13487
    error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13488
13488
                                  having);
13489
13489
 
13490
13490
  free_blobs(first_field);
13492
13492
}
13493
13493
 
13494
13494
 
13495
 
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13496
 
                                   uint32_t offset, Item *having)
 
13495
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
 
13496
                                   ulong offset, Item *having)
13497
13497
{
13498
13498
  handler *file=table->file;
13499
13499
  char *org_record,*new_record;
13500
 
  unsigned char *record;
 
13500
  uchar *record;
13501
13501
  int error;
13502
 
  uint32_t reclength= table->s->reclength-offset;
 
13502
  ulong reclength= table->s->reclength-offset;
13503
13503
 
13504
13504
  org_record=(char*) (record=table->record[0])+offset;
13505
13505
  new_record=(char*) table->record[1]+offset;
13508
13508
  error=file->rnd_next(record);
13509
13509
  for (;;)
13510
13510
  {
13511
 
    if (session->killed)
 
13511
    if (thd->killed)
13512
13512
    {
13513
 
      session->send_kill_message();
 
13513
      thd->send_kill_message();
13514
13514
      error=0;
13515
13515
      goto err;
13516
13516
    }
13583
13583
    Note that this will not work on tables with blobs!
13584
13584
*/
13585
13585
 
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,
 
13587
                                      uint field_count,
13588
13588
                                      Field **first_field,
13589
 
                                      uint32_t key_length,
 
13589
                                      ulong key_length,
13590
13590
                                      Item *having)
13591
13591
{
13592
 
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
 
13592
  uchar *key_buffer, *key_pos, *record=table->record[0];
13593
13593
  int error;
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;
13597
13597
  HASH hash;
13598
13598
 
13599
13599
  if (!my_multi_malloc(MYF(MY_WME),
13602
13602
                               (long) file->stats.records),
13603
13603
                       &field_lengths,
13604
13604
                       (uint) (field_count*sizeof(*field_lengths)),
13605
 
                       NULL))
 
13605
                       NullS))
13606
13606
    return(1);
13607
13607
 
13608
13608
  {
13609
13609
    Field **ptr;
13610
 
    uint32_t total_length= 0;
 
13610
    ulong total_length= 0;
13611
13611
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
13612
13612
    {
13613
 
      uint32_t length= (*ptr)->sort_length();
 
13613
      uint length= (*ptr)->sort_length();
13614
13614
      (*field_length++)= length;
13615
13615
      total_length+= length;
13616
13616
    }
13622
13622
  if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0, 
13623
13623
                key_length, (hash_get_key) 0, 0, 0))
13624
13624
  {
13625
 
    free((char*) key_buffer);
 
13625
    my_free((char*) key_buffer,MYF(0));
13626
13626
    return(1);
13627
13627
  }
13628
13628
 
13630
13630
  key_pos=key_buffer;
13631
13631
  for (;;)
13632
13632
  {
13633
 
    unsigned char *org_key_pos;
13634
 
    if (session->killed)
 
13633
    uchar *org_key_pos;
 
13634
    if (thd->killed)
13635
13635
    {
13636
 
      session->send_kill_message();
 
13636
      thd->send_kill_message();
13637
13637
      error=0;
13638
13638
      goto err;
13639
13639
    }
13671
13671
      (void) my_hash_insert(&hash, org_key_pos);
13672
13672
    key_pos+=extra_length;
13673
13673
  }
13674
 
  free((char*) key_buffer);
 
13674
  my_free((char*) key_buffer,MYF(0));
13675
13675
  hash_free(&hash);
13676
13676
  file->extra(HA_EXTRA_NO_CACHE);
13677
13677
  (void) file->ha_rnd_end();
13678
13678
  return(0);
13679
13679
 
13680
13680
err:
13681
 
  free((char*) key_buffer);
 
13681
  my_free((char*) key_buffer,MYF(0));
13682
13682
  hash_free(&hash);
13683
13683
  file->extra(HA_EXTRA_NO_CACHE);
13684
13684
  (void) file->ha_rnd_end();
13688
13688
}
13689
13689
 
13690
13690
 
13691
 
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length,
 
13691
SORT_FIELD *make_unireg_sortorder(order_st *order, uint *length,
13692
13692
                                  SORT_FIELD *sortorder)
13693
13693
{
13694
 
  uint32_t count;
 
13694
  uint count;
13695
13695
  SORT_FIELD *sort,*pos;
13696
13696
 
13697
13697
  count=0;
13699
13699
    count++;
13700
13700
  if (!sortorder)
13701
13701
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
13702
 
                                       (cmax(count, *length) + 1));
 
13702
                                       (max(count, *length) + 1));
13703
13703
  pos= sort= sortorder;
13704
13704
 
13705
13705
  if (!pos)
13734
13734
******************************************************************************/
13735
13735
 
13736
13736
static int
13737
 
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
 
13737
join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
13738
13738
{
13739
13739
  register unsigned int i;
13740
13740
  unsigned int length, blobs;
13750
13750
  for (i=0 ; i < table_count ; i++,join_tab++)
13751
13751
  {
13752
13752
    if (!join_tab->used_fieldlength)            /* Not calced yet */
13753
 
      calc_used_field_length(session, join_tab);
 
13753
      calc_used_field_length(thd, join_tab);
13754
13754
    cache->fields+=join_tab->used_fields;
13755
13755
    blobs+=join_tab->used_blobs;
13756
13756
 
13766
13766
 
13767
13767
                  sizeof(CACHE_FIELD*))))
13768
13768
  {
13769
 
    free((unsigned char*) cache->buff);         /* purecov: inspected */
 
13769
    my_free((uchar*) cache->buff,MYF(0));               /* purecov: inspected */
13770
13770
    cache->buff=0;                              /* purecov: inspected */
13771
13771
    return(1);                          /* purecov: inspected */
13772
13772
  }
13777
13777
  length=0;
13778
13778
  for (i=0 ; i < table_count ; i++)
13779
13779
  {
13780
 
    uint32_t null_fields=0, used_fields;
 
13780
    uint null_fields=0, used_fields;
13781
13781
    Field **f_ptr,*field;
13782
13782
    MY_BITMAP *read_set= tables[i].table->read_set;
13783
13783
    for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
13812
13812
    /* If outer join table, copy null_row flag */
13813
13813
    if (tables[i].table->maybe_null)
13814
13814
    {
13815
 
      copy->str= (unsigned char*) &tables[i].table->null_row;
 
13815
      copy->str= (uchar*) &tables[i].table->null_row;
13816
13816
      copy->length=sizeof(tables[i].table->null_row);
13817
13817
      copy->strip=0;
13818
13818
      copy->blob_field=0;
13843
13843
  cache->length=length+blobs*sizeof(char*);
13844
13844
  cache->blobs=blobs;
13845
13845
  *blob_ptr=0;                                  /* End sequentel */
13846
 
  size=cmax(session->variables.join_buff_size, (uint32_t)cache->length);
13847
 
  if (!(cache->buff=(unsigned char*) my_malloc(size,MYF(0))))
 
13846
  size=max(thd->variables.join_buff_size, (ulong)cache->length);
 
13847
  if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
13848
13848
    return(1);                          /* Don't use cache */ /* purecov: inspected */
13849
13849
  cache->end=cache->buff+size;
13850
13850
  reset_cache_write(cache);
13852
13852
}
13853
13853
 
13854
13854
 
13855
 
static uint32_t used_blob_length(CACHE_FIELD **ptr)
 
13855
static ulong
 
13856
used_blob_length(CACHE_FIELD **ptr)
13856
13857
{
13857
 
  uint32_t length,blob_length;
 
13858
  uint length,blob_length;
13858
13859
  for (length=0 ; *ptr ; ptr++)
13859
13860
  {
13860
13861
    (*ptr)->blob_length=blob_length=(*ptr)->blob_field->get_length();
13868
13869
static bool
13869
13870
store_record_in_cache(JOIN_CACHE *cache)
13870
13871
{
13871
 
  uint32_t length;
13872
 
  unsigned char *pos;
 
13872
  uint length;
 
13873
  uchar *pos;
13873
13874
  CACHE_FIELD *copy,*end_field;
13874
13875
  bool last_record;
13875
13876
 
13878
13879
 
13879
13880
  length=cache->length;
13880
13881
  if (cache->blobs)
13881
 
    length+= used_blob_length(cache->blob_ptr);
 
13882
    length+=used_blob_length(cache->blob_ptr);
13882
13883
  if ((last_record= (length + cache->length > (size_t) (cache->end - pos))))
13883
13884
    cache->ptr_record=cache->records;
13884
13885
  /*
13911
13912
 
13912
13913
      if (copy->strip)
13913
13914
      {
13914
 
        unsigned char *str,*end;
 
13915
        uchar *str,*end;
13915
13916
        for (str=copy->str,end= str+copy->length;
13916
13917
             end > str && end[-1] == ' ' ;
13917
13918
             end--) ;
13951
13952
static void
13952
13953
read_cached_record(JOIN_TAB *tab)
13953
13954
{
13954
 
  unsigned char *pos;
13955
 
  uint32_t length;
 
13955
  uchar *pos;
 
13956
  uint length;
13956
13957
  bool last_record;
13957
13958
  CACHE_FIELD *copy,*end_field;
13958
13959
 
14030
14031
  }
14031
14032
  else 
14032
14033
    no_prev_key= true;
14033
 
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->session, &tab->ref)) ||
 
14034
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) ||
14034
14035
      no_prev_key)
14035
14036
    return 1;
14036
14037
  return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
14039
14040
 
14040
14041
 
14041
14042
bool
14042
 
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
 
14043
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
14043
14044
{
14044
 
  enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
14045
 
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
14045
  enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
 
14046
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
14046
14047
  bool result= 0;
14047
14048
 
14048
14049
  for (store_key **copy=ref->key_copy ; *copy ; copy++)
14053
14054
      break;
14054
14055
    }
14055
14056
  }
14056
 
  session->count_cuted_fields= save_count_cuted_fields;
 
14057
  thd->count_cuted_fields= save_count_cuted_fields;
14057
14058
  return result;
14058
14059
}
14059
14060
 
14078
14079
 
14079
14080
  ref_pointer_array and all_fields are updated.
14080
14081
 
14081
 
  @param[in] session                 Pointer to current thread structure
 
14082
  @param[in] thd                     Pointer to current thread structure
14082
14083
  @param[in,out] ref_pointer_array  All select, group and order by fields
14083
14084
  @param[in] tables                 List of tables to search in (usually
14084
14085
    FROM clause)
14096
14097
*/
14097
14098
 
14098
14099
static bool
14099
 
find_order_in_list(Session *session, Item **ref_pointer_array, TableList *tables,
 
14100
find_order_in_list(THD *thd, Item **ref_pointer_array, TableList *tables,
14100
14101
                   order_st *order, List<Item> &fields, List<Item> &all_fields,
14101
14102
                   bool is_group_field)
14102
14103
{
14104
14105
  Item::Type order_item_type;
14105
14106
  Item **select_item; /* The corresponding item from the SELECT clause. */
14106
14107
  Field *from_field;  /* The corresponding field from the FROM clause. */
14107
 
  uint32_t counter;
 
14108
  uint counter;
14108
14109
  enum_resolution_type resolution;
14109
14110
 
14110
14111
  /*
14113
14114
  */
14114
14115
  if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
14115
14116
  {                                             /* Order by position */
14116
 
    uint32_t count= (uint) order_item->val_int();
 
14117
    uint count= (uint) order_item->val_int();
14117
14118
    if (!count || count > fields.elements)
14118
14119
    {
14119
14120
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
14120
 
               order_item->full_name(), session->where);
 
14121
               order_item->full_name(), thd->where);
14121
14122
      return true;
14122
14123
    }
14123
14124
    order->item= ref_pointer_array + count - 1;
14143
14144
      for this name (in case if we would perform lookup in all tables).
14144
14145
    */
14145
14146
    if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14146
 
        order_item->fix_fields(session, order->item))
 
14147
        order_item->fix_fields(thd, order->item))
14147
14148
      return true;
14148
14149
 
14149
14150
    /* Lookup the current GROUP field in the FROM clause. */
14152
14153
    if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14153
14154
        order_item_type == Item::REF_ITEM)
14154
14155
    {
14155
 
      from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
 
14156
      from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
14156
14157
                                       NULL, &view_ref, IGNORE_ERRORS, true,
14157
14158
                                       false);
14158
14159
      if (!from_field)
14192
14193
        warning so the user knows that the field from the FROM clause
14193
14194
        overshadows the column reference from the SELECT list.
14194
14195
      */
14195
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
 
14196
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14196
14197
                          ER(ER_NON_UNIQ_ERROR),
14197
14198
                          ((Item_ident*) order_item)->field_name,
14198
 
                          current_session->where);
 
14199
                          current_thd->where);
14199
14200
    }
14200
14201
  }
14201
14202
 
14212
14213
    arguments for which fix_fields already was called.
14213
14214
  */
14214
14215
  if (!order_item->fixed &&
14215
 
      (order_item->fix_fields(session, order->item) ||
 
14216
      (order_item->fix_fields(thd, order->item) ||
14216
14217
       (order_item= *order->item)->check_cols(1) ||
14217
 
       session->is_fatal_error))
 
14218
       thd->is_fatal_error))
14218
14219
    return true; /* Wrong field. */
14219
14220
 
14220
 
  uint32_t el= all_fields.elements;
 
14221
  uint el= all_fields.elements;
14221
14222
  all_fields.push_front(order_item); /* Add new field to field list. */
14222
14223
  ref_pointer_array[el]= order_item;
14223
14224
  order->item= ref_pointer_array + el;
14232
14233
  the field list.
14233
14234
*/
14234
14235
 
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)
14237
14238
{
14238
 
  session->where="order clause";
 
14239
  thd->where="order clause";
14239
14240
  for (; order; order=order->next)
14240
14241
  {
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))
14243
14244
      return 1;
14244
14245
  }
14249
14250
/**
14250
14251
  Intitialize the GROUP BY list.
14251
14252
 
14252
 
  @param session                        Thread handler
 
14253
  @param thd                    Thread handler
14253
14254
  @param ref_pointer_array      We store references to all fields that was
14254
14255
                               not in 'fields' here.
14255
14256
  @param fields         All fields in the select part. Any item in
14273
14274
*/
14274
14275
 
14275
14276
int
14276
 
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
 
14277
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
14277
14278
            List<Item> &fields, List<Item> &all_fields, order_st *order,
14278
14279
            bool *hidden_group_fields)
14279
14280
{
14283
14284
  if (!order)
14284
14285
    return 0;                           /* Everything is ok */
14285
14286
 
14286
 
  uint32_t org_fields=all_fields.elements;
 
14287
  uint org_fields=all_fields.elements;
14287
14288
 
14288
 
  session->where="group statement";
 
14289
  thd->where="group statement";
14289
14290
  for (ord= order; ord; ord= ord->next)
14290
14291
  {
14291
 
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
 
14292
    if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
14292
14293
                           all_fields, true))
14293
14294
      return 1;
14294
14295
    (*ord->item)->marker= UNDEF_POS;            /* Mark found */
14319
14320
    Item_field *field;
14320
14321
    int cur_pos_in_select_list= 0;
14321
14322
    List_iterator<Item> li(fields);
14322
 
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
 
14323
    List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
14323
14324
 
14324
14325
    field= naf_it++;
14325
14326
    while (field && (item=li++))
14370
14371
*/
14371
14372
 
14372
14373
static order_st *
14373
 
create_distinct_group(Session *session, Item **ref_pointer_array,
 
14374
create_distinct_group(THD *thd, Item **ref_pointer_array,
14374
14375
                      order_st *order_list, List<Item> &fields,
14375
 
                      List<Item> &, bool *all_order_by_fields_used)
 
14376
                      List<Item> &all_fields __attribute__((unused)),
 
14377
                      bool *all_order_by_fields_used)
14376
14378
{
14377
14379
  List_iterator<Item> li(fields);
14378
14380
  Item *item;
14387
14389
  {
14388
14390
    if (order->in_field_list)
14389
14391
    {
14390
 
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
 
14392
      order_st *ord=(order_st*) thd->memdup((char*) order,sizeof(order_st));
14391
14393
      if (!ord)
14392
14394
        return 0;
14393
14395
      *prev=ord;
14412
14414
        if ((*ord_iter->item)->eq(item, 1))
14413
14415
          goto next_item;
14414
14416
      
14415
 
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
 
14417
      order_st *ord=(order_st*) thd->calloc(sizeof(order_st));
14416
14418
      if (!ord)
14417
14419
        return 0;
14418
14420
 
14465
14467
            param->quick_group=0;                       // UDF SUM function
14466
14468
          param->sum_func_count++;
14467
14469
 
14468
 
          for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
 
14470
          for (uint i=0 ; i < sum_item->arg_count ; i++)
14469
14471
          {
14470
14472
            if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
14471
14473
              param->field_count++;
14544
14546
static void
14545
14547
calc_group_buffer(JOIN *join,order_st *group)
14546
14548
{
14547
 
  uint32_t key_length=0, parts=0, null_parts=0;
 
14549
  uint key_length=0, parts=0, null_parts=0;
14548
14550
 
14549
14551
  if (group)
14550
14552
    join->group= 1;
14585
14587
          by 8 as maximum pack length of such fields.
14586
14588
        */
14587
14589
        if (type == DRIZZLE_TYPE_TIME ||
14588
 
            type == DRIZZLE_TYPE_DATE ||
 
14590
            type == DRIZZLE_TYPE_NEWDATE ||
14589
14591
            type == DRIZZLE_TYPE_DATETIME ||
14590
14592
            type == DRIZZLE_TYPE_TIMESTAMP)
14591
14593
        {
14662
14664
  {
14663
14665
    for (; group ; group=group->next)
14664
14666
    {
14665
 
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
 
14667
      Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
14666
14668
      if (!tmp || join->group_fields.push_front(tmp))
14667
14669
        return true;
14668
14670
    }
14709
14711
  Change old item_field to use a new field with points at saved fieldvalue
14710
14712
  This function is only called before use of send_fields.
14711
14713
 
14712
 
  @param session                   Session pointer
 
14714
  @param thd                   THD pointer
14713
14715
  @param param                 temporary table parameters
14714
14716
  @param ref_pointer_array     array of pointers to top elements of filed list
14715
14717
  @param res_selected_fields   new list of items of select item list
14730
14732
*/
14731
14733
 
14732
14734
bool
14733
 
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
 
14735
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
14734
14736
                  Item **ref_pointer_array,
14735
14737
                  List<Item> &res_selected_fields, List<Item> &res_all_fields,
14736
 
                  uint32_t elements, List<Item> &all_fields)
 
14738
                  uint elements, List<Item> &all_fields)
14737
14739
{
14738
14740
  Item *pos;
14739
14741
  List_iterator_fast<Item> li(all_fields);
14742
14744
  res_all_fields.empty();
14743
14745
  List_iterator_fast<Item> itr(res_all_fields);
14744
14746
  List<Item> extra_funcs;
14745
 
  uint32_t i, border= all_fields.elements - elements;
 
14747
  uint i, border= all_fields.elements - elements;
14746
14748
 
14747
14749
  if (param->field_count && 
14748
14750
      !(copy=param->copy_field= new Copy_field[param->field_count]))
14752
14754
  for (i= 0; (pos= li++); i++)
14753
14755
  {
14754
14756
    Field *field;
14755
 
    unsigned char *tmp;
 
14757
    uchar *tmp;
14756
14758
    Item *real_pos= pos->real_item();
14757
14759
    if (real_pos->type() == Item::FIELD_ITEM)
14758
14760
    {
14759
14761
      Item_field *item;
14760
 
      if (!(item= new Item_field(session, ((Item_field*) real_pos))))
 
14762
      if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
14761
14763
        goto err;
14762
14764
      if (pos->type() == Item::REF_ITEM)
14763
14765
      {
14791
14793
           saved value
14792
14794
        */
14793
14795
        field= item->field;
14794
 
        item->result_field=field->new_field(session->mem_root,field->table, 1);
 
14796
        item->result_field=field->new_field(thd->mem_root,field->table, 1);
14795
14797
        /*
14796
14798
          We need to allocate one extra byte for null handling and
14797
14799
          another extra byte to not get warnings from purify in
14798
14800
          Field_varstring::val_int
14799
14801
        */
14800
 
        if (!(tmp= (unsigned char*) sql_alloc(field->pack_length()+2)))
 
14802
        if (!(tmp= (uchar*) sql_alloc(field->pack_length()+2)))
14801
14803
          goto err;
14802
14804
        if (copy)
14803
14805
        {
14894
14896
 
14895
14897
bool JOIN::alloc_func_list()
14896
14898
{
14897
 
  uint32_t func_count, group_parts;
 
14899
  uint func_count, group_parts;
14898
14900
 
14899
14901
  func_count= tmp_table_param.sum_func_count;
14900
14902
  /*
14925
14927
  }
14926
14928
 
14927
14929
  /* This must use calloc() as rollup_make_fields depends on this */
14928
 
  sum_funcs= (Item_sum**) session->calloc(sizeof(Item_sum**) * (func_count+1) +
 
14930
  sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
14929
14931
                                      sizeof(Item_sum***) * (group_parts+1));
14930
14932
  sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
14931
14933
  return(sum_funcs == 0);
14972
14974
  }
14973
14975
  else if (rollup.state == ROLLUP::STATE_NONE)
14974
14976
  {
14975
 
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
 
14977
    for (uint i=0 ; i <= send_group_parts ;i++)
14976
14978
      sum_funcs_end[i]= func;
14977
14979
  }
14978
14980
  else if (rollup.state == ROLLUP::STATE_READY)
14986
14988
  Change all funcs and sum_funcs to fields in tmp table, and create
14987
14989
  new list of all items.
14988
14990
 
14989
 
  @param session                   Session pointer
 
14991
  @param thd                   THD pointer
14990
14992
  @param ref_pointer_array     array of pointers to top elements of filed list
14991
14993
  @param res_selected_fields   new list of items of select item list
14992
14994
  @param res_all_fields        new list of all items
15000
15002
*/
15001
15003
 
15002
15004
static bool
15003
 
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
 
15005
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
15004
15006
                         List<Item> &res_selected_fields,
15005
15007
                         List<Item> &res_all_fields,
15006
 
                         uint32_t elements, List<Item> &all_fields)
 
15008
                         uint elements, List<Item> &all_fields)
15007
15009
{
15008
15010
  List_iterator_fast<Item> it(all_fields);
15009
15011
  Item *item_field,*item;
15011
15013
  res_selected_fields.empty();
15012
15014
  res_all_fields.empty();
15013
15015
 
15014
 
  uint32_t i, border= all_fields.elements - elements;
 
15016
  uint i, border= all_fields.elements - elements;
15015
15017
  for (i= 0; (item= it++); i++)
15016
15018
  {
15017
15019
    Field *field;
15024
15026
    {
15025
15027
      if (item->type() == Item::FIELD_ITEM)
15026
15028
      {
15027
 
        item_field= item->get_tmp_table_item(session);
 
15029
        item_field= item->get_tmp_table_item(thd);
15028
15030
      }
15029
15031
      else if ((field= item->get_tmp_table_field()))
15030
15032
      {
15066
15068
  Change all sum_func refs to fields to point at fields in tmp table.
15067
15069
  Change all funcs to be fields in tmp table.
15068
15070
 
15069
 
  @param session                   Session pointer
 
15071
  @param thd                   THD pointer
15070
15072
  @param ref_pointer_array     array of pointers to top elements of filed list
15071
15073
  @param res_selected_fields   new list of items of select item list
15072
15074
  @param res_all_fields        new list of all items
15080
15082
*/
15081
15083
 
15082
15084
static bool
15083
 
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
 
15085
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
15084
15086
                          List<Item> &res_selected_fields,
15085
 
                          List<Item> &res_all_fields, uint32_t elements,
 
15087
                          List<Item> &res_all_fields, uint elements,
15086
15088
                          List<Item> &all_fields)
15087
15089
{
15088
15090
  List_iterator_fast<Item> it(all_fields);
15090
15092
  res_selected_fields.empty();
15091
15093
  res_all_fields.empty();
15092
15094
 
15093
 
  uint32_t i, border= all_fields.elements - elements;
 
15095
  uint i, border= all_fields.elements - elements;
15094
15096
  for (i= 0; (item= it++); i++)
15095
15097
  {
15096
 
    res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
 
15098
    res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
15097
15099
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15098
15100
      new_item;
15099
15101
  }
15103
15105
    itr++;
15104
15106
  itr.sublist(res_selected_fields, elements);
15105
15107
 
15106
 
  return session->is_fatal_error;
 
15108
  return thd->is_fatal_error;
15107
15109
}
15108
15110
 
15109
15111
 
15116
15118
/**
15117
15119
  Call ::setup for all sum functions.
15118
15120
 
15119
 
  @param session           thread handler
 
15121
  @param thd           thread handler
15120
15122
  @param func_ptr      sum function list
15121
15123
 
15122
15124
  @retval
15125
15127
    true   error
15126
15128
*/
15127
15129
 
15128
 
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr)
 
15130
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
15129
15131
{
15130
15132
  Item_sum *func;
15131
15133
  while ((func= *(func_ptr++)))
15132
15134
  {
15133
 
    if (func->setup(session))
 
15135
    if (func->setup(thd))
15134
15136
      return(true);
15135
15137
  }
15136
15138
  return(false);
15149
15151
/** Update record 0 in tmp_table from record 1. */
15150
15152
 
15151
15153
static void
15152
 
update_tmptable_sum_func(Item_sum **func_ptr, Table *)
 
15154
update_tmptable_sum_func(Item_sum **func_ptr,
 
15155
                         Table *tmp_table __attribute__((unused)))
15153
15156
{
15154
15157
  Item_sum *func;
15155
15158
  while ((func= *(func_ptr++)))
15212
15215
  currenct select for the table.
15213
15216
*/
15214
15217
 
15215
 
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab)
 
15218
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
15216
15219
{
15217
15220
  if (!join_tab->ref.key_parts)
15218
15221
    return(false);
15223
15226
  if (!cond)
15224
15227
    return(true);
15225
15228
 
15226
 
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
 
15229
  for (uint i=0 ; i < join_tab->ref.key_parts ; i++)
15227
15230
  {
15228
15231
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
15229
15232
                              fieldnr-1];
15230
15233
    Item *value=join_tab->ref.items[i];
15231
15234
    cond->add(new Item_func_equal(new Item_field(field), value));
15232
15235
  }
15233
 
  if (session->is_fatal_error)
 
15236
  if (thd->is_fatal_error)
15234
15237
    return(true);
15235
15238
 
15236
15239
  if (!cond->fixed)
15237
 
    cond->fix_fields(session, (Item**)&cond);
 
15240
    cond->fix_fields(thd, (Item**)&cond);
15238
15241
  if (join_tab->select)
15239
15242
  {
15240
15243
    error=(int) cond->add(join_tab->select->cond);
15251
15254
/**
15252
15255
  Free joins of subselect of this select.
15253
15256
 
15254
 
  @param session      Session pointer
 
15257
  @param thd      THD pointer
15255
15258
  @param select   pointer to st_select_lex which subselects joins we will free
15256
15259
*/
15257
15260
 
15258
 
void free_underlaid_joins(Session *, SELECT_LEX *select)
 
15261
void free_underlaid_joins(THD *thd __attribute__((unused)),
 
15262
                          SELECT_LEX *select)
15259
15263
{
15260
15264
  for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15261
15265
       unit;
15292
15296
    This substitution is needed GROUP BY queries with ROLLUP if
15293
15297
    SELECT list contains expressions over group by attributes.
15294
15298
 
15295
 
  @param session                  reference to the context
 
15299
  @param thd                  reference to the context
15296
15300
  @param expr                 expression to make replacement
15297
15301
  @param group_list           list of references to group by items
15298
15302
  @param changed        out:  returns 1 if item contains a replaced field item
15307
15311
    1   on error
15308
15312
*/
15309
15313
 
15310
 
static bool change_group_ref(Session *session, Item_func *expr, order_st *group_list,
 
15314
static bool change_group_ref(THD *thd, Item_func *expr, order_st *group_list,
15311
15315
                             bool *changed)
15312
15316
{
15313
15317
  if (expr->arg_count)
15314
15318
  {
15315
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
15319
    Name_resolution_context *context= &thd->lex->current_select->context;
15316
15320
    Item **arg,**arg_end;
15317
15321
    bool arg_changed= false;
15318
15322
    for (arg= expr->arguments(),
15331
15335
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15332
15336
                                        item->name)))
15333
15337
              return 1;                                 // fatal_error is set
15334
 
            session->change_item_tree(arg, new_item);
 
15338
            thd->change_item_tree(arg, new_item);
15335
15339
            arg_changed= true;
15336
15340
          }
15337
15341
        }
15338
15342
      }
15339
15343
      else if (item->type() == Item::FUNC_ITEM)
15340
15344
      {
15341
 
        if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
 
15345
        if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
15342
15346
          return 1;
15343
15347
      }
15344
15348
    }
15356
15360
 
15357
15361
bool JOIN::rollup_init()
15358
15362
{
15359
 
  uint32_t i,j;
 
15363
  uint i,j;
15360
15364
  Item **ref_array;
15361
15365
 
15362
15366
  tmp_table_param.quick_group= 0;       // Can't create groups in tmp table
15368
15372
  */
15369
15373
  tmp_table_param.group_parts= send_group_parts;
15370
15374
 
15371
 
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
 
15375
  if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
15372
15376
                                                sizeof(Item**) +
15373
15377
                                                sizeof(List<Item>) +
15374
15378
                                                ref_pointer_array_size)
15385
15389
  */
15386
15390
  for (i= 0 ; i < send_group_parts ; i++)
15387
15391
  {
15388
 
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
15392
    rollup.null_items[i]= new (thd->mem_root) Item_null_result();
15389
15393
    List<Item> *rollup_fields= &rollup.fields[i];
15390
15394
    rollup_fields->empty();
15391
15395
    rollup.ref_pointer_arrays[i]= ref_array;
15427
15431
          Item* new_item= new Item_func_rollup_const(item);
15428
15432
          if (!new_item)
15429
15433
            return 1;
15430
 
          new_item->fix_fields(session, (Item **) 0);
15431
 
          session->change_item_tree(it.ref(), new_item);
 
15434
          new_item->fix_fields(thd, (Item **) 0);
 
15435
          thd->change_item_tree(it.ref(), new_item);
15432
15436
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15433
15437
          { 
15434
15438
            if (*tmp->item == item)
15435
 
              session->change_item_tree(tmp->item, new_item);
 
15439
              thd->change_item_tree(tmp->item, new_item);
15436
15440
          }
15437
15441
        }
15438
15442
      }
15440
15444
    if (item->type() == Item::FUNC_ITEM && !found_in_group)
15441
15445
    {
15442
15446
      bool changed= false;
15443
 
      if (change_group_ref(session, (Item_func *) item, group_list, &changed))
 
15447
      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
15444
15448
        return 1;
15445
15449
      /*
15446
15450
        We have to prevent creation of a field in a temporary table for
15476
15480
{
15477
15481
  List_iterator_fast<Item> it(fields_arg);
15478
15482
  Item *first_field= sel_fields.head();
15479
 
  uint32_t level;
 
15483
  uint level;
15480
15484
 
15481
15485
  /*
15482
15486
    Create field lists for the different levels
15501
15505
 
15502
15506
  for (level=0 ; level < send_group_parts ; level++)
15503
15507
  {
15504
 
    uint32_t i;
15505
 
    uint32_t pos= send_group_parts - level -1;
 
15508
    uint i;
 
15509
    uint pos= send_group_parts - level -1;
15506
15510
    bool real_fields= 0;
15507
15511
    Item *item;
15508
15512
    List_iterator<Item> new_it(rollup.fields[pos]);
15543
15547
          sub select.  Fortunately it's not common to have rollup in
15544
15548
          sub selects.
15545
15549
        */
15546
 
        item= item->copy_or_same(session);
 
15550
        item= item->copy_or_same(thd);
15547
15551
        ((Item_sum*) item)->make_unique();
15548
15552
        *(*func)= (Item_sum*) item;
15549
15553
        (*func)++;
15561
15565
              This is an element that is used by the GROUP BY and should be
15562
15566
              set to NULL in this level
15563
15567
            */
15564
 
            Item_null_result *null_item= new (session->mem_root) Item_null_result();
 
15568
            Item_null_result *null_item= new (thd->mem_root) Item_null_result();
15565
15569
            if (!null_item)
15566
15570
              return 1;
15567
15571
            item->maybe_null= 1;                // Value will be null sometimes
15605
15609
    1   If send_data_failed()
15606
15610
*/
15607
15611
 
15608
 
int JOIN::rollup_send_data(uint32_t idx)
 
15612
int JOIN::rollup_send_data(uint idx)
15609
15613
{
15610
 
  uint32_t i;
 
15614
  uint i;
15611
15615
  for (i= send_group_parts ; i-- > idx ; )
15612
15616
  {
15613
15617
    /* Get reference pointers to sum functions in place */
15646
15650
    1   if write_data_failed()
15647
15651
*/
15648
15652
 
15649
 
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
 
15653
int JOIN::rollup_write_data(uint idx, Table *table_arg)
15650
15654
{
15651
 
  uint32_t i;
 
15655
  uint i;
15652
15656
  for (i= send_group_parts ; i-- > idx ; )
15653
15657
  {
15654
15658
    /* Get reference pointers to sum functions in place */
15667
15671
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15668
15672
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15669
15673
      {
15670
 
        if (create_myisam_from_heap(session, table_arg, 
 
15674
        if (create_myisam_from_heap(thd, table_arg, 
15671
15675
                                    tmp_table_param.start_recinfo,
15672
15676
                                    &tmp_table_param.recinfo,
15673
15677
                                    write_error, 0))
15709
15713
{
15710
15714
  List<Item> field_list;
15711
15715
  List<Item> item_list;
15712
 
  Session *session=join->session;
 
15716
  THD *thd=join->thd;
15713
15717
  select_result *result=join->result;
15714
15718
  Item *item_null= new Item_null();
15715
15719
  const CHARSET_INFO * const cs= system_charset_info;
15716
15720
  int quick_type;
15717
15721
  /* Don't log this into the slow query log */
15718
 
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
 
15722
  thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15719
15723
  join->unit->offset_limit_cnt= 0;
15720
15724
 
15721
15725
  /* 
15722
15726
    NOTE: the number/types of items pushed into item_list must be in sync with
15723
 
    EXPLAIN column types as they're "defined" in Session::send_explain_fields()
 
15727
    EXPLAIN column types as they're "defined" in THD::send_explain_fields()
15724
15728
  */
15725
15729
  if (message)
15726
15730
  {
15728
15732
                                     join->select_lex->select_number));
15729
15733
    item_list.push_back(new Item_string(join->select_lex->type,
15730
15734
                                        strlen(join->select_lex->type), cs));
15731
 
    for (uint32_t i=0 ; i < 7; i++)
 
15735
    for (uint i=0 ; i < 7; i++)
15732
15736
      item_list.push_back(item_null);
15733
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15737
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15734
15738
      item_list.push_back(item_null);
15735
15739
  
15736
15740
    item_list.push_back(new Item_string(message,strlen(message),cs));
15757
15761
    /* table */
15758
15762
    {
15759
15763
      SELECT_LEX *sl= join->unit->first_select();
15760
 
      uint32_t len= 6, lastop= 0;
 
15764
      uint len= 6, lastop= 0;
15761
15765
      memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
15762
15766
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
15763
15767
      {
15790
15794
    /* ref */
15791
15795
    item_list.push_back(item_null);
15792
15796
    /* in_rows */
15793
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15797
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15794
15798
      item_list.push_back(item_null);
15795
15799
    /* rows */
15796
15800
    item_list.push_back(item_null);
15807
15811
  else
15808
15812
  {
15809
15813
    table_map used_tables=0;
15810
 
    for (uint32_t i=0 ; i < join->tables ; i++)
 
15814
    for (uint i=0 ; i < join->tables ; i++)
15811
15815
    {
15812
15816
      JOIN_TAB *tab=join->join_tab+i;
15813
15817
      Table *table=tab->table;
15867
15871
      /* Build "possible_keys" value and add it to item_list */
15868
15872
      if (!tab->keys.is_clear_all())
15869
15873
      {
15870
 
        uint32_t j;
 
15874
        uint j;
15871
15875
        for (j=0 ; j < table->s->keys ; j++)
15872
15876
        {
15873
15877
          if (tab->keys.is_set(j))
15889
15893
      if (tab->ref.key_parts)
15890
15894
      {
15891
15895
        KEY *key_info=table->key_info+ tab->ref.key;
15892
 
        register uint32_t length;
 
15896
        register uint length;
15893
15897
        item_list.push_back(new Item_string(key_info->name,
15894
15898
                                            strlen(key_info->name),
15895
15899
                                            system_charset_info));
15909
15913
      else if (tab->type == JT_NEXT)
15910
15914
      {
15911
15915
        KEY *key_info=table->key_info+ tab->index;
15912
 
        register uint32_t length;
 
15916
        register uint length;
15913
15917
        item_list.push_back(new Item_string(key_info->name,
15914
15918
                                            strlen(key_info->name),cs));
15915
15919
        length= int64_t2str(key_info->key_length, keylen_str_buf, 10) - 
15961
15965
      if (table_list->schema_table)
15962
15966
      {
15963
15967
        /* in_rows */
15964
 
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15968
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15965
15969
          item_list.push_back(item_null);
15966
15970
        /* rows */
15967
15971
        item_list.push_back(item_null);
15981
15985
                                         MY_INT64_NUM_DECIMAL_DIGITS));
15982
15986
 
15983
15987
        /* Add "filtered" field to item_list. */
15984
 
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15988
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15985
15989
        {
15986
15990
          float f= 0.0; 
15987
15991
          if (examined_rows)
16022
16026
      }
16023
16027
      else
16024
16028
      {
16025
 
        uint32_t keyno= MAX_KEY;
 
16029
        uint keyno= MAX_KEY;
16026
16030
        if (tab->ref.key_parts)
16027
16031
          keyno= tab->ref.key;
16028
16032
        else if (tab->select && tab->select->quick)
16054
16058
          {
16055
16059
            const COND *pushed_cond= tab->table->file->pushed_cond;
16056
16060
 
16057
 
            if (session->variables.engine_condition_pushdown && pushed_cond)
 
16061
            if (thd->variables.engine_condition_pushdown && pushed_cond)
16058
16062
            {
16059
16063
              extra.append(STRING_WITH_LEN("; Using where with pushed "
16060
16064
                                           "condition"));
16061
 
              if (session->lex->describe & DESCRIBE_EXTENDED)
 
16065
              if (thd->lex->describe & DESCRIBE_EXTENDED)
16062
16066
              {
16063
16067
                extra.append(STRING_WITH_LEN(": "));
16064
16068
                ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16113
16117
          need_order=0;
16114
16118
          extra.append(STRING_WITH_LEN("; Using filesort"));
16115
16119
        }
16116
 
        if (distinct & test_all_bits(used_tables,session->used_tables))
 
16120
        if (distinct & test_all_bits(used_tables,thd->used_tables))
16117
16121
          extra.append(STRING_WITH_LEN("; Distinct"));
16118
16122
 
16119
16123
        if (tab->insideout_match_tab)
16143
16147
          extra.append(STRING_WITH_LEN(")"));
16144
16148
        }
16145
16149
 
16146
 
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
 
16150
        for (uint part= 0; part < tab->ref.key_parts; part++)
16147
16151
        {
16148
16152
          if (tab->ref.cond_guards[part])
16149
16153
          {
16175
16179
       unit;
16176
16180
       unit= unit->next_unit())
16177
16181
  {
16178
 
    if (mysql_explain_union(session, unit, result))
 
16182
    if (mysql_explain_union(thd, unit, result))
16179
16183
      return;
16180
16184
  }
16181
16185
  return;
16182
16186
}
16183
16187
 
16184
16188
 
16185
 
bool mysql_explain_union(Session *session, SELECT_LEX_UNIT *unit, select_result *result)
 
16189
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
16186
16190
{
16187
16191
  bool res= 0;
16188
16192
  SELECT_LEX *first= unit->first_select();
16193
16197
  {
16194
16198
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16195
16199
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16196
 
    sl->type= (((&session->lex->select_lex)==sl)?
 
16200
    sl->type= (((&thd->lex->select_lex)==sl)?
16197
16201
               (sl->first_inner_unit() || sl->next_select() ? 
16198
16202
                "PRIMARY" : "SIMPLE"):
16199
16203
               ((sl == first)?
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();
16220
16224
  }
16221
16225
  else
16222
16226
  {
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);
16237
16241
  }
16238
 
  return(res || session->is_error());
 
16242
  return(res || thd->is_error());
16239
16243
}
16240
16244
 
16241
16245
 
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)
16244
16248
{
16245
 
  (*table)->print(session, str, QT_ORDINARY);
 
16249
  (*table)->print(thd, str, QT_ORDINARY);
16246
16250
 
16247
16251
  for (TableList **tbl= table + 1; tbl < end; tbl++)
16248
16252
  {
16258
16262
      str->append(STRING_WITH_LEN(" semi join "));
16259
16263
    else
16260
16264
      str->append(STRING_WITH_LEN(" join "));
16261
 
    curr->print(session, str, QT_ORDINARY);
 
16265
    curr->print(thd, str, QT_ORDINARY);
16262
16266
    if (curr->on_expr)
16263
16267
    {
16264
16268
      str->append(STRING_WITH_LEN(" on("));
16271
16275
 
16272
16276
/**
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
16278
16282
*/
16279
16283
 
16280
 
static void print_join(Session *session, String *str,
16281
 
                       List<TableList> *tables, enum_query_type)
 
16284
static void print_join(THD *thd,
 
16285
                       String *str,
 
16286
                       List<TableList> *tables,
 
16287
                       enum_query_type query_type __attribute__((unused)))
16282
16288
{
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
16309
16315
    }
16310
16316
  }
16311
16317
  assert(tables->elements >= 1);
16312
 
  print_table_array(session, str, table, table + tables->elements);
 
16318
  print_table_array(thd, str, table, table + tables->elements);
16313
16319
}
16314
16320
 
16315
16321
 
16318
16324
 
16319
16325
  @details Prints out the USE|FORCE|IGNORE index hint.
16320
16326
 
16321
 
  @param      session         the current thread
 
16327
  @param      thd         the current thread
16322
16328
  @param[out] str         appends the index hint here
16323
16329
  @param      hint        what the hint is (as string : "USE INDEX"|
16324
16330
                          "FORCE INDEX"|"IGNORE INDEX")
16327
16333
*/
16328
16334
 
16329
16335
void 
16330
 
Index_hint::print(Session *session, String *str)
 
16336
Index_hint::print(THD *thd, String *str)
16331
16337
{
16332
16338
  switch (type)
16333
16339
  {
16338
16344
  str->append (STRING_WITH_LEN(" ("));
16339
16345
  if (key_name.length)
16340
16346
  {
16341
 
    if (session && is_primary_key_name(key_name.str))
16342
 
      str->append(is_primary_key_name(key_name.str));
 
16347
    if (thd && !my_strnncoll(system_charset_info,
 
16348
                             (const uchar *)key_name.str, key_name.length, 
 
16349
                             (const uchar *)primary_key_name, 
 
16350
                             strlen(primary_key_name)))
 
16351
      str->append(primary_key_name);
16343
16352
    else
16344
 
      append_identifier(session, str, key_name.str, key_name.length);
 
16353
      append_identifier(thd, str, key_name.str, key_name.length);
16345
16354
  }
16346
16355
  str->append(')');
16347
16356
}
16353
16362
  @param str   string where table should be printed
16354
16363
*/
16355
16364
 
16356
 
void TableList::print(Session *session, String *str, enum_query_type query_type)
 
16365
void TableList::print(THD *thd, String *str, enum_query_type query_type)
16357
16366
{
16358
16367
  if (nested_join)
16359
16368
  {
16360
16369
    str->append('(');
16361
 
    print_join(session, str, &nested_join->join_list, query_type);
 
16370
    print_join(thd, str, &nested_join->join_list, query_type);
16362
16371
    str->append(')');
16363
16372
  }
16364
16373
  else
16376
16385
    {
16377
16386
      // A normal table
16378
16387
      {
16379
 
        append_identifier(session, str, db, db_length);
 
16388
        append_identifier(thd, str, db, db_length);
16380
16389
        str->append('.');
16381
16390
      }
16382
16391
      if (schema_table)
16383
16392
      {
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;
16387
16396
      }
16388
16397
      else
16389
16398
      {
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;
16392
16401
      }
16393
16402
    }
16401
16410
      {
16402
16411
        if (alias && alias[0])
16403
16412
        {
16404
 
          my_stpcpy(t_alias_buff, alias);
 
16413
          stpcpy(t_alias_buff, alias);
16405
16414
          my_casedn_str(files_charset_info, t_alias_buff);
16406
16415
          t_alias= t_alias_buff;
16407
16416
        }
16408
16417
      }
16409
16418
 
16410
 
      append_identifier(session, str, t_alias, strlen(t_alias));
 
16419
      append_identifier(thd, str, t_alias, strlen(t_alias));
16411
16420
    }
16412
16421
 
16413
16422
    if (index_hints)
16418
16427
      while ((hint= it++))
16419
16428
      {
16420
16429
        str->append (STRING_WITH_LEN(" "));
16421
 
        hint->print (session, str);
 
16430
        hint->print (thd, str);
16422
16431
      }
16423
16432
    }
16424
16433
  }
16425
16434
}
16426
16435
 
16427
16436
 
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)
16429
16438
{
16430
 
  /* QQ: session may not be set for sub queries, but this should be fixed */
16431
 
  if (!session)
16432
 
    session= current_session;
 
16439
  /* QQ: thd may not be set for sub queries, but this should be fixed */
 
16440
  if (!thd)
 
16441
    thd= current_thd;
16433
16442
 
16434
16443
  str->append(STRING_WITH_LEN("select "));
16435
16444
 
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 "));
16471
16480
  {
16472
16481
    str->append(STRING_WITH_LEN(" from "));
16473
16482
    /* go through join tree */
16474
 
    print_join(session, str, &top_join_list, query_type);
 
16483
    print_join(thd, str, &top_join_list, query_type);
16475
16484
  }
16476
16485
  else if (where)
16477
16486
  {
16534
16543
  }
16535
16544
 
16536
16545
  // limit
16537
 
  print_limit(session, str, query_type);
 
16546
  print_limit(thd, str, query_type);
16538
16547
 
16539
16548
  // PROCEDURE unsupported here
16540
16549
}