~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

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/nested_join.h>
36
 
#include <drizzled/probes.h>
37
 
#include CMATH_H
38
 
 
39
 
#if defined(CMATH_NAMESPACE)
40
 
using namespace CMATH_NAMESPACE;
41
 
#endif
 
31
#include <drizzled/drizzled_error_messages.h>
 
32
#include <libdrizzle/gettext.h>
42
33
 
43
34
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
44
35
                              "MAYBE_REF","ALL","range","index",
51
42
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
52
43
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
53
44
                                 DYNAMIC_ARRAY *keyuse);
54
 
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
 
45
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
55
46
                                JOIN_TAB *join_tab,
56
 
                                uint32_t tables, COND *conds,
 
47
                                uint tables, COND *conds,
57
48
                                COND_EQUAL *cond_equal,
58
49
                                table_map table_map, SELECT_LEX *select_lex,
59
50
                                st_sargable_param **sargables);
60
51
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
61
 
static void set_position(JOIN *join,uint32_t index,JOIN_TAB *table,KEYUSE *key);
 
52
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
62
53
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
63
54
                               table_map used_tables);
64
55
static bool choose_plan(JOIN *join,table_map join_tables);
65
56
 
66
 
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
67
 
                             table_map remaining_tables, uint32_t idx,
 
57
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
 
58
                             table_map remaining_tables, uint idx,
68
59
                             double record_count, double read_time);
69
60
static void optimize_straight_join(JOIN *join, table_map join_tables);
70
61
static bool greedy_search(JOIN *join, table_map remaining_tables,
71
 
                             uint32_t depth, uint32_t prune_level);
 
62
                             uint depth, uint prune_level);
72
63
static bool best_extension_by_limited_search(JOIN *join,
73
64
                                             table_map remaining_tables,
74
 
                                             uint32_t idx, double record_count,
75
 
                                             double read_time, uint32_t depth,
76
 
                                             uint32_t prune_level);
77
 
static uint32_t determine_search_depth(JOIN* join);
 
65
                                             uint idx, double record_count,
 
66
                                             double read_time, uint depth,
 
67
                                             uint prune_level);
 
68
static uint determine_search_depth(JOIN* join);
78
69
static int join_tab_cmp(const void* ptr1, const void* ptr2);
79
70
static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
80
71
/*
81
72
  TODO: 'find_best' is here only temporarily until 'greedy_search' is
82
73
  tested and approved.
83
74
*/
84
 
static bool find_best(JOIN *join,table_map rest_tables,uint32_t index,
 
75
static bool find_best(JOIN *join,table_map rest_tables,uint index,
85
76
                      double record_count,double read_time);
86
 
static uint32_t cache_record_length(JOIN *join,uint32_t index);
87
 
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
77
static uint cache_record_length(JOIN *join,uint index);
 
78
static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
88
79
static bool get_best_combination(JOIN *join);
89
 
static store_key *get_store_key(Session *session,
 
80
static store_key *get_store_key(THD *thd,
90
81
                                KEYUSE *keyuse, table_map used_tables,
91
 
                                KEY_PART_INFO *key_part, unsigned char *key_buff,
92
 
                                uint32_t maybe_null);
 
82
                                KEY_PART_INFO *key_part, uchar *key_buff,
 
83
                                uint maybe_null);
93
84
static bool make_simple_join(JOIN *join,Table *tmp_table);
94
85
static void make_outerjoin_info(JOIN *join);
95
86
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
96
 
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
87
static bool make_join_readinfo(JOIN *join, uint64_t options, uint no_jbuf_after);
97
88
static bool only_eq_ref_tables(JOIN *join, order_st *order, table_map tables);
98
89
static void update_depend_map(JOIN *join);
99
90
static void update_depend_map(JOIN *join, order_st *order);
103
94
                            List<Item> &fields, bool send_row,
104
95
                            uint64_t select_options, const char *info,
105
96
                            Item *having);
106
 
static COND *build_equal_items(Session *session, COND *cond,
 
97
static COND *build_equal_items(THD *thd, COND *cond,
107
98
                               COND_EQUAL *inherited,
108
99
                               List<TableList> *join_list,
109
100
                               COND_EQUAL **cond_equal_ref);
115
106
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
116
107
static void restore_prev_nj_state(JOIN_TAB *last);
117
108
static void reset_nj_counters(List<TableList> *join_list);
118
 
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list,
119
 
                                          uint32_t first_unused);
 
109
static uint build_bitmap_for_nested_joins(List<TableList> *join_list,
 
110
                                          uint first_unused);
120
111
 
121
112
static 
122
113
void advance_sj_state(const table_map remaining_tables, const JOIN_TAB *tab);
176
167
                          bool (*find_func) (Field *, void *), void *data);
177
168
static bool find_field_in_item_list (Field *field, void *data);
178
169
static bool find_field_in_order_list (Field *field, void *data);
179
 
static int create_sort_index(Session *session, JOIN *join, order_st *order,
 
170
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
180
171
                             ha_rows filesort_limit, ha_rows select_limit,
181
172
                             bool is_order_by);
182
173
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
183
174
                             Item *having);
184
 
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
185
 
                                   uint32_t offset, Item *having);
186
 
static int remove_dup_with_hash_index(Session *session,Table *table,
187
 
                                      uint32_t field_count, Field **first_field,
188
 
                                      uint32_t key_length, Item *having);
189
 
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
190
 
static uint32_t used_blob_length(CACHE_FIELD **ptr);
 
175
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
 
176
                                   ulong offset,Item *having);
 
177
static int remove_dup_with_hash_index(THD *thd,Table *table,
 
178
                                      uint field_count, Field **first_field,
 
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);
191
183
static bool store_record_in_cache(JOIN_CACHE *cache);
192
184
static void reset_cache_read(JOIN_CACHE *cache);
193
185
static void reset_cache_write(JOIN_CACHE *cache);
194
186
static void read_cached_record(JOIN_TAB *tab);
195
187
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
196
 
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
 
188
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
197
189
                                    order_st *order, List<Item> &fields,
198
190
                                    List<Item> &all_fields,
199
191
                                    bool *all_order_by_fields_used);
203
195
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
204
196
static bool alloc_group_fields(JOIN *join,order_st *group);
205
197
// Create list for using with tempory table
206
 
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
 
198
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
207
199
                                     List<Item> &new_list1,
208
200
                                     List<Item> &new_list2,
209
 
                                     uint32_t elements, List<Item> &items);
 
201
                                     uint elements, List<Item> &items);
210
202
// Create list for using with tempory table
211
 
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
 
203
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
212
204
                                      List<Item> &new_list1,
213
205
                                      List<Item> &new_list2,
214
 
                                      uint32_t elements, List<Item> &items);
 
206
                                      uint elements, List<Item> &items);
215
207
static void init_tmptable_sum_functions(Item_sum **func);
216
208
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
217
209
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
218
 
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
219
 
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
 
210
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
 
211
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
220
212
static bool init_sum_functions(Item_sum **func, Item_sum **end);
221
213
static bool update_sum_func(Item_sum **func);
222
214
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
223
 
                            bool distinct, const char *message=NULL);
 
215
                            bool distinct, const char *message=NullS);
224
216
static Item *remove_additional_cond(Item* conds);
225
217
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
226
218
static bool test_if_ref(Item_field *left_item,Item *right_item);
244
236
  This handles SELECT with and without UNION.
245
237
*/
246
238
 
247
 
bool handle_select(Session *session, LEX *lex, select_result *result,
 
239
bool handle_select(THD *thd, LEX *lex, select_result *result,
248
240
                   ulong setup_tables_done_option)
249
241
{
250
242
  bool res;
253
245
 
254
246
  if (select_lex->master_unit()->is_union() || 
255
247
      select_lex->master_unit()->fake_select_lex)
256
 
    res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
 
248
    res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
257
249
  else
258
250
  {
259
251
    SELECT_LEX_UNIT *unit= &lex->unit;
260
252
    unit->set_limit(unit->global_parameters);
261
 
    session->session_marker= 0;
 
253
    thd->thd_marker= 0;
262
254
    /*
263
255
      'options' of mysql_select will be set in JOIN, as far as JOIN for
264
256
      every PS/SP execution new, we will not need reset this flag if 
265
257
      setup_tables_done_option changed for next rexecution
266
258
    */
267
 
    res= mysql_select(session, &select_lex->ref_pointer_array,
 
259
    res= mysql_select(thd, &select_lex->ref_pointer_array,
268
260
                      (TableList*) select_lex->table_list.first,
269
261
                      select_lex->with_wild, select_lex->item_list,
270
262
                      select_lex->where,
274
266
                      (order_st*) select_lex->group_list.first,
275
267
                      select_lex->having,
276
268
                      (order_st*) lex->proc_list.first,
277
 
                      select_lex->options | session->options |
 
269
                      select_lex->options | thd->options |
278
270
                      setup_tables_done_option,
279
271
                      result, unit, select_lex);
280
272
  }
281
 
  res|= session->is_error();
 
273
  res|= thd->is_error();
282
274
  if (unlikely(res))
283
275
    result->abort();
284
276
 
292
284
 
293
285
  SYNOPSIS
294
286
    fix_inner_refs()
295
 
    session               Thread handle
 
287
    thd               Thread handle
296
288
    all_fields        List of all fields used in select
297
289
    select            Current select
298
290
    ref_pointer_array Array of references to Items used in current select
329
321
*/
330
322
 
331
323
bool
332
 
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,
333
325
                 Item **ref_pointer_array)
334
326
{
335
327
  Item_outer_ref *ref;
390
382
    ref->outer_ref= new_ref;
391
383
    ref->ref= &ref->outer_ref;
392
384
 
393
 
    if (!ref->fixed && ref->fix_fields(session, 0))
 
385
    if (!ref->fixed && ref->fix_fields(thd, 0))
394
386
      return true;
395
 
    session->used_tables|= item->used_tables();
 
387
    thd->used_tables|= item->used_tables();
396
388
  }
397
389
  return res;
398
390
}
399
391
 
 
392
#define MAGIC_IN_WHERE_TOP_LEVEL 10
400
393
/**
401
394
  Function to setup clauses without sum functions.
402
395
*/
403
 
inline int setup_without_group(Session *session, Item **ref_pointer_array,
 
396
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
404
397
                               TableList *tables,
405
398
                               TableList *leaves,
406
399
                               List<Item> &fields,
410
403
                               order_st *group, bool *hidden_group_fields)
411
404
{
412
405
  int res;
413
 
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
414
 
 
415
 
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
416
 
  res= setup_conds(session, tables, leaves, conds);
417
 
 
418
 
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
419
 
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
 
406
  nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
 
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,
420
413
                          order);
421
 
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
422
 
  res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
 
414
  thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
 
415
  res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
423
416
                          group, hidden_group_fields);
424
 
  session->lex->allow_sum_func= save_allow_sum_func;
 
417
  thd->lex->allow_sum_func= save_allow_sum_func;
425
418
  return(res);
426
419
}
427
420
 
445
438
int
446
439
JOIN::prepare(Item ***rref_pointer_array,
447
440
              TableList *tables_init,
448
 
              uint32_t wild_num, COND *conds_init, uint32_t og_num,
 
441
              uint wild_num, COND *conds_init, uint og_num,
449
442
              order_st *order_init, order_st *group_init,
450
443
              Item *having_init,
451
444
              order_st *proc_param_init, SELECT_LEX *select_lex_arg,
466
459
  join_list= &select_lex->top_join_list;
467
460
  union_part= unit_arg->is_union();
468
461
 
469
 
  session->lex->current_select->is_item_list_lookup= 1;
 
462
  thd->lex->current_select->is_item_list_lookup= 1;
470
463
  /*
471
464
    If we have already executed SELECT, then it have not sense to prevent
472
465
    its table from update (see unique_table())
473
466
  */
474
 
  if (session->derived_tables_processing)
 
467
  if (thd->derived_tables_processing)
475
468
    select_lex->exclude_from_table_unique_test= true;
476
469
 
477
470
  /* Check that all tables, fields, conds and order are ok */
478
471
 
479
472
  if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
480
 
      setup_tables_and_check_access(session, &select_lex->context, join_list,
 
473
      setup_tables_and_check_access(thd, &select_lex->context, join_list,
481
474
                                    tables_list, &select_lex->leaf_tables,
482
475
                                    false))
483
476
      return(-1);
488
481
       table_ptr= table_ptr->next_leaf)
489
482
    tables++;
490
483
 
491
 
  if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
492
 
      select_lex->setup_ref_array(session, og_num) ||
493
 
      setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
 
484
  if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
 
485
      select_lex->setup_ref_array(thd, og_num) ||
 
486
      setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
494
487
                   &all_fields, 1) ||
495
 
      setup_without_group(session, (*rref_pointer_array), tables_list,
 
488
      setup_without_group(thd, (*rref_pointer_array), tables_list,
496
489
                          select_lex->leaf_tables, fields_list,
497
490
                          all_fields, &conds, order, group_list,
498
491
                          &hidden_group_fields))
502
495
  
503
496
  if (having)
