~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2008-10-23 23:53:49 UTC
  • mto: This revision was merged to the branch mainline in revision 557.
  • Revision ID: monty@inaugust.com-20081023235349-317wgwqwgccuacmq
SplitĀ outĀ nested_join.h.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "sj_tmp_table.h"
29
29
 
30
30
#include <mysys/my_bit.h>
31
 
#include <drizzled/drizzled_error_messages.h>
32
 
#include <libdrizzle/gettext.h>
 
31
#include <drizzled/error.h>
 
32
#include <drizzled/gettext.h>
 
33
#include <drizzled/util/test.h>
 
34
#include <drizzled/nested_join.h>
33
35
 
34
36
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
35
37
                              "MAYBE_REF","ALL","range","index",
42
44
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
43
45
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
44
46
                                 DYNAMIC_ARRAY *keyuse);
45
 
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
 
47
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
46
48
                                JOIN_TAB *join_tab,
47
49
                                uint32_t tables, COND *conds,
48
50
                                COND_EQUAL *cond_equal,
54
56
                               table_map used_tables);
55
57
static bool choose_plan(JOIN *join,table_map join_tables);
56
58
 
57
 
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
 
59
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
58
60
                             table_map remaining_tables, uint32_t idx,
59
61
                             double record_count, double read_time);
60
62
static void optimize_straight_join(JOIN *join, table_map join_tables);
77
79
static uint32_t cache_record_length(JOIN *join,uint32_t index);
78
80
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
79
81
static bool get_best_combination(JOIN *join);
80
 
static store_key *get_store_key(THD *thd,
 
82
static store_key *get_store_key(Session *session,
81
83
                                KEYUSE *keyuse, table_map used_tables,
82
84
                                KEY_PART_INFO *key_part, unsigned char *key_buff,
83
85
                                uint32_t maybe_null);
94
96
                            List<Item> &fields, bool send_row,
95
97
                            uint64_t select_options, const char *info,
96
98
                            Item *having);
97
 
static COND *build_equal_items(THD *thd, COND *cond,
 
99
static COND *build_equal_items(Session *session, COND *cond,
98
100
                               COND_EQUAL *inherited,
99
101
                               List<TableList> *join_list,
100
102
                               COND_EQUAL **cond_equal_ref);
167
169
                          bool (*find_func) (Field *, void *), void *data);
168
170
static bool find_field_in_item_list (Field *field, void *data);
169
171
static bool find_field_in_order_list (Field *field, void *data);
170
 
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
 
172
static int create_sort_index(Session *session, JOIN *join, order_st *order,
171
173
                             ha_rows filesort_limit, ha_rows select_limit,
172
174
                             bool is_order_by);
173
175
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
174
176
                             Item *having);
175
 
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
 
177
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
176
178
                                   ulong offset,Item *having);
177
 
static int remove_dup_with_hash_index(THD *thd,Table *table,
 
179
static int remove_dup_with_hash_index(Session *session,Table *table,
178
180
                                      uint32_t field_count, Field **first_field,
179
181
 
180
182
                                      ulong key_length,Item *having);
181
 
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count);
 
183
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
182
184
static ulong used_blob_length(CACHE_FIELD **ptr);
183
185
static bool store_record_in_cache(JOIN_CACHE *cache);
184
186
static void reset_cache_read(JOIN_CACHE *cache);
185
187
static void reset_cache_write(JOIN_CACHE *cache);
186
188
static void read_cached_record(JOIN_TAB *tab);
187
189
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
188
 
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
 
190
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
189
191
                                    order_st *order, List<Item> &fields,
190
192
                                    List<Item> &all_fields,
191
193
                                    bool *all_order_by_fields_used);
195
197
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
196
198
static bool alloc_group_fields(JOIN *join,order_st *group);
197
199
// Create list for using with tempory table
198
 
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
 
200
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
199
201
                                     List<Item> &new_list1,
200
202
                                     List<Item> &new_list2,
201
203
                                     uint32_t elements, List<Item> &items);
202
204
// Create list for using with tempory table
203
 
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
 
205
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
204
206
                                      List<Item> &new_list1,
205
207
                                      List<Item> &new_list2,
206
208
                                      uint32_t elements, List<Item> &items);
207
209
static void init_tmptable_sum_functions(Item_sum **func);
208
210
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
209
211
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
210
 
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
211
 
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
 
212
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
 
213
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
212
214
static bool init_sum_functions(Item_sum **func, Item_sum **end);
213
215
static bool update_sum_func(Item_sum **func);
214
216
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
236
238
  This handles SELECT with and without UNION.
237
239
*/
238
240
 
239
 
bool handle_select(THD *thd, LEX *lex, select_result *result,
 
241
bool handle_select(Session *session, LEX *lex, select_result *result,
240
242
                   ulong setup_tables_done_option)
241
243
{
242
244
  bool res;
245
247
 
246
248
  if (select_lex->master_unit()->is_union() || 
247
249
      select_lex->master_unit()->fake_select_lex)
248
 
    res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
 
250
    res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
249
251
  else
250
252
  {
251
253
    SELECT_LEX_UNIT *unit= &lex->unit;
252
254
    unit->set_limit(unit->global_parameters);
253
 
    thd->thd_marker= 0;
 
255
    session->session_marker= 0;
254
256
    /*
255
257
      'options' of mysql_select will be set in JOIN, as far as JOIN for
256
258
      every PS/SP execution new, we will not need reset this flag if 
257
259
      setup_tables_done_option changed for next rexecution
258
260
    */
259
 
    res= mysql_select(thd, &select_lex->ref_pointer_array,
 
261
    res= mysql_select(session, &select_lex->ref_pointer_array,
260
262
                      (TableList*) select_lex->table_list.first,
261
263
                      select_lex->with_wild, select_lex->item_list,
262
264
                      select_lex->where,
266
268
                      (order_st*) select_lex->group_list.first,
267
269
                      select_lex->having,
268
270
                      (order_st*) lex->proc_list.first,
269
 
                      select_lex->options | thd->options |
 
271
                      select_lex->options | session->options |
270
272
                      setup_tables_done_option,
271
273
                      result, unit, select_lex);
272
274
  }
273
 
  res|= thd->is_error();
 
275
  res|= session->is_error();
274
276
  if (unlikely(res))
275
277
    result->abort();
276
278
 
284
286
 
285
287
  SYNOPSIS
286
288
    fix_inner_refs()
287
 
    thd               Thread handle
 
289
    session               Thread handle
288
290
    all_fields        List of all fields used in select
289
291
    select            Current select
290
292
    ref_pointer_array Array of references to Items used in current select
321
323
*/
322
324
 
323
325
bool
324
 
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
 
326
fix_inner_refs(Session *session, List<Item> &all_fields, SELECT_LEX *select,
325
327
                 Item **ref_pointer_array)
326
328
{
327
329
  Item_outer_ref *ref;
382
384
    ref->outer_ref= new_ref;
383
385
    ref->ref= &ref->outer_ref;
384
386
 
385
 
    if (!ref->fixed && ref->fix_fields(thd, 0))
 
387
    if (!ref->fixed && ref->fix_fields(session, 0))
386
388
      return true;
387
 
    thd->used_tables|= item->used_tables();
 
389
    session->used_tables|= item->used_tables();
388
390
  }
389
391
  return res;
390
392
}
391
393
 
392
 
#define MAGIC_IN_WHERE_TOP_LEVEL 10
393
394
/**
394
395
  Function to setup clauses without sum functions.
395
396
*/
396
 
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
 
397
inline int setup_without_group(Session *session, Item **ref_pointer_array,
397
398
                               TableList *tables,
398
399
                               TableList *leaves,
399
400
                               List<Item> &fields,
403
404
                               order_st *group, bool *hidden_group_fields)
404
405
{
405
406
  int res;
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,
 
407
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
 
408
 
 
409
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
410
  res= setup_conds(session, tables, leaves, conds);
 
411
 
 
412
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
413
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
413
414
                          order);
414
 
  thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
415
 
  res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
 
415
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
416
  res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
416
417
                          group, hidden_group_fields);
417
 
  thd->lex->allow_sum_func= save_allow_sum_func;
 
418
  session->lex->allow_sum_func= save_allow_sum_func;
418
419
  return(res);
419
420
}
420
421
 
459
460
  join_list= &select_lex->top_join_list;
460
461
  union_part= unit_arg->is_union();
461
462
 
462
 
  thd->lex->current_select->is_item_list_lookup= 1;
 
463
  session->lex->current_select->is_item_list_lookup= 1;
463
464
  /*
464
465
    If we have already executed SELECT, then it have not sense to prevent
465
466
    its table from update (see unique_table())
466
467
  */
467
 
  if (thd->derived_tables_processing)
 
468
  if (session->derived_tables_processing)
468
469
    select_lex->exclude_from_table_unique_test= true;
469
470
 
470
471
  /* Check that all tables, fields, conds and order are ok */
471
472
 
472
473
  if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
473
 
      setup_tables_and_check_access(thd, &select_lex->context, join_list,
 
474
      setup_tables_and_check_access(session, &select_lex->context, join_list,
474
475
                                    tables_list, &select_lex->leaf_tables,
475
476
                                    false))
476
477
      return(-1);
481
482
       table_ptr= table_ptr->next_leaf)
482
483
    tables++;
483
484
 
484
 
  if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
485
 
      select_lex->setup_ref_array(thd, og_num) ||
486
 
      setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
 
485
  if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
 
486
      select_lex->setup_ref_array(session, og_num) ||
 
487
      setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
487
488
                   &all_fields, 1) ||
488
 
      setup_without_group(thd, (*rref_pointer_array), tables_list,
 
489
      setup_without_group(session, (*rref_pointer_array), tables_list,
489
490
                          select_lex->leaf_tables, fields_list,
490
491
                          all_fields, &conds, order, group_list,
491
492
                          &hidden_group_fields))
495
496
  
496
497
  if (having)