504
497
  {
505
 
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
506
 
    session->where="having clause";
507
 
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
 
498
    nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
 
499
    thd->where="having clause";
 
500
    thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
508
501
    select_lex->having_fix_field= 1;
509
502
    bool having_fix_rc= (!having->fixed &&
510
 
                         (having->fix_fields(session, &having) ||
 
503
                         (having->fix_fields(thd, &having) ||
511
504
                          having->check_cols(1)));
512
505
    select_lex->having_fix_field= 0;
513
 
    if (having_fix_rc || session->is_error())
 
506
    if (having_fix_rc || thd->is_error())
514
507
      return(-1);                               /* purecov: inspected */
515
 
    session->lex->allow_sum_func= save_allow_sum_func;
 
508
    thd->lex->allow_sum_func= save_allow_sum_func;
516
509
  }
517
510
 
518
511
  {
524
517
    */
525
518
    if ((subselect= select_lex->master_unit()->item))
526
519
    {
527
 
      bool do_semijoin= !test(session->variables.optimizer_switch &
 
520
      bool do_semijoin= !test(thd->variables.optimizer_switch &
528
521
                              OPTIMIZER_SWITCH_NO_SEMIJOIN);
529
522
      if (subselect->substype() == Item_subselect::IN_SUBS)
530
523
        in_subs= (Item_in_subselect*)subselect;
551
544
          !select_lex->master_unit()->first_select()->next_select() &&  // 2
552
545
          !select_lex->group_list.elements && !order &&                 // 3
553
546
          !having && !select_lex->with_sum_func &&                      // 4
554
 
          session->session_marker &&                                            // 5
 
547
          thd->thd_marker &&                                            // 5
555
548
          select_lex->outer_select()->join &&                           // (*)
556
549
          select_lex->master_unit()->first_select()->leaf_tables &&     // (**) 
557
550
          do_semijoin &&
559
552
      {
560
553
        {
561
554
          if (!in_subs->left_expr->fixed &&
562
 
               in_subs->left_expr->fix_fields(session, &in_subs->left_expr))
 
555
               in_subs->left_expr->fix_fields(thd, &in_subs->left_expr))
563
556
          {
564
557
            return(-1);
565
558
          }
577
570
        }
578
571
 
579
572
        /* Register the subquery for further processing */
580
 
        select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
581
 
        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;
582
575
      }
583
576
      else
584
577
      {
585
 
        bool do_materialize= !test(session->variables.optimizer_switch &
 
578
        bool do_materialize= !test(thd->variables.optimizer_switch &
586
579
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
587
580
        /*
588
581
          Check if the subquery predicate can be executed via materialization.
617
610
            in_subs  &&                                                   // 1
618
611
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
619
612
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
620
 
            session->lex->sql_command == SQLCOM_SELECT)                       // *
 
613
            thd->lex->sql_command == SQLCOM_SELECT)                       // *
621
614
        {
622
615
          if (in_subs->is_top_level_item() &&                             // 4
623
616
              !in_subs->is_correlated &&                                  // 5
642
635
    {
643
636
      Item *item= *ord->item;
644
637
      if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
645
 
        item->split_sum_func(session, ref_pointer_array, all_fields);
 
638
        item->split_sum_func(thd, ref_pointer_array, all_fields);
646
639
    }
647
640
  }
648
641
 
649
642
  if (having && having->with_sum_func)
650
 
    having->split_sum_func2(session, ref_pointer_array, all_fields,
 
643
    having->split_sum_func2(thd, ref_pointer_array, all_fields,
651
644
                            &having, true);
652
645
  if (select_lex->inner_sum_func_list)
653
646
  {
656
649
    do
657
650
    { 
658
651
      item_sum= item_sum->next;
659
 
      item_sum->split_sum_func2(session, ref_pointer_array,
 
652
      item_sum->split_sum_func2(thd, ref_pointer_array,
660
653
                                all_fields, item_sum->ref_by, false);
661
654
    } while (item_sum != end);
662
655
  }
663
656
 
664
657
  if (select_lex->inner_refs_list.elements &&
665
 
      fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
 
658
      fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
666
659
    return(-1);
667
660
 
668
661
  /*
786
779
    join_tab->packed_info |= TAB_INFO_USING_INDEX;
787
780
  if (where)
788
781
    join_tab->packed_info |= TAB_INFO_USING_WHERE;
789
 
  for (uint32_t i = 0; i < join_tab->ref.key_parts; i++)
 
782
  for (uint i = 0; i < join_tab->ref.key_parts; i++)
790
783
  {
791
784
    if (join_tab->ref.cond_guards[i])
792
785
    {
836
829
  if (join_tab->type == JT_EQ_REF)
837
830
  {
838
831
    Table_map_iterator it(join_tab->ref.depend_map & ~PSEUDO_TABLE_BITS);
839
 
    uint32_t idx;
 
832
    uint idx;
840
833
    while ((idx= it.next_bit())!=Table_map_iterator::BITMAP_END)
841
834
    {
842
835
      JOIN_TAB *ref_tab= join->join_tab + idx;
948
941
*/
949
942
 
950
943
static
951
 
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)
952
945
{
953
946
  table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
954
947
  struct {
958
951
      2 - Temptable (maybe confluent),
959
952
      3 - Temptable with join buffering
960
953
    */
961
 
    uint32_t strategy;
962
 
    uint32_t start_idx; /* Left range bound */
963
 
    uint32_t end_idx;   /* Right range bound */
 
954
    uint strategy;
 
955
    uint start_idx; /* Left range bound */
 
956
    uint end_idx;   /* Right range bound */
964
957
    /* 
965
958
      For Temptable strategy: Bitmap of all outer and correlated tables from 
966
959
      all involved join nests.
975
968
  table_map range_start_map= 0; /* table_map at current range start */
976
969
  bool dealing_with_jbuf= false; /* true <=> table within cur range uses join buf */
977
970
  int cur_range= 0;
978
 
  uint32_t i;
 
971
  uint i;
979
972
 
980
973
  /*
981
974
    First pass: locate the duplicate-generating ranges and pick the strategies.
1098
1091
    }
1099
1092
  }
1100
1093
 
1101
 
  Session *session= join->session;
 
1094
  THD *thd= join->thd;
1102
1095
  SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
1103
1096
  /*
1104
1097
    Second pass: setup the chosen strategies    
1116
1109
    {
1117
1110
      SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
1118
1111
      table_map cur_map= join->const_table_map | PSEUDO_TABLE_BITS;
1119
 
      uint32_t jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
1120
 
      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
1121
1114
      SJ_TMP_TABLE::TAB *last_tab= sjtabs;
1122
 
      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;
1123
1116
      JOIN_TAB *last_outer_tab= tab - 1;
1124
1117
      /*
1125
1118
        Walk through the range and remember
1151
1144
      if (jt_rowid_offset) /* Temptable has at least one rowid */
1152
1145
      {
1153
1146
        SJ_TMP_TABLE *sjtbl;
1154
 
        uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
1155
 
        if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
1156
 
            !(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)))
1157
1150
          return(true);
1158
1151
        memcpy(sjtbl->tabs, sjtabs, tabs_size);
1159
1152
        sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1166
1159
        sjtbl->next= NULL;
1167
1160
 
1168
1161
        sjtbl->tmp_table= 
1169
 
          create_duplicate_weedout_tmp_table(session, 
 
1162
          create_duplicate_weedout_tmp_table(thd, 
1170
1163
                                             sjtbl->rowid_len + 
1171
1164
                                             sjtbl->null_bytes,
1172
1165
                                             sjtbl);
1198
1191
  {
1199
1192
    if (sj_tbl->tmp_table)
1200
1193
    {
1201
 
      sj_tbl->tmp_table->free_tmp_table(join->session);
 
1194
      sj_tbl->tmp_table->free_tmp_table(join->thd);
1202
1195
    }
1203
1196
  }
1204
1197
  join->sj_tmp_tables= NULL;
1205
1198
}
1206
1199
 
1207
 
uint32_t make_join_orderinfo(JOIN *join);
 
1200
uint make_join_orderinfo(JOIN *join);
1208
1201
 
1209
1202
/**
1210
1203
  global select optimisation.
1226
1219
    return(0);
1227
1220
  optimized= 1;
1228
1221
 
1229
 
  session->set_proc_info("optimizing");
 
1222
  thd_proc_info(thd, "optimizing");
1230
1223
  row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
1231
1224
              unit->select_limit_cnt);
1232
1225
  /* select_limit is used to decide if we are likely to scan the whole table */
1235
1228
    select_limit= HA_POS_ERROR;
1236
1229
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1237
1230
  // Ignore errors of execution if option IGNORE present
1238
 
  if (session->lex->ignore)
1239
 
    session->lex->current_select->no_error= 1;
 
1231
  if (thd->lex->ignore)
 
1232
    thd->lex->current_select->no_error= 1;
1240
1233
 
1241
1234
#ifdef HAVE_REF_TO_FIELDS                       // Not done yet
1242
1235
  /* Add HAVING to WHERE if possible */
1253
1246
        Item_cond_and can't be fixed after creation, so we do not check
1254
1247
        conds->fixed
1255
1248
      */
1256
 
      conds->fix_fields(session, &conds);
1257
 
      conds->change_ref_to_fields(session, tables_list);
 
1249
      conds->fix_fields(thd, &conds);
 
1250
      conds->change_ref_to_fields(thd, tables_list);
1258
1251
      conds->top_level_item();
1259
1252
      having= 0;
1260
1253
    }
1261
1254
  }
1262
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;
1263
1264
 
1264
 
  /* Convert all outer joins to inner joins if possible */
1265
 
  conds= simplify_joins(this, join_list, conds, true, false);
1266
 
  build_bitmap_for_nested_joins(join_list, 0);
 
1265
    /* Convert all outer joins to inner joins if possible */
 
1266
    conds= simplify_joins(this, join_list, conds, true, false);
 
1267
    build_bitmap_for_nested_joins(join_list, 0);
 
1268
  }
1267
1269
 
1268
1270
  conds= optimize_cond(this, conds, join_list, &cond_value);   
1269
 
  if (session->is_error())
 
1271
  if (thd->is_error())
1270
1272
  {
1271
1273
    error= 1;
1272
1274
    return(1);
1274
1276
 
1275
1277
  {
1276
1278
    having= optimize_cond(this, having, join_list, &having_value);
1277
 
    if (session->is_error())
 
1279
    if (thd->is_error())
1278
1280
    {
1279
1281
      error= 1;
1280
1282
      return(1);
1294
1296
    }
1295
1297
  }
1296
1298
 
1297
 
  /* Optimize count(*), cmin() and cmax() */
 
1299
  /* Optimize count(*), min() and max() */
1298
1300
  if (tables_list && tmp_table_param.sum_func_count && ! group_list)
1299
1301
  {
1300
1302
    int res;
1335
1337
        conjunctions.
1336
1338
        Preserve conditions for EXPLAIN.
1337
1339
      */
1338
 
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
 
1340
      if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
1339
1341
      {
1340
1342
        COND *table_independent_conds=
1341
1343
          make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1352
1354
  sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1353
1355
 
1354
1356
  /* Calculate how to do the join */
1355
 
  session->set_proc_info("statistics");
 
1357
  thd_proc_info(thd, "statistics");
1356
1358
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1357
 
      session->is_fatal_error)
 
1359
      thd->is_fatal_error)
1358
1360
  {
1359
1361
    return(1);
1360
1362
  }
1361
1363
 
1362
1364
  /* Remove distinct if only const tables */
1363
1365
  select_distinct= select_distinct && (const_tables != tables);
1364
 
  session->set_proc_info("preparing");
 
1366
  thd_proc_info(thd, "preparing");
1365
1367
  if (result->initialize_tables(this))
1366
1368
  {
1367
1369
    return(1);                          // error == -1
1370
1372
      !(select_options & SELECT_DESCRIBE) &&
1371
1373
      (!conds ||
1372
1374
       !(conds->used_tables() & RAND_TABLE_BIT) ||
1373
 
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
 
1375
       select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
1374
1376
  {
1375
1377
    zero_result_cause= "no matching row in const table";
1376
1378
    error= 0;
1377
1379
    return(0);
1378
1380
  }
1379
 
  if (!(session->options & OPTION_BIG_SELECTS) &&
1380
 
      best_read > (double) session->variables.max_join_size &&
 
1381
  if (!(thd->options & OPTION_BIG_SELECTS) &&
 
1382
      best_read > (double) thd->variables.max_join_size &&
1381
1383
      !(select_options & SELECT_DESCRIBE))
1382
1384
  {                                             /* purecov: inspected */
1383
1385
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1384
1386
    error= -1;
1385
1387
    return(1);
1386
1388
  }
1387
 
  if (const_tables && !session->locked_tables &&
 
1389
  if (const_tables && !thd->locked_tables &&
1388
1390
      !(select_options & SELECT_NO_UNLOCK))
1389
 
    mysql_unlock_some_tables(session, table, const_tables);
 
1391
    mysql_unlock_some_tables(thd, table, const_tables);
1390
1392
  if (!conds && outer_join)
1391
1393
  {
1392
1394
    /* Handle the case where we have an OUTER JOIN without a WHERE */
1432
1434
 
1433
1435
  if (conds &&!outer_join && const_table_map != found_const_table_map && 
1434
1436
      (select_options & SELECT_DESCRIBE) &&
1435
 
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
 
1437
      select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
1436
1438
  {
1437
1439
    conds=new Item_int((int64_t) 0,1);  // Always false
1438
1440
  }
1449
1451
  {
1450
1452
    order_st *org_order= order;
1451
1453
    order=remove_const(this, order,conds,1, &simple_order);
1452
 
    if (session->is_error())
 
1454
    if (thd->is_error())
1453
1455
    {
1454
1456
      error= 1;
1455
1457
      return(1);
1547
1549
    if (order)
1548
1550
      skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1, 
1549
1551
        &tab->table->keys_in_use_for_order_by);
1550
 
    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,
1551
1553
                                          order, fields_list, all_fields,
1552
1554
                                          &all_order_fields_used)))
1553
1555
    {
1579
1581
      else
1580
1582
        group_list= 0;
1581
1583
    }
1582
 
    else if (session->is_fatal_error)                   // End of memory
 
1584
    else if (thd->is_fatal_error)                       // End of memory
1583
1585
      return(1);
1584
1586
  }
1585
1587
  simple_group= 0;
1588
1590
    group_list= remove_const(this, (old_group_list= group_list), conds,
1589
1591
                             rollup.state == ROLLUP::STATE_NONE,
1590
1592
                             &simple_group);
1591
 
    if (session->is_error())
 
1593
    if (thd->is_error())
1592
1594
    {
1593
1595
      error= 1;
1594
1596
      return(1);
1634
1636
              (group_list && order) ||
1635
1637
              test(select_options & OPTION_BUFFER_RESULT)));
1636
1638
 
1637
 
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
1639
  uint no_jbuf_after= make_join_orderinfo(this);
1638
1640
  uint64_t select_opts_for_readinfo= 
1639
1641
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
1640
1642
 
1671
1673
        error= 0;
1672
1674
        return(unit->item->
1673
1675
                    change_engine(new
1674
 
                                  subselect_uniquesubquery_engine(session,
 
1676
                                  subselect_uniquesubquery_engine(thd,
1675
1677
                                                                  join_tab,
1676
1678
                                                                  unit->item,
1677
1679
                                                                  where)));
1685
1687
        error= 0;
1686
1688
        return(unit->item->
1687
1689
                    change_engine(new
1688
 
                                  subselect_indexsubquery_engine(session,
 
1690
                                  subselect_indexsubquery_engine(thd,
1689
1691
                                                                 join_tab,
1690
1692
                                                                 unit->item,
1691
1693
                                                                 where,
1701
1703
      conds= remove_additional_cond(conds);
1702
1704
      save_index_subquery_explain_info(join_tab, conds);
1703
1705
      return(unit->item->
1704
 
                  change_engine(new subselect_indexsubquery_engine(session,
 
1706
                  change_engine(new subselect_indexsubquery_engine(thd,
1705
1707
                                                                   join_tab,
1706
1708
                                                                   unit->item,
1707
1709
                                                                   conds,
1718
1720
  */
1719
1721
  if (need_tmp || select_distinct || group_list || order)
1720
1722
  {
1721
 
    for (uint32_t i = const_tables; i < tables; i++)
 
1723
    for (uint i = const_tables; i < tables; i++)
1722
1724
      join_tab[i].table->prepare_for_position();
1723
1725
  }
1724
1726
 
1735
1737
        (join_tab[const_tables].type != JT_REF_OR_NULL) &&
1736
1738
        ((order && simple_order) || (group_list && simple_group)))
1737
1739
    {
1738
 
      if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
 
1740
      if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
1739
1741
        return(1);
1740
1742
      }
1741
1743
    }
1796
1798
  /* Create a tmp table if distinct or if the sort is too complicated */
1797
1799
  if (need_tmp)
1798
1800
  {
1799
 
    session->set_proc_info("Creating tmp table");
 
1801
    thd_proc_info(thd, "Creating tmp table");
1800
1802
 
1801
1803
    init_items_ref_array();
1802
1804
 
1812
1814
    */
1813
1815
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1814
1816
                             !tmp_group &&
1815
 
                             !session->lex->current_select->with_sum_func) ?
 
1817
                             !thd->lex->current_select->with_sum_func) ?
1816
1818
                            select_limit : HA_POS_ERROR;
1817
1819
 
1818
1820
    if (!(exec_tmp_table1=
1819
 
          create_tmp_table(session, &tmp_table_param, all_fields,
 
1821
          create_tmp_table(thd, &tmp_table_param, all_fields,
1820
1822
                           tmp_group,
1821
1823
                           group_list ? 0 : select_distinct,
1822
1824
                           group_list && simple_group,
1844
1846
    /* if group or order on first table, sort first */
1845
1847
    if (group_list && simple_group)
1846
1848
    {
1847
 
      session->set_proc_info("Sorting for group");
1848
 
      if (create_sort_index(session, this, group_list,
 
1849
      thd_proc_info(thd, "Sorting for group");
 
1850
      if (create_sort_index(thd, this, group_list,
1849
1851
                            HA_POS_ERROR, HA_POS_ERROR, false) ||
1850
1852
          alloc_group_fields(this, group_list) ||
1851
1853
          make_sum_func_list(all_fields, fields_list, 1) ||
1852
 
          setup_sum_funcs(session, sum_funcs))
 
1854
          setup_sum_funcs(thd, sum_funcs))
1853
1855
      {
1854
1856
        return(1);
1855
1857
      }
1858
1860
    else
1859
1861
    {
1860
1862
      if (make_sum_func_list(all_fields, fields_list, 0) ||
1861
 
          setup_sum_funcs(session, sum_funcs))
 
1863
          setup_sum_funcs(thd, sum_funcs))
1862
1864
      {
1863
1865
        return(1);
1864
1866
      }
1865
1867
 
1866
1868
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1867
1869
      {
1868
 
        session->set_proc_info("Sorting for order");
1869
 
        if (create_sort_index(session, this, order,
 
1870
        thd_proc_info(thd, "Sorting for order");
 
1871
        if (create_sort_index(thd, this, order,
1870
1872
                              HA_POS_ERROR, HA_POS_ERROR, true))
1871
1873
        {
1872
1874
          return(1);
1883
1885
 
1884
1886
    if (exec_tmp_table1->distinct)
1885
1887
    {
1886
 
      table_map used_tables= session->used_tables;
 
1888
      table_map used_tables= thd->used_tables;
1887
1889
      JOIN_TAB *last_join_tab= join_tab+tables-1;
1888
1890
      do
1889
1891
      {
1931
1933
{
1932
1934
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1933
1935
                                    select_lex->offset_limit->val_uint() :
1934
 
                                    0UL);
 
1936
                                    0ULL);
1935
1937
 
1936
1938
  first_record= 0;
1937
1939
 
1983
1985
bool
1984
1986
JOIN::init_save_join_tab()
1985
1987
{
1986
 
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1988
  if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
1987
1989
    return 1;                                  /* purecov: inspected */
1988
1990
  error= 0;                                    // Ensure that tmp_join.error= 0
1989
1991
  restore_tmp();
1996
1998
{
1997
1999
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1998
2000
  {
1999
 
    if (!(join_tab_save= (JOIN_TAB*)session->memdup((unsigned char*) join_tab,
 
2001
    if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab,
2000
2002
                                                sizeof(JOIN_TAB) * tables)))
2001
2003
      return 1;
2002
2004
  }
2013
2015
    the query.  It's never shown in EXPLAIN!
2014
2016
 
2015
2017
  @todo
2016
 
    When can we have here session->net.report_error not zero?
 
2018
    When can we have here thd->net.report_error not zero?
2017
2019
*/
2018
2020
void
2019
2021
JOIN::exec()
2021
2023
  List<Item> *columns_list= &fields_list;
2022
2024
  int      tmp_error;
2023
2025
 
2024
 
  session->set_proc_info("executing");
 
2026
  thd_proc_info(thd, "executing");
2025
2027
  error= 0;
2026
2028
  (void) result->prepare2(); // Currently, this cannot fail.
2027
2029
 
2049
2051
        {
2050
2052
          error= (int) result->send_eof();
2051
2053
          send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
2052
 
                         session->sent_row_count);
 
2054
                         thd->sent_row_count);
2053
2055
        }
2054
2056
      }
2055
2057
      else
2059
2061
      }
2060
2062
    }
2061
2063
    /* Single select (without union) always returns 0 or 1 row */
2062
 
    session->limit_found_rows= send_records;
2063
 
    session->examined_row_count= 0;
 
2064
    thd->limit_found_rows= send_records;
 
2065
    thd->examined_row_count= 0;
2064
2066
    return;
2065
2067
  }
2066
2068
  /*
2069
2071
    It must be accumulated from all join iterations of all join parts.
2070
2072
  */
2071
2073
  if (tables)
2072
 
    session->limit_found_rows= 0;
 
2074
    thd->limit_found_rows= 0;
2073
2075
 
2074
2076
  if (zero_result_cause)
2075
2077
  {
2116
2118
    select_describe(this, need_tmp,
2117
2119
                    order != 0 && !skip_sort_order,
2118
2120
                    select_distinct,
2119
 
                    !tables ? "No tables used" : NULL);
 
2121
                    !tables ? "No tables used" : NullS);
2120
2122
    return;
2121
2123
  }
2122
2124
 
2147
2149
    curr_tmp_table= exec_tmp_table1;
2148
2150
 
2149
2151
    /* Copy data to the temporary table */
2150
 
    session->set_proc_info("Copying to tmp table");
 
2152
    thd_proc_info(thd, "Copying to tmp table");
2151
2153
    if (!curr_join->sort_and_group &&
2152
2154
        curr_join->const_tables != curr_join->tables)
2153
2155
      curr_join->join_tab[curr_join->const_tables].sorted= 0;
2168
2170
      items1= items0 + all_fields.elements;
2169
2171
      if (sort_and_group || curr_tmp_table->group)
2170
2172
      {
2171
 
        if (change_to_use_tmp_fields(session, items1,
 
2173
        if (change_to_use_tmp_fields(thd, items1,
2172
2174
                                     tmp_fields_list1, tmp_all_fields1,
2173
2175
                                     fields_list.elements, all_fields))
2174
2176
          return;
2175
2177
      }
2176
2178
      else
2177
2179
      {
2178
 
        if (change_refs_to_tmp_fields(session, items1,
 
2180
        if (change_refs_to_tmp_fields(thd, items1,
2179
2181
                                      tmp_fields_list1, tmp_all_fields1,
2180
2182
                                      fields_list.elements, all_fields))
2181
2183
          return;
2248
2250
          curr_join->tmp_table_param.precomputed_group_by= true;
2249
2251
 
2250
2252
        if (!(curr_tmp_table=
2251
 
              exec_tmp_table2= create_tmp_table(session,
 
2253
              exec_tmp_table2= create_tmp_table(thd,
2252
2254
                                                &curr_join->tmp_table_param,
2253
2255
                                                *curr_all_fields,
2254
2256
                                                (order_st*) 0,
2262
2264
      }
2263
2265
      if (curr_join->group_list)
2264
2266
      {
2265
 
        session->set_proc_info("Creating sort index");
 
2267
        thd_proc_info(thd, "Creating sort index");
2266
2268
        if (curr_join->join_tab == join_tab && save_join_tab())
2267
2269
        {
2268
2270
          return;
2269
2271
        }
2270
 
        if (create_sort_index(session, curr_join, curr_join->group_list,
 
2272
        if (create_sort_index(thd, curr_join, curr_join->group_list,
2271
2273
                              HA_POS_ERROR, HA_POS_ERROR, false) ||
2272
2274
            make_group_fields(this, curr_join))
2273
2275
        {
2276
2278
        sortorder= curr_join->sortorder;
2277
2279
      }
2278
2280
      
2279
 
      session->set_proc_info("Copying to group table");
 
2281
      thd_proc_info(thd, "Copying to group table");
2280
2282
      tmp_error= -1;
2281
2283
      if (curr_join != this)
2282
2284
      {
2299
2301
      if (!curr_join->sort_and_group &&
2300
2302
          curr_join->const_tables != curr_join->tables)
2301
2303
        curr_join->join_tab[curr_join->const_tables].sorted= 0;
2302
 
      if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
 
2304
      if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2303
2305
          (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2304
2306
      {
2305
2307
        error= tmp_error;
2313
2315
      if (!items2)
2314
2316
      {
2315
2317
        items2= items1 + all_fields.elements;
2316
 
        if (change_to_use_tmp_fields(session, items2,
 
2318
        if (change_to_use_tmp_fields(thd, items2,
2317
2319
                                     tmp_fields_list2, tmp_all_fields2, 
2318
2320
                                     fields_list.elements, tmp_all_fields1))
2319
2321
          return;
2333
2335
    curr_join->join_free();                     /* Free quick selects */
2334
2336
    if (curr_join->select_distinct && ! curr_join->group_list)
2335
2337
    {
2336
 
      session->set_proc_info("Removing duplicates");
 
2338
      thd_proc_info(thd, "Removing duplicates");
2337
2339
      if (curr_join->tmp_having)
2338
2340
        curr_join->tmp_having->update_used_tables();
2339
2341
      if (remove_duplicates(curr_join, curr_tmp_table,
2362
2364
      if (!items0)
2363
2365
        init_items_ref_array();
2364
2366
      items3= ref_pointer_array + (all_fields.elements*4);
2365
 
      setup_copy_fields(session, &curr_join->tmp_table_param,
 
2367
      setup_copy_fields(thd, &curr_join->tmp_table_param,
2366
2368
                        items3, tmp_fields_list3, tmp_all_fields3,
2367
2369
                        curr_fields_list->elements, *curr_all_fields);
2368
2370
      tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2385
2387
 
2386
2388
    if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
2387
2389
                                      1, true) || 
2388
 
        setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2389
 
        session->is_fatal_error)
 
2390
        setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
 
2391
        thd->is_fatal_error)
2390
2392
      return;
2391
2393
  }
2392
2394
  if (curr_join->group_list || curr_join->order)
2393
2395
  {
2394
 
    session->set_proc_info("Sorting result");
 
2396
    thd_proc_info(thd, "Sorting result");
2395
2397
    /* If we have already done the group, add HAVING to sorted table */
2396
2398
    if (curr_join->tmp_having && ! curr_join->group_list && 
2397
2399
        ! curr_join->sort_and_group)
2437
2439
      else
2438
2440
      {
2439
2441
        /*
2440
 
          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
2441
2443
          WHERE clause for any tables after the sorted one.
2442
2444
        */
2443
2445
        JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
2470
2472
        the query. XXX: it's never shown in EXPLAIN!
2471
2473
        OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2472
2474
      */
2473
 
      if (create_sort_index(session, curr_join,
 
2475
      if (create_sort_index(thd, curr_join,
2474
2476
                            curr_join->group_list ? 
2475
2477
                            curr_join->group_list : curr_join->order,
2476
2478
                            curr_join->select_limit,
2491
2493
      }
2492
2494
    }
2493
2495
  }
2494
 
  /* XXX: When can we have here session->is_error() not zero? */
2495
 
  if (session->is_error())
 
2496
  /* XXX: When can we have here thd->is_error() not zero? */
 
2497
  if (thd->is_error())
2496
2498
  {
2497
 
    error= session->is_error();
 
2499
    error= thd->is_error();
2498
2500
    return;
2499
2501
  }
2500
2502
  curr_join->having= curr_join->tmp_having;
2501
2503
  curr_join->fields= curr_fields_list;
2502
2504
 
2503
2505
  {
2504
 
    session->set_proc_info("Sending data");
 
2506
    thd_proc_info(thd, "Sending data");
2505
2507
    result->send_fields(*curr_fields_list,
2506
2508
                        Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2507
2509
    error= do_select(curr_join, curr_fields_list, NULL);
2508
 
    session->limit_found_rows= curr_join->send_records;
 
2510
    thd->limit_found_rows= curr_join->send_records;
2509
2511
  }
2510
2512
 
2511
2513
  /* Accumulate the counts from all join iterations of all join parts. */
2512
 
  session->examined_row_count+= curr_join->examined_rows;
 
2514
  thd->examined_row_count+= curr_join->examined_rows;
2513
2515
 
2514
2516
  /* 
2515
2517
    With EXPLAIN EXTENDED we have to restore original ref_array
2517
2519
    Otherwise we would not be able to print the query  correctly.
2518
2520
  */ 
2519
2521
  if (items0 &&
2520
 
      (session->lex->describe & DESCRIBE_EXTENDED) &&
 
2522
      (thd->lex->describe & DESCRIBE_EXTENDED) &&
2521
2523
      select_lex->linkage == DERIVED_TABLE_TYPE)      
2522
2524
    set_items_ref_array(items0);
2523
2525
 
2553
2555
 
2554
2556
  cleanup(1);
2555
2557
  if (exec_tmp_table1)
2556
 
    exec_tmp_table1->free_tmp_table(session);
 
2558
    exec_tmp_table1->free_tmp_table(thd);
2557
2559
  if (exec_tmp_table2)
2558
 
    exec_tmp_table2->free_tmp_table(session);
 
2560
    exec_tmp_table2->free_tmp_table(thd);
2559
2561
  delete select;
2560
2562
  delete_dynamic(&keyuse);
2561
2563
  return(error);
2566
2568
/**
2567
2569
  An entry point to single-unit select (a select without UNION).
2568
2570
 
2569
 
  @param session                  thread handler
 
2571
  @param thd                  thread handler
2570
2572
  @param rref_pointer_array   a reference to ref_pointer_array of
2571
2573
                              the top-level select_lex for this query
2572
2574
  @param tables               list of all tables used in this query.
2608
2610
*/
2609
2611
 
2610
2612
bool
2611
 
mysql_select(Session *session, Item ***rref_pointer_array,
2612
 
             TableList *tables, uint32_t wild_num, List<Item> &fields,
2613
 
             COND *conds, uint32_t og_num,  order_st *order, order_st *group,
 
2613
mysql_select(THD *thd, Item ***rref_pointer_array,
 
2614
             TableList *tables, uint wild_num, List<Item> &fields,
 
2615
             COND *conds, uint og_num,  order_st *order, order_st *group,
2614
2616
             Item *having, order_st *proc_param, uint64_t select_options,
2615
2617
             select_result *result, SELECT_LEX_UNIT *unit,
2616
2618
             SELECT_LEX *select_lex)
2653
2655
  }
2654
2656
  else
2655
2657
  {
2656
 
    if (!(join= new JOIN(session, fields, select_options, result)))
 
2658
    if (!(join= new JOIN(thd, fields, select_options, result)))
2657
2659
        return(true);
2658
 
    session->set_proc_info("init");
2659
 
    session->used_tables=0;                         // Updated by setup_fields
 
2660
    thd_proc_info(thd, "init");
 
2661
    thd->used_tables=0;                         // Updated by setup_fields
2660
2662
    if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2661
2663
                           conds, og_num, order, group, having, proc_param,
2662
2664
                           select_lex, unit)) == true)
2678
2680
    goto err;                                   // 1
2679
2681
  }
2680
2682
 
2681
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
2683
  if (thd->lex->describe & DESCRIBE_EXTENDED)
2682
2684
  {
2683
2685
    join->conds_history= join->conds;
2684
2686
    join->having_history= (join->having?join->having:join->tmp_having);
2685
2687
  }
2686
2688
 
2687
 
  if (session->is_error())
 
2689
  if (thd->is_error())
2688
2690
    goto err;
2689
2691
 
2690
2692
  join->exec();
2691
2693
 
2692
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
2694
  if (thd->lex->describe & DESCRIBE_EXTENDED)
2693
2695
  {
2694
2696
    select_lex->where= join->conds_history;
2695
2697
    select_lex->having= join->having_history;
2698
2700
err:
2699
2701
  if (free_join)
2700
2702
  {
2701
 
    session->set_proc_info("end");
 
2703
    thd_proc_info(thd, "end");
2702
2704
    err|= select_lex->cleanup();
2703
 
    return(err || session->is_error());
 
2705
    return(err || thd->is_error());
2704
2706
  }
2705
2707
  return(join->error);
2706
2708
}
2720
2722
}
2721
2723
 
2722
2724
 
2723
 
static TableList *alloc_join_nest(Session *session)
 
2725
static TableList *alloc_join_nest(THD *thd)
2724
2726
{
2725
2727
  TableList *tbl;
2726
 
  if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
 
2728
  if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
2727
2729
                                       sizeof(nested_join_st))))
2728
2730
    return NULL;
2729
 
  tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl + 
 
2731
  tbl->nested_join= (nested_join_st*) ((uchar*)tbl + 
2730
2732
                                    ALIGN_SIZE(sizeof(TableList)));
2731
2733
  return tbl;
2732
2734
}
2779
2781
  SELECT_LEX *parent_lex= parent_join->select_lex;
2780
2782
  TableList *emb_tbl_nest= NULL;
2781
2783
  List<TableList> *emb_join_list= &parent_lex->top_join_list;
2782
 
  Session *session= parent_join->session;
 
2784
  THD *thd= parent_join->thd;
2783
2785
 
2784
2786
  /*
2785
2787
    1. Find out where to put the predicate into.
2836
2838
        A3: changes in the TableList::outer_join will make everything work
2837
2839
            automatically.
2838
2840
      */
2839
 
      if (!(wrap_nest= alloc_join_nest(parent_join->session)))
 
2841
      if (!(wrap_nest= alloc_join_nest(parent_join->thd)))
2840
2842
      {
2841
2843
        return(true);
2842
2844
      }
2881
2883
 
2882
2884
  TableList *sj_nest;
2883
2885
  nested_join_st *nested_join;
2884
 
  if (!(sj_nest= alloc_join_nest(parent_join->session)))
 
2886
  if (!(sj_nest= alloc_join_nest(parent_join->thd)))
2885
2887
  {
2886
2888
    return(true);
2887
2889
  }
2942
2944
  /*TODO: also reset the 'with_subselect' there. */
2943
2945
 
2944
2946
  /* n. Adjust the parent_join->tables counter */
2945
 
  uint32_t table_no= parent_join->tables;
 
2947
  uint table_no= parent_join->tables;
2946
2948
  /* n. Walk through child's tables and adjust table->map */
2947
2949
  for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
2948
2950
  {
2959
2961
    Put the subquery's WHERE into semi-join's sj_on_expr
2960
2962
    Add the subquery-induced equalities too.
2961
2963
  */
2962
 
  SELECT_LEX *save_lex= session->lex->current_select;
2963
 
  session->lex->current_select=subq_lex;
 
2964
  SELECT_LEX *save_lex= thd->lex->current_select;
 
2965
  thd->lex->current_select=subq_lex;
2964
2966
  if (!subq_pred->left_expr->fixed &&
2965
 
       subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
 
2967
       subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
2966
2968
    return(true);
2967
 
  session->lex->current_select=save_lex;
 
2969
  thd->lex->current_select=save_lex;
2968
2970
 
2969
2971
  sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2970
2972
  sj_nest->nested_join->sj_depends_on=  subq_pred->used_tables() |
3000
3002
  }
3001
3003
  else
3002
3004
  {
3003
 
    for (uint32_t i= 0; i < subq_pred->left_expr->cols(); i++)
 
3005
    for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
3004
3006
    {
3005
3007
      nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->
3006
3008
                                                element_index(i));
3012
3014
    }
3013
3015
  }
3014
3016
  /* Fix the created equality and AND */
3015
 
  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);
3016
3018
 
3017
3019
  /*
3018
3020
    Walk through sj nest's WHERE and ON expressions and call
3030
3032
  {
3031
3033
    emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr, 
3032
3034
                                     sj_nest->sj_on_expr);
3033
 
    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);
3034
3036
  }
3035
3037
  else
3036
3038
  {
3037
3039
    /* Inject into the WHERE */
3038
3040
    parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
3039
 
    parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
 
3041
    parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
3040
3042
    parent_join->select_lex->where= parent_join->conds;
3041
3043
  }
3042
3044
 
3125
3127
    if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
3126
3128
      return(true);
3127
3129
 
3128
 
    //if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
 
3130
    //if ((*in_subq)->fix_fields(thd, (*in_subq)->ref_ptr))
3129
3131
    //  return(true);
3130
3132
  }
3131
3133
  sj_subselects.clear();
3202
3204
bool find_eq_ref_candidate(Table *table, table_map sj_inner_tables)
3203
3205
{
3204
3206
  KEYUSE *keyuse= table->reginfo.join_tab->keyuse;
3205
 
  uint32_t key;
 
3207
  uint key;
3206
3208
 
3207
3209
  if (keyuse)
3208
3210
  {
3366
3368
*****************************************************************************/
3367
3369
 
3368
3370
 
3369
 
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
 
3371
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
3370
3372
                                      Table *table,
3371
3373
                                      const key_map *keys,ha_rows limit)
3372
3374
{
3373
3375
  int error;
3374
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
 
3376
  if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
3375
3377
    return(0);                           // Fatal error flag is set
3376
3378
  if (select)
3377
3379
  {
3378
3380
    select->head=table;
3379
3381
    table->reginfo.impossible_range=0;
3380
 
    if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
 
3382
    if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
3381
3383
                                          limit, 0, false)) == 1)
3382
3384
      return(select->quick->records);
3383
3385
    if (error == -1)
3400
3402
{
3401
3403
  Field *field;              /* field against which to check sargability */
3402
3404
  Item **arg_value;          /* values of potential keys for lookups     */
3403
 
  uint32_t num_values;           /* number of values in the above array      */
 
3405
  uint num_values;           /* number of values in the above array      */
3404
3406
} SARGABLE_PARAM;  
3405
3407
 
3406
3408
/**
3418
3420
{
3419
3421
  int error;
3420
3422
  Table *table;
3421
 
  uint32_t i,table_count,const_count,key;
 
3423
  uint i,table_count,const_count,key;
3422
3424
  table_map found_const_table_map, all_table_map, found_ref, refs;
3423
3425
  key_map const_ref, eq_part;
3424
3426
  Table **table_vector;
3429
3431
  JOIN_TAB *stat_vector[MAX_TABLES+1];
3430
3432
 
3431
3433
  table_count=join->tables;
3432
 
  stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
3433
 
  stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3434
 
  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));
3435
3437
  if (!stat || !stat_ref || !table_vector)
3436
3438
    return(1);                          // Eom /* purecov: inspected */
3437
3439
 
3527
3529
    */
3528
3530
    for (i= 0, s= stat ; i < table_count ; i++, s++)
3529
3531
    {
3530
 
      for (uint32_t j= 0 ; j < table_count ; j++)
 
3532
      for (uint j= 0 ; j < table_count ; j++)
3531
3533
      {
3532
3534
        table= stat[j].table;
3533
3535
        if (s->dependent & table->map)
3550
3552
  }
3551
3553
 
3552
3554
  if (conds || outer_join)
3553
 
    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,
3554
3556
                            conds, join->cond_equal,
3555
3557
                            ~outer_join, join->select_lex, &sargables))
3556
3558
      return(1);
3724
3726
      key_map possible_keys= field->key_start;
3725
3727
      possible_keys.intersect(field->table->keys_in_use_for_query);
3726
3728
      bool is_const= 1;
3727
 
      for (uint32_t j=0; j < sargables->num_values; j++)
 
3729
      for (uint j=0; j < sargables->num_values; j++)
3728
3730
        is_const&= sargables->arg_value[j]->const_item();
3729
3731
      if (is_const)
3730
3732
        join_tab[0].const_keys.merge(possible_keys);
3753
3755
      This is can't be to high as otherwise we are likely to use
3754
3756
      table scan.
3755
3757
    */
3756
 
    s->worst_seeks= cmin((double) s->found_records / 10,
 
3758
    s->worst_seeks= min((double) s->found_records / 10,
3757
3759
                        (double) s->read_time*3);
3758
3760
    if (s->worst_seeks < 2.0)                   // Fix for small tables
3759
3761
      s->worst_seeks=2.0;
3775
3777
                          1, &error);
3776
3778
      if (!select)
3777
3779
        return(1);
3778
 
      records= get_quick_record_count(join->session, select, s->table,
 
3780
      records= get_quick_record_count(join->thd, select, s->table,
3779
3781
                                      &s->const_keys, join->row_limit);
3780
3782
      s->quick=select->quick;
3781
3783
      s->needed_reg=select->needed_reg;
3829
3831
    join->best_read=1.0;
3830
3832
  }
3831
3833
  /* Generate an execution plan from the found optimal join order. */
3832
 
  return(join->session->killed || get_best_combination(join));
 
3834
  return(join->thd->killed || get_best_combination(join));
3833
3835
}
3834
3836
 
3835
3837
 
3854
3856
  */
3855
3857
  bool          null_rejecting; 
3856
3858
  bool          *cond_guard; /* See KEYUSE::cond_guard */
3857
 
  uint32_t          sj_pred_no; /* See KEYUSE::sj_pred_no */
 
3859
  uint          sj_pred_no; /* See KEYUSE::sj_pred_no */
3858
3860
} KEY_FIELD;
3859
3861
 
3860
3862
/**
3883
3885
 
3884
3886
static KEY_FIELD *
3885
3887
merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
3886
 
                 uint32_t and_level)
 
3888
                 uint and_level)
3887
3889
{
3888
3890
  if (start == new_fields)
3889
3891
    return start;                               // Impossible or
4010
4012
*/
4011
4013
 
4012
4014
static void
4013
 
add_key_field(KEY_FIELD **key_fields,uint32_t and_level, Item_func *cond,
4014
 
              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,
4015
4017
              table_map usable_tables, SARGABLE_PARAM **sargables)
4016
4018
{
4017
 
  uint32_t exists_optimize= 0;
 
4019
  uint exists_optimize= 0;
4018
4020
  if (!(field->flags & PART_KEY_FLAG))
4019
4021
  {
4020
4022
    // Don't remove column IS NULL on a LEFT JOIN table
4028
4030
  {
4029
4031
    table_map used_tables=0;
4030
4032
    bool optimizable=0;
4031
 
    for (uint32_t i=0; i<num_values; i++)
 
4033
    for (uint i=0; i<num_values; i++)
4032
4034
    {
4033
4035
      used_tables|=(value[i])->used_tables();
4034
4036
      if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
4064
4066
      stat[0].key_dependent|=used_tables;
4065
4067
 
4066
4068
      bool is_const=1;
4067
 
      for (uint32_t i=0; i<num_values; i++)
 
4069
      for (uint i=0; i<num_values; i++)
4068
4070
      {
4069
4071
        if (!(is_const&= value[i]->const_item()))
4070
4072
          break;
4182
4184
*/
4183
4185
 
4184
4186
static void
4185
 
add_key_equal_fields(KEY_FIELD **key_fields, uint32_t and_level,
 
4187
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
4186
4188
                     Item_func *cond, Item_field *field_item,
4187
4189
                     bool eq_func, Item **val,
4188
 
                     uint32_t num_values, table_map usable_tables,
 
4190
                     uint num_values, table_map usable_tables,
4189
4191
                     SARGABLE_PARAM **sargables)
4190
4192
{
4191
4193
  Field *field= field_item->field;
4213
4215
}
4214
4216
 
4215
4217
static void
4216
 
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,
4217
4219
               COND *cond, table_map usable_tables,
4218
4220
               SARGABLE_PARAM **sargables)
4219
4221
{
4306
4308
    if (cond_func->functype() == Item_func::BETWEEN)
4307
4309
    {
4308
4310
      values= cond_func->arguments();
4309
 
      for (uint32_t i= 1 ; i < cond_func->argument_count() ; i++)
 
4311
      for (uint i= 1 ; i < cond_func->argument_count() ; i++)
4310
4312
      {
4311
4313
        Item_field *field_item;
4312
4314
        if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM
4417
4419
static uint
4418
4420
max_part_bit(key_part_map bits)
4419
4421
{
4420
 
  uint32_t found;
 
4422
  uint found;
4421
4423
  for (found=0; bits & 1 ; found++,bits>>=1) ;
4422
4424
  return found;
4423
4425
}
4431
4433
 
4432
4434
  if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
4433
4435
  {
4434
 
    for (uint32_t key= 0 ; key < form->sizeKeys() ; key++)
 
4436
    for (uint key= 0 ; key < form->sizeKeys() ; key++)
4435
4437
    {
4436
4438
      if (!(form->keys_in_use_for_query.is_set(key)))
4437
4439
        continue;
4438
4440
 
4439
 
      uint32_t key_parts= (uint) form->key_info[key].key_parts;
4440
 
      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++)
4441
4443
      {
4442
4444
        if (field->eq(form->key_info[key].key_part[part].field))
4443
4445
        {
4451
4453
          keyuse.null_rejecting= key_field->null_rejecting;
4452
4454
          keyuse.cond_guard= key_field->cond_guard;
4453
4455
          keyuse.sj_pred_no= key_field->sj_pred_no;
4454
 
          insert_dynamic(keyuse_array,(unsigned char*) &keyuse);
 
4456
          VOID(insert_dynamic(keyuse_array,(uchar*) &keyuse));
4455
4457
        }
4456
4458
      }
4457
4459
    }
4514
4516
*/
4515
4517
 
4516
4518
static void add_key_fields_for_nj(JOIN *join, TableList *nested_join_table,
4517
 
                                  KEY_FIELD **end, uint32_t *and_level,
 
4519
                                  KEY_FIELD **end, uint *and_level,
4518
4520
                                  SARGABLE_PARAM **sargables)
4519
4521
{
4520
4522
  List_iterator<TableList> li(nested_join_table->nested_join->join_list);
4552
4554
/**
4553
4555
  Update keyuse array with all possible keys we can use to fetch rows.
4554
4556
  
4555
 
  @param       session 
 
4557
  @param       thd 
4556
4558
  @param[out]  keyuse         Put here ordered array of KEYUSE structures
4557
4559
  @param       join_tab       Array in tablenr_order
4558
4560
  @param       tables         Number of tables in join
4571
4573
*/
4572
4574
 
4573
4575
static bool
4574
 
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4575
 
                    uint32_t tables, COND *cond, COND_EQUAL *,
 
4576
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
 
4577
                    uint tables, COND *cond,
 
4578
                    COND_EQUAL *cond_equal __attribute__((unused)),
4576
4579
                    table_map normal_tables, SELECT_LEX *select_lex,
4577
4580
                    SARGABLE_PARAM **sargables)
4578
4581
{
4579
4582
  uint  and_level,i,found_eq_constant;
4580
4583
  KEY_FIELD *key_fields, *end, *field;
4581
 
  uint32_t sz;
4582
 
  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);
4583
4586
  
4584
4587
  /* 
4585
4588
    We use the same piece of memory to store both  KEY_FIELD 
4602
4605
    can be not more than select_lex->max_equal_elems such 
4603
4606
    substitutions.
4604
4607
  */ 
4605
 
  sz= cmax(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
4606
 
      (((session->lex->current_select->cond_count+1)*2 +
4607
 
        session->lex->current_select->between_count)*m+1);
4608
 
  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)))
4609
4612
    return true; /* purecov: inspected */
4610
4613
  and_level= 0;
4611
4614
  field= end= key_fields;
4679
4682
          (qsort_cmp) sort_keyuse);
4680
4683
 
4681
4684
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
4682
 
    insert_dynamic(keyuse,(unsigned char*) &key_end);
 
4685
    VOID(insert_dynamic(keyuse,(uchar*) &key_end));
4683
4686
 
4684
4687
    use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
4685
4688
    prev= &key_end;
4712
4715
      save_pos++;
4713
4716
    }
4714
4717
    i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
4715
 
    set_dynamic(keyuse,(unsigned char*) &key_end,i);
 
4718
    VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
4716
4719
    keyuse->elements=i;
4717
4720
  }
4718
4721
  return false;
4742
4745
        (map= (keyuse->used_tables & ~join->const_table_map &
4743
4746
               ~OUTER_REF_TABLE_BIT)))
4744
4747
    {
4745
 
      uint32_t tablenr;
 
4748
      uint tablenr;
4746
4749
      for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
4747
4750
      if (map == 1)                     // Only one table
4748
4751
      {
4749
4752
        Table *tmp_table=join->all_tables[tablenr];
4750
 
        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);
4751
4754
      }
4752
4755
    }
4753
4756
    /*
4791
4794
  { /* Collect all query fields referenced in the GROUP clause. */
4792
4795
    for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
4793
4796
      (*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
4794
 
                               (unsigned char*) &indexed_fields);
 
4797
                               (uchar*) &indexed_fields);
4795
4798
  }
4796
4799
  else if (join->select_distinct)
4797
4800
  { /* Collect all query fields referenced in the SELECT clause. */
4800
4803
    Item *item;
4801
4804
    while ((item= select_items_it++))
4802
4805
      item->walk(&Item::collect_item_field_processor, 0,
4803
 
                 (unsigned char*) &indexed_fields);
 
4806
                 (uchar*) &indexed_fields);
4804
4807
  }
4805
4808
  else
4806
4809
    return;
4829
4832
/** Save const tables first as used tables. */
4830
4833
 
4831
4834
static void
4832
 
set_position(JOIN *join,uint32_t idx,JOIN_TAB *table,KEYUSE *key)
 
4835
set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
4833
4836
{
4834
4837
  join->positions[idx].table= table;
4835
4838
  join->positions[idx].key=key;
4871
4874
{
4872
4875
  List_iterator<Item> li(sj_nest->nested_join->sj_outer_expr_list);
4873
4876
  Item *item;
4874
 
  uint32_t i= 0;
 
4877
  uint i= 0;
4875
4878
  uint64_t res= 0;
4876
4879
  while ((item= li++))
4877
4880
  {
4883
4886
    */
4884
4887
    if (!(item->used_tables() & remaining_tables))
4885
4888
    {
4886
 
      res |= 1UL < i;
 
4889
      res |= 1ULL < i;
4887
4890
    }
4888
4891
  }
4889
4892
  return res;
4904
4907
  @param join             pointer to the structure providing all context info
4905
4908
                          for the query
4906
4909
  @param s                the table to be joined by the function
4907
 
  @param session              thread for the connection that submitted the query
 
4910
  @param thd              thread for the connection that submitted the query
4908
4911
  @param remaining_tables set of tables not included into the partial plan yet
4909
4912
  @param idx              the length of the partial plan
4910
4913
  @param record_count     estimate for the number of records returned by the
4918
4921
static void
4919
4922
best_access_path(JOIN      *join,
4920
4923
                 JOIN_TAB  *s,
4921
 
                 Session       *session,
 
4924
                 THD       *thd,
4922
4925
                 table_map remaining_tables,
4923
 
                 uint32_t      idx,
 
4926
                 uint      idx,
4924
4927
                 double    record_count,
4925
 
                 double)
 
4928
                 double    read_time __attribute__((unused)))
4926
4929
{
4927
4930
  KEYUSE *best_key=         0;
4928
 
  uint32_t best_max_key_part=   0;
 
4931
  uint best_max_key_part=   0;
4929
4932
  bool found_constraint= 0;
4930
4933
  double best=              DBL_MAX;
4931
4934
  double best_time=         DBL_MAX;
4933
4936
  table_map best_ref_depends_map= 0;
4934
4937
  double tmp;
4935
4938
  ha_rows rec;
4936
 
  uint32_t best_is_sj_inside_out=    0;
 
4939
  uint best_is_sj_inside_out=    0;
4937
4940
 
4938
4941
  if (s->keyuse)
4939
4942
  {                                            /* Use key if possible */
4971
4974
    {
4972
4975
      key_part_map found_part= 0;
4973
4976
      table_map found_ref= 0;
4974
 
      uint32_t key= keyuse->key;
 
4977
      uint key= keyuse->key;
4975
4978
      KEY *keyinfo= table->key_info+key;
4976
4979
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
4977
4980
      key_part_map const_part= 0;
4985
4988
 
4986
4989
      do /* For each keypart */
4987
4990
      {
4988
 
        uint32_t keypart= keyuse->keypart;
 
4991
        uint keypart= keyuse->keypart;
4989
4992
        table_map best_part_found_ref= 0;
4990
4993
        double best_prev_record_reads= DBL_MAX;
4991
4994
        
5024
5027
          if (try_sj_inside_out && keyuse->sj_pred_no != UINT_MAX)
5025
5028
          {
5026
5029
            if (!(remaining_tables & keyuse->used_tables))
5027
 
              bound_sj_equalities |= 1UL << keyuse->sj_pred_no;
 
5030
              bound_sj_equalities |= 1ULL << keyuse->sj_pred_no;
5028
5031
            else
5029
5032
            {
5030
 
              handled_sj_equalities |= 1UL << keyuse->sj_pred_no;
 
5033
              handled_sj_equalities |= 1ULL << keyuse->sj_pred_no;
5031
5034
              sj_insideout_map |= ((key_part_map)1) << keyuse->keypart;
5032
5035
            }
5033
5036
          }
5061
5064
            (handled_sj_equalities | bound_sj_equalities) ==     // (1)
5062
5065
            PREV_BITS(uint64_t, s->emb_sj_nest->sj_in_exprs)) // (1)
5063
5066
        {
5064
 
          uint32_t n_fixed_parts= max_part_bit(found_part);
 
5067
          uint n_fixed_parts= max_part_bit(found_part);
5065
5068
          if (n_fixed_parts != keyinfo->key_parts &&
5066
5069
              (PREV_BITS(uint, n_fixed_parts) | sj_insideout_map) ==
5067
5070
               PREV_BITS(uint, keyinfo->key_parts))
5169
5172
            }
5170
5173
            /* Limit the number of matched rows */
5171
5174
            tmp= records;
5172
 
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
 
5175
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5173
5176
            if (table->covering_keys.is_set(key))
5174
5177
            {
5175
5178
              /* we can use only index tree */
5176
5179
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5177
5180
            }
5178
5181
            else
5179
 
              tmp= record_count*cmin(tmp,s->worst_seeks);
 
5182
              tmp= record_count*min(tmp,s->worst_seeks);
5180
5183
          }
5181
5184
        }
5182
5185
        else
5232
5235
            */
5233
5236
            if (table->quick_keys.is_set(key) && !found_ref &&          //(C1)
5234
5237
                table->quick_key_parts[key] == max_key_part &&          //(C2)
5235
 
                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)
5236
5239
            {
5237
5240
              tmp= records= (double) table->quick_rows[key];
5238
5241
            }
5300
5303
                    tmp= a;
5301
5304
                  set_if_bigger(tmp,1.0);
5302
5305
                }
5303
 
                records = (uint32_t) tmp;
 
5306
                records = (ulong) tmp;
5304
5307
              }
5305
5308
 
5306
5309
              if (ref_or_null_part)
5325
5328
              if (table->quick_keys.is_set(key) &&
5326
5329
                  table->quick_key_parts[key] <= max_key_part &&
5327
5330
                  const_part & (1 << table->quick_key_parts[key]) &&
5328
 
                  table->quick_n_ranges[key] == 1 + ((ref_or_null_part &
5329
 
                                                     const_part) ? 1 : 0) &&
 
5331
                  table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
 
5332
                                                         const_part) &&
5330
5333
                  records > (double) table->quick_rows[key])
5331
5334
              {
5332
5335
                tmp= records= (double) table->quick_rows[key];
5334
5337
            }
5335
5338
 
5336
5339
            /* Limit the number of matched rows */
5337
 
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
 
5340
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
5338
5341
            if (table->covering_keys.is_set(key))
5339
5342
            {
5340
5343
              /* we can use only index tree */
5341
5344
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5342
5345
            }
5343
5346
            else
5344
 
              tmp= record_count * cmin(tmp,s->worst_seeks);
 
5347
              tmp= record_count * min(tmp,s->worst_seeks);
5345
5348
          }
5346
5349
          else
5347
5350
            tmp= best_time;                    // Do nothing
5464
5467
        /* We read the table as many times as join buffer becomes full. */
5465
5468
        tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5466
5469
                           record_count /
5467
 
                           (double) session->variables.join_buff_size));
 
5470
                           (double) thd->variables.join_buff_size));
5468
5471
        /* 
5469
5472
            We don't make full cartesian product between rows in the scanned
5470
5473
           table and existing records because we skip all rows from the
5542
5545
static bool
5543
5546
choose_plan(JOIN *join, table_map join_tables)
5544
5547
{
5545
 
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
5546
 
  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;
5547
5550
  bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5548
5551
 
5549
5552
  join->cur_embedding_map= 0;
5591
5594
    i.e. they have subqueries, unions or call stored procedures.
5592
5595
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
5593
5596
  */
5594
 
  if (join->session->lex->is_single_level_stmt())
5595
 
    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;
5596
5599
  return(false);
5597
5600
}
5598
5601
 
5677
5680
 
5678
5681
  @todo
5679
5682
    this value should be determined dynamically, based on statistics:
5680
 
    uint32_t max_tables_for_exhaustive_opt= 7;
 
5683
    uint max_tables_for_exhaustive_opt= 7;
5681
5684
 
5682
5685
  @todo
5683
5686
    this value could be determined by some mapping of the form:
5692
5695
static uint
5693
5696
determine_search_depth(JOIN *join)
5694
5697
{
5695
 
  uint32_t table_count=  join->tables - join->const_tables;
5696
 
  uint32_t search_depth;
 
5698
  uint table_count=  join->tables - join->const_tables;
 
5699
  uint search_depth;
5697
5700
  /* TODO: this value should be determined dynamically, based on statistics: */
5698
 
  uint32_t max_tables_for_exhaustive_opt= 7;
 
5701
  uint max_tables_for_exhaustive_opt= 7;
5699
5702
 
5700
5703
  if (table_count <= max_tables_for_exhaustive_opt)
5701
5704
    search_depth= table_count+1; // use exhaustive for small number of tables
5737
5740
optimize_straight_join(JOIN *join, table_map join_tables)
5738
5741
{
5739
5742
  JOIN_TAB *s;
5740
 
  uint32_t idx= join->const_tables;
 
5743
  uint idx= join->const_tables;
5741
5744
  double    record_count= 1.0;
5742
5745
  double    read_time=    0.0;
5743
5746
 
5745
5748
  {
5746
5749
    /* Find the best access method from 's' to the current partial plan */
5747
5750
    advance_sj_state(join_tables, s);
5748
 
    best_access_path(join, s, join->session, join_tables, idx,
 
5751
    best_access_path(join, s, join->thd, join_tables, idx,
5749
5752
                     record_count, read_time);
5750
5753
    /* compute the cost of the new plan extended with 's' */
5751
5754
    record_count*= join->positions[idx].records_read;
5847
5850
static bool
5848
5851
greedy_search(JOIN      *join,
5849
5852
              table_map remaining_tables,
5850
 
              uint32_t      search_depth,
5851
 
              uint32_t      prune_level)
 
5853
              uint      search_depth,
 
5854
              uint      prune_level)
5852
5855
{
5853
5856
  double    record_count= 1.0;
5854
5857
  double    read_time=    0.0;
5855
 
  uint32_t      idx= join->const_tables; // index into 'join->best_ref'
5856
 
  uint32_t      best_idx;
5857
 
  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
5858
5861
  POSITION  best_pos;
5859
5862
  JOIN_TAB  *best_table; // the next plan node to be added to the curr QEP
5860
5863
 
6027
6030
static bool
6028
6031
best_extension_by_limited_search(JOIN      *join,
6029
6032
                                 table_map remaining_tables,
6030
 
                                 uint32_t      idx,
 
6033
                                 uint      idx,
6031
6034
                                 double    record_count,
6032
6035
                                 double    read_time,
6033
 
                                 uint32_t      search_depth,
6034
 
                                 uint32_t      prune_level)
 
6036
                                 uint      search_depth,
 
6037
                                 uint      prune_level)
6035
6038
{
6036
 
  Session *session= join->session;
6037
 
  if (session->killed)  // Abort
 
6039
  THD *thd= join->thd;
 
6040
  if (thd->killed)  // Abort
6038
6041
    return(true);
6039
6042
 
6040
6043
  /* 
6063
6066
          when the depth is insufficient??)
6064
6067
      */
6065
6068
      /* Find the best access method from 's' to the current partial plan */
6066
 
      best_access_path(join, s, session, remaining_tables, idx,
 
6069
      best_access_path(join, s, thd, remaining_tables, idx,
6067
6070
                       record_count, read_time);
6068
6071
      /* Compute the cost of extending the plan with 's' */
6069
6072
      current_record_count= record_count * join->positions[idx].records_read;
6155
6158
    true        Fatal error
6156
6159
*/
6157
6160
static bool
6158
 
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,
6159
6162
          double read_time)
6160
6163
{
6161
 
  Session *session= join->session;
6162
 
  if (session->killed)
 
6164
  THD *thd= join->thd;
 
6165
  if (thd->killed)
6163
6166
    return(true);
6164
6167
  if (!rest_tables)
6165
6168
  {
6188
6191
    {
6189
6192
      double records, best;
6190
6193
      advance_sj_state(rest_tables, s);
6191
 
      best_access_path(join, s, session, rest_tables, idx, record_count, 
 
6194
      best_access_path(join, s, thd, rest_tables, idx, record_count, 
6192
6195
                       read_time);
6193
6196
      records= join->positions[idx].records_read;
6194
6197
      best= join->positions[idx].read_time;
6229
6232
  Find how much space the prevous read not const tables takes in cache.
6230
6233
*/
6231
6234
 
6232
 
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)
6233
6237
{
6234
 
  uint32_t null_fields,blobs,fields,rec_length;
 
6238
  uint null_fields,blobs,fields,rec_length;
6235
6239
  Field **f_ptr,*field;
6236
6240
  MY_BITMAP *read_set= join_tab->table->read_set;;
6237
6241
 
6240
6244
  {
6241
6245
    if (bitmap_is_set(read_set, field->field_index))
6242
6246
    {
6243
 
      uint32_t flags=field->flags;
 
6247
      uint flags=field->flags;
6244
6248
      fields++;
6245
6249
      rec_length+=field->pack_length();
6246
6250
      if (flags & BLOB_FLAG)
6255
6259
    rec_length+=sizeof(bool);
6256
6260
  if (blobs)
6257
6261
  {
6258
 
    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-
6259
6263
                             (join_tab->table->getRecordLength()- rec_length));
6260
 
    rec_length+=(uint) cmax((uint)4,blob_length);
 
6264
    rec_length+=(uint) max((uint)4,blob_length);
6261
6265
  }
6262
6266
  join_tab->used_fields=fields;
6263
6267
  join_tab->used_fieldlength=rec_length;
6266
6270
 
6267
6271
 
6268
6272
static uint
6269
 
cache_record_length(JOIN *join,uint32_t idx)
 
6273
cache_record_length(JOIN *join,uint idx)
6270
6274
{
6271
 
  uint32_t length=0;
 
6275
  uint length=0;
6272
6276
  JOIN_TAB **pos,**end;
6273
 
  Session *session=join->session;
 
6277
  THD *thd=join->thd;
6274
6278
 
6275
6279
  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
6276
6280
       pos != end ;
6278
6282
  {
6279
6283
    JOIN_TAB *join_tab= *pos;
6280
6284
    if (!join_tab->used_fieldlength)            /* Not calced yet */
6281
 
      calc_used_field_length(session, join_tab);
 
6285
      calc_used_field_length(thd, join_tab);
6282
6286
    length+=join_tab->used_fieldlength;
6283
6287
  }
6284
6288
  return length;
6337
6341
*/
6338
6342
 
6339
6343
static double
6340
 
prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
 
6344
prev_record_reads(JOIN *join, uint idx, table_map found_ref)
6341
6345
{
6342
6346
  double found=1.0;
6343
6347
  POSITION *pos_end= join->positions - 1;
6377
6381
static bool
6378
6382
get_best_combination(JOIN *join)
6379
6383
{
6380
 
  uint32_t i,tablenr;
 
6384
  uint i,tablenr;
6381
6385
  table_map used_tables;
6382
6386
  JOIN_TAB *join_tab,*j;
6383
6387
  KEYUSE *keyuse;
6384
 
  uint32_t table_count;
6385
 
  Session *session=join->session;
 
6388
  uint table_count;
 
6389
  THD *thd=join->thd;
6386
6390
 
6387
6391
  table_count=join->tables;
6388
6392
  if (!(join->join_tab=join_tab=
6389
 
        (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB)*table_count)))
 
6393
        (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
6390
6394
    return(true);
6391
6395
 
6392
6396
  join->full_join=0;
6430
6434
                               table_map used_tables)
6431
6435
{
6432
6436
  KEYUSE *keyuse=org_keyuse;
6433
 
  Session  *session= join->session;
6434
 
  uint32_t keyparts,length,key;
 
6437
  THD  *thd= join->thd;
 
6438
  uint keyparts,length,key;
6435
6439
  Table *table;
6436
6440
  KEY *keyinfo;
6437
6441
 
6442
6446
 
6443
6447
  {
6444
6448
    keyparts=length=0;
6445
 
    uint32_t found_part_ref_or_null= 0;
 
6449
    uint found_part_ref_or_null= 0;
6446
6450
    /*
6447
6451
      Calculate length for the used key
6448
6452
      Stop if there is a missing key part or when we find second key_part
6469
6473
  j->ref.key_parts=keyparts;
6470
6474
  j->ref.key_length=length;
6471
6475
  j->ref.key=(int) key;
6472
 
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
6473
 
      !(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*) *
6474
6478
                                                   (keyparts+1)))) ||
6475
 
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
6476
 
      !(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)))
6477
6481
  {
6478
6482
    return(true);
6479
6483
  }
6484
6488
  keyuse=org_keyuse;
6485
6489
 
6486
6490
  store_key **ref_key= j->ref.key_copy;
6487
 
  unsigned char *key_buff=j->ref.key_buff, *null_ref_key= 0;
 
6491
  uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
6488
6492
  bool keyuse_uses_no_tables= true;
6489
6493
  {
6490
 
    uint32_t i;
 
6494
    uint i;
6491
6495
    for (i=0 ; i < keyparts ; keyuse++,i++)
6492
6496
    {
6493
6497
      while (keyuse->keypart != i ||
6494
6498
             ((~used_tables) & keyuse->used_tables))
6495
6499
        keyuse++;                               /* Skip other parts */
6496
6500
 
6497
 
      uint32_t maybe_null= test(keyinfo->key_part[i].null_bit);
 
6501
      uint maybe_null= test(keyinfo->key_part[i].null_bit);
6498
6502
      j->ref.items[i]=keyuse->val;              // Save for cond removal
6499
6503
      j->ref.cond_guards[i]= keyuse->cond_guard;
6500
6504
      if (keyuse->null_rejecting) 
6503
6507
      if (!keyuse->used_tables &&
6504
6508
          !(join->select_options & SELECT_DESCRIBE))
6505
6509
      {                                 // Compare against constant
6506
 
        store_key_item tmp(session, keyinfo->key_part[i].field,
 
6510
        store_key_item tmp(thd, keyinfo->key_part[i].field,
6507
6511
                           key_buff + maybe_null,
6508
6512
                           maybe_null ?  key_buff : 0,
6509
6513
                           keyinfo->key_part[i].length, keyuse->val);
6510
 
        if (session->is_fatal_error)
 
6514
        if (thd->is_fatal_error)
6511
6515
          return(true);
6512
6516
        tmp.copy();
6513
6517
      }
6514
6518
      else
6515
 
        *ref_key++= get_store_key(session,
 
6519
        *ref_key++= get_store_key(thd,
6516
6520
                                  keyuse,join->const_table_map,
6517
6521
                                  &keyinfo->key_part[i],
6518
6522
                                  key_buff, maybe_null);
6555
6559
 
6556
6560
 
6557
6561
static store_key *
6558
 
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6559
 
              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)
6560
6564
{
6561
6565
  if (!((~used_tables) & keyuse->used_tables))          // if const item
6562
6566
  {
6563
 
    return new store_key_const_item(session,
 
6567
    return new store_key_const_item(thd,
6564
6568
                                    key_part->field,
6565
6569
                                    key_buff + maybe_null,
6566
6570
                                    maybe_null ? key_buff : 0,
6573
6577
            (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6574
6578
             Item_ref::DIRECT_REF && 
6575
6579
            keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6576
 
    return new store_key_field(session,
 
6580
    return new store_key_field(thd,
6577
6581
                               key_part->field,
6578
6582
                               key_buff + maybe_null,
6579
6583
                               maybe_null ? key_buff : 0,
6580
6584
                               key_part->length,
6581
6585
                               ((Item_field*) keyuse->val->real_item())->field,
6582
6586
                               keyuse->val->full_name());
6583
 
  return new store_key_item(session,
 
6587
  return new store_key_item(thd,
6584
6588
                            key_part->field,
6585
6589
                            key_buff + maybe_null,
6586
6590
                            maybe_null ? key_buff : 0,
6600
6604
{
6601
6605
  bool error;
6602
6606
  Table *table= field->table;
6603
 
  Session *session= table->in_use;
6604
 
  ha_rows cuted_fields=session->cuted_fields;
 
6607
  THD *thd= table->in_use;
 
6608
  ha_rows cuted_fields=thd->cuted_fields;
6605
6609
 
6606
6610
  /*
6607
6611
    we should restore old value of count_cuted_fields because
6608
6612
    store_val_in_field can be called from mysql_insert 
6609
6613
    with select_insert, which make count_cuted_fields= 1
6610
6614
   */
6611
 
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
6612
 
  session->count_cuted_fields= check_flag;
 
6615
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
 
6616
  thd->count_cuted_fields= check_flag;
6613
6617
  error= item->save_in_field(field, 1);
6614
 
  session->count_cuted_fields= old_count_cuted_fields;
6615
 
  return error || cuted_fields != session->cuted_fields;
 
6618
  thd->count_cuted_fields= old_count_cuted_fields;
 
6619
  return error || cuted_fields != thd->cuted_fields;
6616
6620
}
6617
6621
 
6618
6622
 
6628
6632
  */
6629
6633
  if (!join->table_reexec)
6630
6634
  {
6631
 
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
 
6635
    if (!(join->table_reexec= (Table**) join->thd->alloc(sizeof(Table*))))
6632
6636
      return(true);                        /* purecov: inspected */
6633
6637
    if (join->tmp_join)
6634
6638
      join->tmp_join->table_reexec= join->table_reexec;
6636
6640
  if (!join->join_tab_reexec)
6637
6641
  {
6638
6642
    if (!(join->join_tab_reexec=
6639
 
          (JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
 
6643
          (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
6640
6644
      return(true);                        /* purecov: inspected */
6641
6645
    if (join->tmp_join)
6642
6646
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6753
6757
 
6754
6758
static void add_not_null_conds(JOIN *join)
6755
6759
{
6756
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6760
  for (uint i=join->const_tables ; i < join->tables ; i++)
6757
6761
  {
6758
6762
    JOIN_TAB *tab=join->join_tab+i;
6759
6763
    if ((tab->type == JT_REF || tab->type == JT_EQ_REF || 
6760
6764
         tab->type == JT_REF_OR_NULL) &&
6761
6765
        !tab->table->maybe_null)
6762
6766
    {
6763
 
      for (uint32_t keypart= 0; keypart < tab->ref.key_parts; keypart++)
 
6767
      for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
6764
6768
      {
6765
6769
        if (tab->ref.null_rejecting & (1 << keypart))
6766
6770
        {
6784
6788
            when it is called from make_join_select after this function is 
6785
6789
            called.
6786
6790
          */
6787
 
          if (notnull->fix_fields(join->session, &notnull))
 
6791
          if (notnull->fix_fields(join->thd, &notnull))
6788
6792
            return;
6789
6793
          add_cond_and_fix(&referred_tab->select_cond, notnull);
6790
6794
        }
6873
6877
static void
6874
6878
make_outerjoin_info(JOIN *join)
6875
6879
{
6876
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6880
  for (uint i=join->const_tables ; i < join->tables ; i++)
6877
6881
  {
6878
6882
    JOIN_TAB *tab=join->join_tab+i;
6879
6883
    Table *table=tab->table;
6926
6930
static bool
6927
6931
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
6928
6932
{
6929
 
  Session *session= join->session;
 
6933
  THD *thd= join->thd;
6930
6934
  if (select)
6931
6935
  {
6932
6936
    add_not_null_conds(join);
6936
6940
      if (join->tables > 1)
6937
6941
        cond->update_used_tables();             // Tablenr may have changed
6938
6942
      if (join->const_tables == join->tables &&
6939
 
          session->lex->current_select->master_unit() ==
6940
 
          &session->lex->unit)          // not upper level SELECT
 
6943
          thd->lex->current_select->master_unit() ==
 
6944
          &thd->lex->unit)              // not upper level SELECT
6941
6945
        join->const_table_map|=RAND_TABLE_BIT;
6942
6946
      {                                         // Check const tables
6943
6947
        COND *const_cond=
6975
6979
    }
6976
6980
    used_tables=((select->const_tables=join->const_table_map) |
6977
6981
                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
6978
 
    for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
6982
    for (uint i=join->const_tables ; i < join->tables ; i++)
6979
6983
    {
6980
6984
      JOIN_TAB *tab=join->join_tab+i;
6981
6985
      /*
7044
7048
          tab->type == JT_EQ_REF)
7045
7049
      {
7046
7050
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
7047
 
                                       session->memdup((unsigned char*) select,
 
7051
                                       thd->memdup((uchar*) select,
7048
7052
                                                   sizeof(*select)));
7049
7053
        if (!sel)
7050
7054
          return(1);                    // End of memory
7066
7070
          /* Push condition to storage engine if this is enabled
7067
7071
             and the condition is not guarded */
7068
7072
          tab->table->file->pushed_cond= NULL;
7069
 
          if (session->variables.engine_condition_pushdown)
 
7073
          if (thd->variables.engine_condition_pushdown)
7070
7074
          {
7071
7075
            COND *push_cond= 
7072
7076
              make_cond_for_table(tmp, current_map, current_map, 0);
7099
7103
          }
7100
7104
          tab->quick=0;
7101
7105
        }
7102
 
        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;
7103
7107
        if (i == join->const_tables && ref_key)
7104
7108
        {
7105
7109
          if (!tab->const_keys.is_clear_all() &&
7135
7139
            if (sel->cond && !sel->cond->fixed)
7136
7140
              sel->cond->quick_fix_field();
7137
7141
 
7138
 
            if (sel->test_quick_select(session, tab->keys,
 
7142
            if (sel->test_quick_select(thd, tab->keys,
7139
7143
                                       used_tables & ~ current_map,
7140
7144
                                       (join->select_options &
7141
7145
                                        OPTION_FOUND_ROWS ?
7149
7153
              */
7150
7154
              sel->cond=orig_cond;
7151
7155
              if (!*tab->on_expr_ref ||
7152
 
                  sel->test_quick_select(session, tab->keys,
 
7156
                  sel->test_quick_select(thd, tab->keys,
7153
7157
                                         used_tables & ~ current_map,
7154
7158
                                         (join->select_options &
7155
7159
                                          OPTION_FOUND_ROWS ?
7191
7195
                                         current_map, 0)))
7192
7196
            {
7193
7197
              tab->cache.select=(SQL_SELECT*)
7194
 
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
7198
                thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
7195
7199
              tab->cache.select->cond=tmp;
7196
7200
              tab->cache.select->read_tables=join->const_table_map;
7197
7201
            }
7309
7313
    false  No
7310
7314
*/
7311
7315
 
7312
 
bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, 
 
7316
bool uses_index_fields_only(Item *item, Table *tbl, uint keyno, 
7313
7317
                            bool other_tbls_ok)
7314
7318
{
7315
7319
  if (item->const_item())
7404
7408
    Index condition, or NULL if no condition could be inferred.
7405
7409
*/
7406
7410
 
7407
 
Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno,
 
7411
Item *make_cond_for_index(Item *cond, Table *table, uint keyno,
7408
7412
                          bool other_tbls_ok)
7409
7413
{
7410
7414
  if (!cond)
7411
7415
    return NULL;
7412
7416
  if (cond->type() == Item::COND_ITEM)
7413
7417
  {
7414
 
    uint32_t n_marked= 0;
 
7418
    uint n_marked= 0;
7415
7419
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
7416
7420
    {
7417
7421
      Item_cond_and *new_cond=new Item_cond_and;
7543
7547
    Try to extract and push the index condition down to table handler
7544
7548
*/
7545
7549
 
7546
 
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)
7547
7551
{
7548
7552
  Item *idx_cond;
7549
7553
  if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7550
 
      tab->join->session->variables.engine_condition_pushdown)
 
7554
      tab->join->thd->variables.engine_condition_pushdown)
7551
7555
  {
7552
7556
    idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7553
7557
                                  other_tbls_ok);
7605
7609
      ordered. If there is a temp table the ordering is done as a last
7606
7610
      operation and doesn't prevent join cache usage.
7607
7611
    */
7608
 
uint32_t make_join_orderinfo(JOIN *join)
 
7612
uint make_join_orderinfo(JOIN *join)
7609
7613
{
7610
 
  uint32_t i;
 
7614
  uint i;
7611
7615
  if (join->need_tmp)
7612
7616
    return join->tables;
7613
7617
 
7649
7653
*/
7650
7654
 
7651
7655
static bool
7652
 
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)
7653
7657
{
7654
 
  uint32_t i;
 
7658
  uint i;
7655
7659
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
7656
7660
  bool sorted= 1;
7657
7661
 
7671
7675
    sorted= 0;                                  // only first must be sorted
7672
7676
    if (tab->insideout_match_tab)
7673
7677
    {
7674
 
      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
7675
7679
                                                         [tab->index].
7676
7680
                                                         key_length)))
7677
7681
        return true;
7755
7759
          !tab->insideout_match_tab)
7756
7760
      {
7757
7761
        if ((options & SELECT_DESCRIBE) ||
7758
 
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
7762
            !join_init_cache(join->thd,join->join_tab+join->const_tables,
7759
7763
                             i-join->const_tables))
7760
7764
        {
7761
7765
          using_join_cache= true;
7765
7769
      /* These init changes read_record */
7766
7770
      if (tab->use_quick == 2)
7767
7771
      {
7768
 
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
7772
        join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7769
7773
        tab->read_first_record= join_init_quick_read_record;
7770
7774
        if (statistics)
7771
 
          status_var_increment(join->session->status_var.select_range_check_count);
 
7775
          status_var_increment(join->thd->status_var.select_range_check_count);
7772
7776
      }
7773
7777
      else
7774
7778
      {
7778
7782
          if (tab->select && tab->select->quick)
7779
7783
          {
7780
7784
            if (statistics)
7781
 
              status_var_increment(join->session->status_var.select_range_count);
 
7785
              status_var_increment(join->thd->status_var.select_range_count);
7782
7786
          }
7783
7787
          else
7784
7788
          {
7785
 
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7789
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7786
7790
            if (statistics)
7787
 
              status_var_increment(join->session->status_var.select_scan_count);
 
7791
              status_var_increment(join->thd->status_var.select_scan_count);
7788
7792
          }
7789
7793
        }
7790
7794
        else
7792
7796
          if (tab->select && tab->select->quick)
7793
7797
          {
7794
7798
            if (statistics)
7795
 
              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);
7796
7800
          }
7797
7801
          else
7798
7802
          {
7799
 
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7803
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
7800
7804
            if (statistics)
7801
 
              status_var_increment(join->session->status_var.select_full_join_count);
 
7805
              status_var_increment(join->thd->status_var.select_full_join_count);
7802
7806
          }
7803
7807
        }
7804
7808
        if (!table->no_keyread)
7887
7891
  select= 0;
7888
7892
  delete quick;
7889
7893
  quick= 0;
7890
 
  if (cache.buff)
7891
 
    free(cache.buff);
 
7894
  x_free(cache.buff);
7892
7895
  cache.buff= 0;
7893
7896
  limit= 0;
7894
7897
  if (table)
7942
7945
    a correlated subquery itself, but has subqueries, we can free it
7943
7946
    fully and also free JOINs of all its subqueries. The exception
7944
7947
    is a subquery in SELECT list, e.g: @n
7945
 
    SELECT a, (select cmax(b) from t1) group by c @n
 
7948
    SELECT a, (select max(b) from t1) group by c @n
7946
7949
    This subquery will not be evaluated at first sweep and its value will
7947
7950
    not be inserted into the temporary table. Instead, it's evaluated
7948
7951
    when selecting from the temporary table. Therefore, it can't be freed
7960
7963
    Optimization: if not EXPLAIN and we are done with the JOIN,
7961
7964
    free all tables.
7962
7965
  */
7963
 
  bool full= (!select_lex->uncacheable && !session->lex->describe);
 
7966
  bool full= (!select_lex->uncacheable && !thd->lex->describe);
7964
7967
  bool can_unlock= full;
7965
7968
 
7966
7969
  cleanup(full);
7990
7993
    We are not using tables anymore
7991
7994
    Unlock all tables. We may be in an INSERT .... SELECT statement.
7992
7995
  */
7993
 
  if (can_unlock && lock && session->lock &&
 
7996
  if (can_unlock && lock && thd->lock &&
7994
7997
      !(select_options & SELECT_NO_UNLOCK) &&
7995
7998
      !select_lex->subquery_in_having &&
7996
 
      (select_lex == (session->lex->unit.fake_select_lex ?
7997
 
                      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)))
7998
8001
  {
7999
8002
    /*
8000
8003
      TODO: unlock tables even if the join isn't top level select in the
8001
8004
      tree.
8002
8005
    */
8003
 
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
 
8006
    mysql_unlock_read_tables(thd, lock);           // Don't free join->lock
8004
8007
    lock= 0;
8005
8008
  }
8006
8009
 
8118
8121
    return (tab->eq_ref_table=0);               // We must use this
8119
8122
  Item **ref_item=tab->ref.items;
8120
8123
  Item **end=ref_item+tab->ref.key_parts;
8121
 
  uint32_t found=0;
 
8124
  uint found=0;
8122
8125
  table_map map=tab->table->map;
8123
8126
 
8124
8127
  for (; ref_item != end ; ref_item++)
8180
8183
    TABLE_REF *ref= &join_tab->ref;
8181
8184
    table_map depend_map=0;
8182
8185
    Item **item=ref->items;
8183
 
    uint32_t i;
 
8186
    uint i;
8184
8187
    for (i=0 ; i < ref->key_parts ; i++,item++)
8185
8188
      depend_map|=(*item)->used_tables();
8186
8189
    ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
8337
8340
    result->send_eof();                         // Should be safe
8338
8341
  }
8339
8342
  /* Update results for FOUND_ROWS */
8340
 
  join->session->limit_found_rows= join->session->examined_row_count= 0;
 
8343
  join->thd->limit_found_rows= join->thd->examined_row_count= 0;
8341
8344
  return(0);
8342
8345
}
8343
8346
 
8350
8353
    must clear only the non-const tables, as const tables
8351
8354
    are not re-calculated.
8352
8355
  */
8353
 
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
8356
  for (uint i=join->const_tables ; i < join->tables ; i++)
8354
8357
    mark_as_null_row(join->table[i]);           // All fields are NULL
8355
8358
}
8356
8359
 
8369
8372
  {
8370
8373
    return (void*) sql_alloc((uint) size);
8371
8374
  }
8372
 
  static void operator delete(void *, size_t)
 
8375
  static void operator delete(void *ptr __attribute__((unused)),
 
8376
                              size_t size __attribute__((unused)))
8373
8377
  { TRASH(ptr, size); }
8374
8378
 
8375
8379
  Item *and_level;
8696
8700
    simple equality nor a row equality the item for this predicate is added
8697
8701
    to eq_list.
8698
8702
 
8699
 
  @param session        thread handle
 
8703
  @param thd        thread handle
8700
8704
  @param left_row   left term of the row equality to be processed
8701
8705
  @param right_row  right term of the row equality to be processed
8702
8706
  @param cond_equal multiple equalities that must hold together with the
8710
8714
    false   otherwise
8711
8715
*/
8712
8716
 
8713
 
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,
8714
8718
                               COND_EQUAL *cond_equal, List<Item>* eq_list)
8715
8719
8716
 
  uint32_t n= left_row->cols();
8717
 
  for (uint32_t i= 0 ; i < n; i++)
 
8720
  uint n= left_row->cols();
 
8721
  for (uint i= 0 ; i < n; i++)
8718
8722
  {
8719
8723
    bool is_converted;
8720
8724
    Item *left_item= left_row->element_index(i);
8722
8726
    if (left_item->type() == Item::ROW_ITEM &&
8723
8727
        right_item->type() == Item::ROW_ITEM)
8724
8728
    {
8725
 
      is_converted= check_row_equality(session, 
 
8729
      is_converted= check_row_equality(thd, 
8726
8730
                                       (Item_row *) left_item,
8727
8731
                                       (Item_row *) right_item,
8728
8732
                                       cond_equal, eq_list);
8729
8733
      if (!is_converted)
8730
 
        session->lex->current_select->cond_count++;      
 
8734
        thd->lex->current_select->cond_count++;      
8731
8735
    }
8732
8736
    else
8733
8737
    { 
8734
8738
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8735
 
      session->lex->current_select->cond_count++;
 
8739
      thd->lex->current_select->cond_count++;
8736
8740
    }  
8737
8741
 
8738
8742
    if (!is_converted)
8763
8767
    equalities which are treated in the same way as original equality
8764
8768
    predicates.
8765
8769
 
8766
 
  @param session        thread handle
 
8770
  @param thd        thread handle
8767
8771
  @param item       predicate to process
8768
8772
  @param cond_equal multiple equalities that must hold together with the
8769
8773
                    predicate
8779
8783
           or, if the procedure fails by a fatal error.
8780
8784
*/
8781
8785
 
8782
 
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,
8783
8787
                           List<Item> *eq_list)
8784
8788
{
8785
8789
  if (item->type() == Item::FUNC_ITEM &&
8791
8795
    if (left_item->type() == Item::ROW_ITEM &&
8792
8796
        right_item->type() == Item::ROW_ITEM)
8793
8797
    {
8794
 
      session->lex->current_select->cond_count--;
8795
 
      return check_row_equality(session,
 
8798
      thd->lex->current_select->cond_count--;
 
8799
      return check_row_equality(thd,
8796
8800
                                (Item_row *) left_item,
8797
8801
                                (Item_row *) right_item,
8798
8802
                                cond_equal, eq_list);
8823
8827
    just an argument of a comparison predicate.
8824
8828
    The function also determines the maximum number of members in 
8825
8829
    equality lists of each Item_cond_and object assigning it to
8826
 
    session->lex->current_select->max_equal_elems.
 
8830
    thd->lex->current_select->max_equal_elems.
8827
8831
 
8828
8832
  @note
8829
8833
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8860
8864
    We need to do things in this order as lower AND levels need to know about
8861
8865
    all possible Item_equal objects in upper levels.
8862
8866
 
8863
 
  @param session        thread handle
 
8867
  @param thd        thread handle
8864
8868
  @param cond       condition(expression) where to make replacement
8865
8869
  @param inherited  path to all inherited multiple equality items
8866
8870
 
8868
8872
    pointer to the transformed condition
8869
8873
*/
8870
8874
 
8871
 
static COND *build_equal_items_for_cond(Session *session, COND *cond,
 
8875
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
8872
8876
                                        COND_EQUAL *inherited)
8873
8877
{
8874
8878
  Item_equal *item_equal;
8900
8904
          structure here because it's restored before each
8901
8905
          re-execution of any prepared statement/stored procedure.
8902
8906
        */
8903
 
        if (check_equality(session, item, &cond_equal, &eq_list))
 
8907
        if (check_equality(thd, item, &cond_equal, &eq_list))
8904
8908
          li.remove();
8905
8909
      }
8906
8910
 
8909
8913
      {
8910
8914
        item_equal->fix_length_and_dec();
8911
8915
        item_equal->update_used_tables();
8912
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
8916
        set_if_bigger(thd->lex->current_select->max_equal_elems,
8913
8917
                      item_equal->members());  
8914
8918
      }
8915
8919
 
8924
8928
    while ((item= li++))
8925
8929
    { 
8926
8930
      Item *new_item;
8927
 
      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)
8928
8932
      {
8929
8933
        /* This replacement happens only for standalone equalities */
8930
8934
        /*
8954
8958
      for WHERE a=b AND c=d AND (b=c OR d=5)
8955
8959
      b=c is replaced by =(a,b,c,d).  
8956
8960
     */
8957
 
    if (check_equality(session, cond, &cond_equal, &eq_list))
 
8961
    if (check_equality(thd, cond, &cond_equal, &eq_list))
8958
8962
    {
8959
8963
      int n= cond_equal.current_level.elements + eq_list.elements;
8960
8964
      if (n == 0)
8968
8972
        }
8969
8973
        else
8970
8974
          item_equal= (Item_equal *) eq_list.pop();
8971
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
8975
        set_if_bigger(thd->lex->current_select->max_equal_elems,
8972
8976
                      item_equal->members());  
8973
8977
        return item_equal;
8974
8978
      }
8986
8990
        {
8987
8991
          item_equal->fix_length_and_dec();
8988
8992
          item_equal->update_used_tables();
8989
 
          set_if_bigger(session->lex->current_select->max_equal_elems,
 
8993
          set_if_bigger(thd->lex->current_select->max_equal_elems,
8990
8994
                        item_equal->members());  
8991
8995
        }
8992
8996
        and_cond->cond_equal= cond_equal;
9001
9005
      as soon the field is not of a string type or the field reference is
9002
9006
      an argument of a comparison predicate. 
9003
9007
    */ 
9004
 
    unsigned char *is_subst_valid= (unsigned char *) 1;
 
9008
    uchar *is_subst_valid= (uchar *) 1;
9005
9009
    cond= cond->compile(&Item::subst_argument_checker,
9006
9010
                        &is_subst_valid, 
9007
9011
                        &Item::equal_fields_propagator,
9008
 
                        (unsigned char *) inherited);
 
9012
                        (uchar *) inherited);
9009
9013
    cond->update_used_tables();
9010
9014
  }
9011
9015
  return cond;
9066
9070
    can get more freedom in performing join operations.
9067
9071
    Althogh we don't use this property now, it probably makes sense to use 
9068
9072
    it in the future.    
9069
 
  @param session                      Thread handler
 
9073
  @param thd                  Thread handler
9070
9074
  @param cond                condition to build the multiple equalities for
9071
9075
  @param inherited           path to all inherited multiple equality items
9072
9076
  @param join_list           list of join tables to which the condition
9078
9082
    pointer to the transformed condition containing multiple equalities
9079
9083
*/
9080
9084
   
9081
 
static COND *build_equal_items(Session *session, COND *cond,
 
9085
static COND *build_equal_items(THD *thd, COND *cond,
9082
9086
                               COND_EQUAL *inherited,
9083
9087
                               List<TableList> *join_list,
9084
9088
                               COND_EQUAL **cond_equal_ref)
9087
9091
 
9088
9092
  if (cond) 
9089
9093
  {
9090
 
    cond= build_equal_items_for_cond(session, cond, inherited);
 
9094
    cond= build_equal_items_for_cond(thd, cond, inherited);
9091
9095
    cond->update_used_tables();
9092
9096
    if (cond->type() == Item::COND_ITEM &&
9093
9097
        ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9121
9125
          We can modify table->on_expr because its old value will
9122
9126
          be restored before re-execution of PS/SP.
9123
9127
        */
9124
 
        table->on_expr= build_equal_items(session, table->on_expr, inherited,
 
9128
        table->on_expr= build_equal_items(thd, table->on_expr, inherited,
9125
9129
                                          nested_join_list,
9126
9130
                                          &table->cond_equal);
9127
9131
      }
9459
9463
*/
9460
9464
 
9461
9465
static void
9462
 
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,
9463
9467
                         Item *and_father, Item *cond,
9464
9468
                         Item *field, Item *value)
9465
9469
{
9470
9474
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9471
9475
    Item *item;
9472
9476
    while ((item=li++))
9473
 
      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,
9474
9478
                               field, value);
9475
9479
    return;
9476
9480
  }
9494
9498
    
9495
9499
    if (tmp)
9496
9500
    {
9497
 
      session->change_item_tree(args + 1, tmp);
 
9501
      thd->change_item_tree(args + 1, tmp);
9498
9502
      func->update_used_tables();
9499
9503
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9500
9504
          && and_father != cond && !left_item->const_item())
9518
9522
    
9519
9523
    if (tmp)
9520
9524
    {
9521
 
      session->change_item_tree(args, tmp);
 
9525
      thd->change_item_tree(args, tmp);
9522
9526
      value= tmp;
9523
9527
      func->update_used_tables();
9524
9528
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9525
9529
          && and_father != cond && !right_item->const_item())
9526
9530
      {
9527
9531
        args[0]= args[1];                       // For easy check
9528
 
        session->change_item_tree(args + 1, value);
 
9532
        thd->change_item_tree(args + 1, value);
9529
9533
        cond->marker=1;
9530
9534
        COND_CMP *tmp2;
9531
9535
        if ((tmp2=new COND_CMP(and_father,func)))
9569
9573
}
9570
9574
 
9571
9575
static void
9572
 
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
 
9576
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
9573
9577
                         COND *and_father, COND *cond)
9574
9578
{
9575
9579
  if (cond->type() == Item::COND_ITEM)
9581
9585
    I_List<COND_CMP> save;
9582
9586
    while ((item=li++))
9583
9587
    {
9584
 
      propagate_cond_constants(session, &save,and_level ? cond : item, item);
 
9588
      propagate_cond_constants(thd, &save,and_level ? cond : item, item);
9585
9589
    }
9586
9590
    if (and_level)
9587
9591
    {                                           // Handle other found items
9591
9595
      {
9592
9596
        Item **args= cond_cmp->cmp_func->arguments();
9593
9597
        if (!args[0]->const_item())
9594
 
          change_cond_ref_to_const(session, &save,cond_cmp->and_level,
 
9598
          change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
9595
9599
                                   cond_cmp->and_level, args[0], args[1]);
9596
9600
      }
9597
9601
    }
9611
9615
      {
9612
9616
        if (right_const)
9613
9617
        {
9614
 
          resolve_const_item(session, &args[1], args[0]);
 
9618
          resolve_const_item(thd, &args[1], args[0]);
9615
9619
          func->update_used_tables();
9616
 
          change_cond_ref_to_const(session, save_list, and_father, and_father,
 
9620
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
9617
9621
                                   args[0], args[1]);
9618
9622
        }
9619
9623
        else if (left_const)
9620
9624
        {
9621
 
          resolve_const_item(session, &args[0], args[1]);
 
9625
          resolve_const_item(thd, &args[0], args[1]);
9622
9626
          func->update_used_tables();
9623
 
          change_cond_ref_to_const(session, save_list, and_father, and_father,
 
9627
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
9624
9628
                                   args[1], args[0]);
9625
9629
        }
9626
9630
      }
9793
9797
          assert(expr);
9794
9798
 
9795
9799
          table->on_expr= expr;
9796
 
          table->prep_on_expr= expr->copy_andor_structure(join->session);
 
9800
          table->prep_on_expr= expr->copy_andor_structure(join->thd);
9797
9801
        }
9798
9802
      }
9799
9803
      nested_join->used_tables= (table_map) 0;
9834
9838
          conds->top_level_item();
9835
9839
          /* conds is always a new item as both cond and on_expr existed */
9836
9840
          assert(!conds->fixed);
9837
 
          conds->fix_fields(join->session, &conds);
 
9841
          conds->fix_fields(join->thd, &conds);
9838
9842
        }
9839
9843
        else
9840
9844
          conds= table->on_expr; 
9941
9945
    First unused bit in nested_join_map after the call.
9942
9946
*/
9943
9947
 
9944
 
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, 
9945
 
                                          uint32_t first_unused)
 
9948
static uint build_bitmap_for_nested_joins(List<TableList> *join_list, 
 
9949
                                          uint first_unused)
9946
9950
{
9947
9951
  List_iterator<TableList> li(*join_list);
9948
9952
  TableList *table;
10213
10217
optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list,
10214
10218
              Item::cond_result *cond_value)
10215
10219
{
10216
 
  Session *session= join->session;
 
10220
  THD *thd= join->thd;
10217
10221
 
10218
10222
  if (!conds)
10219
10223
    *cond_value= Item::COND_TRUE;
10227
10231
      predicate. Substitute a constant instead of this field if the
10228
10232
      multiple equality contains a constant.
10229
10233
    */ 
10230
 
    conds= build_equal_items(join->session, conds, NULL, join_list,
 
10234
    conds= build_equal_items(join->thd, conds, NULL, join_list,
10231
10235
                             &join->cond_equal);
10232
10236
 
10233
10237
    /* change field = field to field = const for each found field = const */
10234
 
    propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
 
10238
    propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
10235
10239
    /*
10236
10240
      Remove all instances of item == item
10237
10241
      Remove all and-levels where CONST item != CONST item
10238
10242
    */
10239
 
    conds= remove_eq_conds(session, conds, cond_value) ;
 
10243
    conds= remove_eq_conds(thd, conds, cond_value) ;
10240
10244
  }
10241
10245
  return(conds);
10242
10246
}
10254
10258
*/
10255
10259
 
10256
10260
COND *
10257
 
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)
10258
10262
{
10259
10263
  if (cond->type() == Item::COND_ITEM)
10260
10264
  {
10268
10272
    Item *item;
10269
10273
    while ((item=li++))
10270
10274
    {
10271
 
      Item *new_item=remove_eq_conds(session, item, &tmp_cond_value);
 
10275
      Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
10272
10276
      if (!new_item)
10273
10277
        li.remove();
10274
10278
      else if (item != new_item)
10275
10279
      {
10276
 
        li.replace(new_item);
 
10280
        VOID(li.replace(new_item));
10277
10281
        should_fix_fields=1;
10278
10282
      }
10279
10283
      if (*cond_value == Item::COND_UNDEF)
10333
10337
    {
10334
10338
      Field *field=((Item_field*) args[0])->field;
10335
10339
      if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
10336
 
          (session->options & OPTION_AUTO_IS_NULL) &&
10337
 
          (session->first_successful_insert_id_in_prev_stmt > 0 &&
10338
 
           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))
10339
10343
      {
10340
10344
        COND *new_cond;
10341
10345
        if ((new_cond= new Item_func_eq(args[0],
10342
10346
                                        new Item_int("last_insert_id()",
10343
 
                                                     session->read_first_successful_insert_id_in_prev_stmt(),
 
10347
                                                     thd->read_first_successful_insert_id_in_prev_stmt(),
10344
10348
                                                     MY_INT64_NUM_DECIMAL_DIGITS))))
10345
10349
        {
10346
10350
          cond=new_cond;
10349
10353
            cond->fixed, also it do not need tables so we use 0 as second
10350
10354
            argument.
10351
10355
          */
10352
 
          cond->fix_fields(session, &cond);
 
10356
          cond->fix_fields(thd, &cond);
10353
10357
        }
10354
10358
        /*
10355
10359
          IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10356
10360
          clear for next row
10357
10361
        */
10358
 
        session->substitute_null_with_insert_id= false;
 
10362
        thd->substitute_null_with_insert_id= false;
10359
10363
      }
10360
10364
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10361
10365
      else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10372
10376
            cond->fixed, also it do not need tables so we use 0 as second
10373
10377
            argument.
10374
10378
          */
10375
 
          cond->fix_fields(session, &cond);
 
10379
          cond->fix_fields(thd, &cond);
10376
10380
        }
10377
10381
      }
10378
10382
    }
10598
10602
 
10599
10603
  if (table)
10600
10604
  {
10601
 
    table->file->extra(HA_EXTRA_WRITE_CACHE);
 
10605
    VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
10602
10606
    empty_record(table);
10603
10607
    if (table->group && join->tmp_table_param.sum_func_count &&
10604
10608
        table->s->keys && !table->file->inited)
10631
10635
        so we don't touch it here.
10632
10636
      */
10633
10637
      join->examined_rows++;
10634
 
      join->session->row_count++;
 
10638
      join->thd->row_count++;
10635
10639
      assert(join->examined_rows <= 1);
10636
10640
    }
10637
10641
    else if (join->send_row_on_empty_set())
10685
10689
    if (new_errno)
10686
10690
      table->file->print_error(new_errno,MYF(0));
10687
10691
  }
10688
 
  return(join->session->is_error() ? -1 : rc);
 
10692
  return(join->thd->is_error() ? -1 : rc);
10689
10693
}
10690
10694
 
10691
10695
 
10701
10705
      rc= sub_select(join,join_tab,end_of_records);
10702
10706
    return rc;
10703
10707
  }
10704
 
  if (join->session->killed)            // If aborted by user
 
10708
  if (join->thd->killed)                // If aborted by user
10705
10709
  {
10706
 
    join->session->send_kill_message();
 
10710
    join->thd->send_kill_message();
10707
10711
    return NESTED_LOOP_KILLED;                   /* purecov: inspected */
10708
10712
  }
10709
10713
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10881
10885
      /* Set first_unmatched for the last inner table of this group */
10882
10886
      join_tab->last_inner->first_unmatched= join_tab;
10883
10887
    }
10884
 
    join->session->row_count= 0;
 
10888
    join->thd->row_count= 0;
10885
10889
 
10886
10890
    error= (*join_tab->read_first_record)(join_tab);
10887
10891
    rc= evaluate_join_record(join, join_tab, error);
10921
10925
    0   The row combination is not a duplicate (continue)
10922
10926
*/
10923
10927
 
10924
 
int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl) 
 
10928
int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl) 
10925
10929
{
10926
10930
  int error;
10927
10931
  SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
10928
10932
  SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
10929
 
  unsigned char *ptr= sjtbl->tmp_table->record[0] + 1;
10930
 
  unsigned char *nulls_ptr= ptr;
 
10933
  uchar *ptr= sjtbl->tmp_table->record[0] + 1;
 
10934
  uchar *nulls_ptr= ptr;
10931
10935
  
10932
10936
  /* Put the the rowids tuple into table->record[0]: */
10933
10937
 
10934
10938
  // 1. Store the length 
10935
10939
  if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
10936
10940
  {
10937
 
    *ptr= (unsigned char)(sjtbl->rowid_len + sjtbl->null_bytes);
 
10941
    *ptr= (uchar)(sjtbl->rowid_len + sjtbl->null_bytes);
10938
10942
    ptr++;
10939
10943
  }
10940
10944
  else
10951
10955
  }
10952
10956
 
10953
10957
  // 3. Put the rowids
10954
 
  for (uint32_t i=0; tab != tab_end; tab++, i++)
 
10958
  for (uint i=0; tab != tab_end; tab++, i++)
10955
10959
  {
10956
10960
    handler *h= tab->join_tab->table->file;
10957
10961
    if (tab->join_tab->table->maybe_null && tab->join_tab->table->null_row)
10974
10978
  {
10975
10979
    /* create_myisam_from_heap will generate error if needed */
10976
10980
    if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10977
 
        create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo, 
 
10981
        create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo, 
10978
10982
                                &sjtbl->recinfo, error, 1))
10979
10983
      return -1;
10980
10984
    //return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11011
11015
  ha_rows found_records=join->found_records;
11012
11016
  COND *select_cond= join_tab->select_cond;
11013
11017
 
11014
 
  if (error > 0 || (join->session->is_error()))     // Fatal error
 
11018
  if (error > 0 || (join->thd->is_error()))     // Fatal error
11015
11019
    return NESTED_LOOP_ERROR;
11016
11020
  if (error < 0)
11017
11021
    return NESTED_LOOP_NO_MORE_ROWS;
11018
 
  if (join->session->killed)                    // Aborted by user
 
11022
  if (join->thd->killed)                        // Aborted by user
11019
11023
  {
11020
 
    join->session->send_kill_message();
 
11024
    join->thd->send_kill_message();
11021
11025
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
11022
11026
  }
11023
11027
  if (!select_cond || select_cond->val_int())
11080
11084
    join_tab->found_match= true;
11081
11085
    if (join_tab->check_weed_out_table)
11082
11086
    {
11083
 
      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);
11084
11088
      if (res == -1)
11085
11089
        return NESTED_LOOP_ERROR;
11086
11090
      if (res == 1)
11101
11105
      (See above join->return_tab= tab).
11102
11106
    */
11103
11107
    join->examined_rows++;
11104
 
    join->session->row_count++;
 
11108
    join->thd->row_count++;
11105
11109
 
11106
11110
    if (found)
11107
11111
    {
11133
11137
      with the beginning coinciding with the current partial join.
11134
11138
    */
11135
11139
    join->examined_rows++;
11136
 
    join->session->row_count++;
 
11140
    join->thd->row_count++;
11137
11141
    join_tab->read_record.file->unlock_row();
11138
11142
  }
11139
11143
  return NESTED_LOOP_OK;
11243
11247
  info= &join_tab->read_record;
11244
11248
  do
11245
11249
  {
11246
 
    if (join->session->killed)
 
11250
    if (join->thd->killed)
11247
11251
    {
11248
 
      join->session->send_kill_message();
 
11252
      join->thd->send_kill_message();
11249
11253
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11250
11254
    }
11251
11255
    SQL_SELECT *select=join_tab->select;
11252
11256
    if (rc == NESTED_LOOP_OK &&
11253
11257
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
11254
11258
    {
11255
 
      uint32_t i;
 
11259
      uint i;
11256
11260
      reset_cache_read(&join_tab->cache);
11257
11261
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
11258
11262
      {
11261
11265
        {
11262
11266
          int res= 0;
11263
11267
          if (!join_tab->check_weed_out_table || 
11264
 
              !(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)))
11265
11269
          {
11266
11270
            rc= (join_tab->next_select)(join,join_tab+1,0);
11267
11271
            if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11395
11399
      empty_record(table);                      // Make empty record
11396
11400
      return -1;
11397
11401
    }
11398
 
    update_virtual_fields_marked_for_write(table);
11399
11402
    store_record(table,record[1]);
11400
11403
  }
11401
11404
  else if (!table->status)                      // Only happens with left join
11426
11429
  if (table->status & STATUS_GARBAGE)           // If first read
11427
11430
  {
11428
11431
    table->status= 0;
11429
 
    if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11432
    if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11430
11433
      error=HA_ERR_KEY_NOT_FOUND;
11431
11434
    else
11432
11435
    {
11433
11436
      error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
11434
 
                                            (unsigned char*) tab->ref.key_buff,
 
11437
                                            (uchar*) tab->ref.key_buff,
11435
11438
                                            make_prev_keypart_map(tab->ref.key_parts),
11436
11439
                                            HA_READ_KEY_EXACT);
11437
11440
    }
11444
11447
        return table->report_error(error);
11445
11448
      return -1;
11446
11449
    }
11447
 
    update_virtual_fields_marked_for_write(table);
11448
11450
    store_record(table,record[1]);
11449
11451
  }
11450
11452
  else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
11536
11538
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11537
11539
 
11538
11540
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
11539
 
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
 
11541
  for (uint i= 0 ; i < tab->ref.key_parts ; i++)
11540
11542
  {
11541
11543
    if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
11542
11544
        return -1;
11543
11545
  }
11544
11546
 
11545
 
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11547
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11546
11548
    return -1;
11547
11549
  if ((error=table->file->index_read_map(table->record[0],
11548
11550
                                         tab->ref.key_buff,
11553
11555
      return table->report_error(error);
11554
11556
    return -1; /* purecov: inspected */
11555
11557
  }
11556
 
  update_virtual_fields_marked_for_write(table);
11557
11558
  return 0;
11558
11559
}
11559
11560
 
11571
11572
 
11572
11573
  if (!table->file->inited)
11573
11574
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11574
 
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
 
11575
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
11575
11576
    return -1;
11576
11577
  if ((error=table->file->index_read_last_map(table->record[0],
11577
11578
                                              tab->ref.key_buff,
11587
11588
 
11588
11589
        /* ARGSUSED */
11589
11590
static int
11590
 
join_no_more_records(READ_RECORD *)
 
11591
join_no_more_records(READ_RECORD *info __attribute__((unused)))
11591
11592
{
11592
11593
  return -1;
11593
11594
}
11640
11641
    table->status= STATUS_GARBAGE;
11641
11642
    return -1;
11642
11643
  }
11643
 
  update_virtual_fields_marked_for_write(table);
11644
11644
  return 0;
11645
11645
}
11646
11646
 
11660
11660
    table->status=STATUS_NOT_FOUND;
11661
11661
    error= -1;
11662
11662
  }
11663
 
  update_virtual_fields_marked_for_write(table);
11664
11663
  return error;
11665
11664
}
11666
11665
 
11688
11687
{
11689
11688
  delete tab->select->quick;
11690
11689
  tab->select->quick=0;
11691
 
  return tab->select->test_quick_select(tab->join->session, tab->keys,
 
11690
  return tab->select->test_quick_select(tab->join->thd, tab->keys,
11692
11691
                                        (table_map) 0, HA_POS_ERROR, 0,
11693
11692
                                        false);
11694
11693
}
11699
11698
{
11700
11699
  if (tab->select && tab->select->quick && tab->select->quick->reset())
11701
11700
    return 1;
11702
 
  init_read_record(&tab->read_record, tab->join->session, tab->table,
 
11701
  init_read_record(&tab->read_record, tab->join->thd, tab->table,
11703
11702
                   tab->select,1,1);
11704
11703
  return (*tab->read_record.read_record)(&tab->read_record);
11705
11704
}
11741
11740
      table->report_error(error);
11742
11741
    return -1;
11743
11742
  }
11744
 
  if (not error)
11745
 
    update_virtual_fields_marked_for_write(tab->table);
11746
11743
  return 0;
11747
11744
}
11748
11745
 
11762
11759
 
11763
11760
      if ((error=info->file->index_next(info->record)))
11764
11761
        return info->table->report_error(error);
11765
 
      if (not error)
11766
 
        update_virtual_fields_marked_for_write(tab->table);
 
11762
      
11767
11763
    } while (!key_cmp(tab->table->key_info[tab->index].key_part, 
11768
11764
                      tab->insideout_buf, key->key_length));
11769
11765
    tab->insideout_match_tab->found_match= 0;
11780
11776
  int error;
11781
11777
  if ((error=info->file->index_next(info->record)))
11782
11778
    return info->table->report_error(error);
11783
 
  if (not error)
11784
 
    update_virtual_fields_marked_for_write(info->table);
11785
11779
  return 0;
11786
11780
}
11787
11781
 
11807
11801
    table->file->ha_index_init(tab->index, 1);
11808
11802
  if ((error= tab->table->file->index_last(tab->table->record[0])))
11809
11803
    return table->report_error(error);
11810
 
  if (not error)
11811
 
    update_virtual_fields_marked_for_write(tab->table);
11812
11804
  return 0;
11813
11805
}
11814
11806
 
11819
11811
  int error;
11820
11812
  if ((error= info->file->index_prev(info->record)))
11821
11813
    return info->table->report_error(error);
11822
 
  if (not error)
11823
 
    update_virtual_fields_marked_for_write(info->table);
11824
11814
  return 0;
11825
11815
}
11826
11816
 
11887
11877
 
11888
11878
/* ARGSUSED */
11889
11879
static enum_nested_loop_state
11890
 
end_send(JOIN *join, JOIN_TAB *,
11891
 
         bool end_of_records)
 
11880
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
11881
         bool end_of_records)
11892
11882
{
11893
11883
  if (!end_of_records)
11894
11884
  {
11952
11942
}
11953
11943
 
11954
11944
 
11955
 
/* ARGSUSED */
 
11945
        /* ARGSUSED */
11956
11946
enum_nested_loop_state
11957
 
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)
11958
11949
{
11959
11950
  int idx= -1;
11960
11951
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
11962
11953
  if (!join->first_record || end_of_records ||
11963
11954
      (idx=test_if_item_cache_changed(join->group_fields)) >= 0)
11964
11955
  {
11965
 
    if (join->first_record ||
 
11956
    if (join->first_record || 
11966
11957
        (end_of_records && !join->group && !join->group_optimized_away))
11967
11958
    {
11968
11959
      if (idx < (int) join->send_group_parts)
12024
12015
      if (end_of_records)
12025
12016
        return(NESTED_LOOP_OK);
12026
12017
      join->first_record=1;
12027
 
      test_if_item_cache_changed(join->group_fields);
 
12018
      VOID(test_if_item_cache_changed(join->group_fields));
12028
12019
    }
12029
12020
    if (idx < (int) join->send_group_parts)
12030
12021
    {
12044
12035
}
12045
12036
 
12046
12037
 
12047
 
/* ARGSUSED */
 
12038
        /* ARGSUSED */
12048
12039
enum_nested_loop_state
12049
 
end_write(JOIN *join, JOIN_TAB *,
12050
 
          bool end_of_records)
 
12040
end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12041
          bool end_of_records)
12051
12042
{
12052
12043
  Table *table=join->tmp_table;
12053
12044
 
12054
 
  if (join->session->killed)                    // Aborted by user
 
12045
  if (join->thd->killed)                        // Aborted by user
12055
12046
  {
12056
 
    join->session->send_kill_message();
 
12047
    join->thd->send_kill_message();
12057
12048
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12058
12049
  }
12059
12050
  if (!end_of_records)
12060
12051
  {
12061
12052
    copy_fields(&join->tmp_table_param);
12062
12053
    copy_funcs(join->tmp_table_param.items_to_copy);
 
12054
#ifdef TO_BE_DELETED
 
12055
    if (!table->uniques)                        // If not unique handling
 
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
12063
12070
    if (!join->having || join->having->val_int())
12064
12071
    {
12065
12072
      int error;
12068
12075
      {
12069
12076
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12070
12077
          goto end;
12071
 
        if (create_myisam_from_heap(join->session, table,
 
12078
        if (create_myisam_from_heap(join->thd, table,
12072
12079
                                    join->tmp_table_param.start_recinfo,
12073
12080
                                    &join->tmp_table_param.recinfo,
12074
12081
                                    error, 1))
12094
12101
/** Group by searching after group record and updating it if possible. */
12095
12102
 
12096
12103
static enum_nested_loop_state
12097
 
end_update(JOIN *join, JOIN_TAB *,
12098
 
           bool end_of_records)
 
12104
end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12105
           bool end_of_records)
12099
12106
{
12100
12107
  Table *table=join->tmp_table;
12101
12108
  order_st   *group;
12103
12110
 
12104
12111
  if (end_of_records)
12105
12112
    return(NESTED_LOOP_OK);
12106
 
  if (join->session->killed)                    // Aborted by user
 
12113
  if (join->thd->killed)                        // Aborted by user
12107
12114
  {
12108
 
    join->session->send_kill_message();
 
12115
    join->thd->send_kill_message();
12109
12116
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12110
12117
  }
12111
12118
 
12153
12160
  copy_funcs(join->tmp_table_param.items_to_copy);
12154
12161
  if ((error=table->file->ha_write_row(table->record[0])))
12155
12162
  {
12156
 
    if (create_myisam_from_heap(join->session, table,
 
12163
    if (create_myisam_from_heap(join->thd, table,
12157
12164
                                join->tmp_table_param.start_recinfo,
12158
12165
                                &join->tmp_table_param.recinfo,
12159
12166
                                error, 0))
12170
12177
/** Like end_update, but this is done with unique constraints instead of keys.  */
12171
12178
 
12172
12179
static enum_nested_loop_state
12173
 
end_unique_update(JOIN *join, JOIN_TAB *,
12174
 
                  bool end_of_records)
 
12180
end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12181
                  bool end_of_records)
12175
12182
{
12176
12183
  Table *table=join->tmp_table;
12177
12184
  int     error;
12178
12185
 
12179
12186
  if (end_of_records)
12180
12187
    return(NESTED_LOOP_OK);
12181
 
  if (join->session->killed)                    // Aborted by user
 
12188
  if (join->thd->killed)                        // Aborted by user
12182
12189
  {
12183
 
    join->session->send_kill_message();
 
12190
    join->thd->send_kill_message();
12184
12191
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12185
12192
  }
12186
12193
 
12215
12222
}
12216
12223
 
12217
12224
 
12218
 
/* ARGSUSED */
 
12225
        /* ARGSUSED */
12219
12226
enum_nested_loop_state
12220
 
end_write_group(JOIN *join, JOIN_TAB *,
12221
 
                bool end_of_records)
 
12227
end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 
12228
                bool end_of_records)
12222
12229
{
12223
12230
  Table *table=join->tmp_table;
12224
12231
  int     idx= -1;
12225
12232
 
12226
 
  if (join->session->killed)
 
12233
  if (join->thd->killed)
12227
12234
  {                                             // Aborted by user
12228
 
    join->session->send_kill_message();
 
12235
    join->thd->send_kill_message();
12229
12236
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12230
12237
  }
12231
12238
  if (!join->first_record || end_of_records ||
12246
12253
        if (!join->having || join->having->val_int())
12247
12254
        {
12248
12255
          int error= table->file->ha_write_row(table->record[0]);
12249
 
          if (error && create_myisam_from_heap(join->session, table,
 
12256
          if (error && create_myisam_from_heap(join->thd, table,
12250
12257
                                               join->tmp_table_param.start_recinfo,
12251
12258
                                                &join->tmp_table_param.recinfo,
12252
12259
                                               error, 0))
12266
12273
      if (end_of_records)
12267
12274
        return(NESTED_LOOP_OK);
12268
12275
      join->first_record=1;
12269
 
      test_if_item_cache_changed(join->group_fields);
 
12276
      VOID(test_if_item_cache_changed(join->group_fields));
12270
12277
    }
12271
12278
    if (idx < (int) join->send_group_parts)
12272
12279
    {
12350
12357
   @param join The top-level query.
12351
12358
   @param old_cond The expression to be replaced.
12352
12359
   @param new_cond The expression to be substituted.
12353
 
   @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
12354
12361
   the new expression.
12355
12362
   @return <code>true</code> if there was an error, <code>false</code> if
12356
12363
   successful.
12361
12368
  if (join->conds == old_cond) {
12362
12369
    join->conds= new_cond;
12363
12370
    if (do_fix_fields)
12364
 
      new_cond->fix_fields(join->session, &join->conds);
 
12371
      new_cond->fix_fields(join->thd, &join->conds);
12365
12372
    return false;
12366
12373
  }
12367
12374
  
12373
12380
      {
12374
12381
        li.replace(new_cond);
12375
12382
        if (do_fix_fields)
12376
 
          new_cond->fix_fields(join->session, li.ref());
 
12383
          new_cond->fix_fields(join->thd, li.ref());
12377
12384
        return false;
12378
12385
      }
12379
12386
  }
12533
12540
  if (!table->reginfo.join_tab)
12534
12541
    return (Item*) 0;             // field from outer non-select (UPDATE,...)
12535
12542
 
12536
 
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
 
12543
  uint ref_parts=table->reginfo.join_tab->ref.key_parts;
12537
12544
  if (ref_parts)
12538
12545
  {
12539
12546
    KEY_PART_INFO *key_part=
12540
12547
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
12541
 
    uint32_t part;
 
12548
    uint part;
12542
12549
 
12543
12550
    for (part=0 ; part < ref_parts ; part++)
12544
12551
    {
12686
12693
*/
12687
12694
 
12688
12695
static uint
12689
 
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,
12690
12697
               const key_map *usable_keys)
12691
12698
{
12692
12699
  uint32_t nr;
12749
12756
list_contains_unique_index(Table *table,
12750
12757
                          bool (*find_func) (Field *, void *), void *data)
12751
12758
{
12752
 
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
 
12759
  for (uint keynr= 0; keynr < table->s->keys; keynr++)
12753
12760
  {
12754
12761
    if (keynr == table->s->primary_key ||
12755
12762
         (table->key_info[keynr].flags & HA_NOSAME))
12873
12880
                        bool no_changes, const key_map *map)
12874
12881
{
12875
12882
  int32_t ref_key;
12876
 
  uint32_t ref_key_parts;
 
12883
  uint ref_key_parts;
12877
12884
  int order_direction;
12878
12885
  uint32_t used_key_parts;
12879
12886
  Table *table=tab->table;
12937
12944
      /*
12938
12945
        We come here when ref_key is not among usable_keys
12939
12946
      */
12940
 
      uint32_t new_ref_key;
 
12947
      uint new_ref_key;
12941
12948
      /*
12942
12949
        If using index only read, only consider other possible index only
12943
12950
        keys
12982
12989
          new_ref_key_map.clear_all();  // Force the creation of quick select
12983
12990
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12984
12991
 
12985
 
          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,
12986
12993
                                        (tab->join->select_options &
12987
12994
                                         OPTION_FOUND_ROWS) ?
12988
12995
                                        HA_POS_ERROR :
13007
13014
      or a table scan.
13008
13015
      It may be the case if order_st/GROUP BY is used with LIMIT.
13009
13016
    */
13010
 
    uint32_t nr;
 
13017
    uint nr;
13011
13018
    key_map keys;
13012
 
    uint32_t best_key_parts= 0;
 
13019
    uint best_key_parts= 0;
13013
13020
    int best_key_direction= 0;
13014
13021
    ha_rows best_records= 0;
13015
13022
    double read_time;
13017
13024
    bool is_best_covering= false;
13018
13025
    double fanout= 1;
13019
13026
    JOIN *join= tab->join;
13020
 
    uint32_t tablenr= tab - join->join_tab;
 
13027
    uint tablenr= tab - join->join_tab;
13021
13028
    ha_rows table_records= table->file->stats.records;
13022
13029
    bool group= join->group && order == join->group_list;
13023
13030
 
13051
13058
      keys= usable_keys;
13052
13059
 
13053
13060
    read_time= join->best_positions[tablenr].read_time;
13054
 
    for (uint32_t i= tablenr+1; i < join->tables; i++)
 
13061
    for (uint i= tablenr+1; i < join->tables; i++)
13055
13062
      fanout*= join->best_positions[i].records_read; // fanout is always >= 1
13056
13063
 
13057
13064
    for (nr=0; nr < table->s->keys ; nr++)
13136
13143
            index entry.
13137
13144
          */
13138
13145
          index_scan_time= select_limit/rec_per_key *
13139
 
                           cmin(rec_per_key, table->file->scan_time());
 
13146
                           min(rec_per_key, table->file->scan_time());
13140
13147
          if (is_covering || (ref_key < 0 && (group || table->force_index)) ||
13141
13148
              index_scan_time < read_time)
13142
13149
          {
13146
13153
            if (table->quick_keys.is_set(nr))
13147
13154
              quick_records= table->quick_rows[nr];
13148
13155
            if (best_key < 0 ||
13149
 
                (select_limit <= cmin(quick_records,best_records) ?
 
13156
                (select_limit <= min(quick_records,best_records) ?
13150
13157
                 keyinfo->key_parts < best_key_parts :
13151
13158
                 quick_records < best_records))
13152
13159
            {
13169
13176
        map.clear_all();       // Force the creation of quick select
13170
13177
        map.set_bit(best_key); // only best_key.
13171
13178
        quick_created=         
13172
 
          select->test_quick_select(join->session, map, 0,
 
13179
          select->test_quick_select(join->thd, map, 0,
13173
13180
                                    join->select_options & OPTION_FOUND_ROWS ?
13174
13181
                                    HA_POS_ERROR :
13175
13182
                                    join->unit->select_limit_cnt,
13288
13295
 
13289
13296
  SYNOPSIS
13290
13297
   create_sort_index()
13291
 
     session            Thread handler
 
13298
     thd                Thread handler
13292
13299
     tab                Table to sort (in join structure)
13293
13300
     order              How table should be sorted
13294
13301
     filesort_limit     Max number of rows that needs to be sorted
13313
13320
*/
13314
13321
 
13315
13322
static int
13316
 
create_sort_index(Session *session, JOIN *join, order_st *order,
 
13323
create_sort_index(THD *thd, JOIN *join, order_st *order,
13317
13324
                  ha_rows filesort_limit, ha_rows select_limit,
13318
13325
                  bool is_order_by)
13319
13326
{
13320
 
  uint32_t length= 0;
 
13327
  uint length= 0;
13321
13328
  ha_rows examined_rows;
13322
13329
  Table *table;
13323
13330
  SQL_SELECT *select;
13377
13384
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13378
13385
        field, quick will contain an empty record set.
13379
13386
      */
13380
 
      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, 
13381
13388
                                                     tab->found_records))))
13382
13389
        goto err;
13383
13390
    }
13390
13397
 
13391
13398
  if (table->s->tmp_table)
13392
13399
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
13393
 
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
13400
  table->sort.found_records=filesort(thd, table,join->sortorder, length,
13394
13401
                                     select, filesort_limit, 0,
13395
13402
                                     &examined_rows);
13396
13403
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
13440
13447
remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
13441
13448
{
13442
13449
  int error;
13443
 
  uint32_t reclength,offset;
13444
 
  uint32_t field_count;
13445
 
  Session *session= join->session;
 
13450
  ulong reclength,offset;
 
13451
  uint field_count;
 
13452
  THD *thd= join->thd;
13446
13453
 
13447
13454
  entry->reginfo.lock_type=TL_WRITE;
13448
13455
 
13465
13472
  offset= (field_count ? 
13466
13473
           entry->field[entry->s->fields - field_count]->
13467
13474
           offset(entry->record[0]) : 0);
13468
 
  reclength= entry->s->reclength-offset;
 
13475
  reclength=entry->s->reclength-offset;
13469
13476
 
13470
13477
  free_io_cache(entry);                         // Safety
13471
13478
  entry->file->info(HA_STATUS_VARIABLE);
13472
13479
  if (entry->s->db_type() == heap_hton ||
13473
13480
      (!entry->s->blob_fields &&
13474
13481
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13475
 
        session->variables.sortbuff_size)))
13476
 
    error= remove_dup_with_hash_index(join->session, entry,
 
13482
        thd->variables.sortbuff_size)))
 
13483
    error=remove_dup_with_hash_index(join->thd, entry,
13477
13484
                                     field_count, first_field,
13478
13485
                                     reclength, having);
13479
13486
  else
13480
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
13487
    error=remove_dup_with_compare(join->thd, entry, first_field, offset,
13481
13488
                                  having);
13482
13489
 
13483
13490
  free_blobs(first_field);
13485
13492
}
13486
13493
 
13487
13494
 
13488
 
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13489
 
                                   uint32_t offset, Item *having)
 
13495
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
 
13496
                                   ulong offset, Item *having)
13490
13497
{
13491
13498
  handler *file=table->file;
13492
13499
  char *org_record,*new_record;
13493
 
  unsigned char *record;
 
13500
  uchar *record;
13494
13501
  int error;
13495
 
  uint32_t reclength= table->s->reclength-offset;
 
13502
  ulong reclength= table->s->reclength-offset;
13496
13503
 
13497
13504
  org_record=(char*) (record=table->record[0])+offset;
13498
13505
  new_record=(char*) table->record[1]+offset;
13501
13508
  error=file->rnd_next(record);
13502
13509
  for (;;)
13503
13510
  {
13504
 
    if (session->killed)
 
13511
    if (thd->killed)
13505
13512
    {
13506
 
      session->send_kill_message();
 
13513
      thd->send_kill_message();
13507
13514
      error=0;
13508
13515
      goto err;
13509
13516
    }
13576
13583
    Note that this will not work on tables with blobs!
13577
13584
*/
13578
13585
 
13579
 
static int remove_dup_with_hash_index(Session *session, Table *table,
13580
 
                                      uint32_t field_count,
 
13586
static int remove_dup_with_hash_index(THD *thd, Table *table,
 
13587
                                      uint field_count,
13581
13588
                                      Field **first_field,
13582
 
                                      uint32_t key_length,
 
13589
                                      ulong key_length,
13583
13590
                                      Item *having)
13584
13591
{
13585
 
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
 
13592
  uchar *key_buffer, *key_pos, *record=table->record[0];
13586
13593
  int error;
13587
13594
  handler *file= table->file;
13588
 
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
13589
 
  uint32_t *field_lengths,*field_length;
 
13595
  ulong extra_length= ALIGN_SIZE(key_length)-key_length;
 
13596
  uint *field_lengths,*field_length;
13590
13597
  HASH hash;
13591
13598
 
13592
13599
  if (!my_multi_malloc(MYF(MY_WME),
13595
13602
                               (long) file->stats.records),
13596
13603
                       &field_lengths,
13597
13604
                       (uint) (field_count*sizeof(*field_lengths)),
13598
 
                       NULL))
 
13605
                       NullS))
13599
13606
    return(1);
13600
13607
 
13601
13608
  {
13602
13609
    Field **ptr;
13603
 
    uint32_t total_length= 0;
 
13610
    ulong total_length= 0;
13604
13611
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
13605
13612
    {
13606
 
      uint32_t length= (*ptr)->sort_length();
 
13613
      uint length= (*ptr)->sort_length();
13607
13614
      (*field_length++)= length;
13608
13615
      total_length+= length;
13609
13616
    }
13615
13622
  if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0, 
13616
13623
                key_length, (hash_get_key) 0, 0, 0))
13617
13624
  {
13618
 
    free((char*) key_buffer);
 
13625
    my_free((char*) key_buffer,MYF(0));
13619
13626
    return(1);
13620
13627
  }
13621
13628
 
13623
13630
  key_pos=key_buffer;
13624
13631
  for (;;)
13625
13632
  {
13626
 
    unsigned char *org_key_pos;
13627
 
    if (session->killed)
 
13633
    uchar *org_key_pos;
 
13634
    if (thd->killed)
13628
13635
    {
13629
 
      session->send_kill_message();
 
13636
      thd->send_kill_message();
13630
13637
      error=0;
13631
13638
      goto err;
13632
13639
    }
13664
13671
      (void) my_hash_insert(&hash, org_key_pos);
13665
13672
    key_pos+=extra_length;
13666
13673
  }
13667
 
  free((char*) key_buffer);
 
13674
  my_free((char*) key_buffer,MYF(0));
13668
13675
  hash_free(&hash);
13669
13676
  file->extra(HA_EXTRA_NO_CACHE);
13670
13677
  (void) file->ha_rnd_end();
13671
13678
  return(0);
13672
13679
 
13673
13680
err:
13674
 
  free((char*) key_buffer);
 
13681
  my_free((char*) key_buffer,MYF(0));
13675
13682
  hash_free(&hash);
13676
13683
  file->extra(HA_EXTRA_NO_CACHE);
13677
13684
  (void) file->ha_rnd_end();
13681
13688
}
13682
13689
 
13683
13690
 
13684
 
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length,
 
13691
SORT_FIELD *make_unireg_sortorder(order_st *order, uint *length,
13685
13692
                                  SORT_FIELD *sortorder)
13686
13693
{
13687
 
  uint32_t count;
 
13694
  uint count;
13688
13695
  SORT_FIELD *sort,*pos;
13689
13696
 
13690
13697
  count=0;
13692
13699
    count++;
13693
13700
  if (!sortorder)
13694
13701
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
13695
 
                                       (cmax(count, *length) + 1));
 
13702
                                       (max(count, *length) + 1));
13696
13703
  pos= sort= sortorder;
13697
13704
 
13698
13705
  if (!pos)
13727
13734
******************************************************************************/
13728
13735
 
13729
13736
static int
13730
 
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
 
13737
join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
13731
13738
{
13732
13739
  register unsigned int i;
13733
13740
  unsigned int length, blobs;
13743
13750
  for (i=0 ; i < table_count ; i++,join_tab++)
13744
13751
  {
13745
13752
    if (!join_tab->used_fieldlength)            /* Not calced yet */
13746
 
      calc_used_field_length(session, join_tab);
 
13753
      calc_used_field_length(thd, join_tab);
13747
13754
    cache->fields+=join_tab->used_fields;
13748
13755
    blobs+=join_tab->used_blobs;
13749
13756
 
13759
13766
 
13760
13767
                  sizeof(CACHE_FIELD*))))
13761
13768
  {
13762
 
    free((unsigned char*) cache->buff);         /* purecov: inspected */
 
13769
    my_free((uchar*) cache->buff,MYF(0));               /* purecov: inspected */
13763
13770
    cache->buff=0;                              /* purecov: inspected */
13764
13771
    return(1);                          /* purecov: inspected */
13765
13772
  }
13770
13777
  length=0;
13771
13778
  for (i=0 ; i < table_count ; i++)
13772
13779
  {
13773
 
    uint32_t null_fields=0, used_fields;
 
13780
    uint null_fields=0, used_fields;
13774
13781
    Field **f_ptr,*field;
13775
13782
    MY_BITMAP *read_set= tables[i].table->read_set;
13776
13783
    for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
13805
13812
    /* If outer join table, copy null_row flag */
13806
13813
    if (tables[i].table->maybe_null)
13807
13814
    {
13808
 
      copy->str= (unsigned char*) &tables[i].table->null_row;
 
13815
      copy->str= (uchar*) &tables[i].table->null_row;
13809
13816
      copy->length=sizeof(tables[i].table->null_row);
13810
13817
      copy->strip=0;
13811
13818
      copy->blob_field=0;
13836
13843
  cache->length=length+blobs*sizeof(char*);
13837
13844
  cache->blobs=blobs;
13838
13845
  *blob_ptr=0;                                  /* End sequentel */
13839
 
  size=cmax(session->variables.join_buff_size, (uint32_t)cache->length);
13840
 
  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))))
13841
13848
    return(1);                          /* Don't use cache */ /* purecov: inspected */
13842
13849
  cache->end=cache->buff+size;
13843
13850
  reset_cache_write(cache);
13845
13852
}
13846
13853
 
13847
13854
 
13848
 
static uint32_t used_blob_length(CACHE_FIELD **ptr)
 
13855
static ulong
 
13856
used_blob_length(CACHE_FIELD **ptr)
13849
13857
{
13850
 
  uint32_t length,blob_length;
 
13858
  uint length,blob_length;
13851
13859
  for (length=0 ; *ptr ; ptr++)
13852
13860
  {
13853
13861
    (*ptr)->blob_length=blob_length=(*ptr)->blob_field->get_length();
13861
13869
static bool
13862
13870
store_record_in_cache(JOIN_CACHE *cache)
13863
13871
{
13864
 
  uint32_t length;
13865
 
  unsigned char *pos;
 
13872
  uint length;
 
13873
  uchar *pos;
13866
13874
  CACHE_FIELD *copy,*end_field;
13867
13875
  bool last_record;
13868
13876
 
13871
13879
 
13872
13880
  length=cache->length;
13873
13881
  if (cache->blobs)
13874
 
    length+= used_blob_length(cache->blob_ptr);
 
13882
    length+=used_blob_length(cache->blob_ptr);
13875
13883
  if ((last_record= (length + cache->length > (size_t) (cache->end - pos))))
13876
13884
    cache->ptr_record=cache->records;
13877
13885
  /*
13904
13912
 
13905
13913
      if (copy->strip)
13906
13914
      {
13907
 
        unsigned char *str,*end;
 
13915
        uchar *str,*end;
13908
13916
        for (str=copy->str,end= str+copy->length;
13909
13917
             end > str && end[-1] == ' ' ;
13910
13918
             end--) ;
13944
13952
static void
13945
13953
read_cached_record(JOIN_TAB *tab)
13946
13954
{
13947
 
  unsigned char *pos;
13948
 
  uint32_t length;
 
13955
  uchar *pos;
 
13956
  uint length;
13949
13957
  bool last_record;
13950
13958
  CACHE_FIELD *copy,*end_field;
13951
13959
 
14023
14031
  }
14024
14032
  else 
14025
14033
    no_prev_key= true;
14026
 
  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)) ||
14027
14035
      no_prev_key)
14028
14036
    return 1;
14029
14037
  return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
14032
14040
 
14033
14041
 
14034
14042
bool
14035
 
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
 
14043
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
14036
14044
{
14037
 
  enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
14038
 
  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;
14039
14047
  bool result= 0;
14040
14048
 
14041
14049
  for (store_key **copy=ref->key_copy ; *copy ; copy++)
14046
14054
      break;
14047
14055
    }
14048
14056
  }
14049
 
  session->count_cuted_fields= save_count_cuted_fields;
 
14057
  thd->count_cuted_fields= save_count_cuted_fields;
14050
14058
  return result;
14051
14059
}
14052
14060
 
14071
14079
 
14072
14080
  ref_pointer_array and all_fields are updated.
14073
14081
 
14074
 
  @param[in] session                 Pointer to current thread structure
 
14082
  @param[in] thd                     Pointer to current thread structure
14075
14083
  @param[in,out] ref_pointer_array  All select, group and order by fields
14076
14084
  @param[in] tables                 List of tables to search in (usually
14077
14085
    FROM clause)
14089
14097
*/
14090
14098
 
14091
14099
static bool
14092
 
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,
14093
14101
                   order_st *order, List<Item> &fields, List<Item> &all_fields,
14094
14102
                   bool is_group_field)
14095
14103
{
14097
14105
  Item::Type order_item_type;
14098
14106
  Item **select_item; /* The corresponding item from the SELECT clause. */
14099
14107
  Field *from_field;  /* The corresponding field from the FROM clause. */
14100
 
  uint32_t counter;
 
14108
  uint counter;
14101
14109
  enum_resolution_type resolution;
14102
14110
 
14103
14111
  /*
14106
14114
  */
14107
14115
  if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
14108
14116
  {                                             /* Order by position */
14109
 
    uint32_t count= (uint) order_item->val_int();
 
14117
    uint count= (uint) order_item->val_int();
14110
14118
    if (!count || count > fields.elements)
14111
14119
    {
14112
14120
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
14113
 
               order_item->full_name(), session->where);
 
14121
               order_item->full_name(), thd->where);
14114
14122
      return true;
14115
14123
    }
14116
14124
    order->item= ref_pointer_array + count - 1;
14136
14144
      for this name (in case if we would perform lookup in all tables).
14137
14145
    */
14138
14146
    if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14139
 
        order_item->fix_fields(session, order->item))
 
14147
        order_item->fix_fields(thd, order->item))
14140
14148
      return true;
14141
14149
 
14142
14150
    /* Lookup the current GROUP field in the FROM clause. */
14145
14153
    if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14146
14154
        order_item_type == Item::REF_ITEM)
14147
14155
    {
14148
 
      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,
14149
14157
                                       NULL, &view_ref, IGNORE_ERRORS, true,
14150
14158
                                       false);
14151
14159
      if (!from_field)
14185
14193
        warning so the user knows that the field from the FROM clause
14186
14194
        overshadows the column reference from the SELECT list.
14187
14195
      */
14188
 
      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,
14189
14197
                          ER(ER_NON_UNIQ_ERROR),
14190
14198
                          ((Item_ident*) order_item)->field_name,
14191
 
                          current_session->where);
 
14199
                          current_thd->where);
14192
14200
    }
14193
14201
  }
14194
14202
 
14205
14213
    arguments for which fix_fields already was called.
14206
14214
  */
14207
14215
  if (!order_item->fixed &&
14208
 
      (order_item->fix_fields(session, order->item) ||
 
14216
      (order_item->fix_fields(thd, order->item) ||
14209
14217
       (order_item= *order->item)->check_cols(1) ||
14210
 
       session->is_fatal_error))
 
14218
       thd->is_fatal_error))
14211
14219
    return true; /* Wrong field. */
14212
14220
 
14213
 
  uint32_t el= all_fields.elements;
 
14221
  uint el= all_fields.elements;
14214
14222
  all_fields.push_front(order_item); /* Add new field to field list. */
14215
14223
  ref_pointer_array[el]= order_item;
14216
14224
  order->item= ref_pointer_array + el;
14225
14233
  the field list.
14226
14234
*/
14227
14235
 
14228
 
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
 
14236
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
14229
14237
                List<Item> &fields, List<Item> &all_fields, order_st *order)
14230
14238
{
14231
 
  session->where="order clause";
 
14239
  thd->where="order clause";
14232
14240
  for (; order; order=order->next)
14233
14241
  {
14234
 
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
 
14242
    if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
14235
14243
                           all_fields, false))
14236
14244
      return 1;
14237
14245
  }
14242
14250
/**
14243
14251
  Intitialize the GROUP BY list.
14244
14252
 
14245
 
  @param session                        Thread handler
 
14253
  @param thd                    Thread handler
14246
14254
  @param ref_pointer_array      We store references to all fields that was
14247
14255
                               not in 'fields' here.
14248
14256
  @param fields         All fields in the select part. Any item in
14266
14274
*/
14267
14275
 
14268
14276
int
14269
 
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
 
14277
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
14270
14278
            List<Item> &fields, List<Item> &all_fields, order_st *order,
14271
14279
            bool *hidden_group_fields)
14272
14280
{
14276
14284
  if (!order)
14277
14285
    return 0;                           /* Everything is ok */
14278
14286
 
14279
 
  uint32_t org_fields=all_fields.elements;
 
14287
  uint org_fields=all_fields.elements;
14280
14288
 
14281
 
  session->where="group statement";
 
14289
  thd->where="group statement";
14282
14290
  for (ord= order; ord; ord= ord->next)
14283
14291
  {
14284
 
    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,
14285
14293
                           all_fields, true))
14286
14294
      return 1;
14287
14295
    (*ord->item)->marker= UNDEF_POS;            /* Mark found */
14312
14320
    Item_field *field;
14313
14321
    int cur_pos_in_select_list= 0;
14314
14322
    List_iterator<Item> li(fields);
14315
 
    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);
14316
14324
 
14317
14325
    field= naf_it++;
14318
14326
    while (field && (item=li++))
14363
14371
*/
14364
14372
 
14365
14373
static order_st *
14366
 
create_distinct_group(Session *session, Item **ref_pointer_array,
 
14374
create_distinct_group(THD *thd, Item **ref_pointer_array,
14367
14375
                      order_st *order_list, List<Item> &fields,
14368
 
                      List<Item> &, bool *all_order_by_fields_used)
 
14376
                      List<Item> &all_fields __attribute__((unused)),
 
14377
                      bool *all_order_by_fields_used)
14369
14378
{
14370
14379
  List_iterator<Item> li(fields);
14371
14380
  Item *item;
14380
14389
  {
14381
14390
    if (order->in_field_list)
14382
14391
    {
14383
 
      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));
14384
14393
      if (!ord)
14385
14394
        return 0;
14386
14395
      *prev=ord;
14405
14414
        if ((*ord_iter->item)->eq(item, 1))
14406
14415
          goto next_item;
14407
14416
      
14408
 
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
 
14417
      order_st *ord=(order_st*) thd->calloc(sizeof(order_st));
14409
14418
      if (!ord)
14410
14419
        return 0;
14411
14420
 
14458
14467
            param->quick_group=0;                       // UDF SUM function
14459
14468
          param->sum_func_count++;
14460
14469
 
14461
 
          for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
 
14470
          for (uint i=0 ; i < sum_item->arg_count ; i++)
14462
14471
          {
14463
14472
            if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
14464
14473
              param->field_count++;
14537
14546
static void
14538
14547
calc_group_buffer(JOIN *join,order_st *group)
14539
14548
{
14540
 
  uint32_t key_length=0, parts=0, null_parts=0;
 
14549
  uint key_length=0, parts=0, null_parts=0;
14541
14550
 
14542
14551
  if (group)
14543
14552
    join->group= 1;
14655
14664
  {
14656
14665
    for (; group ; group=group->next)
14657
14666
    {
14658
 
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
 
14667
      Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
14659
14668
      if (!tmp || join->group_fields.push_front(tmp))
14660
14669
        return true;
14661
14670
    }
14702
14711
  Change old item_field to use a new field with points at saved fieldvalue
14703
14712
  This function is only called before use of send_fields.
14704
14713
 
14705
 
  @param session                   Session pointer
 
14714
  @param thd                   THD pointer
14706
14715
  @param param                 temporary table parameters
14707
14716
  @param ref_pointer_array     array of pointers to top elements of filed list
14708
14717
  @param res_selected_fields   new list of items of select item list
14723
14732
*/
14724
14733
 
14725
14734
bool
14726
 
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
 
14735
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
14727
14736
                  Item **ref_pointer_array,
14728
14737
                  List<Item> &res_selected_fields, List<Item> &res_all_fields,
14729
 
                  uint32_t elements, List<Item> &all_fields)
 
14738
                  uint elements, List<Item> &all_fields)
14730
14739
{
14731
14740
  Item *pos;
14732
14741
  List_iterator_fast<Item> li(all_fields);
14735
14744
  res_all_fields.empty();
14736
14745
  List_iterator_fast<Item> itr(res_all_fields);
14737
14746
  List<Item> extra_funcs;
14738
 
  uint32_t i, border= all_fields.elements - elements;
 
14747
  uint i, border= all_fields.elements - elements;
14739
14748
 
14740
14749
  if (param->field_count && 
14741
14750
      !(copy=param->copy_field= new Copy_field[param->field_count]))
14745
14754
  for (i= 0; (pos= li++); i++)
14746
14755
  {
14747
14756
    Field *field;
14748
 
    unsigned char *tmp;
 
14757
    uchar *tmp;
14749
14758
    Item *real_pos= pos->real_item();
14750
14759
    if (real_pos->type() == Item::FIELD_ITEM)
14751
14760
    {
14752
14761
      Item_field *item;
14753
 
      if (!(item= new Item_field(session, ((Item_field*) real_pos))))
 
14762
      if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
14754
14763
        goto err;
14755
14764
      if (pos->type() == Item::REF_ITEM)
14756
14765
      {
14784
14793
           saved value
14785
14794
        */
14786
14795
        field= item->field;
14787
 
        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);
14788
14797
        /*
14789
14798
          We need to allocate one extra byte for null handling and
14790
14799
          another extra byte to not get warnings from purify in
14791
14800
          Field_varstring::val_int
14792
14801
        */
14793
 
        if (!(tmp= (unsigned char*) sql_alloc(field->pack_length()+2)))
 
14802
        if (!(tmp= (uchar*) sql_alloc(field->pack_length()+2)))
14794
14803
          goto err;
14795
14804
        if (copy)
14796
14805
        {
14887
14896
 
14888
14897
bool JOIN::alloc_func_list()
14889
14898
{
14890
 
  uint32_t func_count, group_parts;
 
14899
  uint func_count, group_parts;
14891
14900
 
14892
14901
  func_count= tmp_table_param.sum_func_count;
14893
14902
  /*
14918
14927
  }
14919
14928
 
14920
14929
  /* This must use calloc() as rollup_make_fields depends on this */
14921
 
  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) +
14922
14931
                                      sizeof(Item_sum***) * (group_parts+1));
14923
14932
  sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
14924
14933
  return(sum_funcs == 0);
14965
14974
  }
14966
14975
  else if (rollup.state == ROLLUP::STATE_NONE)
14967
14976
  {
14968
 
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
 
14977
    for (uint i=0 ; i <= send_group_parts ;i++)
14969
14978
      sum_funcs_end[i]= func;
14970
14979
  }
14971
14980
  else if (rollup.state == ROLLUP::STATE_READY)
14979
14988
  Change all funcs and sum_funcs to fields in tmp table, and create
14980
14989
  new list of all items.
14981
14990
 
14982
 
  @param session                   Session pointer
 
14991
  @param thd                   THD pointer
14983
14992
  @param ref_pointer_array     array of pointers to top elements of filed list
14984
14993
  @param res_selected_fields   new list of items of select item list
14985
14994
  @param res_all_fields        new list of all items
14993
15002
*/
14994
15003
 
14995
15004
static bool
14996
 
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
 
15005
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
14997
15006
                         List<Item> &res_selected_fields,
14998
15007
                         List<Item> &res_all_fields,
14999
 
                         uint32_t elements, List<Item> &all_fields)
 
15008
                         uint elements, List<Item> &all_fields)
15000
15009
{
15001
15010
  List_iterator_fast<Item> it(all_fields);
15002
15011
  Item *item_field,*item;
15004
15013
  res_selected_fields.empty();
15005
15014
  res_all_fields.empty();
15006
15015
 
15007
 
  uint32_t i, border= all_fields.elements - elements;
 
15016
  uint i, border= all_fields.elements - elements;
15008
15017
  for (i= 0; (item= it++); i++)
15009
15018
  {
15010
15019
    Field *field;
15017
15026
    {
15018
15027
      if (item->type() == Item::FIELD_ITEM)
15019
15028
      {
15020
 
        item_field= item->get_tmp_table_item(session);
 
15029
        item_field= item->get_tmp_table_item(thd);
15021
15030
      }
15022
15031
      else if ((field= item->get_tmp_table_field()))
15023
15032
      {
15059
15068
  Change all sum_func refs to fields to point at fields in tmp table.
15060
15069
  Change all funcs to be fields in tmp table.
15061
15070
 
15062
 
  @param session                   Session pointer
 
15071
  @param thd                   THD pointer
15063
15072
  @param ref_pointer_array     array of pointers to top elements of filed list
15064
15073
  @param res_selected_fields   new list of items of select item list
15065
15074
  @param res_all_fields        new list of all items
15073
15082
*/
15074
15083
 
15075
15084
static bool
15076
 
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
 
15085
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
15077
15086
                          List<Item> &res_selected_fields,
15078
 
                          List<Item> &res_all_fields, uint32_t elements,
 
15087
                          List<Item> &res_all_fields, uint elements,
15079
15088
                          List<Item> &all_fields)
15080
15089
{
15081
15090
  List_iterator_fast<Item> it(all_fields);
15083
15092
  res_selected_fields.empty();
15084
15093
  res_all_fields.empty();
15085
15094
 
15086
 
  uint32_t i, border= all_fields.elements - elements;
 
15095
  uint i, border= all_fields.elements - elements;
15087
15096
  for (i= 0; (item= it++); i++)
15088
15097
  {
15089
 
    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));
15090
15099
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15091
15100
      new_item;
15092
15101
  }
15096
15105
    itr++;
15097
15106
  itr.sublist(res_selected_fields, elements);
15098
15107
 
15099
 
  return session->is_fatal_error;
 
15108
  return thd->is_fatal_error;
15100
15109
}
15101
15110
 
15102
15111
 
15109
15118
/**
15110
15119
  Call ::setup for all sum functions.
15111
15120
 
15112
 
  @param session           thread handler
 
15121
  @param thd           thread handler
15113
15122
  @param func_ptr      sum function list
15114
15123
 
15115
15124
  @retval
15118
15127
    true   error
15119
15128
*/
15120
15129
 
15121
 
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr)
 
15130
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
15122
15131
{
15123
15132
  Item_sum *func;
15124
15133
  while ((func= *(func_ptr++)))
15125
15134
  {
15126
 
    if (func->setup(session))
 
15135
    if (func->setup(thd))
15127
15136
      return(true);
15128
15137
  }
15129
15138
  return(false);
15142
15151
/** Update record 0 in tmp_table from record 1. */
15143
15152
 
15144
15153
static void
15145
 
update_tmptable_sum_func(Item_sum **func_ptr, Table *)
 
15154
update_tmptable_sum_func(Item_sum **func_ptr,
 
15155
                         Table *tmp_table __attribute__((unused)))
15146
15156
{
15147
15157
  Item_sum *func;
15148
15158
  while ((func= *(func_ptr++)))
15205
15215
  currenct select for the table.
15206
15216
*/
15207
15217
 
15208
 
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)
15209
15219
{
15210
15220
  if (!join_tab->ref.key_parts)
15211
15221
    return(false);
15216
15226
  if (!cond)
15217
15227
    return(true);
15218
15228
 
15219
 
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
 
15229
  for (uint i=0 ; i < join_tab->ref.key_parts ; i++)
15220
15230
  {
15221
15231
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
15222
15232
                              fieldnr-1];
15223
15233
    Item *value=join_tab->ref.items[i];
15224
15234
    cond->add(new Item_func_equal(new Item_field(field), value));
15225
15235
  }
15226
 
  if (session->is_fatal_error)
 
15236
  if (thd->is_fatal_error)
15227
15237
    return(true);
15228
15238
 
15229
15239
  if (!cond->fixed)
15230
 
    cond->fix_fields(session, (Item**)&cond);
 
15240
    cond->fix_fields(thd, (Item**)&cond);
15231
15241
  if (join_tab->select)
15232
15242
  {
15233
15243
    error=(int) cond->add(join_tab->select->cond);
15244
15254
/**
15245
15255
  Free joins of subselect of this select.
15246
15256
 
15247
 
  @param session      Session pointer
 
15257
  @param thd      THD pointer
15248
15258
  @param select   pointer to st_select_lex which subselects joins we will free
15249
15259
*/
15250
15260
 
15251
 
void free_underlaid_joins(Session *, SELECT_LEX *select)
 
15261
void free_underlaid_joins(THD *thd __attribute__((unused)),
 
15262
                          SELECT_LEX *select)
15252
15263
{
15253
15264
  for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15254
15265
       unit;
15285
15296
    This substitution is needed GROUP BY queries with ROLLUP if
15286
15297
    SELECT list contains expressions over group by attributes.
15287
15298
 
15288
 
  @param session                  reference to the context
 
15299
  @param thd                  reference to the context
15289
15300
  @param expr                 expression to make replacement
15290
15301
  @param group_list           list of references to group by items
15291
15302
  @param changed        out:  returns 1 if item contains a replaced field item
15300
15311
    1   on error
15301
15312
*/
15302
15313
 
15303
 
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,
15304
15315
                             bool *changed)
15305
15316
{
15306
15317
  if (expr->arg_count)
15307
15318
  {
15308
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
15319
    Name_resolution_context *context= &thd->lex->current_select->context;
15309
15320
    Item **arg,**arg_end;
15310
15321
    bool arg_changed= false;
15311
15322
    for (arg= expr->arguments(),
15324
15335
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15325
15336
                                        item->name)))
15326
15337
              return 1;                                 // fatal_error is set
15327
 
            session->change_item_tree(arg, new_item);
 
15338
            thd->change_item_tree(arg, new_item);
15328
15339
            arg_changed= true;
15329
15340
          }
15330
15341
        }
15331
15342
      }
15332
15343
      else if (item->type() == Item::FUNC_ITEM)
15333
15344
      {
15334
 
        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))
15335
15346
          return 1;
15336
15347
      }
15337
15348
    }
15349
15360
 
15350
15361
bool JOIN::rollup_init()
15351
15362
{
15352
 
  uint32_t i,j;
 
15363
  uint i,j;
15353
15364
  Item **ref_array;
15354
15365
 
15355
15366
  tmp_table_param.quick_group= 0;       // Can't create groups in tmp table
15361
15372
  */
15362
15373
  tmp_table_param.group_parts= send_group_parts;
15363
15374
 
15364
 
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
 
15375
  if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
15365
15376
                                                sizeof(Item**) +
15366
15377
                                                sizeof(List<Item>) +
15367
15378
                                                ref_pointer_array_size)
15378
15389
  */
15379
15390
  for (i= 0 ; i < send_group_parts ; i++)
15380
15391
  {
15381
 
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
15392
    rollup.null_items[i]= new (thd->mem_root) Item_null_result();
15382
15393
    List<Item> *rollup_fields= &rollup.fields[i];
15383
15394
    rollup_fields->empty();
15384
15395
    rollup.ref_pointer_arrays[i]= ref_array;
15420
15431
          Item* new_item= new Item_func_rollup_const(item);
15421
15432
          if (!new_item)
15422
15433
            return 1;
15423
 
          new_item->fix_fields(session, (Item **) 0);
15424
 
          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);
15425
15436
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15426
15437
          { 
15427
15438
            if (*tmp->item == item)
15428
 
              session->change_item_tree(tmp->item, new_item);
 
15439
              thd->change_item_tree(tmp->item, new_item);
15429
15440
          }
15430
15441
        }
15431
15442
      }
15433
15444
    if (item->type() == Item::FUNC_ITEM && !found_in_group)
15434
15445
    {
15435
15446
      bool changed= false;
15436
 
      if (change_group_ref(session, (Item_func *) item, group_list, &changed))
 
15447
      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
15437
15448
        return 1;
15438
15449
      /*
15439
15450
        We have to prevent creation of a field in a temporary table for
15469
15480
{
15470
15481
  List_iterator_fast<Item> it(fields_arg);
15471
15482
  Item *first_field= sel_fields.head();
15472
 
  uint32_t level;
 
15483
  uint level;
15473
15484
 
15474
15485
  /*
15475
15486
    Create field lists for the different levels
15494
15505
 
15495
15506
  for (level=0 ; level < send_group_parts ; level++)
15496
15507
  {
15497
 
    uint32_t i;
15498
 
    uint32_t pos= send_group_parts - level -1;
 
15508
    uint i;
 
15509
    uint pos= send_group_parts - level -1;
15499
15510
    bool real_fields= 0;
15500
15511
    Item *item;
15501
15512
    List_iterator<Item> new_it(rollup.fields[pos]);
15536
15547
          sub select.  Fortunately it's not common to have rollup in
15537
15548
          sub selects.
15538
15549
        */
15539
 
        item= item->copy_or_same(session);
 
15550
        item= item->copy_or_same(thd);
15540
15551
        ((Item_sum*) item)->make_unique();
15541
15552
        *(*func)= (Item_sum*) item;
15542
15553
        (*func)++;
15554
15565
              This is an element that is used by the GROUP BY and should be
15555
15566
              set to NULL in this level
15556
15567
            */
15557
 
            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();
15558
15569
            if (!null_item)
15559
15570
              return 1;
15560
15571
            item->maybe_null= 1;                // Value will be null sometimes
15598
15609
    1   If send_data_failed()
15599
15610
*/
15600
15611
 
15601
 
int JOIN::rollup_send_data(uint32_t idx)
 
15612
int JOIN::rollup_send_data(uint idx)
15602
15613
{
15603
 
  uint32_t i;
 
15614
  uint i;
15604
15615
  for (i= send_group_parts ; i-- > idx ; )
15605
15616
  {
15606
15617
    /* Get reference pointers to sum functions in place */
15639
15650
    1   if write_data_failed()
15640
15651
*/
15641
15652
 
15642
 
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
 
15653
int JOIN::rollup_write_data(uint idx, Table *table_arg)
15643
15654
{
15644
 
  uint32_t i;
 
15655
  uint i;
15645
15656
  for (i= send_group_parts ; i-- > idx ; )
15646
15657
  {
15647
15658
    /* Get reference pointers to sum functions in place */
15660
15671
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15661
15672
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15662
15673
      {
15663
 
        if (create_myisam_from_heap(session, table_arg, 
 
15674
        if (create_myisam_from_heap(thd, table_arg, 
15664
15675
                                    tmp_table_param.start_recinfo,
15665
15676
                                    &tmp_table_param.recinfo,
15666
15677
                                    write_error, 0))
15702
15713
{
15703
15714
  List<Item> field_list;
15704
15715
  List<Item> item_list;
15705
 
  Session *session=join->session;
 
15716
  THD *thd=join->thd;
15706
15717
  select_result *result=join->result;
15707
15718
  Item *item_null= new Item_null();
15708
15719
  const CHARSET_INFO * const cs= system_charset_info;
15709
15720
  int quick_type;
15710
15721
  /* Don't log this into the slow query log */
15711
 
  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);
15712
15723
  join->unit->offset_limit_cnt= 0;
15713
15724
 
15714
15725
  /* 
15715
15726
    NOTE: the number/types of items pushed into item_list must be in sync with
15716
 
    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()
15717
15728
  */
15718
15729
  if (message)
15719
15730
  {
15721
15732
                                     join->select_lex->select_number));
15722
15733
    item_list.push_back(new Item_string(join->select_lex->type,
15723
15734
                                        strlen(join->select_lex->type), cs));
15724
 
    for (uint32_t i=0 ; i < 7; i++)
 
15735
    for (uint i=0 ; i < 7; i++)
15725
15736
      item_list.push_back(item_null);
15726
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15737
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15727
15738
      item_list.push_back(item_null);
15728
15739
  
15729
15740
    item_list.push_back(new Item_string(message,strlen(message),cs));
15750
15761
    /* table */
15751
15762
    {
15752
15763
      SELECT_LEX *sl= join->unit->first_select();
15753
 
      uint32_t len= 6, lastop= 0;
 
15764
      uint len= 6, lastop= 0;
15754
15765
      memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
15755
15766
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
15756
15767
      {
15783
15794
    /* ref */
15784
15795
    item_list.push_back(item_null);
15785
15796
    /* in_rows */
15786
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15797
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15787
15798
      item_list.push_back(item_null);
15788
15799
    /* rows */
15789
15800
    item_list.push_back(item_null);
15800
15811
  else
15801
15812
  {
15802
15813
    table_map used_tables=0;
15803
 
    for (uint32_t i=0 ; i < join->tables ; i++)
 
15814
    for (uint i=0 ; i < join->tables ; i++)
15804
15815
    {
15805
15816
      JOIN_TAB *tab=join->join_tab+i;
15806
15817
      Table *table=tab->table;
15860
15871
      /* Build "possible_keys" value and add it to item_list */
15861
15872
      if (!tab->keys.is_clear_all())
15862
15873
      {
15863
 
        uint32_t j;
 
15874
        uint j;
15864
15875
        for (j=0 ; j < table->s->keys ; j++)
15865
15876
        {
15866
15877
          if (tab->keys.is_set(j))
15882
15893
      if (tab->ref.key_parts)
15883
15894
      {
15884
15895
        KEY *key_info=table->key_info+ tab->ref.key;
15885
 
        register uint32_t length;
 
15896
        register uint length;
15886
15897
        item_list.push_back(new Item_string(key_info->name,
15887
15898
                                            strlen(key_info->name),
15888
15899
                                            system_charset_info));
15902
15913
      else if (tab->type == JT_NEXT)
15903
15914
      {
15904
15915
        KEY *key_info=table->key_info+ tab->index;
15905
 
        register uint32_t length;
 
15916
        register uint length;
15906
15917
        item_list.push_back(new Item_string(key_info->name,
15907
15918
                                            strlen(key_info->name),cs));
15908
15919
        length= int64_t2str(key_info->key_length, keylen_str_buf, 10) - 
15954
15965
      if (table_list->schema_table)
15955
15966
      {
15956
15967
        /* in_rows */
15957
 
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15968
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15958
15969
          item_list.push_back(item_null);
15959
15970
        /* rows */
15960
15971
        item_list.push_back(item_null);
15974
15985
                                         MY_INT64_NUM_DECIMAL_DIGITS));
15975
15986
 
15976
15987
        /* Add "filtered" field to item_list. */
15977
 
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
15988
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
15978
15989
        {
15979
15990
          float f= 0.0; 
15980
15991
          if (examined_rows)
16015
16026
      }
16016
16027
      else
16017
16028
      {
16018
 
        uint32_t keyno= MAX_KEY;
 
16029
        uint keyno= MAX_KEY;
16019
16030
        if (tab->ref.key_parts)
16020
16031
          keyno= tab->ref.key;
16021
16032
        else if (tab->select && tab->select->quick)
16047
16058
          {
16048
16059
            const COND *pushed_cond= tab->table->file->pushed_cond;
16049
16060
 
16050
 
            if (session->variables.engine_condition_pushdown && pushed_cond)
 
16061
            if (thd->variables.engine_condition_pushdown && pushed_cond)
16051
16062
            {
16052
16063
              extra.append(STRING_WITH_LEN("; Using where with pushed "
16053
16064
                                           "condition"));
16054
 
              if (session->lex->describe & DESCRIBE_EXTENDED)
 
16065
              if (thd->lex->describe & DESCRIBE_EXTENDED)
16055
16066
              {
16056
16067
                extra.append(STRING_WITH_LEN(": "));
16057
16068
                ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16106
16117
          need_order=0;
16107
16118
          extra.append(STRING_WITH_LEN("; Using filesort"));
16108
16119
        }
16109
 
        if (distinct & test_all_bits(used_tables,session->used_tables))
 
16120
        if (distinct & test_all_bits(used_tables,thd->used_tables))
16110
16121
          extra.append(STRING_WITH_LEN("; Distinct"));
16111
16122
 
16112
16123
        if (tab->insideout_match_tab)
16136
16147
          extra.append(STRING_WITH_LEN(")"));
16137
16148
        }
16138
16149
 
16139
 
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
 
16150
        for (uint part= 0; part < tab->ref.key_parts; part++)
16140
16151
        {
16141
16152
          if (tab->ref.cond_guards[part])
16142
16153
          {
16168
16179
       unit;
16169
16180
       unit= unit->next_unit())
16170
16181
  {
16171
 
    if (mysql_explain_union(session, unit, result))
 
16182
    if (mysql_explain_union(thd, unit, result))
16172
16183
      return;
16173
16184
  }
16174
16185
  return;
16175
16186
}
16176
16187
 
16177
16188
 
16178
 
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)
16179
16190
{
16180
16191
  bool res= 0;
16181
16192
  SELECT_LEX *first= unit->first_select();
16186
16197
  {
16187
16198
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16188
16199
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16189
 
    sl->type= (((&session->lex->select_lex)==sl)?
 
16200
    sl->type= (((&thd->lex->select_lex)==sl)?
16190
16201
               (sl->first_inner_unit() || sl->next_select() ? 
16191
16202
                "PRIMARY" : "SIMPLE"):
16192
16203
               ((sl == first)?
16207
16218
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16208
16219
    unit->fake_select_lex->type= "UNION RESULT";
16209
16220
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
16210
 
    if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
 
16221
    if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16211
16222
      res= unit->exec();
16212
16223
    res|= unit->cleanup();
16213
16224
  }
16214
16225
  else
16215
16226
  {
16216
 
    session->lex->current_select= first;
 
16227
    thd->lex->current_select= first;
16217
16228
    unit->set_limit(unit->global_parameters);
16218
 
    res= mysql_select(session, &first->ref_pointer_array,
 
16229
    res= mysql_select(thd, &first->ref_pointer_array,
16219
16230
                        (TableList*) first->table_list.first,
16220
16231
                        first->with_wild, first->item_list,
16221
16232
                        first->where,
16224
16235
                        (order_st*) first->order_list.first,
16225
16236
                        (order_st*) first->group_list.first,
16226
16237
                        first->having,
16227
 
                        (order_st*) session->lex->proc_list.first,
16228
 
                        first->options | session->options | SELECT_DESCRIBE,
 
16238
                        (order_st*) thd->lex->proc_list.first,
 
16239
                        first->options | thd->options | SELECT_DESCRIBE,
16229
16240
                        result, unit, first);
16230
16241
  }
16231
 
  return(res || session->is_error());
 
16242
  return(res || thd->is_error());
16232
16243
}
16233
16244
 
16234
16245
 
16235
 
static void print_table_array(Session *session, String *str, TableList **table, 
 
16246
static void print_table_array(THD *thd, String *str, TableList **table, 
16236
16247
                              TableList **end)
16237
16248
{
16238
 
  (*table)->print(session, str, QT_ORDINARY);
 
16249
  (*table)->print(thd, str, QT_ORDINARY);
16239
16250
 
16240
16251
  for (TableList **tbl= table + 1; tbl < end; tbl++)
16241
16252
  {
16251
16262
      str->append(STRING_WITH_LEN(" semi join "));
16252
16263
    else
16253
16264
      str->append(STRING_WITH_LEN(" join "));
16254
 
    curr->print(session, str, QT_ORDINARY);
 
16265
    curr->print(thd, str, QT_ORDINARY);
16255
16266
    if (curr->on_expr)
16256
16267
    {
16257
16268
      str->append(STRING_WITH_LEN(" on("));
16264
16275
 
16265
16276
/**
16266
16277
  Print joins from the FROM clause.
16267
 
  @param session     thread handler
 
16278
  @param thd     thread handler
16268
16279
  @param str     string where table should be printed
16269
16280
  @param tables  list of tables in join
16270
16281
  @query_type    type of the query is being generated
16271
16282
*/
16272
16283
 
16273
 
static void print_join(Session *session, String *str,
16274
 
                       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)))
16275
16288
{
16276
16289
  /* List is reversed => we should reverse it before using */
16277
16290
  List_iterator_fast<TableList> ti(*tables);
16278
 
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
 
16291
  TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
16279
16292
                                                tables->elements);
16280
16293
  if (table == 0)
16281
16294
    return;  // out of memory
16302
16315
    }
16303
16316
  }
16304
16317
  assert(tables->elements >= 1);
16305
 
  print_table_array(session, str, table, table + tables->elements);
 
16318
  print_table_array(thd, str, table, table + tables->elements);
16306
16319
}
16307
16320
 
16308
16321
 
16311
16324
 
16312
16325
  @details Prints out the USE|FORCE|IGNORE index hint.
16313
16326
 
16314
 
  @param      session         the current thread
 
16327
  @param      thd         the current thread
16315
16328
  @param[out] str         appends the index hint here
16316
16329
  @param      hint        what the hint is (as string : "USE INDEX"|
16317
16330
                          "FORCE INDEX"|"IGNORE INDEX")
16320
16333
*/
16321
16334
 
16322
16335
void 
16323
 
Index_hint::print(Session *session, String *str)
 
16336
Index_hint::print(THD *thd, String *str)
16324
16337
{
16325
16338
  switch (type)
16326
16339
  {
16331
16344
  str->append (STRING_WITH_LEN(" ("));
16332
16345
  if (key_name.length)
16333
16346
  {
16334
 
    if (session && !my_strnncoll(system_charset_info,
16335
 
                             (const unsigned char *)key_name.str, key_name.length, 
16336
 
                             (const unsigned char *)primary_key_name, 
 
16347
    if (thd && !my_strnncoll(system_charset_info,
 
16348
                             (const uchar *)key_name.str, key_name.length, 
 
16349
                             (const uchar *)primary_key_name, 
16337
16350
                             strlen(primary_key_name)))
16338
16351
      str->append(primary_key_name);
16339
16352
    else
16340
 
      append_identifier(session, str, key_name.str, key_name.length);
 
16353
      append_identifier(thd, str, key_name.str, key_name.length);
16341
16354
  }
16342
16355
  str->append(')');
16343
16356
}
16349
16362
  @param str   string where table should be printed
16350
16363
*/
16351
16364
 
16352
 
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)
16353
16366
{
16354
16367
  if (nested_join)
16355
16368
  {
16356
16369
    str->append('(');
16357
 
    print_join(session, str, &nested_join->join_list, query_type);
 
16370
    print_join(thd, str, &nested_join->join_list, query_type);
16358
16371
    str->append(')');
16359
16372
  }
16360
16373
  else
16372
16385
    {
16373
16386
      // A normal table
16374
16387
      {
16375
 
        append_identifier(session, str, db, db_length);
 
16388
        append_identifier(thd, str, db, db_length);
16376
16389
        str->append('.');
16377
16390
      }
16378
16391
      if (schema_table)
16379
16392
      {
16380
 
        append_identifier(session, str, schema_table_name,
 
16393
        append_identifier(thd, str, schema_table_name,
16381
16394
                          strlen(schema_table_name));
16382
16395
        cmp_name= schema_table_name;
16383
16396
      }
16384
16397
      else
16385
16398
      {
16386
 
        append_identifier(session, str, table_name, table_name_length);
 
16399
        append_identifier(thd, str, table_name, table_name_length);
16387
16400
        cmp_name= table_name;
16388
16401
      }
16389
16402
    }
16397
16410
      {
16398
16411
        if (alias && alias[0])
16399
16412
        {
16400
 
          my_stpcpy(t_alias_buff, alias);
 
16413
          stpcpy(t_alias_buff, alias);
16401
16414
          my_casedn_str(files_charset_info, t_alias_buff);
16402
16415
          t_alias= t_alias_buff;
16403
16416
        }
16404
16417
      }
16405
16418
 
16406
 
      append_identifier(session, str, t_alias, strlen(t_alias));
 
16419
      append_identifier(thd, str, t_alias, strlen(t_alias));
16407
16420
    }
16408
16421
 
16409
16422
    if (index_hints)
16414
16427
      while ((hint= it++))
16415
16428
      {
16416
16429
        str->append (STRING_WITH_LEN(" "));
16417
 
        hint->print (session, str);
 
16430
        hint->print (thd, str);
16418
16431
      }
16419
16432
    }
16420
16433
  }
16421
16434
}
16422
16435
 
16423
16436
 
16424
 
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
 
16437
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
16425
16438
{
16426
 
  /* QQ: session may not be set for sub queries, but this should be fixed */
16427
 
  if (!session)
16428
 
    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;
16429
16442
 
16430
16443
  str->append(STRING_WITH_LEN("select "));
16431
16444
 
16432
16445
  /* First add options */
16433
16446
  if (options & SELECT_STRAIGHT_JOIN)
16434
16447
    str->append(STRING_WITH_LEN("straight_join "));
16435
 
  if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16436
 
      (this == &session->lex->select_lex))
 
16448
  if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
 
16449
      (this == &thd->lex->select_lex))
16437
16450
    str->append(STRING_WITH_LEN("high_priority "));
16438
16451
  if (options & SELECT_DISTINCT)
16439
16452
    str->append(STRING_WITH_LEN("distinct "));
16467
16480
  {
16468
16481
    str->append(STRING_WITH_LEN(" from "));
16469
16482
    /* go through join tree */
16470
 
    print_join(session, str, &top_join_list, query_type);
 
16483
    print_join(thd, str, &top_join_list, query_type);
16471
16484
  }
16472
16485
  else if (where)
16473
16486
  {
16530
16543
  }
16531
16544
 
16532
16545
  // limit
16533
 
  print_limit(session, str, query_type);
 
16546
  print_limit(thd, str, query_type);
16534
16547
 
16535
16548
  // PROCEDURE unsupported here
16536
16549
}