497
498
  {
498
 
    nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
499
 
    thd->where="having clause";
500
 
    thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
 
499
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
500
    session->where="having clause";
 
501
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
501
502
    select_lex->having_fix_field= 1;
502
503
    bool having_fix_rc= (!having->fixed &&
503
 
                         (having->fix_fields(thd, &having) ||
 
504
                         (having->fix_fields(session, &having) ||
504
505
                          having->check_cols(1)));
505
506
    select_lex->having_fix_field= 0;
506
 
    if (having_fix_rc || thd->is_error())
 
507
    if (having_fix_rc || session->is_error())
507
508
      return(-1);                               /* purecov: inspected */
508
 
    thd->lex->allow_sum_func= save_allow_sum_func;
 
509
    session->lex->allow_sum_func= save_allow_sum_func;
509
510
  }
510
511
 
511
512
  {
517
518
    */
518
519
    if ((subselect= select_lex->master_unit()->item))
519
520
    {
520
 
      bool do_semijoin= !test(thd->variables.optimizer_switch &
 
521
      bool do_semijoin= !test(session->variables.optimizer_switch &
521
522
                              OPTIMIZER_SWITCH_NO_SEMIJOIN);
522
523
      if (subselect->substype() == Item_subselect::IN_SUBS)
523
524
        in_subs= (Item_in_subselect*)subselect;
544
545
          !select_lex->master_unit()->first_select()->next_select() &&  // 2
545
546
          !select_lex->group_list.elements && !order &&                 // 3
546
547
          !having && !select_lex->with_sum_func &&                      // 4
547
 
          thd->thd_marker &&                                            // 5
 
548
          session->session_marker &&                                            // 5
548
549
          select_lex->outer_select()->join &&                           // (*)
549
550
          select_lex->master_unit()->first_select()->leaf_tables &&     // (**) 
550
551
          do_semijoin &&
552
553
      {
553
554
        {
554
555
          if (!in_subs->left_expr->fixed &&
555
 
               in_subs->left_expr->fix_fields(thd, &in_subs->left_expr))
 
556
               in_subs->left_expr->fix_fields(session, &in_subs->left_expr))
556
557
          {
557
558
            return(-1);
558
559
          }
570
571
        }
571
572
 
572
573
        /* Register the subquery for further processing */
573
 
        select_lex->outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
574
 
        in_subs->expr_join_nest= (TableList*)thd->thd_marker;
 
574
        select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
 
575
        in_subs->expr_join_nest= (TableList*)session->session_marker;
575
576
      }
576
577
      else
577
578
      {
578
 
        bool do_materialize= !test(thd->variables.optimizer_switch &
 
579
        bool do_materialize= !test(session->variables.optimizer_switch &
579
580
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
580
581
        /*
581
582
          Check if the subquery predicate can be executed via materialization.
610
611
            in_subs  &&                                                   // 1
611
612
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
612
613
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
613
 
            thd->lex->sql_command == SQLCOM_SELECT)                       // *
 
614
            session->lex->sql_command == SQLCOM_SELECT)                       // *
614
615
        {
615
616
          if (in_subs->is_top_level_item() &&                             // 4
616
617
              !in_subs->is_correlated &&                                  // 5
635
636
    {
636
637
      Item *item= *ord->item;
637
638
      if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
638
 
        item->split_sum_func(thd, ref_pointer_array, all_fields);
 
639
        item->split_sum_func(session, ref_pointer_array, all_fields);
639
640
    }
640
641
  }
641
642
 
642
643
  if (having && having->with_sum_func)
643
 
    having->split_sum_func2(thd, ref_pointer_array, all_fields,
 
644
    having->split_sum_func2(session, ref_pointer_array, all_fields,
644
645
                            &having, true);
645
646
  if (select_lex->inner_sum_func_list)
646
647
  {
649
650
    do
650
651
    { 
651
652
      item_sum= item_sum->next;
652
 
      item_sum->split_sum_func2(thd, ref_pointer_array,
 
653
      item_sum->split_sum_func2(session, ref_pointer_array,
653
654
                                all_fields, item_sum->ref_by, false);
654
655
    } while (item_sum != end);
655
656
  }
656
657
 
657
658
  if (select_lex->inner_refs_list.elements &&
658
 
      fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
 
659
      fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
659
660
    return(-1);
660
661
 
661
662
  /*
1091
1092
    }
1092
1093
  }
1093
1094
 
1094
 
  THD *thd= join->thd;
 
1095
  Session *session= join->session;
1095
1096
  SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
1096
1097
  /*
1097
1098
    Second pass: setup the chosen strategies    
1145
1146
      {
1146
1147
        SJ_TMP_TABLE *sjtbl;
1147
1148
        uint32_t tabs_size= (last_tab - sjtabs) * sizeof(SJ_TMP_TABLE::TAB);
1148
 
        if (!(sjtbl= (SJ_TMP_TABLE*)thd->alloc(sizeof(SJ_TMP_TABLE))) ||
1149
 
            !(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) thd->alloc(tabs_size)))
 
1149
        if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
 
1150
            !(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
1150
1151
          return(true);
1151
1152
        memcpy(sjtbl->tabs, sjtabs, tabs_size);
1152
1153
        sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1159
1160
        sjtbl->next= NULL;
1160
1161
 
1161
1162
        sjtbl->tmp_table= 
1162
 
          create_duplicate_weedout_tmp_table(thd, 
 
1163
          create_duplicate_weedout_tmp_table(session, 
1163
1164
                                             sjtbl->rowid_len + 
1164
1165
                                             sjtbl->null_bytes,
1165
1166
                                             sjtbl);
1191
1192
  {
1192
1193
    if (sj_tbl->tmp_table)
1193
1194
    {
1194
 
      sj_tbl->tmp_table->free_tmp_table(join->thd);
 
1195
      sj_tbl->tmp_table->free_tmp_table(join->session);
1195
1196
    }
1196
1197
  }
1197
1198
  join->sj_tmp_tables= NULL;
1219
1220
    return(0);
1220
1221
  optimized= 1;
1221
1222
 
1222
 
  thd_proc_info(thd, "optimizing");
 
1223
  session->set_proc_info("optimizing");
1223
1224
  row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
1224
1225
              unit->select_limit_cnt);
1225
1226
  /* select_limit is used to decide if we are likely to scan the whole table */
1228
1229
    select_limit= HA_POS_ERROR;
1229
1230
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1230
1231
  // Ignore errors of execution if option IGNORE present
1231
 
  if (thd->lex->ignore)
1232
 
    thd->lex->current_select->no_error= 1;
 
1232
  if (session->lex->ignore)
 
1233
    session->lex->current_select->no_error= 1;
1233
1234
 
1234
1235
#ifdef HAVE_REF_TO_FIELDS                       // Not done yet
1235
1236
  /* Add HAVING to WHERE if possible */
1246
1247
        Item_cond_and can't be fixed after creation, so we do not check
1247
1248
        conds->fixed
1248
1249
      */
1249
 
      conds->fix_fields(thd, &conds);
1250
 
      conds->change_ref_to_fields(thd, tables_list);
 
1250
      conds->fix_fields(session, &conds);
 
1251
      conds->change_ref_to_fields(session, tables_list);
1251
1252
      conds->top_level_item();
1252
1253
      having= 0;
1253
1254
    }
1259
1260
  build_bitmap_for_nested_joins(join_list, 0);
1260
1261
 
1261
1262
  conds= optimize_cond(this, conds, join_list, &cond_value);   
1262
 
  if (thd->is_error())
 
1263
  if (session->is_error())
1263
1264
  {
1264
1265
    error= 1;
1265
1266
    return(1);
1267
1268
 
1268
1269
  {
1269
1270
    having= optimize_cond(this, having, join_list, &having_value);
1270
 
    if (thd->is_error())
 
1271
    if (session->is_error())
1271
1272
    {
1272
1273
      error= 1;
1273
1274
      return(1);
1328
1329
        conjunctions.
1329
1330
        Preserve conditions for EXPLAIN.
1330
1331
      */
1331
 
      if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
 
1332
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
1332
1333
      {
1333
1334
        COND *table_independent_conds=
1334
1335
          make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1345
1346
  sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1346
1347
 
1347
1348
  /* Calculate how to do the join */
1348
 
  thd_proc_info(thd, "statistics");
 
1349
  session->set_proc_info("statistics");
1349
1350
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1350
 
      thd->is_fatal_error)
 
1351
      session->is_fatal_error)
1351
1352
  {
1352
1353
    return(1);
1353
1354
  }
1354
1355
 
1355
1356
  /* Remove distinct if only const tables */
1356
1357
  select_distinct= select_distinct && (const_tables != tables);
1357
 
  thd_proc_info(thd, "preparing");
 
1358
  session->set_proc_info("preparing");
1358
1359
  if (result->initialize_tables(this))
1359
1360
  {
1360
1361
    return(1);                          // error == -1
1363
1364
      !(select_options & SELECT_DESCRIBE) &&
1364
1365
      (!conds ||
1365
1366
       !(conds->used_tables() & RAND_TABLE_BIT) ||
1366
 
       select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
 
1367
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1367
1368
  {
1368
1369
    zero_result_cause= "no matching row in const table";
1369
1370
    error= 0;
1370
1371
    return(0);
1371
1372
  }
1372
 
  if (!(thd->options & OPTION_BIG_SELECTS) &&
1373
 
      best_read > (double) thd->variables.max_join_size &&
 
1373
  if (!(session->options & OPTION_BIG_SELECTS) &&
 
1374
      best_read > (double) session->variables.max_join_size &&
1374
1375
      !(select_options & SELECT_DESCRIBE))
1375
1376
  {                                             /* purecov: inspected */
1376
1377
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1377
1378
    error= -1;
1378
1379
    return(1);
1379
1380
  }
1380
 
  if (const_tables && !thd->locked_tables &&
 
1381
  if (const_tables && !session->locked_tables &&
1381
1382
      !(select_options & SELECT_NO_UNLOCK))
1382
 
    mysql_unlock_some_tables(thd, table, const_tables);
 
1383
    mysql_unlock_some_tables(session, table, const_tables);
1383
1384
  if (!conds && outer_join)
1384
1385
  {
1385
1386
    /* Handle the case where we have an OUTER JOIN without a WHERE */
1425
1426
 
1426
1427
  if (conds &&!outer_join && const_table_map != found_const_table_map && 
1427
1428
      (select_options & SELECT_DESCRIBE) &&
1428
 
      select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
 
1429
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
1429
1430
  {
1430
1431
    conds=new Item_int((int64_t) 0,1);  // Always false
1431
1432
  }
1442
1443
  {
1443
1444
    order_st *org_order= order;
1444
1445
    order=remove_const(this, order,conds,1, &simple_order);
1445
 
    if (thd->is_error())
 
1446
    if (session->is_error())
1446
1447
    {
1447
1448
      error= 1;
1448
1449
      return(1);
1540
1541
    if (order)
1541
1542
      skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1, 
1542
1543
        &tab->table->keys_in_use_for_order_by);
1543
 
    if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
 
1544
    if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
1544
1545
                                          order, fields_list, all_fields,
1545
1546
                                          &all_order_fields_used)))
1546
1547
    {
1572
1573
      else
1573
1574
        group_list= 0;
1574
1575
    }
1575
 
    else if (thd->is_fatal_error)                       // End of memory
 
1576
    else if (session->is_fatal_error)                   // End of memory
1576
1577
      return(1);
1577
1578
  }
1578
1579
  simple_group= 0;
1581
1582
    group_list= remove_const(this, (old_group_list= group_list), conds,
1582
1583
                             rollup.state == ROLLUP::STATE_NONE,
1583
1584
                             &simple_group);
1584
 
    if (thd->is_error())
 
1585
    if (session->is_error())
1585
1586
    {
1586
1587
      error= 1;
1587
1588
      return(1);
1664
1665
        error= 0;
1665
1666
        return(unit->item->
1666
1667
                    change_engine(new
1667
 
                                  subselect_uniquesubquery_engine(thd,
 
1668
                                  subselect_uniquesubquery_engine(session,
1668
1669
                                                                  join_tab,
1669
1670
                                                                  unit->item,
1670
1671
                                                                  where)));
1678
1679
        error= 0;
1679
1680
        return(unit->item->
1680
1681
                    change_engine(new
1681
 
                                  subselect_indexsubquery_engine(thd,
 
1682
                                  subselect_indexsubquery_engine(session,
1682
1683
                                                                 join_tab,
1683
1684
                                                                 unit->item,
1684
1685
                                                                 where,
1694
1695
      conds= remove_additional_cond(conds);
1695
1696
      save_index_subquery_explain_info(join_tab, conds);
1696
1697
      return(unit->item->
1697
 
                  change_engine(new subselect_indexsubquery_engine(thd,
 
1698
                  change_engine(new subselect_indexsubquery_engine(session,
1698
1699
                                                                   join_tab,
1699
1700
                                                                   unit->item,
1700
1701
                                                                   conds,
1728
1729
        (join_tab[const_tables].type != JT_REF_OR_NULL) &&
1729
1730
        ((order && simple_order) || (group_list && simple_group)))
1730
1731
    {
1731
 
      if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
 
1732
      if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
1732
1733
        return(1);
1733
1734
      }
1734
1735
    }
1789
1790
  /* Create a tmp table if distinct or if the sort is too complicated */
1790
1791
  if (need_tmp)
1791
1792
  {
1792
 
    thd_proc_info(thd, "Creating tmp table");
 
1793
    session->set_proc_info("Creating tmp table");
1793
1794
 
1794
1795
    init_items_ref_array();
1795
1796
 
1805
1806
    */
1806
1807
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1807
1808
                             !tmp_group &&
1808
 
                             !thd->lex->current_select->with_sum_func) ?
 
1809
                             !session->lex->current_select->with_sum_func) ?
1809
1810
                            select_limit : HA_POS_ERROR;
1810
1811
 
1811
1812
    if (!(exec_tmp_table1=
1812
 
          create_tmp_table(thd, &tmp_table_param, all_fields,
 
1813
          create_tmp_table(session, &tmp_table_param, all_fields,
1813
1814
                           tmp_group,
1814
1815
                           group_list ? 0 : select_distinct,
1815
1816
                           group_list && simple_group,
1837
1838
    /* if group or order on first table, sort first */
1838
1839
    if (group_list && simple_group)
1839
1840
    {
1840
 
      thd_proc_info(thd, "Sorting for group");
1841
 
      if (create_sort_index(thd, this, group_list,
 
1841
      session->set_proc_info("Sorting for group");
 
1842
      if (create_sort_index(session, this, group_list,
1842
1843
                            HA_POS_ERROR, HA_POS_ERROR, false) ||
1843
1844
          alloc_group_fields(this, group_list) ||
1844
1845
          make_sum_func_list(all_fields, fields_list, 1) ||
1845
 
          setup_sum_funcs(thd, sum_funcs))
 
1846
          setup_sum_funcs(session, sum_funcs))
1846
1847
      {
1847
1848
        return(1);
1848
1849
      }
1851
1852
    else
1852
1853
    {
1853
1854
      if (make_sum_func_list(all_fields, fields_list, 0) ||
1854
 
          setup_sum_funcs(thd, sum_funcs))
 
1855
          setup_sum_funcs(session, sum_funcs))
1855
1856
      {
1856
1857
        return(1);
1857
1858
      }
1858
1859
 
1859
1860
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1860
1861
      {
1861
 
        thd_proc_info(thd, "Sorting for order");
1862
 
        if (create_sort_index(thd, this, order,
 
1862
        session->set_proc_info("Sorting for order");
 
1863
        if (create_sort_index(session, this, order,
1863
1864
                              HA_POS_ERROR, HA_POS_ERROR, true))
1864
1865
        {
1865
1866
          return(1);
1876
1877
 
1877
1878
    if (exec_tmp_table1->distinct)
1878
1879
    {
1879
 
      table_map used_tables= thd->used_tables;
 
1880
      table_map used_tables= session->used_tables;
1880
1881
      JOIN_TAB *last_join_tab= join_tab+tables-1;
1881
1882
      do
1882
1883
      {
1976
1977
bool
1977
1978
JOIN::init_save_join_tab()
1978
1979
{
1979
 
  if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
 
1980
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1980
1981
    return 1;                                  /* purecov: inspected */
1981
1982
  error= 0;                                    // Ensure that tmp_join.error= 0
1982
1983
  restore_tmp();
1989
1990
{
1990
1991
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1991
1992
  {
1992
 
    if (!(join_tab_save= (JOIN_TAB*)thd->memdup((unsigned char*) join_tab,
 
1993
    if (!(join_tab_save= (JOIN_TAB*)session->memdup((unsigned char*) join_tab,
1993
1994
                                                sizeof(JOIN_TAB) * tables)))
1994
1995
      return 1;
1995
1996
  }
2006
2007
    the query.  It's never shown in EXPLAIN!
2007
2008
 
2008
2009
  @todo
2009
 
    When can we have here thd->net.report_error not zero?
 
2010
    When can we have here session->net.report_error not zero?
2010
2011
*/
2011
2012
void
2012
2013
JOIN::exec()
2014
2015
  List<Item> *columns_list= &fields_list;
2015
2016
  int      tmp_error;
2016
2017
 
2017
 
  thd_proc_info(thd, "executing");
 
2018
  session->set_proc_info("executing");
2018
2019
  error= 0;
2019
2020
  (void) result->prepare2(); // Currently, this cannot fail.
2020
2021
 
2042
2043
        {
2043
2044
          error= (int) result->send_eof();
2044
2045
          send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
2045
 
                         thd->sent_row_count);
 
2046
                         session->sent_row_count);
2046
2047
        }
2047
2048
      }
2048
2049
      else
2052
2053
      }
2053
2054
    }
2054
2055
    /* Single select (without union) always returns 0 or 1 row */
2055
 
    thd->limit_found_rows= send_records;
2056
 
    thd->examined_row_count= 0;
 
2056
    session->limit_found_rows= send_records;
 
2057
    session->examined_row_count= 0;
2057
2058
    return;
2058
2059
  }
2059
2060
  /*
2062
2063
    It must be accumulated from all join iterations of all join parts.
2063
2064
  */
2064
2065
  if (tables)
2065
 
    thd->limit_found_rows= 0;
 
2066
    session->limit_found_rows= 0;
2066
2067
 
2067
2068
  if (zero_result_cause)
2068
2069
  {
2140
2141
    curr_tmp_table= exec_tmp_table1;
2141
2142
 
2142
2143
    /* Copy data to the temporary table */
2143
 
    thd_proc_info(thd, "Copying to tmp table");
 
2144
    session->set_proc_info("Copying to tmp table");
2144
2145
    if (!curr_join->sort_and_group &&
2145
2146
        curr_join->const_tables != curr_join->tables)
2146
2147
      curr_join->join_tab[curr_join->const_tables].sorted= 0;
2161
2162
      items1= items0 + all_fields.elements;
2162
2163
      if (sort_and_group || curr_tmp_table->group)
2163
2164
      {
2164
 
        if (change_to_use_tmp_fields(thd, items1,
 
2165
        if (change_to_use_tmp_fields(session, items1,
2165
2166
                                     tmp_fields_list1, tmp_all_fields1,
2166
2167
                                     fields_list.elements, all_fields))
2167
2168
          return;
2168
2169
      }
2169
2170
      else
2170
2171
      {
2171
 
        if (change_refs_to_tmp_fields(thd, items1,
 
2172
        if (change_refs_to_tmp_fields(session, items1,
2172
2173
                                      tmp_fields_list1, tmp_all_fields1,
2173
2174
                                      fields_list.elements, all_fields))
2174
2175
          return;
2241
2242
          curr_join->tmp_table_param.precomputed_group_by= true;
2242
2243
 
2243
2244
        if (!(curr_tmp_table=
2244
 
              exec_tmp_table2= create_tmp_table(thd,
 
2245
              exec_tmp_table2= create_tmp_table(session,
2245
2246
                                                &curr_join->tmp_table_param,
2246
2247
                                                *curr_all_fields,
2247
2248
                                                (order_st*) 0,
2255
2256
      }
2256
2257
      if (curr_join->group_list)
2257
2258
      {
2258
 
        thd_proc_info(thd, "Creating sort index");
 
2259
        session->set_proc_info("Creating sort index");
2259
2260
        if (curr_join->join_tab == join_tab && save_join_tab())
2260
2261
        {
2261
2262
          return;
2262
2263
        }
2263
 
        if (create_sort_index(thd, curr_join, curr_join->group_list,
 
2264
        if (create_sort_index(session, curr_join, curr_join->group_list,
2264
2265
                              HA_POS_ERROR, HA_POS_ERROR, false) ||
2265
2266
            make_group_fields(this, curr_join))
2266
2267
        {
2269
2270
        sortorder= curr_join->sortorder;
2270
2271
      }
2271
2272
      
2272
 
      thd_proc_info(thd, "Copying to group table");
 
2273
      session->set_proc_info("Copying to group table");
2273
2274
      tmp_error= -1;
2274
2275
      if (curr_join != this)
2275
2276
      {
2292
2293
      if (!curr_join->sort_and_group &&
2293
2294
          curr_join->const_tables != curr_join->tables)
2294
2295
        curr_join->join_tab[curr_join->const_tables].sorted= 0;
2295
 
      if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
 
2296
      if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2296
2297
          (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2297
2298
      {
2298
2299
        error= tmp_error;
2306
2307
      if (!items2)
2307
2308
      {
2308
2309
        items2= items1 + all_fields.elements;
2309
 
        if (change_to_use_tmp_fields(thd, items2,
 
2310
        if (change_to_use_tmp_fields(session, items2,
2310
2311
                                     tmp_fields_list2, tmp_all_fields2, 
2311
2312
                                     fields_list.elements, tmp_all_fields1))
2312
2313
          return;
2326
2327
    curr_join->join_free();                     /* Free quick selects */
2327
2328
    if (curr_join->select_distinct && ! curr_join->group_list)
2328
2329
    {
2329
 
      thd_proc_info(thd, "Removing duplicates");
 
2330
      session->set_proc_info("Removing duplicates");
2330
2331
      if (curr_join->tmp_having)
2331
2332
        curr_join->tmp_having->update_used_tables();
2332
2333
      if (remove_duplicates(curr_join, curr_tmp_table,
2355
2356
      if (!items0)
2356
2357
        init_items_ref_array();
2357
2358
      items3= ref_pointer_array + (all_fields.elements*4);
2358
 
      setup_copy_fields(thd, &curr_join->tmp_table_param,
 
2359
      setup_copy_fields(session, &curr_join->tmp_table_param,
2359
2360
                        items3, tmp_fields_list3, tmp_all_fields3,
2360
2361
                        curr_fields_list->elements, *curr_all_fields);
2361
2362
      tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2378
2379
 
2379
2380
    if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
2380
2381
                                      1, true) || 
2381
 
        setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2382
 
        thd->is_fatal_error)
 
2382
        setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
 
2383
        session->is_fatal_error)
2383
2384
      return;
2384
2385
  }
2385
2386
  if (curr_join->group_list || curr_join->order)
2386
2387
  {
2387
 
    thd_proc_info(thd, "Sorting result");
 
2388
    session->set_proc_info("Sorting result");
2388
2389
    /* If we have already done the group, add HAVING to sorted table */
2389
2390
    if (curr_join->tmp_having && ! curr_join->group_list && 
2390
2391
        ! curr_join->sort_and_group)
2430
2431
      else
2431
2432
      {
2432
2433
        /*
2433
 
          We can abort sorting after thd->select_limit rows if we there is no
 
2434
          We can abort sorting after session->select_limit rows if we there is no
2434
2435
          WHERE clause for any tables after the sorted one.
2435
2436
        */
2436
2437
        JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
2463
2464
        the query. XXX: it's never shown in EXPLAIN!
2464
2465
        OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2465
2466
      */
2466
 
      if (create_sort_index(thd, curr_join,
 
2467
      if (create_sort_index(session, curr_join,
2467
2468
                            curr_join->group_list ? 
2468
2469
                            curr_join->group_list : curr_join->order,
2469
2470
                            curr_join->select_limit,
2484
2485
      }
2485
2486
    }
2486
2487
  }
2487
 
  /* XXX: When can we have here thd->is_error() not zero? */
2488
 
  if (thd->is_error())
 
2488
  /* XXX: When can we have here session->is_error() not zero? */
 
2489
  if (session->is_error())
2489
2490
  {
2490
 
    error= thd->is_error();
 
2491
    error= session->is_error();
2491
2492
    return;
2492
2493
  }
2493
2494
  curr_join->having= curr_join->tmp_having;
2494
2495
  curr_join->fields= curr_fields_list;
2495
2496
 
2496
2497
  {
2497
 
    thd_proc_info(thd, "Sending data");
 
2498
    session->set_proc_info("Sending data");
2498
2499
    result->send_fields(*curr_fields_list,
2499
2500
                        Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2500
2501
    error= do_select(curr_join, curr_fields_list, NULL);
2501
 
    thd->limit_found_rows= curr_join->send_records;
 
2502
    session->limit_found_rows= curr_join->send_records;
2502
2503
  }
2503
2504
 
2504
2505
  /* Accumulate the counts from all join iterations of all join parts. */
2505
 
  thd->examined_row_count+= curr_join->examined_rows;
 
2506
  session->examined_row_count+= curr_join->examined_rows;
2506
2507
 
2507
2508
  /* 
2508
2509
    With EXPLAIN EXTENDED we have to restore original ref_array
2510
2511
    Otherwise we would not be able to print the query  correctly.
2511
2512
  */ 
2512
2513
  if (items0 &&
2513
 
      (thd->lex->describe & DESCRIBE_EXTENDED) &&
 
2514
      (session->lex->describe & DESCRIBE_EXTENDED) &&
2514
2515
      select_lex->linkage == DERIVED_TABLE_TYPE)      
2515
2516
    set_items_ref_array(items0);
2516
2517
 
2546
2547
 
2547
2548
  cleanup(1);
2548
2549
  if (exec_tmp_table1)
2549
 
    exec_tmp_table1->free_tmp_table(thd);
 
2550
    exec_tmp_table1->free_tmp_table(session);
2550
2551
  if (exec_tmp_table2)
2551
 
    exec_tmp_table2->free_tmp_table(thd);
 
2552
    exec_tmp_table2->free_tmp_table(session);
2552
2553
  delete select;
2553
2554
  delete_dynamic(&keyuse);
2554
2555
  return(error);
2559
2560
/**
2560
2561
  An entry point to single-unit select (a select without UNION).
2561
2562
 
2562
 
  @param thd                  thread handler
 
2563
  @param session                  thread handler
2563
2564
  @param rref_pointer_array   a reference to ref_pointer_array of
2564
2565
                              the top-level select_lex for this query
2565
2566
  @param tables               list of all tables used in this query.
2601
2602
*/
2602
2603
 
2603
2604
bool
2604
 
mysql_select(THD *thd, Item ***rref_pointer_array,
 
2605
mysql_select(Session *session, Item ***rref_pointer_array,
2605
2606
             TableList *tables, uint32_t wild_num, List<Item> &fields,
2606
2607
             COND *conds, uint32_t og_num,  order_st *order, order_st *group,
2607
2608
             Item *having, order_st *proc_param, uint64_t select_options,
2646
2647
  }
2647
2648
  else
2648
2649
  {
2649
 
    if (!(join= new JOIN(thd, fields, select_options, result)))
 
2650
    if (!(join= new JOIN(session, fields, select_options, result)))
2650
2651
        return(true);
2651
 
    thd_proc_info(thd, "init");
2652
 
    thd->used_tables=0;                         // Updated by setup_fields
 
2652
    session->set_proc_info("init");
 
2653
    session->used_tables=0;                         // Updated by setup_fields
2653
2654
    if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2654
2655
                           conds, og_num, order, group, having, proc_param,
2655
2656
                           select_lex, unit)) == true)
2671
2672
    goto err;                                   // 1
2672
2673
  }
2673
2674
 
2674
 
  if (thd->lex->describe & DESCRIBE_EXTENDED)
 
2675
  if (session->lex->describe & DESCRIBE_EXTENDED)
2675
2676
  {
2676
2677
    join->conds_history= join->conds;
2677
2678
    join->having_history= (join->having?join->having:join->tmp_having);
2678
2679
  }
2679
2680
 
2680
 
  if (thd->is_error())
 
2681
  if (session->is_error())
2681
2682
    goto err;
2682
2683
 
2683
2684
  join->exec();
2684
2685
 
2685
 
  if (thd->lex->describe & DESCRIBE_EXTENDED)
 
2686
  if (session->lex->describe & DESCRIBE_EXTENDED)
2686
2687
  {
2687
2688
    select_lex->where= join->conds_history;
2688
2689
    select_lex->having= join->having_history;
2691
2692
err:
2692
2693
  if (free_join)
2693
2694
  {
2694
 
    thd_proc_info(thd, "end");
 
2695
    session->set_proc_info("end");
2695
2696
    err|= select_lex->cleanup();
2696
 
    return(err || thd->is_error());
 
2697
    return(err || session->is_error());
2697
2698
  }
2698
2699
  return(join->error);
2699
2700
}
2713
2714
}
2714
2715
 
2715
2716
 
2716
 
static TableList *alloc_join_nest(THD *thd)
 
2717
static TableList *alloc_join_nest(Session *session)
2717
2718
{
2718
2719
  TableList *tbl;
2719
 
  if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
 
2720
  if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
2720
2721
                                       sizeof(nested_join_st))))
2721
2722
    return NULL;
2722
2723
  tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl + 
2772
2773
  SELECT_LEX *parent_lex= parent_join->select_lex;
2773
2774
  TableList *emb_tbl_nest= NULL;
2774
2775
  List<TableList> *emb_join_list= &parent_lex->top_join_list;
2775
 
  THD *thd= parent_join->thd;
 
2776
  Session *session= parent_join->session;
2776
2777
 
2777
2778
  /*
2778
2779
    1. Find out where to put the predicate into.
2829
2830
        A3: changes in the TableList::outer_join will make everything work
2830
2831
            automatically.
2831
2832
      */
2832
 
      if (!(wrap_nest= alloc_join_nest(parent_join->thd)))
 
2833
      if (!(wrap_nest= alloc_join_nest(parent_join->session)))
2833
2834
      {
2834
2835
        return(true);
2835
2836
      }
2874
2875
 
2875
2876
  TableList *sj_nest;
2876
2877
  nested_join_st *nested_join;
2877
 
  if (!(sj_nest= alloc_join_nest(parent_join->thd)))
 
2878
  if (!(sj_nest= alloc_join_nest(parent_join->session)))
2878
2879
  {
2879
2880
    return(true);
2880
2881
  }
2952
2953
    Put the subquery's WHERE into semi-join's sj_on_expr
2953
2954
    Add the subquery-induced equalities too.
2954
2955
  */
2955
 
  SELECT_LEX *save_lex= thd->lex->current_select;
2956
 
  thd->lex->current_select=subq_lex;
 
2956
  SELECT_LEX *save_lex= session->lex->current_select;
 
2957
  session->lex->current_select=subq_lex;
2957
2958
  if (!subq_pred->left_expr->fixed &&
2958
 
       subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
 
2959
       subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
2959
2960
    return(true);
2960
 
  thd->lex->current_select=save_lex;
 
2961
  session->lex->current_select=save_lex;
2961
2962
 
2962
2963
  sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2963
2964
  sj_nest->nested_join->sj_depends_on=  subq_pred->used_tables() |
3005
3006
    }
3006
3007
  }
3007
3008
  /* Fix the created equality and AND */
3008
 
  sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
 
3009
  sj_nest->sj_on_expr->fix_fields(parent_join->session, &sj_nest->sj_on_expr);
3009
3010
 
3010
3011
  /*
3011
3012
    Walk through sj nest's WHERE and ON expressions and call
3023
3024
  {
3024
3025
    emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr, 
3025
3026
                                     sj_nest->sj_on_expr);
3026
 
    emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
 
3027
    emb_tbl_nest->on_expr->fix_fields(parent_join->session, &emb_tbl_nest->on_expr);
3027
3028
  }
3028
3029
  else
3029
3030
  {
3030
3031
    /* Inject into the WHERE */
3031
3032
    parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
3032
 
    parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
 
3033
    parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
3033
3034
    parent_join->select_lex->where= parent_join->conds;
3034
3035
  }
3035
3036
 
3118
3119
    if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
3119
3120
      return(true);
3120
3121
 
3121
 
    //if ((*in_subq)->fix_fields(thd, (*in_subq)->ref_ptr))
 
3122
    //if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
3122
3123
    //  return(true);
3123
3124
  }
3124
3125
  sj_subselects.clear();
3359
3360
*****************************************************************************/
3360
3361
 
3361
3362
 
3362
 
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
 
3363
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
3363
3364
                                      Table *table,
3364
3365
                                      const key_map *keys,ha_rows limit)
3365
3366
{
3366
3367
  int error;
3367
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
 
3368
  if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3368
3369
    return(0);                           // Fatal error flag is set
3369
3370
  if (select)
3370
3371
  {
3371
3372
    select->head=table;
3372
3373
    table->reginfo.impossible_range=0;
3373
 
    if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
 
3374
    if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
3374
3375
                                          limit, 0, false)) == 1)
3375
3376
      return(select->quick->records);
3376
3377
    if (error == -1)
3422
3423
  JOIN_TAB *stat_vector[MAX_TABLES+1];
3423
3424
 
3424
3425
  table_count=join->tables;
3425
 
  stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
3426
 
  stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
3427
 
  table_vector=(Table**) join->thd->alloc(sizeof(Table*)*(table_count*2));
 
3426
  stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
 
3427
  stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
 
3428
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
3428
3429
  if (!stat || !stat_ref || !table_vector)
3429
3430
    return(1);                          // Eom /* purecov: inspected */
3430
3431
 
3543
3544
  }
3544
3545
 
3545
3546
  if (conds || outer_join)
3546
 
    if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
 
3547
    if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
3547
3548
                            conds, join->cond_equal,
3548
3549
                            ~outer_join, join->select_lex, &sargables))
3549
3550
      return(1);
3768
3769
                          1, &error);
3769
3770
      if (!select)
3770
3771
        return(1);
3771
 
      records= get_quick_record_count(join->thd, select, s->table,
 
3772
      records= get_quick_record_count(join->session, select, s->table,
3772
3773
                                      &s->const_keys, join->row_limit);
3773
3774
      s->quick=select->quick;
3774
3775
      s->needed_reg=select->needed_reg;
3822
3823
    join->best_read=1.0;
3823
3824
  }
3824
3825
  /* Generate an execution plan from the found optimal join order. */
3825
 
  return(join->thd->killed || get_best_combination(join));
 
3826
  return(join->session->killed || get_best_combination(join));
3826
3827
}
3827
3828
 
3828
3829
 
4545
4546
/**
4546
4547
  Update keyuse array with all possible keys we can use to fetch rows.
4547
4548
  
4548
 
  @param       thd 
 
4549
  @param       session 
4549
4550
  @param[out]  keyuse         Put here ordered array of KEYUSE structures
4550
4551
  @param       join_tab       Array in tablenr_order
4551
4552
  @param       tables         Number of tables in join
4564
4565
*/
4565
4566
 
4566
4567
static bool
4567
 
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
 
4568
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4568
4569
                    uint32_t tables, COND *cond,
4569
4570
                    COND_EQUAL *cond_equal __attribute__((unused)),
4570
4571
                    table_map normal_tables, SELECT_LEX *select_lex,
4597
4598
    substitutions.
4598
4599
  */ 
4599
4600
  sz= cmax(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
4600
 
      (((thd->lex->current_select->cond_count+1)*2 +
4601
 
        thd->lex->current_select->between_count)*m+1);
4602
 
  if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
 
4601
      (((session->lex->current_select->cond_count+1)*2 +
 
4602
        session->lex->current_select->between_count)*m+1);
 
4603
  if (!(key_fields=(KEY_FIELD*) session->alloc(sz)))
4603
4604
    return true; /* purecov: inspected */
4604
4605
  and_level= 0;
4605
4606
  field= end= key_fields;
4898
4899
  @param join             pointer to the structure providing all context info
4899
4900
                          for the query
4900
4901
  @param s                the table to be joined by the function
4901
 
  @param thd              thread for the connection that submitted the query
 
4902
  @param session              thread for the connection that submitted the query
4902
4903
  @param remaining_tables set of tables not included into the partial plan yet
4903
4904
  @param idx              the length of the partial plan
4904
4905
  @param record_count     estimate for the number of records returned by the
4912
4913
static void
4913
4914
best_access_path(JOIN      *join,
4914
4915
                 JOIN_TAB  *s,
4915
 
                 THD       *thd,
 
4916
                 Session       *session,
4916
4917
                 table_map remaining_tables,
4917
4918
                 uint32_t      idx,
4918
4919
                 double    record_count,
5163
5164
            }
5164
5165
            /* Limit the number of matched rows */
5165
5166
            tmp= records;
5166
 
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
 
5167
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5167
5168
            if (table->covering_keys.is_set(key))
5168
5169
            {
5169
5170
              /* we can use only index tree */
5328
5329
            }
5329
5330
 
5330
5331
            /* Limit the number of matched rows */
5331
 
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
 
5332
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5332
5333
            if (table->covering_keys.is_set(key))
5333
5334
            {
5334
5335
              /* we can use only index tree */
5458
5459
        /* We read the table as many times as join buffer becomes full. */
5459
5460
        tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5460
5461
                           record_count /
5461
 
                           (double) thd->variables.join_buff_size));
 
5462
                           (double) session->variables.join_buff_size));
5462
5463
        /* 
5463
5464
            We don't make full cartesian product between rows in the scanned
5464
5465
           table and existing records because we skip all rows from the
5536
5537
static bool
5537
5538
choose_plan(JOIN *join, table_map join_tables)
5538
5539
{
5539
 
  uint32_t search_depth= join->thd->variables.optimizer_search_depth;
5540
 
  uint32_t prune_level=  join->thd->variables.optimizer_prune_level;
 
5540
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
 
5541
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
5541
5542
  bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5542
5543
 
5543
5544
  join->cur_embedding_map= 0;
5585
5586
    i.e. they have subqueries, unions or call stored procedures.
5586
5587
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
5587
5588
  */
5588
 
  if (join->thd->lex->is_single_level_stmt())
5589
 
    join->thd->status_var.last_query_cost= join->best_read;
 
5589
  if (join->session->lex->is_single_level_stmt())
 
5590
    join->session->status_var.last_query_cost= join->best_read;
5590
5591
  return(false);
5591
5592
}
5592
5593
 
5739
5740
  {
5740
5741
    /* Find the best access method from 's' to the current partial plan */
5741
5742
    advance_sj_state(join_tables, s);
5742
 
    best_access_path(join, s, join->thd, join_tables, idx,
 
5743
    best_access_path(join, s, join->session, join_tables, idx,
5743
5744
                     record_count, read_time);
5744
5745
    /* compute the cost of the new plan extended with 's' */
5745
5746
    record_count*= join->positions[idx].records_read;
6027
6028
                                 uint32_t      search_depth,
6028
6029
                                 uint32_t      prune_level)
6029
6030
{
6030
 
  THD *thd= join->thd;
6031
 
  if (thd->killed)  // Abort
 
6031
  Session *session= join->session;
 
6032
  if (session->killed)  // Abort
6032
6033
    return(true);
6033
6034
 
6034
6035
  /* 
6057
6058
          when the depth is insufficient??)
6058
6059
      */
6059
6060
      /* Find the best access method from 's' to the current partial plan */
6060
 
      best_access_path(join, s, thd, remaining_tables, idx,
 
6061
      best_access_path(join, s, session, remaining_tables, idx,
6061
6062
                       record_count, read_time);
6062
6063
      /* Compute the cost of extending the plan with 's' */
6063
6064
      current_record_count= record_count * join->positions[idx].records_read;
6152
6153
find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count,
6153
6154
          double read_time)
6154
6155
{
6155
 
  THD *thd= join->thd;
6156
 
  if (thd->killed)
 
6156
  Session *session= join->session;
 
6157
  if (session->killed)
6157
6158
    return(true);
6158
6159
  if (!rest_tables)
6159
6160
  {
6182
6183
    {
6183
6184
      double records, best;
6184
6185
      advance_sj_state(rest_tables, s);
6185
 
      best_access_path(join, s, thd, rest_tables, idx, record_count, 
 
6186
      best_access_path(join, s, session, rest_tables, idx, record_count, 
6186
6187
                       read_time);
6187
6188
      records= join->positions[idx].records_read;
6188
6189
      best= join->positions[idx].read_time;
6223
6224
  Find how much space the prevous read not const tables takes in cache.
6224
6225
*/
6225
6226
 
6226
 
static void calc_used_field_length(THD *thd __attribute__((unused)),
 
6227
static void calc_used_field_length(Session *session __attribute__((unused)),
6227
6228
                                   JOIN_TAB *join_tab)
6228
6229
{
6229
6230
  uint32_t null_fields,blobs,fields,rec_length;
6265
6266
{
6266
6267
  uint32_t length=0;
6267
6268
  JOIN_TAB **pos,**end;
6268
 
  THD *thd=join->thd;
 
6269
  Session *session=join->session;
6269
6270
 
6270
6271
  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
6271
6272
       pos != end ;
6273
6274
  {
6274
6275
    JOIN_TAB *join_tab= *pos;
6275
6276
    if (!join_tab->used_fieldlength)            /* Not calced yet */
6276
 
      calc_used_field_length(thd, join_tab);
 
6277
      calc_used_field_length(session, join_tab);
6277
6278
    length+=join_tab->used_fieldlength;
6278
6279
  }
6279
6280
  return length;
6377
6378
  JOIN_TAB *join_tab,*j;
6378
6379
  KEYUSE *keyuse;
6379
6380
  uint32_t table_count;
6380
 
  THD *thd=join->thd;
 
6381
  Session *session=join->session;
6381
6382
 
6382
6383
  table_count=join->tables;
6383
6384
  if (!(join->join_tab=join_tab=
6384
 
        (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
 
6385
        (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB)*table_count)))
6385
6386
    return(true);
6386
6387
 
6387
6388
  join->full_join=0;
6425
6426
                               table_map used_tables)
6426
6427
{
6427
6428
  KEYUSE *keyuse=org_keyuse;
6428
 
  THD  *thd= join->thd;
 
6429
  Session  *session= join->session;
6429
6430
  uint32_t keyparts,length,key;
6430
6431
  Table *table;
6431
6432
  KEY *keyinfo;
6464
6465
  j->ref.key_parts=keyparts;
6465
6466
  j->ref.key_length=length;
6466
6467
  j->ref.key=(int) key;
6467
 
  if (!(j->ref.key_buff= (unsigned char*) thd->calloc(ALIGN_SIZE(length)*2)) ||
6468
 
      !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
 
6468
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
 
6469
      !(j->ref.key_copy= (store_key**) session->alloc((sizeof(store_key*) *
6469
6470
                                                   (keyparts+1)))) ||
6470
 
      !(j->ref.items=    (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
6471
 
      !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
 
6471
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
6472
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
6472
6473
  {
6473
6474
    return(true);
6474
6475
  }
6498
6499
      if (!keyuse->used_tables &&
6499
6500
          !(join->select_options & SELECT_DESCRIBE))
6500
6501
      {                                 // Compare against constant
6501
 
        store_key_item tmp(thd, keyinfo->key_part[i].field,
 
6502
        store_key_item tmp(session, keyinfo->key_part[i].field,
6502
6503
                           key_buff + maybe_null,
6503
6504
                           maybe_null ?  key_buff : 0,
6504
6505
                           keyinfo->key_part[i].length, keyuse->val);
6505
 
        if (thd->is_fatal_error)
 
6506
        if (session->is_fatal_error)
6506
6507
          return(true);
6507
6508
        tmp.copy();
6508
6509
      }
6509
6510
      else
6510
 
        *ref_key++= get_store_key(thd,
 
6511
        *ref_key++= get_store_key(session,
6511
6512
                                  keyuse,join->const_table_map,
6512
6513
                                  &keyinfo->key_part[i],
6513
6514
                                  key_buff, maybe_null);
6550
6551
 
6551
6552
 
6552
6553
static store_key *
6553
 
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
 
6554
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6554
6555
              KEY_PART_INFO *key_part, unsigned char *key_buff, uint32_t maybe_null)
6555
6556
{
6556
6557
  if (!((~used_tables) & keyuse->used_tables))          // if const item
6557
6558
  {
6558
 
    return new store_key_const_item(thd,
 
6559
    return new store_key_const_item(session,
6559
6560
                                    key_part->field,
6560
6561
                                    key_buff + maybe_null,
6561
6562
                                    maybe_null ? key_buff : 0,
6568
6569
            (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6569
6570
             Item_ref::DIRECT_REF && 
6570
6571
            keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6571
 
    return new store_key_field(thd,
 
6572
    return new store_key_field(session,
6572
6573
                               key_part->field,
6573
6574
                               key_buff + maybe_null,
6574
6575
                               maybe_null ? key_buff : 0,
6575
6576
                               key_part->length,
6576
6577
                               ((Item_field*) keyuse->val->real_item())->field,
6577
6578
                               keyuse->val->full_name());
6578
 
  return new store_key_item(thd,
 
6579
  return new store_key_item(session,
6579
6580
                            key_part->field,
6580
6581
                            key_buff + maybe_null,
6581
6582
                            maybe_null ? key_buff : 0,
6595
6596
{
6596
6597
  bool error;
6597
6598
  Table *table= field->table;
6598
 
  THD *thd= table->in_use;
6599
 
  ha_rows cuted_fields=thd->cuted_fields;
 
6599
  Session *session= table->in_use;
 
6600
  ha_rows cuted_fields=session->cuted_fields;
6600
6601
 
6601
6602
  /*
6602
6603
    we should restore old value of count_cuted_fields because
6603
6604
    store_val_in_field can be called from mysql_insert 
6604
6605
    with select_insert, which make count_cuted_fields= 1
6605
6606
   */
6606
 
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
6607
 
  thd->count_cuted_fields= check_flag;
 
6607
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
6608
  session->count_cuted_fields= check_flag;
6608
6609
  error= item->save_in_field(field, 1);
6609
 
  thd->count_cuted_fields= old_count_cuted_fields;
6610
 
  return error || cuted_fields != thd->cuted_fields;
 
6610
  session->count_cuted_fields= old_count_cuted_fields;
 
6611
  return error || cuted_fields != session->cuted_fields;
6611
6612
}
6612
6613
 
6613
6614
 
6623
6624
  */
6624
6625
  if (!join->table_reexec)
6625
6626
  {
6626
 
    if (!(join->table_reexec= (Table**) join->thd->alloc(sizeof(Table*))))
 
6627
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
6627
6628
      return(true);                        /* purecov: inspected */
6628
6629
    if (join->tmp_join)
6629
6630
      join->tmp_join->table_reexec= join->table_reexec;
6631
6632
  if (!join->join_tab_reexec)
6632
6633
  {
6633
6634
    if (!(join->join_tab_reexec=
6634
 
          (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
 
6635
          (JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
6635
6636
      return(true);                        /* purecov: inspected */
6636
6637
    if (join->tmp_join)
6637
6638
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6779
6780
            when it is called from make_join_select after this function is 
6780
6781
            called.
6781
6782
          */
6782
 
          if (notnull->fix_fields(join->thd, &notnull))
 
6783
          if (notnull->fix_fields(join->session, &notnull))
6783
6784
            return;
6784
6785
          add_cond_and_fix(&referred_tab->select_cond, notnull);
6785
6786
        }
6921
6922
static bool
6922
6923
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
6923
6924
{
6924
 
  THD *thd= join->thd;
 
6925
  Session *session= join->session;
6925
6926
  if (select)
6926
6927
  {
6927
6928
    add_not_null_conds(join);
6931
6932
      if (join->tables > 1)
6932
6933
        cond->update_used_tables();             // Tablenr may have changed
6933
6934
      if (join->const_tables == join->tables &&
6934
 
          thd->lex->current_select->master_unit() ==
6935
 
          &thd->lex->unit)              // not upper level SELECT
 
6935
          session->lex->current_select->master_unit() ==
 
6936
          &session->lex->unit)          // not upper level SELECT
6936
6937
        join->const_table_map|=RAND_TABLE_BIT;
6937
6938
      {                                         // Check const tables
6938
6939
        COND *const_cond=
7039
7040
          tab->type == JT_EQ_REF)
7040
7041
      {
7041
7042
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
7042
 
                                       thd->memdup((unsigned char*) select,
 
7043
                                       session->memdup((unsigned char*) select,
7043
7044
                                                   sizeof(*select)));
7044
7045
        if (!sel)
7045
7046
          return(1);                    // End of memory
7061
7062
          /* Push condition to storage engine if this is enabled
7062
7063
             and the condition is not guarded */
7063
7064
          tab->table->file->pushed_cond= NULL;
7064
 
          if (thd->variables.engine_condition_pushdown)
 
7065
          if (session->variables.engine_condition_pushdown)
7065
7066
          {
7066
7067
            COND *push_cond= 
7067
7068
              make_cond_for_table(tmp, current_map, current_map, 0);
7130
7131
            if (sel->cond && !sel->cond->fixed)
7131
7132
              sel->cond->quick_fix_field();
7132
7133
 
7133
 
            if (sel->test_quick_select(thd, tab->keys,
 
7134
            if (sel->test_quick_select(session, tab->keys,
7134
7135
                                       used_tables & ~ current_map,
7135
7136
                                       (join->select_options &
7136
7137
                                        OPTION_FOUND_ROWS ?
7144
7145
              */
7145
7146
              sel->cond=orig_cond;
7146
7147
              if (!*tab->on_expr_ref ||
7147
 
                  sel->test_quick_select(thd, tab->keys,
 
7148
                  sel->test_quick_select(session, tab->keys,
7148
7149
                                         used_tables & ~ current_map,
7149
7150
                                         (join->select_options &
7150
7151
                                          OPTION_FOUND_ROWS ?
7186
7187
                                         current_map, 0)))
7187
7188
            {
7188
7189
              tab->cache.select=(SQL_SELECT*)
7189
 
                thd->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
7190
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7190
7191
              tab->cache.select->cond=tmp;
7191
7192
              tab->cache.select->read_tables=join->const_table_map;
7192
7193
            }
7542
7543
{
7543
7544
  Item *idx_cond;
7544
7545
  if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7545
 
      tab->join->thd->variables.engine_condition_pushdown)
 
7546
      tab->join->session->variables.engine_condition_pushdown)
7546
7547
  {
7547
7548
    idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7548
7549
                                  other_tbls_ok);
7666
7667
    sorted= 0;                                  // only first must be sorted
7667
7668
    if (tab->insideout_match_tab)
7668
7669
    {
7669
 
      if (!(tab->insideout_buf= (unsigned char*)join->thd->alloc(tab->table->key_info
 
7670
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
7670
7671
                                                         [tab->index].
7671
7672
                                                         key_length)))
7672
7673
        return true;
7750
7751
          !tab->insideout_match_tab)
7751
7752
      {
7752
7753
        if ((options & SELECT_DESCRIBE) ||
7753
 
            !join_init_cache(join->thd,join->join_tab+join->const_tables,
 
7754
            !join_init_cache(join->session,join->join_tab+join->const_tables,
7754
7755
                             i-join->const_tables))
7755
7756
        {
7756
7757
          using_join_cache= true;
7760
7761
      /* These init changes read_record */
7761
7762
      if (tab->use_quick == 2)
7762
7763
      {
7763
 
        join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
7764
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7764
7765
        tab->read_first_record= join_init_quick_read_record;
7765
7766
        if (statistics)
7766
 
          status_var_increment(join->thd->status_var.select_range_check_count);
 
7767
          status_var_increment(join->session->status_var.select_range_check_count);
7767
7768
      }
7768
7769
      else
7769
7770
      {
7773
7774
          if (tab->select && tab->select->quick)
7774
7775
          {
7775
7776
            if (statistics)
7776
 
              status_var_increment(join->thd->status_var.select_range_count);
 
7777
              status_var_increment(join->session->status_var.select_range_count);
7777
7778
          }
7778
7779
          else
7779
7780
          {
7780
 
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7781
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7781
7782
            if (statistics)
7782
 
              status_var_increment(join->thd->status_var.select_scan_count);
 
7783
              status_var_increment(join->session->status_var.select_scan_count);
7783
7784
          }
7784
7785
        }
7785
7786
        else
7787
7788
          if (tab->select && tab->select->quick)
7788
7789
          {
7789
7790
            if (statistics)
7790
 
              status_var_increment(join->thd->status_var.select_full_range_join_count);
 
7791
              status_var_increment(join->session->status_var.select_full_range_join_count);
7791
7792
          }
7792
7793
          else
7793
7794
          {
7794
 
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7795
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7795
7796
            if (statistics)
7796
 
              status_var_increment(join->thd->status_var.select_full_join_count);
 
7797
              status_var_increment(join->session->status_var.select_full_join_count);
7797
7798
          }
7798
7799
        }
7799
7800
        if (!table->no_keyread)
7955
7956
    Optimization: if not EXPLAIN and we are done with the JOIN,
7956
7957
    free all tables.
7957
7958
  */
7958
 
  bool full= (!select_lex->uncacheable && !thd->lex->describe);
 
7959
  bool full= (!select_lex->uncacheable && !session->lex->describe);
7959
7960
  bool can_unlock= full;
7960
7961
 
7961
7962
  cleanup(full);
7985
7986
    We are not using tables anymore
7986
7987
    Unlock all tables. We may be in an INSERT .... SELECT statement.
7987
7988
  */
7988
 
  if (can_unlock && lock && thd->lock &&
 
7989
  if (can_unlock && lock && session->lock &&
7989
7990
      !(select_options & SELECT_NO_UNLOCK) &&
7990
7991
      !select_lex->subquery_in_having &&
7991
 
      (select_lex == (thd->lex->unit.fake_select_lex ?
7992
 
                      thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
 
7992
      (select_lex == (session->lex->unit.fake_select_lex ?
 
7993
                      session->lex->unit.fake_select_lex : &session->lex->select_lex)))
7993
7994
  {
7994
7995
    /*
7995
7996
      TODO: unlock tables even if the join isn't top level select in the
7996
7997
      tree.
7997
7998
    */
7998
 
    mysql_unlock_read_tables(thd, lock);           // Don't free join->lock
 
7999
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
7999
8000
    lock= 0;
8000
8001
  }
8001
8002
 
8332
8333
    result->send_eof();                         // Should be safe
8333
8334
  }
8334
8335
  /* Update results for FOUND_ROWS */
8335
 
  join->thd->limit_found_rows= join->thd->examined_row_count= 0;
 
8336
  join->session->limit_found_rows= join->session->examined_row_count= 0;
8336
8337
  return(0);
8337
8338
}
8338
8339
 
8692
8693
    simple equality nor a row equality the item for this predicate is added
8693
8694
    to eq_list.
8694
8695
 
8695
 
  @param thd        thread handle
 
8696
  @param session        thread handle
8696
8697
  @param left_row   left term of the row equality to be processed
8697
8698
  @param right_row  right term of the row equality to be processed
8698
8699
  @param cond_equal multiple equalities that must hold together with the
8706
8707
    false   otherwise
8707
8708
*/
8708
8709
 
8709
 
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
 
8710
static bool check_row_equality(Session *session, Item *left_row, Item_row *right_row,
8710
8711
                               COND_EQUAL *cond_equal, List<Item>* eq_list)
8711
8712
8712
8713
  uint32_t n= left_row->cols();
8718
8719
    if (left_item->type() == Item::ROW_ITEM &&
8719
8720
        right_item->type() == Item::ROW_ITEM)
8720
8721
    {
8721
 
      is_converted= check_row_equality(thd, 
 
8722
      is_converted= check_row_equality(session, 
8722
8723
                                       (Item_row *) left_item,
8723
8724
                                       (Item_row *) right_item,
8724
8725
                                       cond_equal, eq_list);
8725
8726
      if (!is_converted)
8726
 
        thd->lex->current_select->cond_count++;      
 
8727
        session->lex->current_select->cond_count++;      
8727
8728
    }
8728
8729
    else
8729
8730
    { 
8730
8731
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8731
 
      thd->lex->current_select->cond_count++;
 
8732
      session->lex->current_select->cond_count++;
8732
8733
    }  
8733
8734
 
8734
8735
    if (!is_converted)
8759
8760
    equalities which are treated in the same way as original equality
8760
8761
    predicates.
8761
8762
 
8762
 
  @param thd        thread handle
 
8763
  @param session        thread handle
8763
8764
  @param item       predicate to process
8764
8765
  @param cond_equal multiple equalities that must hold together with the
8765
8766
                    predicate
8775
8776
           or, if the procedure fails by a fatal error.
8776
8777
*/
8777
8778
 
8778
 
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
 
8779
static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal,
8779
8780
                           List<Item> *eq_list)
8780
8781
{
8781
8782
  if (item->type() == Item::FUNC_ITEM &&
8787
8788
    if (left_item->type() == Item::ROW_ITEM &&
8788
8789
        right_item->type() == Item::ROW_ITEM)
8789
8790
    {
8790
 
      thd->lex->current_select->cond_count--;
8791
 
      return check_row_equality(thd,
 
8791
      session->lex->current_select->cond_count--;
 
8792
      return check_row_equality(session,
8792
8793
                                (Item_row *) left_item,
8793
8794
                                (Item_row *) right_item,
8794
8795
                                cond_equal, eq_list);
8819
8820
    just an argument of a comparison predicate.
8820
8821
    The function also determines the maximum number of members in 
8821
8822
    equality lists of each Item_cond_and object assigning it to
8822
 
    thd->lex->current_select->max_equal_elems.
 
8823
    session->lex->current_select->max_equal_elems.
8823
8824
 
8824
8825
  @note
8825
8826
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8856
8857
    We need to do things in this order as lower AND levels need to know about
8857
8858
    all possible Item_equal objects in upper levels.
8858
8859
 
8859
 
  @param thd        thread handle
 
8860
  @param session        thread handle
8860
8861
  @param cond       condition(expression) where to make replacement
8861
8862
  @param inherited  path to all inherited multiple equality items
8862
8863
 
8864
8865
    pointer to the transformed condition
8865
8866
*/
8866
8867
 
8867
 
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
 
8868
static COND *build_equal_items_for_cond(Session *session, COND *cond,
8868
8869
                                        COND_EQUAL *inherited)
8869
8870
{
8870
8871
  Item_equal *item_equal;
8896
8897
          structure here because it's restored before each
8897
8898
          re-execution of any prepared statement/stored procedure.
8898
8899
        */
8899
 
        if (check_equality(thd, item, &cond_equal, &eq_list))
 
8900
        if (check_equality(session, item, &cond_equal, &eq_list))
8900
8901
          li.remove();
8901
8902
      }
8902
8903
 
8905
8906
      {
8906
8907
        item_equal->fix_length_and_dec();
8907
8908
        item_equal->update_used_tables();
8908
 
        set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8909
        set_if_bigger(session->lex->current_select->max_equal_elems,
8909
8910
                      item_equal->members());  
8910
8911
      }
8911
8912
 
8920
8921
    while ((item= li++))
8921
8922
    { 
8922
8923
      Item *new_item;
8923
 
      if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
 
8924
      if ((new_item= build_equal_items_for_cond(session, item, inherited)) != item)
8924
8925
      {
8925
8926
        /* This replacement happens only for standalone equalities */
8926
8927
        /*
8950
8951
      for WHERE a=b AND c=d AND (b=c OR d=5)
8951
8952
      b=c is replaced by =(a,b,c,d).  
8952
8953
     */
8953
 
    if (check_equality(thd, cond, &cond_equal, &eq_list))
 
8954
    if (check_equality(session, cond, &cond_equal, &eq_list))
8954
8955
    {
8955
8956
      int n= cond_equal.current_level.elements + eq_list.elements;
8956
8957
      if (n == 0)
8964
8965
        }
8965
8966
        else
8966
8967
          item_equal= (Item_equal *) eq_list.pop();
8967
 
        set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8968
        set_if_bigger(session->lex->current_select->max_equal_elems,
8968
8969
                      item_equal->members());  
8969
8970
        return item_equal;
8970
8971
      }
8982
8983
        {
8983
8984
          item_equal->fix_length_and_dec();
8984
8985
          item_equal->update_used_tables();
8985
 
          set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8986
          set_if_bigger(session->lex->current_select->max_equal_elems,
8986
8987
                        item_equal->members());  
8987
8988
        }
8988
8989
        and_cond->cond_equal= cond_equal;
9062
9063
    can get more freedom in performing join operations.
9063
9064
    Althogh we don't use this property now, it probably makes sense to use 
9064
9065
    it in the future.    
9065
 
  @param thd                  Thread handler
 
9066
  @param session                      Thread handler
9066
9067
  @param cond                condition to build the multiple equalities for
9067
9068
  @param inherited           path to all inherited multiple equality items
9068
9069
  @param join_list           list of join tables to which the condition
9074
9075
    pointer to the transformed condition containing multiple equalities
9075
9076
*/
9076
9077
   
9077
 
static COND *build_equal_items(THD *thd, COND *cond,
 
9078
static COND *build_equal_items(Session *session, COND *cond,
9078
9079
                               COND_EQUAL *inherited,
9079
9080
                               List<TableList> *join_list,
9080
9081
                               COND_EQUAL **cond_equal_ref)
9083
9084
 
9084
9085
  if (cond) 
9085
9086
  {
9086
 
    cond= build_equal_items_for_cond(thd, cond, inherited);
 
9087
    cond= build_equal_items_for_cond(session, cond, inherited);
9087
9088
    cond->update_used_tables();
9088
9089
    if (cond->type() == Item::COND_ITEM &&
9089
9090
        ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9117
9118
          We can modify table->on_expr because its old value will
9118
9119
          be restored before re-execution of PS/SP.
9119
9120
        */
9120
 
        table->on_expr= build_equal_items(thd, table->on_expr, inherited,
 
9121
        table->on_expr= build_equal_items(session, table->on_expr, inherited,
9121
9122
                                          nested_join_list,
9122
9123
                                          &table->cond_equal);
9123
9124
      }
9455
9456
*/
9456
9457
 
9457
9458
static void
9458
 
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
 
9459
change_cond_ref_to_const(Session *session, I_List<COND_CMP> *save_list,
9459
9460
                         Item *and_father, Item *cond,
9460
9461
                         Item *field, Item *value)
9461
9462
{
9466
9467
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9467
9468
    Item *item;
9468
9469
    while ((item=li++))
9469
 
      change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
 
9470
      change_cond_ref_to_const(session, save_list,and_level ? cond : item, item,
9470
9471
                               field, value);
9471
9472
    return;
9472
9473
  }
9490
9491
    
9491
9492
    if (tmp)
9492
9493
    {
9493
 
      thd->change_item_tree(args + 1, tmp);
 
9494
      session->change_item_tree(args + 1, tmp);
9494
9495
      func->update_used_tables();
9495
9496
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9496
9497
          && and_father != cond && !left_item->const_item())
9514
9515
    
9515
9516
    if (tmp)
9516
9517
    {
9517
 
      thd->change_item_tree(args, tmp);
 
9518
      session->change_item_tree(args, tmp);
9518
9519
      value= tmp;
9519
9520
      func->update_used_tables();
9520
9521
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9521
9522
          && and_father != cond && !right_item->const_item())
9522
9523
      {
9523
9524
        args[0]= args[1];                       // For easy check
9524
 
        thd->change_item_tree(args + 1, value);
 
9525
        session->change_item_tree(args + 1, value);
9525
9526
        cond->marker=1;
9526
9527
        COND_CMP *tmp2;
9527
9528
        if ((tmp2=new COND_CMP(and_father,func)))
9565
9566
}
9566
9567
 
9567
9568
static void
9568
 
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
 
9569
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
9569
9570
                         COND *and_father, COND *cond)
9570
9571
{
9571
9572
  if (cond->type() == Item::COND_ITEM)
9577
9578
    I_List<COND_CMP> save;
9578
9579
    while ((item=li++))
9579
9580
    {
9580
 
      propagate_cond_constants(thd, &save,and_level ? cond : item, item);
 
9581
      propagate_cond_constants(session, &save,and_level ? cond : item, item);
9581
9582
    }
9582
9583
    if (and_level)
9583
9584
    {                                           // Handle other found items
9587
9588
      {
9588
9589
        Item **args= cond_cmp->cmp_func->arguments();
9589
9590
        if (!args[0]->const_item())
9590
 
          change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
 
9591
          change_cond_ref_to_const(session, &save,cond_cmp->and_level,
9591
9592
                                   cond_cmp->and_level, args[0], args[1]);
9592
9593
      }
9593
9594
    }
9607
9608
      {
9608
9609
        if (right_const)
9609
9610
        {
9610
 
          resolve_const_item(thd, &args[1], args[0]);
 
9611
          resolve_const_item(session, &args[1], args[0]);
9611
9612
          func->update_used_tables();
9612
 
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
 
9613
          change_cond_ref_to_const(session, save_list, and_father, and_father,
9613
9614
                                   args[0], args[1]);
9614
9615
        }
9615
9616
        else if (left_const)
9616
9617
        {
9617
 
          resolve_const_item(thd, &args[0], args[1]);
 
9618
          resolve_const_item(session, &args[0], args[1]);
9618
9619
          func->update_used_tables();
9619
 
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
 
9620
          change_cond_ref_to_const(session, save_list, and_father, and_father,
9620
9621
                                   args[1], args[0]);
9621
9622
        }
9622
9623
      }
9789
9790
          assert(expr);
9790
9791
 
9791
9792
          table->on_expr= expr;
9792
 
          table->prep_on_expr= expr->copy_andor_structure(join->thd);
 
9793
          table->prep_on_expr= expr->copy_andor_structure(join->session);
9793
9794
        }
9794
9795
      }
9795
9796
      nested_join->used_tables= (table_map) 0;
9830
9831
          conds->top_level_item();
9831
9832
          /* conds is always a new item as both cond and on_expr existed */
9832
9833
          assert(!conds->fixed);
9833
 
          conds->fix_fields(join->thd, &conds);
 
9834
          conds->fix_fields(join->session, &conds);
9834
9835
        }
9835
9836
        else
9836
9837
          conds= table->on_expr; 
10209
10210
optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list,
10210
10211
              Item::cond_result *cond_value)
10211
10212
{
10212
 
  THD *thd= join->thd;
 
10213
  Session *session= join->session;
10213
10214
 
10214
10215
  if (!conds)
10215
10216
    *cond_value= Item::COND_TRUE;
10223
10224
      predicate. Substitute a constant instead of this field if the
10224
10225
      multiple equality contains a constant.
10225
10226
    */ 
10226
 
    conds= build_equal_items(join->thd, conds, NULL, join_list,
 
10227
    conds= build_equal_items(join->session, conds, NULL, join_list,
10227
10228
                             &join->cond_equal);
10228
10229
 
10229
10230
    /* change field = field to field = const for each found field = const */
10230
 
    propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
 
10231
    propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10231
10232
    /*
10232
10233
      Remove all instances of item == item
10233
10234
      Remove all and-levels where CONST item != CONST item
10234
10235
    */
10235
 
    conds= remove_eq_conds(thd, conds, cond_value) ;
 
10236
    conds= remove_eq_conds(session, conds, cond_value) ;
10236
10237
  }
10237
10238
  return(conds);
10238
10239
}
10250
10251
*/
10251
10252
 
10252
10253
COND *
10253
 
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
 
10254
remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value)
10254
10255
{
10255
10256
  if (cond->type() == Item::COND_ITEM)
10256
10257
  {
10264
10265
    Item *item;
10265
10266
    while ((item=li++))
10266
10267
    {
10267
 
      Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
 
10268
      Item *new_item=remove_eq_conds(session, item, &tmp_cond_value);
10268
10269
      if (!new_item)
10269
10270
        li.remove();
10270
10271
      else if (item != new_item)
10329
10330
    {
10330
10331
      Field *field=((Item_field*) args[0])->field;
10331
10332
      if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
10332
 
          (thd->options & OPTION_AUTO_IS_NULL) &&
10333
 
          (thd->first_successful_insert_id_in_prev_stmt > 0 &&
10334
 
           thd->substitute_null_with_insert_id))
 
10333
          (session->options & OPTION_AUTO_IS_NULL) &&
 
10334
          (session->first_successful_insert_id_in_prev_stmt > 0 &&
 
10335
           session->substitute_null_with_insert_id))
10335
10336
      {
10336
10337
        COND *new_cond;
10337
10338
        if ((new_cond= new Item_func_eq(args[0],
10338
10339
                                        new Item_int("last_insert_id()",
10339
 
                                                     thd->read_first_successful_insert_id_in_prev_stmt(),
 
10340
                                                     session->read_first_successful_insert_id_in_prev_stmt(),
10340
10341
                                                     MY_INT64_NUM_DECIMAL_DIGITS))))
10341
10342
        {
10342
10343
          cond=new_cond;
10345
10346
            cond->fixed, also it do not need tables so we use 0 as second
10346
10347
            argument.
10347
10348
          */
10348
 
          cond->fix_fields(thd, &cond);
 
10349
          cond->fix_fields(session, &cond);
10349
10350
        }
10350
10351
        /*
10351
10352
          IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10352
10353
          clear for next row
10353
10354
        */
10354
 
        thd->substitute_null_with_insert_id= false;
 
10355
        session->substitute_null_with_insert_id= false;
10355
10356
      }
10356
10357
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10357
10358
      else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10368
10369
            cond->fixed, also it do not need tables so we use 0 as second
10369
10370
            argument.
10370
10371
          */
10371
 
          cond->fix_fields(thd, &cond);
 
10372
          cond->fix_fields(session, &cond);
10372
10373
        }
10373
10374
      }
10374
10375
    }
10627
10628
        so we don't touch it here.
10628
10629
      */
10629
10630
      join->examined_rows++;
10630
 
      join->thd->row_count++;
 
10631
      join->session->row_count++;
10631
10632
      assert(join->examined_rows <= 1);
10632
10633
    }
10633
10634
    else if (join->send_row_on_empty_set())
10681
10682
    if (new_errno)
10682
10683
      table->file->print_error(new_errno,MYF(0));
10683
10684
  }
10684
 
  return(join->thd->is_error() ? -1 : rc);
 
10685
  return(join->session->is_error() ? -1 : rc);
10685
10686
}
10686
10687
 
10687
10688
 
10697
10698
      rc= sub_select(join,join_tab,end_of_records);
10698
10699
    return rc;
10699
10700
  }
10700
 
  if (join->thd->killed)                // If aborted by user
 
10701
  if (join->session->killed)            // If aborted by user
10701
10702
  {
10702
 
    join->thd->send_kill_message();
 
10703
    join->session->send_kill_message();
10703
10704
    return NESTED_LOOP_KILLED;                   /* purecov: inspected */
10704
10705
  }
10705
10706
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10877
10878
      /* Set first_unmatched for the last inner table of this group */
10878
10879
      join_tab->last_inner->first_unmatched= join_tab;
10879
10880
    }
10880
 
    join->thd->row_count= 0;
 
10881
    join->session->row_count= 0;
10881
10882
 
10882
10883
    error= (*join_tab->read_first_record)(join_tab);
10883
10884
    rc= evaluate_join_record(join, join_tab, error);
10917
10918
    0   The row combination is not a duplicate (continue)
10918
10919
*/
10919
10920
 
10920
 
int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl) 
 
10921
int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl) 
10921
10922
{
10922
10923
  int error;
10923
10924
  SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
10970
10971
  {
10971
10972
    /* create_myisam_from_heap will generate error if needed */
10972
10973
    if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10973
 
        create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo, 
 
10974
        create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo, 
10974
10975
                                &sjtbl->recinfo, error, 1))
10975
10976
      return -1;
10976
10977
    //return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11007
11008
  ha_rows found_records=join->found_records;
11008
11009
  COND *select_cond= join_tab->select_cond;
11009
11010
 
11010
 
  if (error > 0 || (join->thd->is_error()))     // Fatal error
 
11011
  if (error > 0 || (join->session->is_error()))     // Fatal error
11011
11012
    return NESTED_LOOP_ERROR;
11012
11013
  if (error < 0)
11013
11014
    return NESTED_LOOP_NO_MORE_ROWS;
11014
 
  if (join->thd->killed)                        // Aborted by user
 
11015
  if (join->session->killed)                    // Aborted by user
11015
11016
  {
11016
 
    join->thd->send_kill_message();
 
11017
    join->session->send_kill_message();
11017
11018
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
11018
11019
  }
11019
11020
  if (!select_cond || select_cond->val_int())
11076
11077
    join_tab->found_match= true;
11077
11078
    if (join_tab->check_weed_out_table)
11078
11079
    {
11079
 
      int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
 
11080
      int res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table);
11080
11081
      if (res == -1)
11081
11082
        return NESTED_LOOP_ERROR;
11082
11083
      if (res == 1)
11097
11098
      (See above join->return_tab= tab).
11098
11099
    */
11099
11100
    join->examined_rows++;
11100
 
    join->thd->row_count++;
 
11101
    join->session->row_count++;
11101
11102
 
11102
11103
    if (found)
11103
11104
    {
11129
11130
      with the beginning coinciding with the current partial join.
11130
11131
    */
11131
11132
    join->examined_rows++;
11132
 
    join->thd->row_count++;
 
11133
    join->session->row_count++;
11133
11134
    join_tab->read_record.file->unlock_row();
11134
11135
  }
11135
11136
  return NESTED_LOOP_OK;
11239
11240
  info= &join_tab->read_record;
11240
11241
  do
11241
11242
  {
11242
 
    if (join->thd->killed)
 
11243
    if (join->session->killed)
11243
11244
    {
11244
 
      join->thd->send_kill_message();
 
11245
      join->session->send_kill_message();
11245
11246
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11246
11247
    }
11247
11248
    SQL_SELECT *select=join_tab->select;
11257
11258
        {
11258
11259
          int res= 0;
11259
11260
          if (!join_tab->check_weed_out_table || 
11260
 
              !(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
 
11261
              !(res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table)))
11261
11262
          {
11262
11263
            rc= (join_tab->next_select)(join,join_tab+1,0);
11263
11264
            if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11391
11392
      empty_record(table);                      // Make empty record
11392
11393
      return -1;
11393
11394
    }
 
11395
    update_virtual_fields_marked_for_write(table);
11394
11396
    store_record(table,record[1]);
11395
11397
  }
11396
11398
  else if (!table->status)                      // Only happens with left join
11421
11423
  if (table->status & STATUS_GARBAGE)           // If first read
11422
11424
  {
11423
11425
    table->status= 0;
11424
 
    if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11426
    if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11425
11427
      error=HA_ERR_KEY_NOT_FOUND;
11426
11428
    else
11427
11429
    {
11439
11441
        return table->report_error(error);
11440
11442
      return -1;
11441
11443
    }
 
11444
    update_virtual_fields_marked_for_write(table);
11442
11445
    store_record(table,record[1]);
11443
11446
  }
11444
11447
  else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
11536
11539
        return -1;
11537
11540
  }
11538
11541
 
11539
 
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11542
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11540
11543
    return -1;
11541
11544
  if ((error=table->file->index_read_map(table->record[0],
11542
11545
                                         tab->ref.key_buff,
11547
11550
      return table->report_error(error);
11548
11551
    return -1; /* purecov: inspected */
11549
11552
  }
 
11553
  update_virtual_fields_marked_for_write(table);
11550
11554
  return 0;
11551
11555
}
11552
11556
 
11564
11568
 
11565
11569
  if (!table->file->inited)
11566
11570
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11567
 
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11571
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11568
11572
    return -1;
11569
11573
  if ((error=table->file->index_read_last_map(table->record[0],
11570
11574
                                              tab->ref.key_buff,
11633
11637
    table->status= STATUS_GARBAGE;
11634
11638
    return -1;
11635
11639
  }
 
11640
  update_virtual_fields_marked_for_write(table);
11636
11641
  return 0;
11637
11642
}
11638
11643
 
11652
11657
    table->status=STATUS_NOT_FOUND;
11653
11658
    error= -1;
11654
11659
  }
 
11660
  update_virtual_fields_marked_for_write(table);
11655
11661
  return error;
11656
11662
}
11657
11663
 
11679
11685
{
11680
11686
  delete tab->select->quick;
11681
11687
  tab->select->quick=0;
11682
 
  return tab->select->test_quick_select(tab->join->thd, tab->keys,
 
11688
  return tab->select->test_quick_select(tab->join->session, tab->keys,
11683
11689
                                        (table_map) 0, HA_POS_ERROR, 0,
11684
11690
                                        false);
11685
11691
}
11690
11696
{
11691
11697
  if (tab->select && tab->select->quick && tab->select->quick->reset())
11692
11698
    return 1;
11693
 
  init_read_record(&tab->read_record, tab->join->thd, tab->table,
 
11699
  init_read_record(&tab->read_record, tab->join->session, tab->table,
11694
11700
                   tab->select,1,1);
11695
11701
  return (*tab->read_record.read_record)(&tab->read_record);
11696
11702
}
11732
11738
      table->report_error(error);
11733
11739
    return -1;
11734
11740
  }
 
11741
  if (not error)
 
11742
    update_virtual_fields_marked_for_write(tab->table);
11735
11743
  return 0;
11736
11744
}
11737
11745
 
11751
11759
 
11752
11760
      if ((error=info->file->index_next(info->record)))
11753
11761
        return info->table->report_error(error);
11754
 
      
 
11762
      if (not error)
 
11763
        update_virtual_fields_marked_for_write(tab->table);
11755
11764
    } while (!key_cmp(tab->table->key_info[tab->index].key_part, 
11756
11765
                      tab->insideout_buf, key->key_length));
11757
11766
    tab->insideout_match_tab->found_match= 0;
11768
11777
  int error;
11769
11778
  if ((error=info->file->index_next(info->record)))
11770
11779
    return info->table->report_error(error);
 
11780
  if (not error)
 
11781
    update_virtual_fields_marked_for_write(info->table);
11771
11782
  return 0;
11772
11783
}
11773
11784
 
11793
11804
    table->file->ha_index_init(tab->index, 1);
11794
11805
  if ((error= tab->table->file->index_last(tab->table->record[0])))
11795
11806
    return table->report_error(error);
 
11807
  if (not error)
 
11808
    update_virtual_fields_marked_for_write(tab->table);
11796
11809
  return 0;
11797
11810
}
11798
11811
 
11803
11816
  int error;
11804
11817
  if ((error= info->file->index_prev(info->record)))
11805
11818
    return info->table->report_error(error);
 
11819
  if (not error)
 
11820
    update_virtual_fields_marked_for_write(info->table);
11806
11821
  return 0;
11807
11822
}
11808
11823
 
12034
12049
{
12035
12050
  Table *table=join->tmp_table;
12036
12051
 
12037
 
  if (join->thd->killed)                        // Aborted by user
 
12052
  if (join->session->killed)                    // Aborted by user
12038
12053
  {
12039
 
    join->thd->send_kill_message();
 
12054
    join->session->send_kill_message();
12040
12055
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12041
12056
  }
12042
12057
  if (!end_of_records)
12043
12058
  {
12044
12059
    copy_fields(&join->tmp_table_param);
12045
12060
    copy_funcs(join->tmp_table_param.items_to_copy);
12046
 
#ifdef TO_BE_DELETED
12047
 
    if (!table->uniques)                        // If not unique handling
12048
 
    {
12049
 
      /* Copy null values from group to row */
12050
 
      order_st   *group;
12051
 
      for (group=table->group ; group ; group=group->next)
12052
 
      {
12053
 
        Item *item= *group->item;
12054
 
        if (item->maybe_null)
12055
 
        {
12056
 
          Field *field=item->get_tmp_table_field();
12057
 
          field->ptr[-1]= (unsigned char) (field->is_null() ? 1 : 0);
12058
 
        }
12059
 
      }
12060
 
    }
12061
 
#endif
12062
12061
    if (!join->having || join->having->val_int())
12063
12062
    {
12064
12063
      int error;
12067
12066
      {
12068
12067
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12069
12068
          goto end;
12070
 
        if (create_myisam_from_heap(join->thd, table,
 
12069
        if (create_myisam_from_heap(join->session, table,
12071
12070
                                    join->tmp_table_param.start_recinfo,
12072
12071
                                    &join->tmp_table_param.recinfo,
12073
12072
                                    error, 1))
12102
12101
 
12103
12102
  if (end_of_records)
12104
12103
    return(NESTED_LOOP_OK);
12105
 
  if (join->thd->killed)                        // Aborted by user
 
12104
  if (join->session->killed)                    // Aborted by user
12106
12105
  {
12107
 
    join->thd->send_kill_message();
 
12106
    join->session->send_kill_message();
12108
12107
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12109
12108
  }
12110
12109
 
12152
12151
  copy_funcs(join->tmp_table_param.items_to_copy);
12153
12152
  if ((error=table->file->ha_write_row(table->record[0])))
12154
12153
  {
12155
 
    if (create_myisam_from_heap(join->thd, table,
 
12154
    if (create_myisam_from_heap(join->session, table,
12156
12155
                                join->tmp_table_param.start_recinfo,
12157
12156
                                &join->tmp_table_param.recinfo,
12158
12157
                                error, 0))
12177
12176
 
12178
12177
  if (end_of_records)
12179
12178
    return(NESTED_LOOP_OK);
12180
 
  if (join->thd->killed)                        // Aborted by user
 
12179
  if (join->session->killed)                    // Aborted by user
12181
12180
  {
12182
 
    join->thd->send_kill_message();
 
12181
    join->session->send_kill_message();
12183
12182
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12184
12183
  }
12185
12184
 
12222
12221
  Table *table=join->tmp_table;
12223
12222
  int     idx= -1;
12224
12223
 
12225
 
  if (join->thd->killed)
 
12224
  if (join->session->killed)
12226
12225
  {                                             // Aborted by user
12227
 
    join->thd->send_kill_message();
 
12226
    join->session->send_kill_message();
12228
12227
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12229
12228
  }
12230
12229
  if (!join->first_record || end_of_records ||
12245
12244
        if (!join->having || join->having->val_int())
12246
12245
        {
12247
12246
          int error= table->file->ha_write_row(table->record[0]);
12248
 
          if (error && create_myisam_from_heap(join->thd, table,
 
12247
          if (error && create_myisam_from_heap(join->session, table,
12249
12248
                                               join->tmp_table_param.start_recinfo,
12250
12249
                                                &join->tmp_table_param.recinfo,
12251
12250
                                               error, 0))
12349
12348
   @param join The top-level query.
12350
12349
   @param old_cond The expression to be replaced.
12351
12350
   @param new_cond The expression to be substituted.
12352
 
   @param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
 
12351
   @param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
12353
12352
   the new expression.
12354
12353
   @return <code>true</code> if there was an error, <code>false</code> if
12355
12354
   successful.
12360
12359
  if (join->conds == old_cond) {
12361
12360
    join->conds= new_cond;
12362
12361
    if (do_fix_fields)
12363
 
      new_cond->fix_fields(join->thd, &join->conds);
 
12362
      new_cond->fix_fields(join->session, &join->conds);
12364
12363
    return false;
12365
12364
  }
12366
12365
  
12372
12371
      {
12373
12372
        li.replace(new_cond);
12374
12373
        if (do_fix_fields)
12375
 
          new_cond->fix_fields(join->thd, li.ref());
 
12374
          new_cond->fix_fields(join->session, li.ref());
12376
12375
        return false;
12377
12376
      }
12378
12377
  }
12981
12980
          new_ref_key_map.clear_all();  // Force the creation of quick select
12982
12981
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12983
12982
 
12984
 
          if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
 
12983
          if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
12985
12984
                                        (tab->join->select_options &
12986
12985
                                         OPTION_FOUND_ROWS) ?
12987
12986
                                        HA_POS_ERROR :
13168
13167
        map.clear_all();       // Force the creation of quick select
13169
13168
        map.set_bit(best_key); // only best_key.
13170
13169
        quick_created=         
13171
 
          select->test_quick_select(join->thd, map, 0,
 
13170
          select->test_quick_select(join->session, map, 0,
13172
13171
                                    join->select_options & OPTION_FOUND_ROWS ?
13173
13172
                                    HA_POS_ERROR :
13174
13173
                                    join->unit->select_limit_cnt,
13287
13286
 
13288
13287
  SYNOPSIS
13289
13288
   create_sort_index()
13290
 
     thd                Thread handler
 
13289
     session            Thread handler
13291
13290
     tab                Table to sort (in join structure)
13292
13291
     order              How table should be sorted
13293
13292
     filesort_limit     Max number of rows that needs to be sorted
13312
13311
*/
13313
13312
 
13314
13313
static int
13315
 
create_sort_index(THD *thd, JOIN *join, order_st *order,
 
13314
create_sort_index(Session *session, JOIN *join, order_st *order,
13316
13315
                  ha_rows filesort_limit, ha_rows select_limit,
13317
13316
                  bool is_order_by)
13318
13317
{
13376
13375
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13377
13376
        field, quick will contain an empty record set.
13378
13377
      */
13379
 
      if (!(select->quick= (get_quick_select_for_ref(thd, table, &tab->ref, 
 
13378
      if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref, 
13380
13379
                                                     tab->found_records))))
13381
13380
        goto err;
13382
13381
    }
13389
13388
 
13390
13389
  if (table->s->tmp_table)
13391
13390
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
13392
 
  table->sort.found_records=filesort(thd, table,join->sortorder, length,
 
13391
  table->sort.found_records=filesort(session, table,join->sortorder, length,
13393
13392
                                     select, filesort_limit, 0,
13394
13393
                                     &examined_rows);
13395
13394
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
13441
13440
  int error;
13442
13441
  ulong reclength,offset;
13443
13442
  uint32_t field_count;
13444
 
  THD *thd= join->thd;
 
13443
  Session *session= join->session;
13445
13444
 
13446
13445
  entry->reginfo.lock_type=TL_WRITE;
13447
13446
 
13471
13470
  if (entry->s->db_type() == heap_hton ||
13472
13471
      (!entry->s->blob_fields &&
13473
13472
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13474
 
        thd->variables.sortbuff_size)))
13475
 
    error=remove_dup_with_hash_index(join->thd, entry,
 
13473
        session->variables.sortbuff_size)))
 
13474
    error=remove_dup_with_hash_index(join->session, entry,
13476
13475
                                     field_count, first_field,
13477
13476
                                     reclength, having);
13478
13477
  else
13479
 
    error=remove_dup_with_compare(join->thd, entry, first_field, offset,
 
13478
    error=remove_dup_with_compare(join->session, entry, first_field, offset,
13480
13479
                                  having);
13481
13480
 
13482
13481
  free_blobs(first_field);
13484
13483
}
13485
13484
 
13486
13485
 
13487
 
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
 
13486
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13488
13487
                                   ulong offset, Item *having)
13489
13488
{
13490
13489
  handler *file=table->file;
13500
13499
  error=file->rnd_next(record);
13501
13500
  for (;;)
13502
13501
  {
13503
 
    if (thd->killed)
 
13502
    if (session->killed)
13504
13503
    {
13505
 
      thd->send_kill_message();
 
13504
      session->send_kill_message();
13506
13505
      error=0;
13507
13506
      goto err;
13508
13507
    }
13575
13574
    Note that this will not work on tables with blobs!
13576
13575
*/
13577
13576
 
13578
 
static int remove_dup_with_hash_index(THD *thd, Table *table,
 
13577
static int remove_dup_with_hash_index(Session *session, Table *table,
13579
13578
                                      uint32_t field_count,
13580
13579
                                      Field **first_field,
13581
13580
                                      ulong key_length,
13623
13622
  for (;;)
13624
13623
  {
13625
13624
    unsigned char *org_key_pos;
13626
 
    if (thd->killed)
 
13625
    if (session->killed)
13627
13626
    {
13628
 
      thd->send_kill_message();
 
13627
      session->send_kill_message();
13629
13628
      error=0;
13630
13629
      goto err;
13631
13630
    }
13726
13725
******************************************************************************/
13727
13726
 
13728
13727
static int
13729
 
join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count)
 
13728
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
13730
13729
{
13731
13730
  register unsigned int i;
13732
13731
  unsigned int length, blobs;
13742
13741
  for (i=0 ; i < table_count ; i++,join_tab++)
13743
13742
  {
13744
13743
    if (!join_tab->used_fieldlength)            /* Not calced yet */
13745
 
      calc_used_field_length(thd, join_tab);
 
13744
      calc_used_field_length(session, join_tab);
13746
13745
    cache->fields+=join_tab->used_fields;
13747
13746
    blobs+=join_tab->used_blobs;
13748
13747
 
13835
13834
  cache->length=length+blobs*sizeof(char*);
13836
13835
  cache->blobs=blobs;
13837
13836
  *blob_ptr=0;                                  /* End sequentel */
13838
 
  size=cmax(thd->variables.join_buff_size, (ulong)cache->length);
 
13837
  size=cmax(session->variables.join_buff_size, (ulong)cache->length);
13839
13838
  if (!(cache->buff=(unsigned char*) my_malloc(size,MYF(0))))
13840
13839
    return(1);                          /* Don't use cache */ /* purecov: inspected */
13841
13840
  cache->end=cache->buff+size;
14023
14022
  }
14024
14023
  else 
14025
14024
    no_prev_key= true;
14026
 
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) ||
 
14025
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->session, &tab->ref)) ||
14027
14026
      no_prev_key)
14028
14027
    return 1;
14029
14028
  return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
14032
14031
 
14033
14032
 
14034
14033
bool
14035
 
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
 
14034
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
14036
14035
{
14037
 
  enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
14038
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
14036
  enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
 
14037
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
14039
14038
  bool result= 0;
14040
14039
 
14041
14040
  for (store_key **copy=ref->key_copy ; *copy ; copy++)
14046
14045
      break;
14047
14046
    }
14048
14047
  }
14049
 
  thd->count_cuted_fields= save_count_cuted_fields;
 
14048
  session->count_cuted_fields= save_count_cuted_fields;
14050
14049
  return result;
14051
14050
}
14052
14051
 
14071
14070
 
14072
14071
  ref_pointer_array and all_fields are updated.
14073
14072
 
14074
 
  @param[in] thd                     Pointer to current thread structure
 
14073
  @param[in] session                 Pointer to current thread structure
14075
14074
  @param[in,out] ref_pointer_array  All select, group and order by fields
14076
14075
  @param[in] tables                 List of tables to search in (usually
14077
14076
    FROM clause)
14089
14088
*/
14090
14089
 
14091
14090
static bool
14092
 
find_order_in_list(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14091
find_order_in_list(Session *session, Item **ref_pointer_array, TableList *tables,
14093
14092
                   order_st *order, List<Item> &fields, List<Item> &all_fields,
14094
14093
                   bool is_group_field)
14095
14094
{
14110
14109
    if (!count || count > fields.elements)
14111
14110
    {
14112
14111
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
14113
 
               order_item->full_name(), thd->where);
 
14112
               order_item->full_name(), session->where);
14114
14113
      return true;
14115
14114
    }
14116
14115
    order->item= ref_pointer_array + count - 1;
14136
14135
      for this name (in case if we would perform lookup in all tables).
14137
14136
    */
14138
14137
    if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14139
 
        order_item->fix_fields(thd, order->item))
 
14138
        order_item->fix_fields(session, order->item))
14140
14139
      return true;
14141
14140
 
14142
14141
    /* Lookup the current GROUP field in the FROM clause. */
14145
14144
    if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14146
14145
        order_item_type == Item::REF_ITEM)
14147
14146
    {
14148
 
      from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
 
14147
      from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
14149
14148
                                       NULL, &view_ref, IGNORE_ERRORS, true,
14150
14149
                                       false);
14151
14150
      if (!from_field)
14185
14184
        warning so the user knows that the field from the FROM clause
14186
14185
        overshadows the column reference from the SELECT list.
14187
14186
      */
14188
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
 
14187
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14189
14188
                          ER(ER_NON_UNIQ_ERROR),
14190
14189
                          ((Item_ident*) order_item)->field_name,
14191
 
                          current_thd->where);
 
14190
                          current_session->where);
14192
14191
    }
14193
14192
  }
14194
14193
 
14205
14204
    arguments for which fix_fields already was called.
14206
14205
  */
14207
14206
  if (!order_item->fixed &&
14208
 
      (order_item->fix_fields(thd, order->item) ||
 
14207
      (order_item->fix_fields(session, order->item) ||
14209
14208
       (order_item= *order->item)->check_cols(1) ||
14210
 
       thd->is_fatal_error))
 
14209
       session->is_fatal_error))
14211
14210
    return true; /* Wrong field. */
14212
14211
 
14213
14212
  uint32_t el= all_fields.elements;
14225
14224
  the field list.
14226
14225
*/
14227
14226
 
14228
 
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14227
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14229
14228
                List<Item> &fields, List<Item> &all_fields, order_st *order)
14230
14229
{
14231
 
  thd->where="order clause";
 
14230
  session->where="order clause";
14232
14231
  for (; order; order=order->next)
14233
14232
  {
14234
 
    if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
 
14233
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
14235
14234
                           all_fields, false))
14236
14235
      return 1;
14237
14236
  }
14242
14241
/**
14243
14242
  Intitialize the GROUP BY list.
14244
14243
 
14245
 
  @param thd                    Thread handler
 
14244
  @param session                        Thread handler
14246
14245
  @param ref_pointer_array      We store references to all fields that was
14247
14246
                               not in 'fields' here.
14248
14247
  @param fields         All fields in the select part. Any item in
14266
14265
*/
14267
14266
 
14268
14267
int
14269
 
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14268
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
14270
14269
            List<Item> &fields, List<Item> &all_fields, order_st *order,
14271
14270
            bool *hidden_group_fields)
14272
14271
{
14278
14277
 
14279
14278
  uint32_t org_fields=all_fields.elements;
14280
14279
 
14281
 
  thd->where="group statement";
 
14280
  session->where="group statement";
14282
14281
  for (ord= order; ord; ord= ord->next)
14283
14282
  {
14284
 
    if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
 
14283
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
14285
14284
                           all_fields, true))
14286
14285
      return 1;
14287
14286
    (*ord->item)->marker= UNDEF_POS;            /* Mark found */
14312
14311
    Item_field *field;
14313
14312
    int cur_pos_in_select_list= 0;
14314
14313
    List_iterator<Item> li(fields);
14315
 
    List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
 
14314
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
14316
14315
 
14317
14316
    field= naf_it++;
14318
14317
    while (field && (item=li++))
14363
14362
*/
14364
14363
 
14365
14364
static order_st *
14366
 
create_distinct_group(THD *thd, Item **ref_pointer_array,
 
14365
create_distinct_group(Session *session, Item **ref_pointer_array,
14367
14366
                      order_st *order_list, List<Item> &fields,
14368
14367
                      List<Item> &all_fields __attribute__((unused)),
14369
14368
                      bool *all_order_by_fields_used)
14381
14380
  {
14382
14381
    if (order->in_field_list)
14383
14382
    {
14384
 
      order_st *ord=(order_st*) thd->memdup((char*) order,sizeof(order_st));
 
14383
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
14385
14384
      if (!ord)
14386
14385
        return 0;
14387
14386
      *prev=ord;
14406
14405
        if ((*ord_iter->item)->eq(item, 1))
14407
14406
          goto next_item;
14408
14407
      
14409
 
      order_st *ord=(order_st*) thd->calloc(sizeof(order_st));
 
14408
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
14410
14409
      if (!ord)
14411
14410
        return 0;
14412
14411
 
14656
14655
  {
14657
14656
    for (; group ; group=group->next)
14658
14657
    {
14659
 
      Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
 
14658
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
14660
14659
      if (!tmp || join->group_fields.push_front(tmp))
14661
14660
        return true;
14662
14661
    }
14703
14702
  Change old item_field to use a new field with points at saved fieldvalue
14704
14703
  This function is only called before use of send_fields.
14705
14704
 
14706
 
  @param thd                   THD pointer
 
14705
  @param session                   Session pointer
14707
14706
  @param param                 temporary table parameters
14708
14707
  @param ref_pointer_array     array of pointers to top elements of filed list
14709
14708
  @param res_selected_fields   new list of items of select item list
14724
14723
*/
14725
14724
 
14726
14725
bool
14727
 
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
 
14726
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
14728
14727
                  Item **ref_pointer_array,
14729
14728
                  List<Item> &res_selected_fields, List<Item> &res_all_fields,
14730
14729
                  uint32_t elements, List<Item> &all_fields)
14751
14750
    if (real_pos->type() == Item::FIELD_ITEM)
14752
14751
    {
14753
14752
      Item_field *item;
14754
 
      if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
 
14753
      if (!(item= new Item_field(session, ((Item_field*) real_pos))))
14755
14754
        goto err;
14756
14755
      if (pos->type() == Item::REF_ITEM)
14757
14756
      {
14785
14784
           saved value
14786
14785
        */
14787
14786
        field= item->field;
14788
 
        item->result_field=field->new_field(thd->mem_root,field->table, 1);
 
14787
        item->result_field=field->new_field(session->mem_root,field->table, 1);
14789
14788
        /*
14790
14789
          We need to allocate one extra byte for null handling and
14791
14790
          another extra byte to not get warnings from purify in
14919
14918
  }
14920
14919
 
14921
14920
  /* This must use calloc() as rollup_make_fields depends on this */
14922
 
  sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
 
14921
  sum_funcs= (Item_sum**) session->calloc(sizeof(Item_sum**) * (func_count+1) +
14923
14922
                                      sizeof(Item_sum***) * (group_parts+1));
14924
14923
  sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
14925
14924
  return(sum_funcs == 0);
14980
14979
  Change all funcs and sum_funcs to fields in tmp table, and create
14981
14980
  new list of all items.
14982
14981
 
14983
 
  @param thd                   THD pointer
 
14982
  @param session                   Session pointer
14984
14983
  @param ref_pointer_array     array of pointers to top elements of filed list
14985
14984
  @param res_selected_fields   new list of items of select item list
14986
14985
  @param res_all_fields        new list of all items
14994
14993
*/
14995
14994
 
14996
14995
static bool
14997
 
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
 
14996
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
14998
14997
                         List<Item> &res_selected_fields,
14999
14998
                         List<Item> &res_all_fields,
15000
14999
                         uint32_t elements, List<Item> &all_fields)
15018
15017
    {
15019
15018
      if (item->type() == Item::FIELD_ITEM)
15020
15019
      {
15021
 
        item_field= item->get_tmp_table_item(thd);
 
15020
        item_field= item->get_tmp_table_item(session);
15022
15021
      }
15023
15022
      else if ((field= item->get_tmp_table_field()))
15024
15023
      {
15060
15059
  Change all sum_func refs to fields to point at fields in tmp table.
15061
15060
  Change all funcs to be fields in tmp table.
15062
15061
 
15063
 
  @param thd                   THD pointer
 
15062
  @param session                   Session pointer
15064
15063
  @param ref_pointer_array     array of pointers to top elements of filed list
15065
15064
  @param res_selected_fields   new list of items of select item list
15066
15065
  @param res_all_fields        new list of all items
15074
15073
*/
15075
15074
 
15076
15075
static bool
15077
 
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
 
15076
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
15078
15077
                          List<Item> &res_selected_fields,
15079
15078
                          List<Item> &res_all_fields, uint32_t elements,
15080
15079
                          List<Item> &all_fields)
15087
15086
  uint32_t i, border= all_fields.elements - elements;
15088
15087
  for (i= 0; (item= it++); i++)
15089
15088
  {
15090
 
    res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
 
15089
    res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
15091
15090
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15092
15091
      new_item;
15093
15092
  }
15097
15096
    itr++;
15098
15097
  itr.sublist(res_selected_fields, elements);
15099
15098
 
15100
 
  return thd->is_fatal_error;
 
15099
  return session->is_fatal_error;
15101
15100
}
15102
15101
 
15103
15102
 
15110
15109
/**
15111
15110
  Call ::setup for all sum functions.
15112
15111
 
15113
 
  @param thd           thread handler
 
15112
  @param session           thread handler
15114
15113
  @param func_ptr      sum function list
15115
15114
 
15116
15115
  @retval
15119
15118
    true   error
15120
15119
*/
15121
15120
 
15122
 
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
 
15121
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr)
15123
15122
{
15124
15123
  Item_sum *func;
15125
15124
  while ((func= *(func_ptr++)))
15126
15125
  {
15127
 
    if (func->setup(thd))
 
15126
    if (func->setup(session))
15128
15127
      return(true);
15129
15128
  }
15130
15129
  return(false);
15207
15206
  currenct select for the table.
15208
15207
*/
15209
15208
 
15210
 
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
 
15209
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab)
15211
15210
{
15212
15211
  if (!join_tab->ref.key_parts)
15213
15212
    return(false);
15225
15224
    Item *value=join_tab->ref.items[i];
15226
15225
    cond->add(new Item_func_equal(new Item_field(field), value));
15227
15226
  }
15228
 
  if (thd->is_fatal_error)
 
15227
  if (session->is_fatal_error)
15229
15228
    return(true);
15230
15229
 
15231
15230
  if (!cond->fixed)
15232
 
    cond->fix_fields(thd, (Item**)&cond);
 
15231
    cond->fix_fields(session, (Item**)&cond);
15233
15232
  if (join_tab->select)
15234
15233
  {
15235
15234
    error=(int) cond->add(join_tab->select->cond);
15246
15245
/**
15247
15246
  Free joins of subselect of this select.
15248
15247
 
15249
 
  @param thd      THD pointer
 
15248
  @param session      Session pointer
15250
15249
  @param select   pointer to st_select_lex which subselects joins we will free
15251
15250
*/
15252
15251
 
15253
 
void free_underlaid_joins(THD *thd __attribute__((unused)),
 
15252
void free_underlaid_joins(Session *session __attribute__((unused)),
15254
15253
                          SELECT_LEX *select)
15255
15254
{
15256
15255
  for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15288
15287
    This substitution is needed GROUP BY queries with ROLLUP if
15289
15288
    SELECT list contains expressions over group by attributes.
15290
15289
 
15291
 
  @param thd                  reference to the context
 
15290
  @param session                  reference to the context
15292
15291
  @param expr                 expression to make replacement
15293
15292
  @param group_list           list of references to group by items
15294
15293
  @param changed        out:  returns 1 if item contains a replaced field item
15303
15302
    1   on error
15304
15303
*/
15305
15304
 
15306
 
static bool change_group_ref(THD *thd, Item_func *expr, order_st *group_list,
 
15305
static bool change_group_ref(Session *session, Item_func *expr, order_st *group_list,
15307
15306
                             bool *changed)
15308
15307
{
15309
15308
  if (expr->arg_count)
15310
15309
  {
15311
 
    Name_resolution_context *context= &thd->lex->current_select->context;
 
15310
    Name_resolution_context *context= &session->lex->current_select->context;
15312
15311
    Item **arg,**arg_end;
15313
15312
    bool arg_changed= false;
15314
15313
    for (arg= expr->arguments(),
15327
15326
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15328
15327
                                        item->name)))
15329
15328
              return 1;                                 // fatal_error is set
15330
 
            thd->change_item_tree(arg, new_item);
 
15329
            session->change_item_tree(arg, new_item);
15331
15330
            arg_changed= true;
15332
15331
          }
15333
15332
        }
15334
15333
      }
15335
15334
      else if (item->type() == Item::FUNC_ITEM)
15336
15335
      {
15337
 
        if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
 
15336
        if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
15338
15337
          return 1;
15339
15338
      }
15340
15339
    }
15364
15363
  */
15365
15364
  tmp_table_param.group_parts= send_group_parts;
15366
15365
 
15367
 
  if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
 
15366
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
15368
15367
                                                sizeof(Item**) +
15369
15368
                                                sizeof(List<Item>) +
15370
15369
                                                ref_pointer_array_size)
15381
15380
  */
15382
15381
  for (i= 0 ; i < send_group_parts ; i++)
15383
15382
  {
15384
 
    rollup.null_items[i]= new (thd->mem_root) Item_null_result();
 
15383
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
15385
15384
    List<Item> *rollup_fields= &rollup.fields[i];
15386
15385
    rollup_fields->empty();
15387
15386
    rollup.ref_pointer_arrays[i]= ref_array;
15423
15422
          Item* new_item= new Item_func_rollup_const(item);
15424
15423
          if (!new_item)
15425
15424
            return 1;
15426
 
          new_item->fix_fields(thd, (Item **) 0);
15427
 
          thd->change_item_tree(it.ref(), new_item);
 
15425
          new_item->fix_fields(session, (Item **) 0);
 
15426
          session->change_item_tree(it.ref(), new_item);
15428
15427
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15429
15428
          { 
15430
15429
            if (*tmp->item == item)
15431
 
              thd->change_item_tree(tmp->item, new_item);
 
15430
              session->change_item_tree(tmp->item, new_item);
15432
15431
          }
15433
15432
        }
15434
15433
      }
15436
15435
    if (item->type() == Item::FUNC_ITEM && !found_in_group)
15437
15436
    {
15438
15437
      bool changed= false;
15439
 
      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
 
15438
      if (change_group_ref(session, (Item_func *) item, group_list, &changed))
15440
15439
        return 1;
15441
15440
      /*
15442
15441
        We have to prevent creation of a field in a temporary table for
15539
15538
          sub select.  Fortunately it's not common to have rollup in
15540
15539
          sub selects.
15541
15540
        */
15542
 
        item= item->copy_or_same(thd);
 
15541
        item= item->copy_or_same(session);
15543
15542
        ((Item_sum*) item)->make_unique();
15544
15543
        *(*func)= (Item_sum*) item;
15545
15544
        (*func)++;
15557
15556
              This is an element that is used by the GROUP BY and should be
15558
15557
              set to NULL in this level
15559
15558
            */
15560
 
            Item_null_result *null_item= new (thd->mem_root) Item_null_result();
 
15559
            Item_null_result *null_item= new (session->mem_root) Item_null_result();
15561
15560
            if (!null_item)
15562
15561
              return 1;
15563
15562
            item->maybe_null= 1;                // Value will be null sometimes
15663
15662
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15664
15663
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15665
15664
      {
15666
 
        if (create_myisam_from_heap(thd, table_arg, 
 
15665
        if (create_myisam_from_heap(session, table_arg, 
15667
15666
                                    tmp_table_param.start_recinfo,
15668
15667
                                    &tmp_table_param.recinfo,
15669
15668
                                    write_error, 0))
15705
15704
{
15706
15705
  List<Item> field_list;
15707
15706
  List<Item> item_list;
15708
 
  THD *thd=join->thd;
 
15707
  Session *session=join->session;
15709
15708
  select_result *result=join->result;
15710
15709
  Item *item_null= new Item_null();
15711
15710
  const CHARSET_INFO * const cs= system_charset_info;
15712
15711
  int quick_type;
15713
15712
  /* Don't log this into the slow query log */
15714
 
  thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
 
15713
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15715
15714
  join->unit->offset_limit_cnt= 0;
15716
15715
 
15717
15716
  /* 
15718
15717
    NOTE: the number/types of items pushed into item_list must be in sync with
15719
 
    EXPLAIN column types as they're "defined" in THD::send_explain_fields()
 
15718
    EXPLAIN column types as they're "defined" in Session::send_explain_fields()
15720
15719
  */
15721
15720
  if (message)
15722
15721
  {
15726
15725
                                        strlen(join->select_lex->type), cs));
15727
15726
    for (uint32_t i=0 ; i < 7; i++)
15728
15727
      item_list.push_back(item_null);
15729
 
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15728
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
15730
15729
      item_list.push_back(item_null);
15731
15730
  
15732
15731
    item_list.push_back(new Item_string(message,strlen(message),cs));
15786
15785
    /* ref */
15787
15786
    item_list.push_back(item_null);
15788
15787
    /* in_rows */
15789
 
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15788
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
15790
15789
      item_list.push_back(item_null);
15791
15790
    /* rows */
15792
15791
    item_list.push_back(item_null);
15957
15956
      if (table_list->schema_table)
15958
15957
      {
15959
15958
        /* in_rows */
15960
 
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15959
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
15961
15960
          item_list.push_back(item_null);
15962
15961
        /* rows */
15963
15962
        item_list.push_back(item_null);
15977
15976
                                         MY_INT64_NUM_DECIMAL_DIGITS));
15978
15977
 
15979
15978
        /* Add "filtered" field to item_list. */
15980
 
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15979
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
15981
15980
        {
15982
15981
          float f= 0.0; 
15983
15982
          if (examined_rows)
16050
16049
          {
16051
16050
            const COND *pushed_cond= tab->table->file->pushed_cond;
16052
16051
 
16053
 
            if (thd->variables.engine_condition_pushdown && pushed_cond)
 
16052
            if (session->variables.engine_condition_pushdown && pushed_cond)
16054
16053
            {
16055
16054
              extra.append(STRING_WITH_LEN("; Using where with pushed "
16056
16055
                                           "condition"));
16057
 
              if (thd->lex->describe & DESCRIBE_EXTENDED)
 
16056
              if (session->lex->describe & DESCRIBE_EXTENDED)
16058
16057
              {
16059
16058
                extra.append(STRING_WITH_LEN(": "));
16060
16059
                ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16109
16108
          need_order=0;
16110
16109
          extra.append(STRING_WITH_LEN("; Using filesort"));
16111
16110
        }
16112
 
        if (distinct & test_all_bits(used_tables,thd->used_tables))
 
16111
        if (distinct & test_all_bits(used_tables,session->used_tables))
16113
16112
          extra.append(STRING_WITH_LEN("; Distinct"));
16114
16113
 
16115
16114
        if (tab->insideout_match_tab)
16171
16170
       unit;
16172
16171
       unit= unit->next_unit())
16173
16172
  {
16174
 
    if (mysql_explain_union(thd, unit, result))
 
16173
    if (mysql_explain_union(session, unit, result))
16175
16174
      return;
16176
16175
  }
16177
16176
  return;
16178
16177
}
16179
16178
 
16180
16179
 
16181
 
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
 
16180
bool mysql_explain_union(Session *session, SELECT_LEX_UNIT *unit, select_result *result)
16182
16181
{
16183
16182
  bool res= 0;
16184
16183
  SELECT_LEX *first= unit->first_select();
16189
16188
  {
16190
16189
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16191
16190
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16192
 
    sl->type= (((&thd->lex->select_lex)==sl)?
 
16191
    sl->type= (((&session->lex->select_lex)==sl)?
16193
16192
               (sl->first_inner_unit() || sl->next_select() ? 
16194
16193
                "PRIMARY" : "SIMPLE"):
16195
16194
               ((sl == first)?
16210
16209
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16211
16210
    unit->fake_select_lex->type= "UNION RESULT";
16212
16211
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
16213
 
    if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
 
16212
    if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16214
16213
      res= unit->exec();
16215
16214
    res|= unit->cleanup();
16216
16215
  }
16217
16216
  else
16218
16217
  {
16219
 
    thd->lex->current_select= first;
 
16218
    session->lex->current_select= first;
16220
16219
    unit->set_limit(unit->global_parameters);
16221
 
    res= mysql_select(thd, &first->ref_pointer_array,
 
16220
    res= mysql_select(session, &first->ref_pointer_array,
16222
16221
                        (TableList*) first->table_list.first,
16223
16222
                        first->with_wild, first->item_list,
16224
16223
                        first->where,
16227
16226
                        (order_st*) first->order_list.first,
16228
16227
                        (order_st*) first->group_list.first,
16229
16228
                        first->having,
16230
 
                        (order_st*) thd->lex->proc_list.first,
16231
 
                        first->options | thd->options | SELECT_DESCRIBE,
 
16229
                        (order_st*) session->lex->proc_list.first,
 
16230
                        first->options | session->options | SELECT_DESCRIBE,
16232
16231
                        result, unit, first);
16233
16232
  }
16234
 
  return(res || thd->is_error());
 
16233
  return(res || session->is_error());
16235
16234
}
16236
16235
 
16237
16236
 
16238
 
static void print_table_array(THD *thd, String *str, TableList **table, 
 
16237
static void print_table_array(Session *session, String *str, TableList **table, 
16239
16238
                              TableList **end)
16240
16239
{
16241
 
  (*table)->print(thd, str, QT_ORDINARY);
 
16240
  (*table)->print(session, str, QT_ORDINARY);
16242
16241
 
16243
16242
  for (TableList **tbl= table + 1; tbl < end; tbl++)
16244
16243
  {
16254
16253
      str->append(STRING_WITH_LEN(" semi join "));
16255
16254
    else
16256
16255
      str->append(STRING_WITH_LEN(" join "));
16257
 
    curr->print(thd, str, QT_ORDINARY);
 
16256
    curr->print(session, str, QT_ORDINARY);
16258
16257
    if (curr->on_expr)
16259
16258
    {
16260
16259
      str->append(STRING_WITH_LEN(" on("));
16267
16266
 
16268
16267
/**
16269
16268
  Print joins from the FROM clause.
16270
 
  @param thd     thread handler
 
16269
  @param session     thread handler
16271
16270
  @param str     string where table should be printed
16272
16271
  @param tables  list of tables in join
16273
16272
  @query_type    type of the query is being generated
16274
16273
*/
16275
16274
 
16276
 
static void print_join(THD *thd,
 
16275
static void print_join(Session *session,
16277
16276
                       String *str,
16278
16277
                       List<TableList> *tables,
16279
16278
                       enum_query_type query_type __attribute__((unused)))
16280
16279
{
16281
16280
  /* List is reversed => we should reverse it before using */
16282
16281
  List_iterator_fast<TableList> ti(*tables);
16283
 
  TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
 
16282
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16284
16283
                                                tables->elements);
16285
16284
  if (table == 0)
16286
16285
    return;  // out of memory
16307
16306
    }
16308
16307
  }
16309
16308
  assert(tables->elements >= 1);
16310
 
  print_table_array(thd, str, table, table + tables->elements);
 
16309
  print_table_array(session, str, table, table + tables->elements);
16311
16310
}
16312
16311
 
16313
16312
 
16316
16315
 
16317
16316
  @details Prints out the USE|FORCE|IGNORE index hint.
16318
16317
 
16319
 
  @param      thd         the current thread
 
16318
  @param      session         the current thread
16320
16319
  @param[out] str         appends the index hint here
16321
16320
  @param      hint        what the hint is (as string : "USE INDEX"|
16322
16321
                          "FORCE INDEX"|"IGNORE INDEX")
16325
16324
*/
16326
16325
 
16327
16326
void 
16328
 
Index_hint::print(THD *thd, String *str)
 
16327
Index_hint::print(Session *session, String *str)
16329
16328
{
16330
16329
  switch (type)
16331
16330
  {
16336
16335
  str->append (STRING_WITH_LEN(" ("));
16337
16336
  if (key_name.length)
16338
16337
  {
16339
 
    if (thd && !my_strnncoll(system_charset_info,
 
16338
    if (session && !my_strnncoll(system_charset_info,
16340
16339
                             (const unsigned char *)key_name.str, key_name.length, 
16341
16340
                             (const unsigned char *)primary_key_name, 
16342
16341
                             strlen(primary_key_name)))
16343
16342
      str->append(primary_key_name);
16344
16343
    else
16345
 
      append_identifier(thd, str, key_name.str, key_name.length);
 
16344
      append_identifier(session, str, key_name.str, key_name.length);
16346
16345
  }
16347
16346
  str->append(')');
16348
16347
}
16354
16353
  @param str   string where table should be printed
16355
16354
*/
16356
16355
 
16357
 
void TableList::print(THD *thd, String *str, enum_query_type query_type)
 
16356
void TableList::print(Session *session, String *str, enum_query_type query_type)
16358
16357
{
16359
16358
  if (nested_join)
16360
16359
  {
16361
16360
    str->append('(');
16362
 
    print_join(thd, str, &nested_join->join_list, query_type);
 
16361
    print_join(session, str, &nested_join->join_list, query_type);
16363
16362
    str->append(')');
16364
16363
  }
16365
16364
  else
16377
16376
    {
16378
16377
      // A normal table
16379
16378
      {
16380
 
        append_identifier(thd, str, db, db_length);
 
16379
        append_identifier(session, str, db, db_length);
16381
16380
        str->append('.');
16382
16381
      }
16383
16382
      if (schema_table)
16384
16383
      {
16385
 
        append_identifier(thd, str, schema_table_name,
 
16384
        append_identifier(session, str, schema_table_name,
16386
16385
                          strlen(schema_table_name));
16387
16386
        cmp_name= schema_table_name;
16388
16387
      }
16389
16388
      else
16390
16389
      {
16391
 
        append_identifier(thd, str, table_name, table_name_length);
 
16390
        append_identifier(session, str, table_name, table_name_length);
16392
16391
        cmp_name= table_name;
16393
16392
      }
16394
16393
    }
16408
16407
        }
16409
16408
      }
16410
16409
 
16411
 
      append_identifier(thd, str, t_alias, strlen(t_alias));
 
16410
      append_identifier(session, str, t_alias, strlen(t_alias));
16412
16411
    }
16413
16412
 
16414
16413
    if (index_hints)
16419
16418
      while ((hint= it++))
16420
16419
      {
16421
16420
        str->append (STRING_WITH_LEN(" "));
16422
 
        hint->print (thd, str);
 
16421
        hint->print (session, str);
16423
16422
      }
16424
16423
    }
16425
16424
  }
16426
16425
}
16427
16426
 
16428
16427
 
16429
 
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
 
16428
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
16430
16429
{
16431
 
  /* QQ: thd may not be set for sub queries, but this should be fixed */
16432
 
  if (!thd)
16433
 
    thd= current_thd;
 
16430
  /* QQ: session may not be set for sub queries, but this should be fixed */
 
16431
  if (!session)
 
16432
    session= current_session;
16434
16433
 
16435
16434
  str->append(STRING_WITH_LEN("select "));
16436
16435
 
16437
16436
  /* First add options */
16438
16437
  if (options & SELECT_STRAIGHT_JOIN)
16439
16438
    str->append(STRING_WITH_LEN("straight_join "));
16440
 
  if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16441
 
      (this == &thd->lex->select_lex))
 
16439
  if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
 
16440
      (this == &session->lex->select_lex))
16442
16441
    str->append(STRING_WITH_LEN("high_priority "));
16443
16442
  if (options & SELECT_DISTINCT)
16444
16443
    str->append(STRING_WITH_LEN("distinct "));
16472
16471
  {
16473
16472
    str->append(STRING_WITH_LEN(" from "));
16474
16473
    /* go through join tree */
16475
 
    print_join(thd, str, &top_join_list, query_type);
 
16474
    print_join(session, str, &top_join_list, query_type);
16476
16475
  }
16477
16476
  else if (where)
16478
16477
  {
16535
16534
  }
16536
16535
 
16537
16536
  // limit
16538
 
  print_limit(thd, str, query_type);
 
16537
  print_limit(session, str, query_type);
16539
16538
 
16540
16539
  // PROCEDURE unsupported here
16541
16540
}