~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2008-10-20 08:48:34 UTC
  • mfrom: (520.1.22 drizzle)
  • Revision ID: monty@inaugust.com-20081020084834-xpb3w01vkcp55o02
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
44
44
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds,
45
45
                                 DYNAMIC_ARRAY *keyuse);
46
 
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
 
46
static bool update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,
47
47
                                JOIN_TAB *join_tab,
48
48
                                uint32_t tables, COND *conds,
49
49
                                COND_EQUAL *cond_equal,
55
55
                               table_map used_tables);
56
56
static bool choose_plan(JOIN *join,table_map join_tables);
57
57
 
58
 
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
 
58
static void best_access_path(JOIN *join, JOIN_TAB *s, Session *session,
59
59
                             table_map remaining_tables, uint32_t idx,
60
60
                             double record_count, double read_time);
61
61
static void optimize_straight_join(JOIN *join, table_map join_tables);
78
78
static uint32_t cache_record_length(JOIN *join,uint32_t index);
79
79
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
80
80
static bool get_best_combination(JOIN *join);
81
 
static store_key *get_store_key(THD *thd,
 
81
static store_key *get_store_key(Session *session,
82
82
                                KEYUSE *keyuse, table_map used_tables,
83
83
                                KEY_PART_INFO *key_part, unsigned char *key_buff,
84
84
                                uint32_t maybe_null);
95
95
                            List<Item> &fields, bool send_row,
96
96
                            uint64_t select_options, const char *info,
97
97
                            Item *having);
98
 
static COND *build_equal_items(THD *thd, COND *cond,
 
98
static COND *build_equal_items(Session *session, COND *cond,
99
99
                               COND_EQUAL *inherited,
100
100
                               List<TableList> *join_list,
101
101
                               COND_EQUAL **cond_equal_ref);
168
168
                          bool (*find_func) (Field *, void *), void *data);
169
169
static bool find_field_in_item_list (Field *field, void *data);
170
170
static bool find_field_in_order_list (Field *field, void *data);
171
 
static int create_sort_index(THD *thd, JOIN *join, order_st *order,
 
171
static int create_sort_index(Session *session, JOIN *join, order_st *order,
172
172
                             ha_rows filesort_limit, ha_rows select_limit,
173
173
                             bool is_order_by);
174
174
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields,
175
175
                             Item *having);
176
 
static int remove_dup_with_compare(THD *thd, Table *entry, Field **field,
 
176
static int remove_dup_with_compare(Session *session, Table *entry, Field **field,
177
177
                                   ulong offset,Item *having);
178
 
static int remove_dup_with_hash_index(THD *thd,Table *table,
 
178
static int remove_dup_with_hash_index(Session *session,Table *table,
179
179
                                      uint32_t field_count, Field **first_field,
180
180
 
181
181
                                      ulong key_length,Item *having);
182
 
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count);
 
182
static int join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count);
183
183
static ulong used_blob_length(CACHE_FIELD **ptr);
184
184
static bool store_record_in_cache(JOIN_CACHE *cache);
185
185
static void reset_cache_read(JOIN_CACHE *cache);
186
186
static void reset_cache_write(JOIN_CACHE *cache);
187
187
static void read_cached_record(JOIN_TAB *tab);
188
188
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
189
 
static order_st *create_distinct_group(THD *thd, Item **ref_pointer_array,
 
189
static order_st *create_distinct_group(Session *session, Item **ref_pointer_array,
190
190
                                    order_st *order, List<Item> &fields,
191
191
                                    List<Item> &all_fields,
192
192
                                    bool *all_order_by_fields_used);
196
196
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
197
197
static bool alloc_group_fields(JOIN *join,order_st *group);
198
198
// Create list for using with tempory table
199
 
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
 
199
static bool change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
200
200
                                     List<Item> &new_list1,
201
201
                                     List<Item> &new_list2,
202
202
                                     uint32_t elements, List<Item> &items);
203
203
// Create list for using with tempory table
204
 
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
 
204
static bool change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
205
205
                                      List<Item> &new_list1,
206
206
                                      List<Item> &new_list2,
207
207
                                      uint32_t elements, List<Item> &items);
208
208
static void init_tmptable_sum_functions(Item_sum **func);
209
209
static void update_tmptable_sum_func(Item_sum **func,Table *tmp_table);
210
210
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
211
 
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
212
 
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
 
211
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab);
 
212
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr);
213
213
static bool init_sum_functions(Item_sum **func, Item_sum **end);
214
214
static bool update_sum_func(Item_sum **func);
215
215
void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
237
237
  This handles SELECT with and without UNION.
238
238
*/
239
239
 
240
 
bool handle_select(THD *thd, LEX *lex, select_result *result,
 
240
bool handle_select(Session *session, LEX *lex, select_result *result,
241
241
                   ulong setup_tables_done_option)
242
242
{
243
243
  bool res;
246
246
 
247
247
  if (select_lex->master_unit()->is_union() || 
248
248
      select_lex->master_unit()->fake_select_lex)
249
 
    res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
 
249
    res= mysql_union(session, lex, result, &lex->unit, setup_tables_done_option);
250
250
  else
251
251
  {
252
252
    SELECT_LEX_UNIT *unit= &lex->unit;
253
253
    unit->set_limit(unit->global_parameters);
254
 
    thd->thd_marker= 0;
 
254
    session->session_marker= 0;
255
255
    /*
256
256
      'options' of mysql_select will be set in JOIN, as far as JOIN for
257
257
      every PS/SP execution new, we will not need reset this flag if 
258
258
      setup_tables_done_option changed for next rexecution
259
259
    */
260
 
    res= mysql_select(thd, &select_lex->ref_pointer_array,
 
260
    res= mysql_select(session, &select_lex->ref_pointer_array,
261
261
                      (TableList*) select_lex->table_list.first,
262
262
                      select_lex->with_wild, select_lex->item_list,
263
263
                      select_lex->where,
267
267
                      (order_st*) select_lex->group_list.first,
268
268
                      select_lex->having,
269
269
                      (order_st*) lex->proc_list.first,
270
 
                      select_lex->options | thd->options |
 
270
                      select_lex->options | session->options |
271
271
                      setup_tables_done_option,
272
272
                      result, unit, select_lex);
273
273
  }
274
 
  res|= thd->is_error();
 
274
  res|= session->is_error();
275
275
  if (unlikely(res))
276
276
    result->abort();
277
277
 
285
285
 
286
286
  SYNOPSIS
287
287
    fix_inner_refs()
288
 
    thd               Thread handle
 
288
    session               Thread handle
289
289
    all_fields        List of all fields used in select
290
290
    select            Current select
291
291
    ref_pointer_array Array of references to Items used in current select
322
322
*/
323
323
 
324
324
bool
325
 
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
 
325
fix_inner_refs(Session *session, List<Item> &all_fields, SELECT_LEX *select,
326
326
                 Item **ref_pointer_array)
327
327
{
328
328
  Item_outer_ref *ref;
383
383
    ref->outer_ref= new_ref;
384
384
    ref->ref= &ref->outer_ref;
385
385
 
386
 
    if (!ref->fixed && ref->fix_fields(thd, 0))
 
386
    if (!ref->fixed && ref->fix_fields(session, 0))
387
387
      return true;
388
 
    thd->used_tables|= item->used_tables();
 
388
    session->used_tables|= item->used_tables();
389
389
  }
390
390
  return res;
391
391
}
393
393
/**
394
394
  Function to setup clauses without sum functions.
395
395
*/
396
 
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
 
396
inline int setup_without_group(Session *session, Item **ref_pointer_array,
397
397
                               TableList *tables,
398
398
                               TableList *leaves,
399
399
                               List<Item> &fields,
403
403
                               order_st *group, bool *hidden_group_fields)
404
404
{
405
405
  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,
 
406
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
 
407
 
 
408
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
409
  res= setup_conds(session, tables, leaves, conds);
 
410
 
 
411
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
412
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
413
413
                          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,
 
414
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
415
  res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
416
416
                          group, hidden_group_fields);
417
 
  thd->lex->allow_sum_func= save_allow_sum_func;
 
417
  session->lex->allow_sum_func= save_allow_sum_func;
418
418
  return(res);
419
419
}
420
420
 
459
459
  join_list= &select_lex->top_join_list;
460
460
  union_part= unit_arg->is_union();
461
461
 
462
 
  thd->lex->current_select->is_item_list_lookup= 1;
 
462
  session->lex->current_select->is_item_list_lookup= 1;
463
463
  /*
464
464
    If we have already executed SELECT, then it have not sense to prevent
465
465
    its table from update (see unique_table())
466
466
  */
467
 
  if (thd->derived_tables_processing)
 
467
  if (session->derived_tables_processing)
468
468
    select_lex->exclude_from_table_unique_test= true;
469
469
 
470
470
  /* Check that all tables, fields, conds and order are ok */
471
471
 
472
472
  if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
473
 
      setup_tables_and_check_access(thd, &select_lex->context, join_list,
 
473
      setup_tables_and_check_access(session, &select_lex->context, join_list,
474
474
                                    tables_list, &select_lex->leaf_tables,
475
475
                                    false))
476
476
      return(-1);
481
481
       table_ptr= table_ptr->next_leaf)
482
482
    tables++;
483
483
 
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,
 
484
  if (setup_wild(session, tables_list, fields_list, &all_fields, wild_num) ||
 
485
      select_lex->setup_ref_array(session, og_num) ||
 
486
      setup_fields(session, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
487
487
                   &all_fields, 1) ||
488
 
      setup_without_group(thd, (*rref_pointer_array), tables_list,
 
488
      setup_without_group(session, (*rref_pointer_array), tables_list,
489
489
                          select_lex->leaf_tables, fields_list,
490
490
                          all_fields, &conds, order, group_list,
491
491
                          &hidden_group_fields))
495
495
  
496
496
  if (having)
497
497
  {
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;
 
498
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
499
    session->where="having clause";
 
500
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
501
501
    select_lex->having_fix_field= 1;
502
502
    bool having_fix_rc= (!having->fixed &&
503
 
                         (having->fix_fields(thd, &having) ||
 
503
                         (having->fix_fields(session, &having) ||
504
504
                          having->check_cols(1)));
505
505
    select_lex->having_fix_field= 0;
506
 
    if (having_fix_rc || thd->is_error())
 
506
    if (having_fix_rc || session->is_error())
507
507
      return(-1);                               /* purecov: inspected */
508
 
    thd->lex->allow_sum_func= save_allow_sum_func;
 
508
    session->lex->allow_sum_func= save_allow_sum_func;
509
509
  }
510
510
 
511
511
  {
517
517
    */
518
518
    if ((subselect= select_lex->master_unit()->item))
519
519
    {
520
 
      bool do_semijoin= !test(thd->variables.optimizer_switch &
 
520
      bool do_semijoin= !test(session->variables.optimizer_switch &
521
521
                              OPTIMIZER_SWITCH_NO_SEMIJOIN);
522
522
      if (subselect->substype() == Item_subselect::IN_SUBS)
523
523
        in_subs= (Item_in_subselect*)subselect;
544
544
          !select_lex->master_unit()->first_select()->next_select() &&  // 2
545
545
          !select_lex->group_list.elements && !order &&                 // 3
546
546
          !having && !select_lex->with_sum_func &&                      // 4
547
 
          thd->thd_marker &&                                            // 5
 
547
          session->session_marker &&                                            // 5
548
548
          select_lex->outer_select()->join &&                           // (*)
549
549
          select_lex->master_unit()->first_select()->leaf_tables &&     // (**) 
550
550
          do_semijoin &&
552
552
      {
553
553
        {
554
554
          if (!in_subs->left_expr->fixed &&
555
 
               in_subs->left_expr->fix_fields(thd, &in_subs->left_expr))
 
555
               in_subs->left_expr->fix_fields(session, &in_subs->left_expr))
556
556
          {
557
557
            return(-1);
558
558
          }
570
570
        }
571
571
 
572
572
        /* 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;
 
573
        select_lex->outer_select()->join->sj_subselects.append(session->mem_root, in_subs);
 
574
        in_subs->expr_join_nest= (TableList*)session->session_marker;
575
575
      }
576
576
      else
577
577
      {
578
 
        bool do_materialize= !test(thd->variables.optimizer_switch &
 
578
        bool do_materialize= !test(session->variables.optimizer_switch &
579
579
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
580
580
        /*
581
581
          Check if the subquery predicate can be executed via materialization.
610
610
            in_subs  &&                                                   // 1
611
611
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
612
612
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
613
 
            thd->lex->sql_command == SQLCOM_SELECT)                       // *
 
613
            session->lex->sql_command == SQLCOM_SELECT)                       // *
614
614
        {
615
615
          if (in_subs->is_top_level_item() &&                             // 4
616
616
              !in_subs->is_correlated &&                                  // 5
635
635
    {
636
636
      Item *item= *ord->item;
637
637
      if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
638
 
        item->split_sum_func(thd, ref_pointer_array, all_fields);
 
638
        item->split_sum_func(session, ref_pointer_array, all_fields);
639
639
    }
640
640
  }
641
641
 
642
642
  if (having && having->with_sum_func)
643
 
    having->split_sum_func2(thd, ref_pointer_array, all_fields,
 
643
    having->split_sum_func2(session, ref_pointer_array, all_fields,
644
644
                            &having, true);
645
645
  if (select_lex->inner_sum_func_list)
646
646
  {
649
649
    do
650
650
    { 
651
651
      item_sum= item_sum->next;
652
 
      item_sum->split_sum_func2(thd, ref_pointer_array,
 
652
      item_sum->split_sum_func2(session, ref_pointer_array,
653
653
                                all_fields, item_sum->ref_by, false);
654
654
    } while (item_sum != end);
655
655
  }
656
656
 
657
657
  if (select_lex->inner_refs_list.elements &&
658
 
      fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
 
658
      fix_inner_refs(session, all_fields, select_lex, ref_pointer_array))
659
659
    return(-1);
660
660
 
661
661
  /*
1091
1091
    }
1092
1092
  }
1093
1093
 
1094
 
  THD *thd= join->thd;
 
1094
  Session *session= join->session;
1095
1095
  SJ_TMP_TABLE **next_sjtbl_ptr= &join->sj_tmp_tables;
1096
1096
  /*
1097
1097
    Second pass: setup the chosen strategies    
1145
1145
      {
1146
1146
        SJ_TMP_TABLE *sjtbl;
1147
1147
        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)))
 
1148
        if (!(sjtbl= (SJ_TMP_TABLE*)session->alloc(sizeof(SJ_TMP_TABLE))) ||
 
1149
            !(sjtbl->tabs= (SJ_TMP_TABLE::TAB*) session->alloc(tabs_size)))
1150
1150
          return(true);
1151
1151
        memcpy(sjtbl->tabs, sjtabs, tabs_size);
1152
1152
        sjtbl->tabs_end= sjtbl->tabs + (last_tab - sjtabs);
1159
1159
        sjtbl->next= NULL;
1160
1160
 
1161
1161
        sjtbl->tmp_table= 
1162
 
          create_duplicate_weedout_tmp_table(thd, 
 
1162
          create_duplicate_weedout_tmp_table(session, 
1163
1163
                                             sjtbl->rowid_len + 
1164
1164
                                             sjtbl->null_bytes,
1165
1165
                                             sjtbl);
1191
1191
  {
1192
1192
    if (sj_tbl->tmp_table)
1193
1193
    {
1194
 
      sj_tbl->tmp_table->free_tmp_table(join->thd);
 
1194
      sj_tbl->tmp_table->free_tmp_table(join->session);
1195
1195
    }
1196
1196
  }
1197
1197
  join->sj_tmp_tables= NULL;
1219
1219
    return(0);
1220
1220
  optimized= 1;
1221
1221
 
1222
 
  thd->set_proc_info("optimizing");
 
1222
  session->set_proc_info("optimizing");
1223
1223
  row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
1224
1224
              unit->select_limit_cnt);
1225
1225
  /* select_limit is used to decide if we are likely to scan the whole table */
1228
1228
    select_limit= HA_POS_ERROR;
1229
1229
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
1230
1230
  // Ignore errors of execution if option IGNORE present
1231
 
  if (thd->lex->ignore)
1232
 
    thd->lex->current_select->no_error= 1;
 
1231
  if (session->lex->ignore)
 
1232
    session->lex->current_select->no_error= 1;
1233
1233
 
1234
1234
#ifdef HAVE_REF_TO_FIELDS                       // Not done yet
1235
1235
  /* Add HAVING to WHERE if possible */
1246
1246
        Item_cond_and can't be fixed after creation, so we do not check
1247
1247
        conds->fixed
1248
1248
      */
1249
 
      conds->fix_fields(thd, &conds);
1250
 
      conds->change_ref_to_fields(thd, tables_list);
 
1249
      conds->fix_fields(session, &conds);
 
1250
      conds->change_ref_to_fields(session, tables_list);
1251
1251
      conds->top_level_item();
1252
1252
      having= 0;
1253
1253
    }
1259
1259
  build_bitmap_for_nested_joins(join_list, 0);
1260
1260
 
1261
1261
  conds= optimize_cond(this, conds, join_list, &cond_value);   
1262
 
  if (thd->is_error())
 
1262
  if (session->is_error())
1263
1263
  {
1264
1264
    error= 1;
1265
1265
    return(1);
1267
1267
 
1268
1268
  {
1269
1269
    having= optimize_cond(this, having, join_list, &having_value);
1270
 
    if (thd->is_error())
 
1270
    if (session->is_error())
1271
1271
    {
1272
1272
      error= 1;
1273
1273
      return(1);
1328
1328
        conjunctions.
1329
1329
        Preserve conditions for EXPLAIN.
1330
1330
      */
1331
 
      if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
 
1331
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
1332
1332
      {
1333
1333
        COND *table_independent_conds=
1334
1334
          make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
1345
1345
  sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
1346
1346
 
1347
1347
  /* Calculate how to do the join */
1348
 
  thd->set_proc_info("statistics");
 
1348
  session->set_proc_info("statistics");
1349
1349
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
1350
 
      thd->is_fatal_error)
 
1350
      session->is_fatal_error)
1351
1351
  {
1352
1352
    return(1);
1353
1353
  }
1354
1354
 
1355
1355
  /* Remove distinct if only const tables */
1356
1356
  select_distinct= select_distinct && (const_tables != tables);
1357
 
  thd->set_proc_info("preparing");
 
1357
  session->set_proc_info("preparing");
1358
1358
  if (result->initialize_tables(this))
1359
1359
  {
1360
1360
    return(1);                          // error == -1
1363
1363
      !(select_options & SELECT_DESCRIBE) &&
1364
1364
      (!conds ||
1365
1365
       !(conds->used_tables() & RAND_TABLE_BIT) ||
1366
 
       select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
 
1366
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
1367
1367
  {
1368
1368
    zero_result_cause= "no matching row in const table";
1369
1369
    error= 0;
1370
1370
    return(0);
1371
1371
  }
1372
 
  if (!(thd->options & OPTION_BIG_SELECTS) &&
1373
 
      best_read > (double) thd->variables.max_join_size &&
 
1372
  if (!(session->options & OPTION_BIG_SELECTS) &&
 
1373
      best_read > (double) session->variables.max_join_size &&
1374
1374
      !(select_options & SELECT_DESCRIBE))
1375
1375
  {                                             /* purecov: inspected */
1376
1376
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
1377
1377
    error= -1;
1378
1378
    return(1);
1379
1379
  }
1380
 
  if (const_tables && !thd->locked_tables &&
 
1380
  if (const_tables && !session->locked_tables &&
1381
1381
      !(select_options & SELECT_NO_UNLOCK))
1382
 
    mysql_unlock_some_tables(thd, table, const_tables);
 
1382
    mysql_unlock_some_tables(session, table, const_tables);
1383
1383
  if (!conds && outer_join)
1384
1384
  {
1385
1385
    /* Handle the case where we have an OUTER JOIN without a WHERE */
1425
1425
 
1426
1426
  if (conds &&!outer_join && const_table_map != found_const_table_map && 
1427
1427
      (select_options & SELECT_DESCRIBE) &&
1428
 
      select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
 
1428
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
1429
1429
  {
1430
1430
    conds=new Item_int((int64_t) 0,1);  // Always false
1431
1431
  }
1442
1442
  {
1443
1443
    order_st *org_order= order;
1444
1444
    order=remove_const(this, order,conds,1, &simple_order);
1445
 
    if (thd->is_error())
 
1445
    if (session->is_error())
1446
1446
    {
1447
1447
      error= 1;
1448
1448
      return(1);
1540
1540
    if (order)
1541
1541
      skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1, 
1542
1542
        &tab->table->keys_in_use_for_order_by);
1543
 
    if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
 
1543
    if ((group_list=create_distinct_group(session, select_lex->ref_pointer_array,
1544
1544
                                          order, fields_list, all_fields,
1545
1545
                                          &all_order_fields_used)))
1546
1546
    {
1572
1572
      else
1573
1573
        group_list= 0;
1574
1574
    }
1575
 
    else if (thd->is_fatal_error)                       // End of memory
 
1575
    else if (session->is_fatal_error)                   // End of memory
1576
1576
      return(1);
1577
1577
  }
1578
1578
  simple_group= 0;
1581
1581
    group_list= remove_const(this, (old_group_list= group_list), conds,
1582
1582
                             rollup.state == ROLLUP::STATE_NONE,
1583
1583
                             &simple_group);
1584
 
    if (thd->is_error())
 
1584
    if (session->is_error())
1585
1585
    {
1586
1586
      error= 1;
1587
1587
      return(1);
1664
1664
        error= 0;
1665
1665
        return(unit->item->
1666
1666
                    change_engine(new
1667
 
                                  subselect_uniquesubquery_engine(thd,
 
1667
                                  subselect_uniquesubquery_engine(session,
1668
1668
                                                                  join_tab,
1669
1669
                                                                  unit->item,
1670
1670
                                                                  where)));
1678
1678
        error= 0;
1679
1679
        return(unit->item->
1680
1680
                    change_engine(new
1681
 
                                  subselect_indexsubquery_engine(thd,
 
1681
                                  subselect_indexsubquery_engine(session,
1682
1682
                                                                 join_tab,
1683
1683
                                                                 unit->item,
1684
1684
                                                                 where,
1694
1694
      conds= remove_additional_cond(conds);
1695
1695
      save_index_subquery_explain_info(join_tab, conds);
1696
1696
      return(unit->item->
1697
 
                  change_engine(new subselect_indexsubquery_engine(thd,
 
1697
                  change_engine(new subselect_indexsubquery_engine(session,
1698
1698
                                                                   join_tab,
1699
1699
                                                                   unit->item,
1700
1700
                                                                   conds,
1728
1728
        (join_tab[const_tables].type != JT_REF_OR_NULL) &&
1729
1729
        ((order && simple_order) || (group_list && simple_group)))
1730
1730
    {
1731
 
      if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
 
1731
      if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
1732
1732
        return(1);
1733
1733
      }
1734
1734
    }
1789
1789
  /* Create a tmp table if distinct or if the sort is too complicated */
1790
1790
  if (need_tmp)
1791
1791
  {
1792
 
    thd->set_proc_info("Creating tmp table");
 
1792
    session->set_proc_info("Creating tmp table");
1793
1793
 
1794
1794
    init_items_ref_array();
1795
1795
 
1805
1805
    */
1806
1806
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1807
1807
                             !tmp_group &&
1808
 
                             !thd->lex->current_select->with_sum_func) ?
 
1808
                             !session->lex->current_select->with_sum_func) ?
1809
1809
                            select_limit : HA_POS_ERROR;
1810
1810
 
1811
1811
    if (!(exec_tmp_table1=
1812
 
          create_tmp_table(thd, &tmp_table_param, all_fields,
 
1812
          create_tmp_table(session, &tmp_table_param, all_fields,
1813
1813
                           tmp_group,
1814
1814
                           group_list ? 0 : select_distinct,
1815
1815
                           group_list && simple_group,
1837
1837
    /* if group or order on first table, sort first */
1838
1838
    if (group_list && simple_group)
1839
1839
    {
1840
 
      thd->set_proc_info("Sorting for group");
1841
 
      if (create_sort_index(thd, this, group_list,
 
1840
      session->set_proc_info("Sorting for group");
 
1841
      if (create_sort_index(session, this, group_list,
1842
1842
                            HA_POS_ERROR, HA_POS_ERROR, false) ||
1843
1843
          alloc_group_fields(this, group_list) ||
1844
1844
          make_sum_func_list(all_fields, fields_list, 1) ||
1845
 
          setup_sum_funcs(thd, sum_funcs))
 
1845
          setup_sum_funcs(session, sum_funcs))
1846
1846
      {
1847
1847
        return(1);
1848
1848
      }
1851
1851
    else
1852
1852
    {
1853
1853
      if (make_sum_func_list(all_fields, fields_list, 0) ||
1854
 
          setup_sum_funcs(thd, sum_funcs))
 
1854
          setup_sum_funcs(session, sum_funcs))
1855
1855
      {
1856
1856
        return(1);
1857
1857
      }
1858
1858
 
1859
1859
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1860
1860
      {
1861
 
        thd->set_proc_info("Sorting for order");
1862
 
        if (create_sort_index(thd, this, order,
 
1861
        session->set_proc_info("Sorting for order");
 
1862
        if (create_sort_index(session, this, order,
1863
1863
                              HA_POS_ERROR, HA_POS_ERROR, true))
1864
1864
        {
1865
1865
          return(1);
1876
1876
 
1877
1877
    if (exec_tmp_table1->distinct)
1878
1878
    {
1879
 
      table_map used_tables= thd->used_tables;
 
1879
      table_map used_tables= session->used_tables;
1880
1880
      JOIN_TAB *last_join_tab= join_tab+tables-1;
1881
1881
      do
1882
1882
      {
1976
1976
bool
1977
1977
JOIN::init_save_join_tab()
1978
1978
{
1979
 
  if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
 
1979
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1980
1980
    return 1;                                  /* purecov: inspected */
1981
1981
  error= 0;                                    // Ensure that tmp_join.error= 0
1982
1982
  restore_tmp();
1989
1989
{
1990
1990
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1991
1991
  {
1992
 
    if (!(join_tab_save= (JOIN_TAB*)thd->memdup((unsigned char*) join_tab,
 
1992
    if (!(join_tab_save= (JOIN_TAB*)session->memdup((unsigned char*) join_tab,
1993
1993
                                                sizeof(JOIN_TAB) * tables)))
1994
1994
      return 1;
1995
1995
  }
2006
2006
    the query.  It's never shown in EXPLAIN!
2007
2007
 
2008
2008
  @todo
2009
 
    When can we have here thd->net.report_error not zero?
 
2009
    When can we have here session->net.report_error not zero?
2010
2010
*/
2011
2011
void
2012
2012
JOIN::exec()
2014
2014
  List<Item> *columns_list= &fields_list;
2015
2015
  int      tmp_error;
2016
2016
 
2017
 
  thd->set_proc_info("executing");
 
2017
  session->set_proc_info("executing");
2018
2018
  error= 0;
2019
2019
  (void) result->prepare2(); // Currently, this cannot fail.
2020
2020
 
2042
2042
        {
2043
2043
          error= (int) result->send_eof();
2044
2044
          send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
2045
 
                         thd->sent_row_count);
 
2045
                         session->sent_row_count);
2046
2046
        }
2047
2047
      }
2048
2048
      else
2052
2052
      }
2053
2053
    }
2054
2054
    /* Single select (without union) always returns 0 or 1 row */
2055
 
    thd->limit_found_rows= send_records;
2056
 
    thd->examined_row_count= 0;
 
2055
    session->limit_found_rows= send_records;
 
2056
    session->examined_row_count= 0;
2057
2057
    return;
2058
2058
  }
2059
2059
  /*
2062
2062
    It must be accumulated from all join iterations of all join parts.
2063
2063
  */
2064
2064
  if (tables)
2065
 
    thd->limit_found_rows= 0;
 
2065
    session->limit_found_rows= 0;
2066
2066
 
2067
2067
  if (zero_result_cause)
2068
2068
  {
2140
2140
    curr_tmp_table= exec_tmp_table1;
2141
2141
 
2142
2142
    /* Copy data to the temporary table */
2143
 
    thd->set_proc_info("Copying to tmp table");
 
2143
    session->set_proc_info("Copying to tmp table");
2144
2144
    if (!curr_join->sort_and_group &&
2145
2145
        curr_join->const_tables != curr_join->tables)
2146
2146
      curr_join->join_tab[curr_join->const_tables].sorted= 0;
2161
2161
      items1= items0 + all_fields.elements;
2162
2162
      if (sort_and_group || curr_tmp_table->group)
2163
2163
      {
2164
 
        if (change_to_use_tmp_fields(thd, items1,
 
2164
        if (change_to_use_tmp_fields(session, items1,
2165
2165
                                     tmp_fields_list1, tmp_all_fields1,
2166
2166
                                     fields_list.elements, all_fields))
2167
2167
          return;
2168
2168
      }
2169
2169
      else
2170
2170
      {
2171
 
        if (change_refs_to_tmp_fields(thd, items1,
 
2171
        if (change_refs_to_tmp_fields(session, items1,
2172
2172
                                      tmp_fields_list1, tmp_all_fields1,
2173
2173
                                      fields_list.elements, all_fields))
2174
2174
          return;
2241
2241
          curr_join->tmp_table_param.precomputed_group_by= true;
2242
2242
 
2243
2243
        if (!(curr_tmp_table=
2244
 
              exec_tmp_table2= create_tmp_table(thd,
 
2244
              exec_tmp_table2= create_tmp_table(session,
2245
2245
                                                &curr_join->tmp_table_param,
2246
2246
                                                *curr_all_fields,
2247
2247
                                                (order_st*) 0,
2255
2255
      }
2256
2256
      if (curr_join->group_list)
2257
2257
      {
2258
 
        thd->set_proc_info("Creating sort index");
 
2258
        session->set_proc_info("Creating sort index");
2259
2259
        if (curr_join->join_tab == join_tab && save_join_tab())
2260
2260
        {
2261
2261
          return;
2262
2262
        }
2263
 
        if (create_sort_index(thd, curr_join, curr_join->group_list,
 
2263
        if (create_sort_index(session, curr_join, curr_join->group_list,
2264
2264
                              HA_POS_ERROR, HA_POS_ERROR, false) ||
2265
2265
            make_group_fields(this, curr_join))
2266
2266
        {
2269
2269
        sortorder= curr_join->sortorder;
2270
2270
      }
2271
2271
      
2272
 
      thd->set_proc_info("Copying to group table");
 
2272
      session->set_proc_info("Copying to group table");
2273
2273
      tmp_error= -1;
2274
2274
      if (curr_join != this)
2275
2275
      {
2292
2292
      if (!curr_join->sort_and_group &&
2293
2293
          curr_join->const_tables != curr_join->tables)
2294
2294
        curr_join->join_tab[curr_join->const_tables].sorted= 0;
2295
 
      if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
 
2295
      if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
2296
2296
          (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table)))
2297
2297
      {
2298
2298
        error= tmp_error;
2306
2306
      if (!items2)
2307
2307
      {
2308
2308
        items2= items1 + all_fields.elements;
2309
 
        if (change_to_use_tmp_fields(thd, items2,
 
2309
        if (change_to_use_tmp_fields(session, items2,
2310
2310
                                     tmp_fields_list2, tmp_all_fields2, 
2311
2311
                                     fields_list.elements, tmp_all_fields1))
2312
2312
          return;
2326
2326
    curr_join->join_free();                     /* Free quick selects */
2327
2327
    if (curr_join->select_distinct && ! curr_join->group_list)
2328
2328
    {
2329
 
      thd->set_proc_info("Removing duplicates");
 
2329
      session->set_proc_info("Removing duplicates");
2330
2330
      if (curr_join->tmp_having)
2331
2331
        curr_join->tmp_having->update_used_tables();
2332
2332
      if (remove_duplicates(curr_join, curr_tmp_table,
2355
2355
      if (!items0)
2356
2356
        init_items_ref_array();
2357
2357
      items3= ref_pointer_array + (all_fields.elements*4);
2358
 
      setup_copy_fields(thd, &curr_join->tmp_table_param,
 
2358
      setup_copy_fields(session, &curr_join->tmp_table_param,
2359
2359
                        items3, tmp_fields_list3, tmp_all_fields3,
2360
2360
                        curr_fields_list->elements, *curr_all_fields);
2361
2361
      tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
2378
2378
 
2379
2379
    if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
2380
2380
                                      1, true) || 
2381
 
        setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
2382
 
        thd->is_fatal_error)
 
2381
        setup_sum_funcs(curr_join->session, curr_join->sum_funcs) ||
 
2382
        session->is_fatal_error)
2383
2383
      return;
2384
2384
  }
2385
2385
  if (curr_join->group_list || curr_join->order)
2386
2386
  {
2387
 
    thd->set_proc_info("Sorting result");
 
2387
    session->set_proc_info("Sorting result");
2388
2388
    /* If we have already done the group, add HAVING to sorted table */
2389
2389
    if (curr_join->tmp_having && ! curr_join->group_list && 
2390
2390
        ! curr_join->sort_and_group)
2430
2430
      else
2431
2431
      {
2432
2432
        /*
2433
 
          We can abort sorting after thd->select_limit rows if we there is no
 
2433
          We can abort sorting after session->select_limit rows if we there is no
2434
2434
          WHERE clause for any tables after the sorted one.
2435
2435
        */
2436
2436
        JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
2463
2463
        the query. XXX: it's never shown in EXPLAIN!
2464
2464
        OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
2465
2465
      */
2466
 
      if (create_sort_index(thd, curr_join,
 
2466
      if (create_sort_index(session, curr_join,
2467
2467
                            curr_join->group_list ? 
2468
2468
                            curr_join->group_list : curr_join->order,
2469
2469
                            curr_join->select_limit,
2484
2484
      }
2485
2485
    }
2486
2486
  }
2487
 
  /* XXX: When can we have here thd->is_error() not zero? */
2488
 
  if (thd->is_error())
 
2487
  /* XXX: When can we have here session->is_error() not zero? */
 
2488
  if (session->is_error())
2489
2489
  {
2490
 
    error= thd->is_error();
 
2490
    error= session->is_error();
2491
2491
    return;
2492
2492
  }
2493
2493
  curr_join->having= curr_join->tmp_having;
2494
2494
  curr_join->fields= curr_fields_list;
2495
2495
 
2496
2496
  {
2497
 
    thd->set_proc_info("Sending data");
 
2497
    session->set_proc_info("Sending data");
2498
2498
    result->send_fields(*curr_fields_list,
2499
2499
                        Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
2500
2500
    error= do_select(curr_join, curr_fields_list, NULL);
2501
 
    thd->limit_found_rows= curr_join->send_records;
 
2501
    session->limit_found_rows= curr_join->send_records;
2502
2502
  }
2503
2503
 
2504
2504
  /* Accumulate the counts from all join iterations of all join parts. */
2505
 
  thd->examined_row_count+= curr_join->examined_rows;
 
2505
  session->examined_row_count+= curr_join->examined_rows;
2506
2506
 
2507
2507
  /* 
2508
2508
    With EXPLAIN EXTENDED we have to restore original ref_array
2510
2510
    Otherwise we would not be able to print the query  correctly.
2511
2511
  */ 
2512
2512
  if (items0 &&
2513
 
      (thd->lex->describe & DESCRIBE_EXTENDED) &&
 
2513
      (session->lex->describe & DESCRIBE_EXTENDED) &&
2514
2514
      select_lex->linkage == DERIVED_TABLE_TYPE)      
2515
2515
    set_items_ref_array(items0);
2516
2516
 
2546
2546
 
2547
2547
  cleanup(1);
2548
2548
  if (exec_tmp_table1)
2549
 
    exec_tmp_table1->free_tmp_table(thd);
 
2549
    exec_tmp_table1->free_tmp_table(session);
2550
2550
  if (exec_tmp_table2)
2551
 
    exec_tmp_table2->free_tmp_table(thd);
 
2551
    exec_tmp_table2->free_tmp_table(session);
2552
2552
  delete select;
2553
2553
  delete_dynamic(&keyuse);
2554
2554
  return(error);
2559
2559
/**
2560
2560
  An entry point to single-unit select (a select without UNION).
2561
2561
 
2562
 
  @param thd                  thread handler
 
2562
  @param session                  thread handler
2563
2563
  @param rref_pointer_array   a reference to ref_pointer_array of
2564
2564
                              the top-level select_lex for this query
2565
2565
  @param tables               list of all tables used in this query.
2601
2601
*/
2602
2602
 
2603
2603
bool
2604
 
mysql_select(THD *thd, Item ***rref_pointer_array,
 
2604
mysql_select(Session *session, Item ***rref_pointer_array,
2605
2605
             TableList *tables, uint32_t wild_num, List<Item> &fields,
2606
2606
             COND *conds, uint32_t og_num,  order_st *order, order_st *group,
2607
2607
             Item *having, order_st *proc_param, uint64_t select_options,
2646
2646
  }
2647
2647
  else
2648
2648
  {
2649
 
    if (!(join= new JOIN(thd, fields, select_options, result)))
 
2649
    if (!(join= new JOIN(session, fields, select_options, result)))
2650
2650
        return(true);
2651
 
    thd->set_proc_info("init");
2652
 
    thd->used_tables=0;                         // Updated by setup_fields
 
2651
    session->set_proc_info("init");
 
2652
    session->used_tables=0;                         // Updated by setup_fields
2653
2653
    if ((err= join->prepare(rref_pointer_array, tables, wild_num,
2654
2654
                           conds, og_num, order, group, having, proc_param,
2655
2655
                           select_lex, unit)) == true)
2671
2671
    goto err;                                   // 1
2672
2672
  }
2673
2673
 
2674
 
  if (thd->lex->describe & DESCRIBE_EXTENDED)
 
2674
  if (session->lex->describe & DESCRIBE_EXTENDED)
2675
2675
  {
2676
2676
    join->conds_history= join->conds;
2677
2677
    join->having_history= (join->having?join->having:join->tmp_having);
2678
2678
  }
2679
2679
 
2680
 
  if (thd->is_error())
 
2680
  if (session->is_error())
2681
2681
    goto err;
2682
2682
 
2683
2683
  join->exec();
2684
2684
 
2685
 
  if (thd->lex->describe & DESCRIBE_EXTENDED)
 
2685
  if (session->lex->describe & DESCRIBE_EXTENDED)
2686
2686
  {
2687
2687
    select_lex->where= join->conds_history;
2688
2688
    select_lex->having= join->having_history;
2691
2691
err:
2692
2692
  if (free_join)
2693
2693
  {
2694
 
    thd->set_proc_info("end");
 
2694
    session->set_proc_info("end");
2695
2695
    err|= select_lex->cleanup();
2696
 
    return(err || thd->is_error());
 
2696
    return(err || session->is_error());
2697
2697
  }
2698
2698
  return(join->error);
2699
2699
}
2713
2713
}
2714
2714
 
2715
2715
 
2716
 
static TableList *alloc_join_nest(THD *thd)
 
2716
static TableList *alloc_join_nest(Session *session)
2717
2717
{
2718
2718
  TableList *tbl;
2719
 
  if (!(tbl= (TableList*) thd->calloc(ALIGN_SIZE(sizeof(TableList))+
 
2719
  if (!(tbl= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
2720
2720
                                       sizeof(nested_join_st))))
2721
2721
    return NULL;
2722
2722
  tbl->nested_join= (nested_join_st*) ((unsigned char*)tbl + 
2772
2772
  SELECT_LEX *parent_lex= parent_join->select_lex;
2773
2773
  TableList *emb_tbl_nest= NULL;
2774
2774
  List<TableList> *emb_join_list= &parent_lex->top_join_list;
2775
 
  THD *thd= parent_join->thd;
 
2775
  Session *session= parent_join->session;
2776
2776
 
2777
2777
  /*
2778
2778
    1. Find out where to put the predicate into.
2829
2829
        A3: changes in the TableList::outer_join will make everything work
2830
2830
            automatically.
2831
2831
      */
2832
 
      if (!(wrap_nest= alloc_join_nest(parent_join->thd)))
 
2832
      if (!(wrap_nest= alloc_join_nest(parent_join->session)))
2833
2833
      {
2834
2834
        return(true);
2835
2835
      }
2874
2874
 
2875
2875
  TableList *sj_nest;
2876
2876
  nested_join_st *nested_join;
2877
 
  if (!(sj_nest= alloc_join_nest(parent_join->thd)))
 
2877
  if (!(sj_nest= alloc_join_nest(parent_join->session)))
2878
2878
  {
2879
2879
    return(true);
2880
2880
  }
2952
2952
    Put the subquery's WHERE into semi-join's sj_on_expr
2953
2953
    Add the subquery-induced equalities too.
2954
2954
  */
2955
 
  SELECT_LEX *save_lex= thd->lex->current_select;
2956
 
  thd->lex->current_select=subq_lex;
 
2955
  SELECT_LEX *save_lex= session->lex->current_select;
 
2956
  session->lex->current_select=subq_lex;
2957
2957
  if (!subq_pred->left_expr->fixed &&
2958
 
       subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
 
2958
       subq_pred->left_expr->fix_fields(session, &subq_pred->left_expr))
2959
2959
    return(true);
2960
 
  thd->lex->current_select=save_lex;
 
2960
  session->lex->current_select=save_lex;
2961
2961
 
2962
2962
  sj_nest->nested_join->sj_corr_tables= subq_pred->used_tables();
2963
2963
  sj_nest->nested_join->sj_depends_on=  subq_pred->used_tables() |
3005
3005
    }
3006
3006
  }
3007
3007
  /* Fix the created equality and AND */
3008
 
  sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
 
3008
  sj_nest->sj_on_expr->fix_fields(parent_join->session, &sj_nest->sj_on_expr);
3009
3009
 
3010
3010
  /*
3011
3011
    Walk through sj nest's WHERE and ON expressions and call
3023
3023
  {
3024
3024
    emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr, 
3025
3025
                                     sj_nest->sj_on_expr);
3026
 
    emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
 
3026
    emb_tbl_nest->on_expr->fix_fields(parent_join->session, &emb_tbl_nest->on_expr);
3027
3027
  }
3028
3028
  else
3029
3029
  {
3030
3030
    /* Inject into the WHERE */
3031
3031
    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);
 
3032
    parent_join->conds->fix_fields(parent_join->session, &parent_join->conds);
3033
3033
    parent_join->select_lex->where= parent_join->conds;
3034
3034
  }
3035
3035
 
3118
3118
    if (replace_where_subcondition(this, *in_subq, substitute, do_fix_fields))
3119
3119
      return(true);
3120
3120
 
3121
 
    //if ((*in_subq)->fix_fields(thd, (*in_subq)->ref_ptr))
 
3121
    //if ((*in_subq)->fix_fields(session, (*in_subq)->ref_ptr))
3122
3122
    //  return(true);
3123
3123
  }
3124
3124
  sj_subselects.clear();
3359
3359
*****************************************************************************/
3360
3360
 
3361
3361
 
3362
 
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
 
3362
static ha_rows get_quick_record_count(Session *session, SQL_SELECT *select,
3363
3363
                                      Table *table,
3364
3364
                                      const key_map *keys,ha_rows limit)
3365
3365
{
3366
3366
  int error;
3367
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
 
3367
  if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
3368
3368
    return(0);                           // Fatal error flag is set
3369
3369
  if (select)
3370
3370
  {
3371
3371
    select->head=table;
3372
3372
    table->reginfo.impossible_range=0;
3373
 
    if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
 
3373
    if ((error= select->test_quick_select(session, *(key_map *)keys,(table_map) 0,
3374
3374
                                          limit, 0, false)) == 1)
3375
3375
      return(select->quick->records);
3376
3376
    if (error == -1)
3422
3422
  JOIN_TAB *stat_vector[MAX_TABLES+1];
3423
3423
 
3424
3424
  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));
 
3425
  stat=(JOIN_TAB*) join->session->calloc(sizeof(JOIN_TAB)*table_count);
 
3426
  stat_ref=(JOIN_TAB**) join->session->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
 
3427
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
3428
3428
  if (!stat || !stat_ref || !table_vector)
3429
3429
    return(1);                          // Eom /* purecov: inspected */
3430
3430
 
3543
3543
  }
3544
3544
 
3545
3545
  if (conds || outer_join)
3546
 
    if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
 
3546
    if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
3547
3547
                            conds, join->cond_equal,
3548
3548
                            ~outer_join, join->select_lex, &sargables))
3549
3549
      return(1);
3768
3768
                          1, &error);
3769
3769
      if (!select)
3770
3770
        return(1);
3771
 
      records= get_quick_record_count(join->thd, select, s->table,
 
3771
      records= get_quick_record_count(join->session, select, s->table,
3772
3772
                                      &s->const_keys, join->row_limit);
3773
3773
      s->quick=select->quick;
3774
3774
      s->needed_reg=select->needed_reg;
3822
3822
    join->best_read=1.0;
3823
3823
  }
3824
3824
  /* Generate an execution plan from the found optimal join order. */
3825
 
  return(join->thd->killed || get_best_combination(join));
 
3825
  return(join->session->killed || get_best_combination(join));
3826
3826
}
3827
3827
 
3828
3828
 
4545
4545
/**
4546
4546
  Update keyuse array with all possible keys we can use to fetch rows.
4547
4547
  
4548
 
  @param       thd 
 
4548
  @param       session 
4549
4549
  @param[out]  keyuse         Put here ordered array of KEYUSE structures
4550
4550
  @param       join_tab       Array in tablenr_order
4551
4551
  @param       tables         Number of tables in join
4564
4564
*/
4565
4565
 
4566
4566
static bool
4567
 
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
 
4567
update_ref_and_keys(Session *session, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
4568
4568
                    uint32_t tables, COND *cond,
4569
4569
                    COND_EQUAL *cond_equal __attribute__((unused)),
4570
4570
                    table_map normal_tables, SELECT_LEX *select_lex,
4597
4597
    substitutions.
4598
4598
  */ 
4599
4599
  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)))
 
4600
      (((session->lex->current_select->cond_count+1)*2 +
 
4601
        session->lex->current_select->between_count)*m+1);
 
4602
  if (!(key_fields=(KEY_FIELD*) session->alloc(sz)))
4603
4603
    return true; /* purecov: inspected */
4604
4604
  and_level= 0;
4605
4605
  field= end= key_fields;
4898
4898
  @param join             pointer to the structure providing all context info
4899
4899
                          for the query
4900
4900
  @param s                the table to be joined by the function
4901
 
  @param thd              thread for the connection that submitted the query
 
4901
  @param session              thread for the connection that submitted the query
4902
4902
  @param remaining_tables set of tables not included into the partial plan yet
4903
4903
  @param idx              the length of the partial plan
4904
4904
  @param record_count     estimate for the number of records returned by the
4912
4912
static void
4913
4913
best_access_path(JOIN      *join,
4914
4914
                 JOIN_TAB  *s,
4915
 
                 THD       *thd,
 
4915
                 Session       *session,
4916
4916
                 table_map remaining_tables,
4917
4917
                 uint32_t      idx,
4918
4918
                 double    record_count,
5163
5163
            }
5164
5164
            /* Limit the number of matched rows */
5165
5165
            tmp= records;
5166
 
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
 
5166
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5167
5167
            if (table->covering_keys.is_set(key))
5168
5168
            {
5169
5169
              /* we can use only index tree */
5328
5328
            }
5329
5329
 
5330
5330
            /* Limit the number of matched rows */
5331
 
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
 
5331
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5332
5332
            if (table->covering_keys.is_set(key))
5333
5333
            {
5334
5334
              /* we can use only index tree */
5458
5458
        /* We read the table as many times as join buffer becomes full. */
5459
5459
        tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
5460
5460
                           record_count /
5461
 
                           (double) thd->variables.join_buff_size));
 
5461
                           (double) session->variables.join_buff_size));
5462
5462
        /* 
5463
5463
            We don't make full cartesian product between rows in the scanned
5464
5464
           table and existing records because we skip all rows from the
5536
5536
static bool
5537
5537
choose_plan(JOIN *join, table_map join_tables)
5538
5538
{
5539
 
  uint32_t search_depth= join->thd->variables.optimizer_search_depth;
5540
 
  uint32_t prune_level=  join->thd->variables.optimizer_prune_level;
 
5539
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
 
5540
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
5541
5541
  bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
5542
5542
 
5543
5543
  join->cur_embedding_map= 0;
5585
5585
    i.e. they have subqueries, unions or call stored procedures.
5586
5586
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
5587
5587
  */
5588
 
  if (join->thd->lex->is_single_level_stmt())
5589
 
    join->thd->status_var.last_query_cost= join->best_read;
 
5588
  if (join->session->lex->is_single_level_stmt())
 
5589
    join->session->status_var.last_query_cost= join->best_read;
5590
5590
  return(false);
5591
5591
}
5592
5592
 
5739
5739
  {
5740
5740
    /* Find the best access method from 's' to the current partial plan */
5741
5741
    advance_sj_state(join_tables, s);
5742
 
    best_access_path(join, s, join->thd, join_tables, idx,
 
5742
    best_access_path(join, s, join->session, join_tables, idx,
5743
5743
                     record_count, read_time);
5744
5744
    /* compute the cost of the new plan extended with 's' */
5745
5745
    record_count*= join->positions[idx].records_read;
6027
6027
                                 uint32_t      search_depth,
6028
6028
                                 uint32_t      prune_level)
6029
6029
{
6030
 
  THD *thd= join->thd;
6031
 
  if (thd->killed)  // Abort
 
6030
  Session *session= join->session;
 
6031
  if (session->killed)  // Abort
6032
6032
    return(true);
6033
6033
 
6034
6034
  /* 
6057
6057
          when the depth is insufficient??)
6058
6058
      */
6059
6059
      /* Find the best access method from 's' to the current partial plan */
6060
 
      best_access_path(join, s, thd, remaining_tables, idx,
 
6060
      best_access_path(join, s, session, remaining_tables, idx,
6061
6061
                       record_count, read_time);
6062
6062
      /* Compute the cost of extending the plan with 's' */
6063
6063
      current_record_count= record_count * join->positions[idx].records_read;
6152
6152
find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count,
6153
6153
          double read_time)
6154
6154
{
6155
 
  THD *thd= join->thd;
6156
 
  if (thd->killed)
 
6155
  Session *session= join->session;
 
6156
  if (session->killed)
6157
6157
    return(true);
6158
6158
  if (!rest_tables)
6159
6159
  {
6182
6182
    {
6183
6183
      double records, best;
6184
6184
      advance_sj_state(rest_tables, s);
6185
 
      best_access_path(join, s, thd, rest_tables, idx, record_count, 
 
6185
      best_access_path(join, s, session, rest_tables, idx, record_count, 
6186
6186
                       read_time);
6187
6187
      records= join->positions[idx].records_read;
6188
6188
      best= join->positions[idx].read_time;
6223
6223
  Find how much space the prevous read not const tables takes in cache.
6224
6224
*/
6225
6225
 
6226
 
static void calc_used_field_length(THD *thd __attribute__((unused)),
 
6226
static void calc_used_field_length(Session *session __attribute__((unused)),
6227
6227
                                   JOIN_TAB *join_tab)
6228
6228
{
6229
6229
  uint32_t null_fields,blobs,fields,rec_length;
6265
6265
{
6266
6266
  uint32_t length=0;
6267
6267
  JOIN_TAB **pos,**end;
6268
 
  THD *thd=join->thd;
 
6268
  Session *session=join->session;
6269
6269
 
6270
6270
  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
6271
6271
       pos != end ;
6273
6273
  {
6274
6274
    JOIN_TAB *join_tab= *pos;
6275
6275
    if (!join_tab->used_fieldlength)            /* Not calced yet */
6276
 
      calc_used_field_length(thd, join_tab);
 
6276
      calc_used_field_length(session, join_tab);
6277
6277
    length+=join_tab->used_fieldlength;
6278
6278
  }
6279
6279
  return length;
6377
6377
  JOIN_TAB *join_tab,*j;
6378
6378
  KEYUSE *keyuse;
6379
6379
  uint32_t table_count;
6380
 
  THD *thd=join->thd;
 
6380
  Session *session=join->session;
6381
6381
 
6382
6382
  table_count=join->tables;
6383
6383
  if (!(join->join_tab=join_tab=
6384
 
        (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
 
6384
        (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB)*table_count)))
6385
6385
    return(true);
6386
6386
 
6387
6387
  join->full_join=0;
6425
6425
                               table_map used_tables)
6426
6426
{
6427
6427
  KEYUSE *keyuse=org_keyuse;
6428
 
  THD  *thd= join->thd;
 
6428
  Session  *session= join->session;
6429
6429
  uint32_t keyparts,length,key;
6430
6430
  Table *table;
6431
6431
  KEY *keyinfo;
6464
6464
  j->ref.key_parts=keyparts;
6465
6465
  j->ref.key_length=length;
6466
6466
  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*) *
 
6467
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
 
6468
      !(j->ref.key_copy= (store_key**) session->alloc((sizeof(store_key*) *
6469
6469
                                                   (keyparts+1)))) ||
6470
 
      !(j->ref.items=    (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
6471
 
      !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
 
6470
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
6471
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
6472
6472
  {
6473
6473
    return(true);
6474
6474
  }
6498
6498
      if (!keyuse->used_tables &&
6499
6499
          !(join->select_options & SELECT_DESCRIBE))
6500
6500
      {                                 // Compare against constant
6501
 
        store_key_item tmp(thd, keyinfo->key_part[i].field,
 
6501
        store_key_item tmp(session, keyinfo->key_part[i].field,
6502
6502
                           key_buff + maybe_null,
6503
6503
                           maybe_null ?  key_buff : 0,
6504
6504
                           keyinfo->key_part[i].length, keyuse->val);
6505
 
        if (thd->is_fatal_error)
 
6505
        if (session->is_fatal_error)
6506
6506
          return(true);
6507
6507
        tmp.copy();
6508
6508
      }
6509
6509
      else
6510
 
        *ref_key++= get_store_key(thd,
 
6510
        *ref_key++= get_store_key(session,
6511
6511
                                  keyuse,join->const_table_map,
6512
6512
                                  &keyinfo->key_part[i],
6513
6513
                                  key_buff, maybe_null);
6550
6550
 
6551
6551
 
6552
6552
static store_key *
6553
 
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
 
6553
get_store_key(Session *session, KEYUSE *keyuse, table_map used_tables,
6554
6554
              KEY_PART_INFO *key_part, unsigned char *key_buff, uint32_t maybe_null)
6555
6555
{
6556
6556
  if (!((~used_tables) & keyuse->used_tables))          // if const item
6557
6557
  {
6558
 
    return new store_key_const_item(thd,
 
6558
    return new store_key_const_item(session,
6559
6559
                                    key_part->field,
6560
6560
                                    key_buff + maybe_null,
6561
6561
                                    maybe_null ? key_buff : 0,
6568
6568
            (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
6569
6569
             Item_ref::DIRECT_REF && 
6570
6570
            keyuse->val->real_item()->type() == Item::FIELD_ITEM))
6571
 
    return new store_key_field(thd,
 
6571
    return new store_key_field(session,
6572
6572
                               key_part->field,
6573
6573
                               key_buff + maybe_null,
6574
6574
                               maybe_null ? key_buff : 0,
6575
6575
                               key_part->length,
6576
6576
                               ((Item_field*) keyuse->val->real_item())->field,
6577
6577
                               keyuse->val->full_name());
6578
 
  return new store_key_item(thd,
 
6578
  return new store_key_item(session,
6579
6579
                            key_part->field,
6580
6580
                            key_buff + maybe_null,
6581
6581
                            maybe_null ? key_buff : 0,
6595
6595
{
6596
6596
  bool error;
6597
6597
  Table *table= field->table;
6598
 
  THD *thd= table->in_use;
6599
 
  ha_rows cuted_fields=thd->cuted_fields;
 
6598
  Session *session= table->in_use;
 
6599
  ha_rows cuted_fields=session->cuted_fields;
6600
6600
 
6601
6601
  /*
6602
6602
    we should restore old value of count_cuted_fields because
6603
6603
    store_val_in_field can be called from mysql_insert 
6604
6604
    with select_insert, which make count_cuted_fields= 1
6605
6605
   */
6606
 
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
6607
 
  thd->count_cuted_fields= check_flag;
 
6606
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
6607
  session->count_cuted_fields= check_flag;
6608
6608
  error= item->save_in_field(field, 1);
6609
 
  thd->count_cuted_fields= old_count_cuted_fields;
6610
 
  return error || cuted_fields != thd->cuted_fields;
 
6609
  session->count_cuted_fields= old_count_cuted_fields;
 
6610
  return error || cuted_fields != session->cuted_fields;
6611
6611
}
6612
6612
 
6613
6613
 
6623
6623
  */
6624
6624
  if (!join->table_reexec)
6625
6625
  {
6626
 
    if (!(join->table_reexec= (Table**) join->thd->alloc(sizeof(Table*))))
 
6626
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
6627
6627
      return(true);                        /* purecov: inspected */
6628
6628
    if (join->tmp_join)
6629
6629
      join->tmp_join->table_reexec= join->table_reexec;
6631
6631
  if (!join->join_tab_reexec)
6632
6632
  {
6633
6633
    if (!(join->join_tab_reexec=
6634
 
          (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
 
6634
          (JOIN_TAB*) join->session->alloc(sizeof(JOIN_TAB))))
6635
6635
      return(true);                        /* purecov: inspected */
6636
6636
    if (join->tmp_join)
6637
6637
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
6779
6779
            when it is called from make_join_select after this function is 
6780
6780
            called.
6781
6781
          */
6782
 
          if (notnull->fix_fields(join->thd, &notnull))
 
6782
          if (notnull->fix_fields(join->session, &notnull))
6783
6783
            return;
6784
6784
          add_cond_and_fix(&referred_tab->select_cond, notnull);
6785
6785
        }
6921
6921
static bool
6922
6922
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
6923
6923
{
6924
 
  THD *thd= join->thd;
 
6924
  Session *session= join->session;
6925
6925
  if (select)
6926
6926
  {
6927
6927
    add_not_null_conds(join);
6931
6931
      if (join->tables > 1)
6932
6932
        cond->update_used_tables();             // Tablenr may have changed
6933
6933
      if (join->const_tables == join->tables &&
6934
 
          thd->lex->current_select->master_unit() ==
6935
 
          &thd->lex->unit)              // not upper level SELECT
 
6934
          session->lex->current_select->master_unit() ==
 
6935
          &session->lex->unit)          // not upper level SELECT
6936
6936
        join->const_table_map|=RAND_TABLE_BIT;
6937
6937
      {                                         // Check const tables
6938
6938
        COND *const_cond=
7039
7039
          tab->type == JT_EQ_REF)
7040
7040
      {
7041
7041
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
7042
 
                                       thd->memdup((unsigned char*) select,
 
7042
                                       session->memdup((unsigned char*) select,
7043
7043
                                                   sizeof(*select)));
7044
7044
        if (!sel)
7045
7045
          return(1);                    // End of memory
7061
7061
          /* Push condition to storage engine if this is enabled
7062
7062
             and the condition is not guarded */
7063
7063
          tab->table->file->pushed_cond= NULL;
7064
 
          if (thd->variables.engine_condition_pushdown)
 
7064
          if (session->variables.engine_condition_pushdown)
7065
7065
          {
7066
7066
            COND *push_cond= 
7067
7067
              make_cond_for_table(tmp, current_map, current_map, 0);
7130
7130
            if (sel->cond && !sel->cond->fixed)
7131
7131
              sel->cond->quick_fix_field();
7132
7132
 
7133
 
            if (sel->test_quick_select(thd, tab->keys,
 
7133
            if (sel->test_quick_select(session, tab->keys,
7134
7134
                                       used_tables & ~ current_map,
7135
7135
                                       (join->select_options &
7136
7136
                                        OPTION_FOUND_ROWS ?
7144
7144
              */
7145
7145
              sel->cond=orig_cond;
7146
7146
              if (!*tab->on_expr_ref ||
7147
 
                  sel->test_quick_select(thd, tab->keys,
 
7147
                  sel->test_quick_select(session, tab->keys,
7148
7148
                                         used_tables & ~ current_map,
7149
7149
                                         (join->select_options &
7150
7150
                                          OPTION_FOUND_ROWS ?
7186
7186
                                         current_map, 0)))
7187
7187
            {
7188
7188
              tab->cache.select=(SQL_SELECT*)
7189
 
                thd->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
7189
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
7190
7190
              tab->cache.select->cond=tmp;
7191
7191
              tab->cache.select->read_tables=join->const_table_map;
7192
7192
            }
7542
7542
{
7543
7543
  Item *idx_cond;
7544
7544
  if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
7545
 
      tab->join->thd->variables.engine_condition_pushdown)
 
7545
      tab->join->session->variables.engine_condition_pushdown)
7546
7546
  {
7547
7547
    idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
7548
7548
                                  other_tbls_ok);
7666
7666
    sorted= 0;                                  // only first must be sorted
7667
7667
    if (tab->insideout_match_tab)
7668
7668
    {
7669
 
      if (!(tab->insideout_buf= (unsigned char*)join->thd->alloc(tab->table->key_info
 
7669
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
7670
7670
                                                         [tab->index].
7671
7671
                                                         key_length)))
7672
7672
        return true;
7750
7750
          !tab->insideout_match_tab)
7751
7751
      {
7752
7752
        if ((options & SELECT_DESCRIBE) ||
7753
 
            !join_init_cache(join->thd,join->join_tab+join->const_tables,
 
7753
            !join_init_cache(join->session,join->join_tab+join->const_tables,
7754
7754
                             i-join->const_tables))
7755
7755
        {
7756
7756
          using_join_cache= true;
7760
7760
      /* These init changes read_record */
7761
7761
      if (tab->use_quick == 2)
7762
7762
      {
7763
 
        join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
7763
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
7764
7764
        tab->read_first_record= join_init_quick_read_record;
7765
7765
        if (statistics)
7766
 
          status_var_increment(join->thd->status_var.select_range_check_count);
 
7766
          status_var_increment(join->session->status_var.select_range_check_count);
7767
7767
      }
7768
7768
      else
7769
7769
      {
7773
7773
          if (tab->select && tab->select->quick)
7774
7774
          {
7775
7775
            if (statistics)
7776
 
              status_var_increment(join->thd->status_var.select_range_count);
 
7776
              status_var_increment(join->session->status_var.select_range_count);
7777
7777
          }
7778
7778
          else
7779
7779
          {
7780
 
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7780
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7781
7781
            if (statistics)
7782
 
              status_var_increment(join->thd->status_var.select_scan_count);
 
7782
              status_var_increment(join->session->status_var.select_scan_count);
7783
7783
          }
7784
7784
        }
7785
7785
        else
7787
7787
          if (tab->select && tab->select->quick)
7788
7788
          {
7789
7789
            if (statistics)
7790
 
              status_var_increment(join->thd->status_var.select_full_range_join_count);
 
7790
              status_var_increment(join->session->status_var.select_full_range_join_count);
7791
7791
          }
7792
7792
          else
7793
7793
          {
7794
 
            join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
7794
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
7795
7795
            if (statistics)
7796
 
              status_var_increment(join->thd->status_var.select_full_join_count);
 
7796
              status_var_increment(join->session->status_var.select_full_join_count);
7797
7797
          }
7798
7798
        }
7799
7799
        if (!table->no_keyread)
7955
7955
    Optimization: if not EXPLAIN and we are done with the JOIN,
7956
7956
    free all tables.
7957
7957
  */
7958
 
  bool full= (!select_lex->uncacheable && !thd->lex->describe);
 
7958
  bool full= (!select_lex->uncacheable && !session->lex->describe);
7959
7959
  bool can_unlock= full;
7960
7960
 
7961
7961
  cleanup(full);
7985
7985
    We are not using tables anymore
7986
7986
    Unlock all tables. We may be in an INSERT .... SELECT statement.
7987
7987
  */
7988
 
  if (can_unlock && lock && thd->lock &&
 
7988
  if (can_unlock && lock && session->lock &&
7989
7989
      !(select_options & SELECT_NO_UNLOCK) &&
7990
7990
      !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)))
 
7991
      (select_lex == (session->lex->unit.fake_select_lex ?
 
7992
                      session->lex->unit.fake_select_lex : &session->lex->select_lex)))
7993
7993
  {
7994
7994
    /*
7995
7995
      TODO: unlock tables even if the join isn't top level select in the
7996
7996
      tree.
7997
7997
    */
7998
 
    mysql_unlock_read_tables(thd, lock);           // Don't free join->lock
 
7998
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
7999
7999
    lock= 0;
8000
8000
  }
8001
8001
 
8332
8332
    result->send_eof();                         // Should be safe
8333
8333
  }
8334
8334
  /* Update results for FOUND_ROWS */
8335
 
  join->thd->limit_found_rows= join->thd->examined_row_count= 0;
 
8335
  join->session->limit_found_rows= join->session->examined_row_count= 0;
8336
8336
  return(0);
8337
8337
}
8338
8338
 
8692
8692
    simple equality nor a row equality the item for this predicate is added
8693
8693
    to eq_list.
8694
8694
 
8695
 
  @param thd        thread handle
 
8695
  @param session        thread handle
8696
8696
  @param left_row   left term of the row equality to be processed
8697
8697
  @param right_row  right term of the row equality to be processed
8698
8698
  @param cond_equal multiple equalities that must hold together with the
8706
8706
    false   otherwise
8707
8707
*/
8708
8708
 
8709
 
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
 
8709
static bool check_row_equality(Session *session, Item *left_row, Item_row *right_row,
8710
8710
                               COND_EQUAL *cond_equal, List<Item>* eq_list)
8711
8711
8712
8712
  uint32_t n= left_row->cols();
8718
8718
    if (left_item->type() == Item::ROW_ITEM &&
8719
8719
        right_item->type() == Item::ROW_ITEM)
8720
8720
    {
8721
 
      is_converted= check_row_equality(thd, 
 
8721
      is_converted= check_row_equality(session, 
8722
8722
                                       (Item_row *) left_item,
8723
8723
                                       (Item_row *) right_item,
8724
8724
                                       cond_equal, eq_list);
8725
8725
      if (!is_converted)
8726
 
        thd->lex->current_select->cond_count++;      
 
8726
        session->lex->current_select->cond_count++;      
8727
8727
    }
8728
8728
    else
8729
8729
    { 
8730
8730
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
8731
 
      thd->lex->current_select->cond_count++;
 
8731
      session->lex->current_select->cond_count++;
8732
8732
    }  
8733
8733
 
8734
8734
    if (!is_converted)
8759
8759
    equalities which are treated in the same way as original equality
8760
8760
    predicates.
8761
8761
 
8762
 
  @param thd        thread handle
 
8762
  @param session        thread handle
8763
8763
  @param item       predicate to process
8764
8764
  @param cond_equal multiple equalities that must hold together with the
8765
8765
                    predicate
8775
8775
           or, if the procedure fails by a fatal error.
8776
8776
*/
8777
8777
 
8778
 
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
 
8778
static bool check_equality(Session *session, Item *item, COND_EQUAL *cond_equal,
8779
8779
                           List<Item> *eq_list)
8780
8780
{
8781
8781
  if (item->type() == Item::FUNC_ITEM &&
8787
8787
    if (left_item->type() == Item::ROW_ITEM &&
8788
8788
        right_item->type() == Item::ROW_ITEM)
8789
8789
    {
8790
 
      thd->lex->current_select->cond_count--;
8791
 
      return check_row_equality(thd,
 
8790
      session->lex->current_select->cond_count--;
 
8791
      return check_row_equality(session,
8792
8792
                                (Item_row *) left_item,
8793
8793
                                (Item_row *) right_item,
8794
8794
                                cond_equal, eq_list);
8819
8819
    just an argument of a comparison predicate.
8820
8820
    The function also determines the maximum number of members in 
8821
8821
    equality lists of each Item_cond_and object assigning it to
8822
 
    thd->lex->current_select->max_equal_elems.
 
8822
    session->lex->current_select->max_equal_elems.
8823
8823
 
8824
8824
  @note
8825
8825
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
8856
8856
    We need to do things in this order as lower AND levels need to know about
8857
8857
    all possible Item_equal objects in upper levels.
8858
8858
 
8859
 
  @param thd        thread handle
 
8859
  @param session        thread handle
8860
8860
  @param cond       condition(expression) where to make replacement
8861
8861
  @param inherited  path to all inherited multiple equality items
8862
8862
 
8864
8864
    pointer to the transformed condition
8865
8865
*/
8866
8866
 
8867
 
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
 
8867
static COND *build_equal_items_for_cond(Session *session, COND *cond,
8868
8868
                                        COND_EQUAL *inherited)
8869
8869
{
8870
8870
  Item_equal *item_equal;
8896
8896
          structure here because it's restored before each
8897
8897
          re-execution of any prepared statement/stored procedure.
8898
8898
        */
8899
 
        if (check_equality(thd, item, &cond_equal, &eq_list))
 
8899
        if (check_equality(session, item, &cond_equal, &eq_list))
8900
8900
          li.remove();
8901
8901
      }
8902
8902
 
8905
8905
      {
8906
8906
        item_equal->fix_length_and_dec();
8907
8907
        item_equal->update_used_tables();
8908
 
        set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8908
        set_if_bigger(session->lex->current_select->max_equal_elems,
8909
8909
                      item_equal->members());  
8910
8910
      }
8911
8911
 
8920
8920
    while ((item= li++))
8921
8921
    { 
8922
8922
      Item *new_item;
8923
 
      if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
 
8923
      if ((new_item= build_equal_items_for_cond(session, item, inherited)) != item)
8924
8924
      {
8925
8925
        /* This replacement happens only for standalone equalities */
8926
8926
        /*
8950
8950
      for WHERE a=b AND c=d AND (b=c OR d=5)
8951
8951
      b=c is replaced by =(a,b,c,d).  
8952
8952
     */
8953
 
    if (check_equality(thd, cond, &cond_equal, &eq_list))
 
8953
    if (check_equality(session, cond, &cond_equal, &eq_list))
8954
8954
    {
8955
8955
      int n= cond_equal.current_level.elements + eq_list.elements;
8956
8956
      if (n == 0)
8964
8964
        }
8965
8965
        else
8966
8966
          item_equal= (Item_equal *) eq_list.pop();
8967
 
        set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8967
        set_if_bigger(session->lex->current_select->max_equal_elems,
8968
8968
                      item_equal->members());  
8969
8969
        return item_equal;
8970
8970
      }
8982
8982
        {
8983
8983
          item_equal->fix_length_and_dec();
8984
8984
          item_equal->update_used_tables();
8985
 
          set_if_bigger(thd->lex->current_select->max_equal_elems,
 
8985
          set_if_bigger(session->lex->current_select->max_equal_elems,
8986
8986
                        item_equal->members());  
8987
8987
        }
8988
8988
        and_cond->cond_equal= cond_equal;
9062
9062
    can get more freedom in performing join operations.
9063
9063
    Althogh we don't use this property now, it probably makes sense to use 
9064
9064
    it in the future.    
9065
 
  @param thd                  Thread handler
 
9065
  @param session                      Thread handler
9066
9066
  @param cond                condition to build the multiple equalities for
9067
9067
  @param inherited           path to all inherited multiple equality items
9068
9068
  @param join_list           list of join tables to which the condition
9074
9074
    pointer to the transformed condition containing multiple equalities
9075
9075
*/
9076
9076
   
9077
 
static COND *build_equal_items(THD *thd, COND *cond,
 
9077
static COND *build_equal_items(Session *session, COND *cond,
9078
9078
                               COND_EQUAL *inherited,
9079
9079
                               List<TableList> *join_list,
9080
9080
                               COND_EQUAL **cond_equal_ref)
9083
9083
 
9084
9084
  if (cond) 
9085
9085
  {
9086
 
    cond= build_equal_items_for_cond(thd, cond, inherited);
 
9086
    cond= build_equal_items_for_cond(session, cond, inherited);
9087
9087
    cond->update_used_tables();
9088
9088
    if (cond->type() == Item::COND_ITEM &&
9089
9089
        ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
9117
9117
          We can modify table->on_expr because its old value will
9118
9118
          be restored before re-execution of PS/SP.
9119
9119
        */
9120
 
        table->on_expr= build_equal_items(thd, table->on_expr, inherited,
 
9120
        table->on_expr= build_equal_items(session, table->on_expr, inherited,
9121
9121
                                          nested_join_list,
9122
9122
                                          &table->cond_equal);
9123
9123
      }
9455
9455
*/
9456
9456
 
9457
9457
static void
9458
 
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
 
9458
change_cond_ref_to_const(Session *session, I_List<COND_CMP> *save_list,
9459
9459
                         Item *and_father, Item *cond,
9460
9460
                         Item *field, Item *value)
9461
9461
{
9466
9466
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
9467
9467
    Item *item;
9468
9468
    while ((item=li++))
9469
 
      change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
 
9469
      change_cond_ref_to_const(session, save_list,and_level ? cond : item, item,
9470
9470
                               field, value);
9471
9471
    return;
9472
9472
  }
9490
9490
    
9491
9491
    if (tmp)
9492
9492
    {
9493
 
      thd->change_item_tree(args + 1, tmp);
 
9493
      session->change_item_tree(args + 1, tmp);
9494
9494
      func->update_used_tables();
9495
9495
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9496
9496
          && and_father != cond && !left_item->const_item())
9514
9514
    
9515
9515
    if (tmp)
9516
9516
    {
9517
 
      thd->change_item_tree(args, tmp);
 
9517
      session->change_item_tree(args, tmp);
9518
9518
      value= tmp;
9519
9519
      func->update_used_tables();
9520
9520
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
9521
9521
          && and_father != cond && !right_item->const_item())
9522
9522
      {
9523
9523
        args[0]= args[1];                       // For easy check
9524
 
        thd->change_item_tree(args + 1, value);
 
9524
        session->change_item_tree(args + 1, value);
9525
9525
        cond->marker=1;
9526
9526
        COND_CMP *tmp2;
9527
9527
        if ((tmp2=new COND_CMP(and_father,func)))
9565
9565
}
9566
9566
 
9567
9567
static void
9568
 
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
 
9568
propagate_cond_constants(Session *session, I_List<COND_CMP> *save_list,
9569
9569
                         COND *and_father, COND *cond)
9570
9570
{
9571
9571
  if (cond->type() == Item::COND_ITEM)
9577
9577
    I_List<COND_CMP> save;
9578
9578
    while ((item=li++))
9579
9579
    {
9580
 
      propagate_cond_constants(thd, &save,and_level ? cond : item, item);
 
9580
      propagate_cond_constants(session, &save,and_level ? cond : item, item);
9581
9581
    }
9582
9582
    if (and_level)
9583
9583
    {                                           // Handle other found items
9587
9587
      {
9588
9588
        Item **args= cond_cmp->cmp_func->arguments();
9589
9589
        if (!args[0]->const_item())
9590
 
          change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
 
9590
          change_cond_ref_to_const(session, &save,cond_cmp->and_level,
9591
9591
                                   cond_cmp->and_level, args[0], args[1]);
9592
9592
      }
9593
9593
    }
9607
9607
      {
9608
9608
        if (right_const)
9609
9609
        {
9610
 
          resolve_const_item(thd, &args[1], args[0]);
 
9610
          resolve_const_item(session, &args[1], args[0]);
9611
9611
          func->update_used_tables();
9612
 
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
 
9612
          change_cond_ref_to_const(session, save_list, and_father, and_father,
9613
9613
                                   args[0], args[1]);
9614
9614
        }
9615
9615
        else if (left_const)
9616
9616
        {
9617
 
          resolve_const_item(thd, &args[0], args[1]);
 
9617
          resolve_const_item(session, &args[0], args[1]);
9618
9618
          func->update_used_tables();
9619
 
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
 
9619
          change_cond_ref_to_const(session, save_list, and_father, and_father,
9620
9620
                                   args[1], args[0]);
9621
9621
        }
9622
9622
      }
9789
9789
          assert(expr);
9790
9790
 
9791
9791
          table->on_expr= expr;
9792
 
          table->prep_on_expr= expr->copy_andor_structure(join->thd);
 
9792
          table->prep_on_expr= expr->copy_andor_structure(join->session);
9793
9793
        }
9794
9794
      }
9795
9795
      nested_join->used_tables= (table_map) 0;
9830
9830
          conds->top_level_item();
9831
9831
          /* conds is always a new item as both cond and on_expr existed */
9832
9832
          assert(!conds->fixed);
9833
 
          conds->fix_fields(join->thd, &conds);
 
9833
          conds->fix_fields(join->session, &conds);
9834
9834
        }
9835
9835
        else
9836
9836
          conds= table->on_expr; 
10209
10209
optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list,
10210
10210
              Item::cond_result *cond_value)
10211
10211
{
10212
 
  THD *thd= join->thd;
 
10212
  Session *session= join->session;
10213
10213
 
10214
10214
  if (!conds)
10215
10215
    *cond_value= Item::COND_TRUE;
10223
10223
      predicate. Substitute a constant instead of this field if the
10224
10224
      multiple equality contains a constant.
10225
10225
    */ 
10226
 
    conds= build_equal_items(join->thd, conds, NULL, join_list,
 
10226
    conds= build_equal_items(join->session, conds, NULL, join_list,
10227
10227
                             &join->cond_equal);
10228
10228
 
10229
10229
    /* change field = field to field = const for each found field = const */
10230
 
    propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
 
10230
    propagate_cond_constants(session, (I_List<COND_CMP> *) 0, conds, conds);
10231
10231
    /*
10232
10232
      Remove all instances of item == item
10233
10233
      Remove all and-levels where CONST item != CONST item
10234
10234
    */
10235
 
    conds= remove_eq_conds(thd, conds, cond_value) ;
 
10235
    conds= remove_eq_conds(session, conds, cond_value) ;
10236
10236
  }
10237
10237
  return(conds);
10238
10238
}
10250
10250
*/
10251
10251
 
10252
10252
COND *
10253
 
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
 
10253
remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value)
10254
10254
{
10255
10255
  if (cond->type() == Item::COND_ITEM)
10256
10256
  {
10264
10264
    Item *item;
10265
10265
    while ((item=li++))
10266
10266
    {
10267
 
      Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
 
10267
      Item *new_item=remove_eq_conds(session, item, &tmp_cond_value);
10268
10268
      if (!new_item)
10269
10269
        li.remove();
10270
10270
      else if (item != new_item)
10329
10329
    {
10330
10330
      Field *field=((Item_field*) args[0])->field;
10331
10331
      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))
 
10332
          (session->options & OPTION_AUTO_IS_NULL) &&
 
10333
          (session->first_successful_insert_id_in_prev_stmt > 0 &&
 
10334
           session->substitute_null_with_insert_id))
10335
10335
      {
10336
10336
        COND *new_cond;
10337
10337
        if ((new_cond= new Item_func_eq(args[0],
10338
10338
                                        new Item_int("last_insert_id()",
10339
 
                                                     thd->read_first_successful_insert_id_in_prev_stmt(),
 
10339
                                                     session->read_first_successful_insert_id_in_prev_stmt(),
10340
10340
                                                     MY_INT64_NUM_DECIMAL_DIGITS))))
10341
10341
        {
10342
10342
          cond=new_cond;
10345
10345
            cond->fixed, also it do not need tables so we use 0 as second
10346
10346
            argument.
10347
10347
          */
10348
 
          cond->fix_fields(thd, &cond);
 
10348
          cond->fix_fields(session, &cond);
10349
10349
        }
10350
10350
        /*
10351
10351
          IS NULL should be mapped to LAST_INSERT_ID only for first row, so
10352
10352
          clear for next row
10353
10353
        */
10354
 
        thd->substitute_null_with_insert_id= false;
 
10354
        session->substitute_null_with_insert_id= false;
10355
10355
      }
10356
10356
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
10357
10357
      else if (((field->type() == DRIZZLE_TYPE_NEWDATE) ||
10368
10368
            cond->fixed, also it do not need tables so we use 0 as second
10369
10369
            argument.
10370
10370
          */
10371
 
          cond->fix_fields(thd, &cond);
 
10371
          cond->fix_fields(session, &cond);
10372
10372
        }
10373
10373
      }
10374
10374
    }
10627
10627
        so we don't touch it here.
10628
10628
      */
10629
10629
      join->examined_rows++;
10630
 
      join->thd->row_count++;
 
10630
      join->session->row_count++;
10631
10631
      assert(join->examined_rows <= 1);
10632
10632
    }
10633
10633
    else if (join->send_row_on_empty_set())
10681
10681
    if (new_errno)
10682
10682
      table->file->print_error(new_errno,MYF(0));
10683
10683
  }
10684
 
  return(join->thd->is_error() ? -1 : rc);
 
10684
  return(join->session->is_error() ? -1 : rc);
10685
10685
}
10686
10686
 
10687
10687
 
10697
10697
      rc= sub_select(join,join_tab,end_of_records);
10698
10698
    return rc;
10699
10699
  }
10700
 
  if (join->thd->killed)                // If aborted by user
 
10700
  if (join->session->killed)            // If aborted by user
10701
10701
  {
10702
 
    join->thd->send_kill_message();
 
10702
    join->session->send_kill_message();
10703
10703
    return NESTED_LOOP_KILLED;                   /* purecov: inspected */
10704
10704
  }
10705
10705
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
10877
10877
      /* Set first_unmatched for the last inner table of this group */
10878
10878
      join_tab->last_inner->first_unmatched= join_tab;
10879
10879
    }
10880
 
    join->thd->row_count= 0;
 
10880
    join->session->row_count= 0;
10881
10881
 
10882
10882
    error= (*join_tab->read_first_record)(join_tab);
10883
10883
    rc= evaluate_join_record(join, join_tab, error);
10917
10917
    0   The row combination is not a duplicate (continue)
10918
10918
*/
10919
10919
 
10920
 
int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl) 
 
10920
int do_sj_dups_weedout(Session *session, SJ_TMP_TABLE *sjtbl) 
10921
10921
{
10922
10922
  int error;
10923
10923
  SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
10970
10970
  {
10971
10971
    /* create_myisam_from_heap will generate error if needed */
10972
10972
    if (sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
10973
 
        create_myisam_from_heap(thd, sjtbl->tmp_table, sjtbl->start_recinfo, 
 
10973
        create_myisam_from_heap(session, sjtbl->tmp_table, sjtbl->start_recinfo, 
10974
10974
                                &sjtbl->recinfo, error, 1))
10975
10975
      return -1;
10976
10976
    //return (error == HA_ERR_FOUND_DUPP_KEY || error== HA_ERR_FOUND_DUPP_UNIQUE) ? 1: -1;
11007
11007
  ha_rows found_records=join->found_records;
11008
11008
  COND *select_cond= join_tab->select_cond;
11009
11009
 
11010
 
  if (error > 0 || (join->thd->is_error()))     // Fatal error
 
11010
  if (error > 0 || (join->session->is_error()))     // Fatal error
11011
11011
    return NESTED_LOOP_ERROR;
11012
11012
  if (error < 0)
11013
11013
    return NESTED_LOOP_NO_MORE_ROWS;
11014
 
  if (join->thd->killed)                        // Aborted by user
 
11014
  if (join->session->killed)                    // Aborted by user
11015
11015
  {
11016
 
    join->thd->send_kill_message();
 
11016
    join->session->send_kill_message();
11017
11017
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
11018
11018
  }
11019
11019
  if (!select_cond || select_cond->val_int())
11076
11076
    join_tab->found_match= true;
11077
11077
    if (join_tab->check_weed_out_table)
11078
11078
    {
11079
 
      int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
 
11079
      int res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table);
11080
11080
      if (res == -1)
11081
11081
        return NESTED_LOOP_ERROR;
11082
11082
      if (res == 1)
11097
11097
      (See above join->return_tab= tab).
11098
11098
    */
11099
11099
    join->examined_rows++;
11100
 
    join->thd->row_count++;
 
11100
    join->session->row_count++;
11101
11101
 
11102
11102
    if (found)
11103
11103
    {
11129
11129
      with the beginning coinciding with the current partial join.
11130
11130
    */
11131
11131
    join->examined_rows++;
11132
 
    join->thd->row_count++;
 
11132
    join->session->row_count++;
11133
11133
    join_tab->read_record.file->unlock_row();
11134
11134
  }
11135
11135
  return NESTED_LOOP_OK;
11239
11239
  info= &join_tab->read_record;
11240
11240
  do
11241
11241
  {
11242
 
    if (join->thd->killed)
 
11242
    if (join->session->killed)
11243
11243
    {
11244
 
      join->thd->send_kill_message();
 
11244
      join->session->send_kill_message();
11245
11245
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
11246
11246
    }
11247
11247
    SQL_SELECT *select=join_tab->select;
11257
11257
        {
11258
11258
          int res= 0;
11259
11259
          if (!join_tab->check_weed_out_table || 
11260
 
              !(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
 
11260
              !(res= do_sj_dups_weedout(join->session, join_tab->check_weed_out_table)))
11261
11261
          {
11262
11262
            rc= (join_tab->next_select)(join,join_tab+1,0);
11263
11263
            if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
11422
11422
  if (table->status & STATUS_GARBAGE)           // If first read
11423
11423
  {
11424
11424
    table->status= 0;
11425
 
    if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11425
    if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11426
11426
      error=HA_ERR_KEY_NOT_FOUND;
11427
11427
    else
11428
11428
    {
11538
11538
        return -1;
11539
11539
  }
11540
11540
 
11541
 
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11541
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11542
11542
    return -1;
11543
11543
  if ((error=table->file->index_read_map(table->record[0],
11544
11544
                                         tab->ref.key_buff,
11567
11567
 
11568
11568
  if (!table->file->inited)
11569
11569
    table->file->ha_index_init(tab->ref.key, tab->sorted);
11570
 
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
 
11570
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
11571
11571
    return -1;
11572
11572
  if ((error=table->file->index_read_last_map(table->record[0],
11573
11573
                                              tab->ref.key_buff,
11684
11684
{
11685
11685
  delete tab->select->quick;
11686
11686
  tab->select->quick=0;
11687
 
  return tab->select->test_quick_select(tab->join->thd, tab->keys,
 
11687
  return tab->select->test_quick_select(tab->join->session, tab->keys,
11688
11688
                                        (table_map) 0, HA_POS_ERROR, 0,
11689
11689
                                        false);
11690
11690
}
11695
11695
{
11696
11696
  if (tab->select && tab->select->quick && tab->select->quick->reset())
11697
11697
    return 1;
11698
 
  init_read_record(&tab->read_record, tab->join->thd, tab->table,
 
11698
  init_read_record(&tab->read_record, tab->join->session, tab->table,
11699
11699
                   tab->select,1,1);
11700
11700
  return (*tab->read_record.read_record)(&tab->read_record);
11701
11701
}
12048
12048
{
12049
12049
  Table *table=join->tmp_table;
12050
12050
 
12051
 
  if (join->thd->killed)                        // Aborted by user
 
12051
  if (join->session->killed)                    // Aborted by user
12052
12052
  {
12053
 
    join->thd->send_kill_message();
 
12053
    join->session->send_kill_message();
12054
12054
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12055
12055
  }
12056
12056
  if (!end_of_records)
12057
12057
  {
12058
12058
    copy_fields(&join->tmp_table_param);
12059
12059
    copy_funcs(join->tmp_table_param.items_to_copy);
12060
 
#ifdef TO_BE_DELETED
12061
 
    if (!table->uniques)                        // If not unique handling
12062
 
    {
12063
 
      /* Copy null values from group to row */
12064
 
      order_st   *group;
12065
 
      for (group=table->group ; group ; group=group->next)
12066
 
      {
12067
 
        Item *item= *group->item;
12068
 
        if (item->maybe_null)
12069
 
        {
12070
 
          Field *field=item->get_tmp_table_field();
12071
 
          field->ptr[-1]= (unsigned char) (field->is_null() ? 1 : 0);
12072
 
        }
12073
 
      }
12074
 
    }
12075
 
#endif
12076
12060
    if (!join->having || join->having->val_int())
12077
12061
    {
12078
12062
      int error;
12081
12065
      {
12082
12066
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
12083
12067
          goto end;
12084
 
        if (create_myisam_from_heap(join->thd, table,
 
12068
        if (create_myisam_from_heap(join->session, table,
12085
12069
                                    join->tmp_table_param.start_recinfo,
12086
12070
                                    &join->tmp_table_param.recinfo,
12087
12071
                                    error, 1))
12116
12100
 
12117
12101
  if (end_of_records)
12118
12102
    return(NESTED_LOOP_OK);
12119
 
  if (join->thd->killed)                        // Aborted by user
 
12103
  if (join->session->killed)                    // Aborted by user
12120
12104
  {
12121
 
    join->thd->send_kill_message();
 
12105
    join->session->send_kill_message();
12122
12106
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12123
12107
  }
12124
12108
 
12166
12150
  copy_funcs(join->tmp_table_param.items_to_copy);
12167
12151
  if ((error=table->file->ha_write_row(table->record[0])))
12168
12152
  {
12169
 
    if (create_myisam_from_heap(join->thd, table,
 
12153
    if (create_myisam_from_heap(join->session, table,
12170
12154
                                join->tmp_table_param.start_recinfo,
12171
12155
                                &join->tmp_table_param.recinfo,
12172
12156
                                error, 0))
12191
12175
 
12192
12176
  if (end_of_records)
12193
12177
    return(NESTED_LOOP_OK);
12194
 
  if (join->thd->killed)                        // Aborted by user
 
12178
  if (join->session->killed)                    // Aborted by user
12195
12179
  {
12196
 
    join->thd->send_kill_message();
 
12180
    join->session->send_kill_message();
12197
12181
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12198
12182
  }
12199
12183
 
12236
12220
  Table *table=join->tmp_table;
12237
12221
  int     idx= -1;
12238
12222
 
12239
 
  if (join->thd->killed)
 
12223
  if (join->session->killed)
12240
12224
  {                                             // Aborted by user
12241
 
    join->thd->send_kill_message();
 
12225
    join->session->send_kill_message();
12242
12226
    return(NESTED_LOOP_KILLED);             /* purecov: inspected */
12243
12227
  }
12244
12228
  if (!join->first_record || end_of_records ||
12259
12243
        if (!join->having || join->having->val_int())
12260
12244
        {
12261
12245
          int error= table->file->ha_write_row(table->record[0]);
12262
 
          if (error && create_myisam_from_heap(join->thd, table,
 
12246
          if (error && create_myisam_from_heap(join->session, table,
12263
12247
                                               join->tmp_table_param.start_recinfo,
12264
12248
                                                &join->tmp_table_param.recinfo,
12265
12249
                                               error, 0))
12363
12347
   @param join The top-level query.
12364
12348
   @param old_cond The expression to be replaced.
12365
12349
   @param new_cond The expression to be substituted.
12366
 
   @param do_fix_fields If true, Item::fix_fields(THD*, Item**) is called for
 
12350
   @param do_fix_fields If true, Item::fix_fields(Session*, Item**) is called for
12367
12351
   the new expression.
12368
12352
   @return <code>true</code> if there was an error, <code>false</code> if
12369
12353
   successful.
12374
12358
  if (join->conds == old_cond) {
12375
12359
    join->conds= new_cond;
12376
12360
    if (do_fix_fields)
12377
 
      new_cond->fix_fields(join->thd, &join->conds);
 
12361
      new_cond->fix_fields(join->session, &join->conds);
12378
12362
    return false;
12379
12363
  }
12380
12364
  
12386
12370
      {
12387
12371
        li.replace(new_cond);
12388
12372
        if (do_fix_fields)
12389
 
          new_cond->fix_fields(join->thd, li.ref());
 
12373
          new_cond->fix_fields(join->session, li.ref());
12390
12374
        return false;
12391
12375
      }
12392
12376
  }
12995
12979
          new_ref_key_map.clear_all();  // Force the creation of quick select
12996
12980
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
12997
12981
 
12998
 
          if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
 
12982
          if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
12999
12983
                                        (tab->join->select_options &
13000
12984
                                         OPTION_FOUND_ROWS) ?
13001
12985
                                        HA_POS_ERROR :
13182
13166
        map.clear_all();       // Force the creation of quick select
13183
13167
        map.set_bit(best_key); // only best_key.
13184
13168
        quick_created=         
13185
 
          select->test_quick_select(join->thd, map, 0,
 
13169
          select->test_quick_select(join->session, map, 0,
13186
13170
                                    join->select_options & OPTION_FOUND_ROWS ?
13187
13171
                                    HA_POS_ERROR :
13188
13172
                                    join->unit->select_limit_cnt,
13301
13285
 
13302
13286
  SYNOPSIS
13303
13287
   create_sort_index()
13304
 
     thd                Thread handler
 
13288
     session            Thread handler
13305
13289
     tab                Table to sort (in join structure)
13306
13290
     order              How table should be sorted
13307
13291
     filesort_limit     Max number of rows that needs to be sorted
13326
13310
*/
13327
13311
 
13328
13312
static int
13329
 
create_sort_index(THD *thd, JOIN *join, order_st *order,
 
13313
create_sort_index(Session *session, JOIN *join, order_st *order,
13330
13314
                  ha_rows filesort_limit, ha_rows select_limit,
13331
13315
                  bool is_order_by)
13332
13316
{
13390
13374
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
13391
13375
        field, quick will contain an empty record set.
13392
13376
      */
13393
 
      if (!(select->quick= (get_quick_select_for_ref(thd, table, &tab->ref, 
 
13377
      if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref, 
13394
13378
                                                     tab->found_records))))
13395
13379
        goto err;
13396
13380
    }
13403
13387
 
13404
13388
  if (table->s->tmp_table)
13405
13389
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
13406
 
  table->sort.found_records=filesort(thd, table,join->sortorder, length,
 
13390
  table->sort.found_records=filesort(session, table,join->sortorder, length,
13407
13391
                                     select, filesort_limit, 0,
13408
13392
                                     &examined_rows);
13409
13393
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
13455
13439
  int error;
13456
13440
  ulong reclength,offset;
13457
13441
  uint32_t field_count;
13458
 
  THD *thd= join->thd;
 
13442
  Session *session= join->session;
13459
13443
 
13460
13444
  entry->reginfo.lock_type=TL_WRITE;
13461
13445
 
13485
13469
  if (entry->s->db_type() == heap_hton ||
13486
13470
      (!entry->s->blob_fields &&
13487
13471
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
13488
 
        thd->variables.sortbuff_size)))
13489
 
    error=remove_dup_with_hash_index(join->thd, entry,
 
13472
        session->variables.sortbuff_size)))
 
13473
    error=remove_dup_with_hash_index(join->session, entry,
13490
13474
                                     field_count, first_field,
13491
13475
                                     reclength, having);
13492
13476
  else
13493
 
    error=remove_dup_with_compare(join->thd, entry, first_field, offset,
 
13477
    error=remove_dup_with_compare(join->session, entry, first_field, offset,
13494
13478
                                  having);
13495
13479
 
13496
13480
  free_blobs(first_field);
13498
13482
}
13499
13483
 
13500
13484
 
13501
 
static int remove_dup_with_compare(THD *thd, Table *table, Field **first_field,
 
13485
static int remove_dup_with_compare(Session *session, Table *table, Field **first_field,
13502
13486
                                   ulong offset, Item *having)
13503
13487
{
13504
13488
  handler *file=table->file;
13514
13498
  error=file->rnd_next(record);
13515
13499
  for (;;)
13516
13500
  {
13517
 
    if (thd->killed)
 
13501
    if (session->killed)
13518
13502
    {
13519
 
      thd->send_kill_message();
 
13503
      session->send_kill_message();
13520
13504
      error=0;
13521
13505
      goto err;
13522
13506
    }
13589
13573
    Note that this will not work on tables with blobs!
13590
13574
*/
13591
13575
 
13592
 
static int remove_dup_with_hash_index(THD *thd, Table *table,
 
13576
static int remove_dup_with_hash_index(Session *session, Table *table,
13593
13577
                                      uint32_t field_count,
13594
13578
                                      Field **first_field,
13595
13579
                                      ulong key_length,
13637
13621
  for (;;)
13638
13622
  {
13639
13623
    unsigned char *org_key_pos;
13640
 
    if (thd->killed)
 
13624
    if (session->killed)
13641
13625
    {
13642
 
      thd->send_kill_message();
 
13626
      session->send_kill_message();
13643
13627
      error=0;
13644
13628
      goto err;
13645
13629
    }
13740
13724
******************************************************************************/
13741
13725
 
13742
13726
static int
13743
 
join_init_cache(THD *thd,JOIN_TAB *tables,uint32_t table_count)
 
13727
join_init_cache(Session *session,JOIN_TAB *tables,uint32_t table_count)
13744
13728
{
13745
13729
  register unsigned int i;
13746
13730
  unsigned int length, blobs;
13756
13740
  for (i=0 ; i < table_count ; i++,join_tab++)
13757
13741
  {
13758
13742
    if (!join_tab->used_fieldlength)            /* Not calced yet */
13759
 
      calc_used_field_length(thd, join_tab);
 
13743
      calc_used_field_length(session, join_tab);
13760
13744
    cache->fields+=join_tab->used_fields;
13761
13745
    blobs+=join_tab->used_blobs;
13762
13746
 
13849
13833
  cache->length=length+blobs*sizeof(char*);
13850
13834
  cache->blobs=blobs;
13851
13835
  *blob_ptr=0;                                  /* End sequentel */
13852
 
  size=cmax(thd->variables.join_buff_size, (ulong)cache->length);
 
13836
  size=cmax(session->variables.join_buff_size, (ulong)cache->length);
13853
13837
  if (!(cache->buff=(unsigned char*) my_malloc(size,MYF(0))))
13854
13838
    return(1);                          /* Don't use cache */ /* purecov: inspected */
13855
13839
  cache->end=cache->buff+size;
14037
14021
  }
14038
14022
  else 
14039
14023
    no_prev_key= true;
14040
 
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) ||
 
14024
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->session, &tab->ref)) ||
14041
14025
      no_prev_key)
14042
14026
    return 1;
14043
14027
  return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
14046
14030
 
14047
14031
 
14048
14032
bool
14049
 
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
 
14033
cp_buffer_from_ref(Session *session, TABLE_REF *ref)
14050
14034
{
14051
 
  enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
14052
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
14035
  enum enum_check_fields save_count_cuted_fields= session->count_cuted_fields;
 
14036
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
14053
14037
  bool result= 0;
14054
14038
 
14055
14039
  for (store_key **copy=ref->key_copy ; *copy ; copy++)
14060
14044
      break;
14061
14045
    }
14062
14046
  }
14063
 
  thd->count_cuted_fields= save_count_cuted_fields;
 
14047
  session->count_cuted_fields= save_count_cuted_fields;
14064
14048
  return result;
14065
14049
}
14066
14050
 
14085
14069
 
14086
14070
  ref_pointer_array and all_fields are updated.
14087
14071
 
14088
 
  @param[in] thd                     Pointer to current thread structure
 
14072
  @param[in] session                 Pointer to current thread structure
14089
14073
  @param[in,out] ref_pointer_array  All select, group and order by fields
14090
14074
  @param[in] tables                 List of tables to search in (usually
14091
14075
    FROM clause)
14103
14087
*/
14104
14088
 
14105
14089
static bool
14106
 
find_order_in_list(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14090
find_order_in_list(Session *session, Item **ref_pointer_array, TableList *tables,
14107
14091
                   order_st *order, List<Item> &fields, List<Item> &all_fields,
14108
14092
                   bool is_group_field)
14109
14093
{
14124
14108
    if (!count || count > fields.elements)
14125
14109
    {
14126
14110
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
14127
 
               order_item->full_name(), thd->where);
 
14111
               order_item->full_name(), session->where);
14128
14112
      return true;
14129
14113
    }
14130
14114
    order->item= ref_pointer_array + count - 1;
14150
14134
      for this name (in case if we would perform lookup in all tables).
14151
14135
    */
14152
14136
    if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
14153
 
        order_item->fix_fields(thd, order->item))
 
14137
        order_item->fix_fields(session, order->item))
14154
14138
      return true;
14155
14139
 
14156
14140
    /* Lookup the current GROUP field in the FROM clause. */
14159
14143
    if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
14160
14144
        order_item_type == Item::REF_ITEM)
14161
14145
    {
14162
 
      from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
 
14146
      from_field= find_field_in_tables(session, (Item_ident*) order_item, tables,
14163
14147
                                       NULL, &view_ref, IGNORE_ERRORS, true,
14164
14148
                                       false);
14165
14149
      if (!from_field)
14199
14183
        warning so the user knows that the field from the FROM clause
14200
14184
        overshadows the column reference from the SELECT list.
14201
14185
      */
14202
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
 
14186
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
14203
14187
                          ER(ER_NON_UNIQ_ERROR),
14204
14188
                          ((Item_ident*) order_item)->field_name,
14205
 
                          current_thd->where);
 
14189
                          current_session->where);
14206
14190
    }
14207
14191
  }
14208
14192
 
14219
14203
    arguments for which fix_fields already was called.
14220
14204
  */
14221
14205
  if (!order_item->fixed &&
14222
 
      (order_item->fix_fields(thd, order->item) ||
 
14206
      (order_item->fix_fields(session, order->item) ||
14223
14207
       (order_item= *order->item)->check_cols(1) ||
14224
 
       thd->is_fatal_error))
 
14208
       session->is_fatal_error))
14225
14209
    return true; /* Wrong field. */
14226
14210
 
14227
14211
  uint32_t el= all_fields.elements;
14239
14223
  the field list.
14240
14224
*/
14241
14225
 
14242
 
int setup_order(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14226
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
14243
14227
                List<Item> &fields, List<Item> &all_fields, order_st *order)
14244
14228
{
14245
 
  thd->where="order clause";
 
14229
  session->where="order clause";
14246
14230
  for (; order; order=order->next)
14247
14231
  {
14248
 
    if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
 
14232
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
14249
14233
                           all_fields, false))
14250
14234
      return 1;
14251
14235
  }
14256
14240
/**
14257
14241
  Intitialize the GROUP BY list.
14258
14242
 
14259
 
  @param thd                    Thread handler
 
14243
  @param session                        Thread handler
14260
14244
  @param ref_pointer_array      We store references to all fields that was
14261
14245
                               not in 'fields' here.
14262
14246
  @param fields         All fields in the select part. Any item in
14280
14264
*/
14281
14265
 
14282
14266
int
14283
 
setup_group(THD *thd, Item **ref_pointer_array, TableList *tables,
 
14267
setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
14284
14268
            List<Item> &fields, List<Item> &all_fields, order_st *order,
14285
14269
            bool *hidden_group_fields)
14286
14270
{
14292
14276
 
14293
14277
  uint32_t org_fields=all_fields.elements;
14294
14278
 
14295
 
  thd->where="group statement";
 
14279
  session->where="group statement";
14296
14280
  for (ord= order; ord; ord= ord->next)
14297
14281
  {
14298
 
    if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
 
14282
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
14299
14283
                           all_fields, true))
14300
14284
      return 1;
14301
14285
    (*ord->item)->marker= UNDEF_POS;            /* Mark found */
14326
14310
    Item_field *field;
14327
14311
    int cur_pos_in_select_list= 0;
14328
14312
    List_iterator<Item> li(fields);
14329
 
    List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
 
14313
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
14330
14314
 
14331
14315
    field= naf_it++;
14332
14316
    while (field && (item=li++))
14377
14361
*/
14378
14362
 
14379
14363
static order_st *
14380
 
create_distinct_group(THD *thd, Item **ref_pointer_array,
 
14364
create_distinct_group(Session *session, Item **ref_pointer_array,
14381
14365
                      order_st *order_list, List<Item> &fields,
14382
14366
                      List<Item> &all_fields __attribute__((unused)),
14383
14367
                      bool *all_order_by_fields_used)
14395
14379
  {
14396
14380
    if (order->in_field_list)
14397
14381
    {
14398
 
      order_st *ord=(order_st*) thd->memdup((char*) order,sizeof(order_st));
 
14382
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
14399
14383
      if (!ord)
14400
14384
        return 0;
14401
14385
      *prev=ord;
14420
14404
        if ((*ord_iter->item)->eq(item, 1))
14421
14405
          goto next_item;
14422
14406
      
14423
 
      order_st *ord=(order_st*) thd->calloc(sizeof(order_st));
 
14407
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
14424
14408
      if (!ord)
14425
14409
        return 0;
14426
14410
 
14670
14654
  {
14671
14655
    for (; group ; group=group->next)
14672
14656
    {
14673
 
      Cached_item *tmp=new_Cached_item(join->thd, *group->item, false);
 
14657
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
14674
14658
      if (!tmp || join->group_fields.push_front(tmp))
14675
14659
        return true;
14676
14660
    }
14717
14701
  Change old item_field to use a new field with points at saved fieldvalue
14718
14702
  This function is only called before use of send_fields.
14719
14703
 
14720
 
  @param thd                   THD pointer
 
14704
  @param session                   Session pointer
14721
14705
  @param param                 temporary table parameters
14722
14706
  @param ref_pointer_array     array of pointers to top elements of filed list
14723
14707
  @param res_selected_fields   new list of items of select item list
14738
14722
*/
14739
14723
 
14740
14724
bool
14741
 
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
 
14725
setup_copy_fields(Session *session, TMP_TABLE_PARAM *param,
14742
14726
                  Item **ref_pointer_array,
14743
14727
                  List<Item> &res_selected_fields, List<Item> &res_all_fields,
14744
14728
                  uint32_t elements, List<Item> &all_fields)
14765
14749
    if (real_pos->type() == Item::FIELD_ITEM)
14766
14750
    {
14767
14751
      Item_field *item;
14768
 
      if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
 
14752
      if (!(item= new Item_field(session, ((Item_field*) real_pos))))
14769
14753
        goto err;
14770
14754
      if (pos->type() == Item::REF_ITEM)
14771
14755
      {
14799
14783
           saved value
14800
14784
        */
14801
14785
        field= item->field;
14802
 
        item->result_field=field->new_field(thd->mem_root,field->table, 1);
 
14786
        item->result_field=field->new_field(session->mem_root,field->table, 1);
14803
14787
        /*
14804
14788
          We need to allocate one extra byte for null handling and
14805
14789
          another extra byte to not get warnings from purify in
14933
14917
  }
14934
14918
 
14935
14919
  /* This must use calloc() as rollup_make_fields depends on this */
14936
 
  sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
 
14920
  sum_funcs= (Item_sum**) session->calloc(sizeof(Item_sum**) * (func_count+1) +
14937
14921
                                      sizeof(Item_sum***) * (group_parts+1));
14938
14922
  sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
14939
14923
  return(sum_funcs == 0);
14994
14978
  Change all funcs and sum_funcs to fields in tmp table, and create
14995
14979
  new list of all items.
14996
14980
 
14997
 
  @param thd                   THD pointer
 
14981
  @param session                   Session pointer
14998
14982
  @param ref_pointer_array     array of pointers to top elements of filed list
14999
14983
  @param res_selected_fields   new list of items of select item list
15000
14984
  @param res_all_fields        new list of all items
15008
14992
*/
15009
14993
 
15010
14994
static bool
15011
 
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
 
14995
change_to_use_tmp_fields(Session *session, Item **ref_pointer_array,
15012
14996
                         List<Item> &res_selected_fields,
15013
14997
                         List<Item> &res_all_fields,
15014
14998
                         uint32_t elements, List<Item> &all_fields)
15032
15016
    {
15033
15017
      if (item->type() == Item::FIELD_ITEM)
15034
15018
      {
15035
 
        item_field= item->get_tmp_table_item(thd);
 
15019
        item_field= item->get_tmp_table_item(session);
15036
15020
      }
15037
15021
      else if ((field= item->get_tmp_table_field()))
15038
15022
      {
15074
15058
  Change all sum_func refs to fields to point at fields in tmp table.
15075
15059
  Change all funcs to be fields in tmp table.
15076
15060
 
15077
 
  @param thd                   THD pointer
 
15061
  @param session                   Session pointer
15078
15062
  @param ref_pointer_array     array of pointers to top elements of filed list
15079
15063
  @param res_selected_fields   new list of items of select item list
15080
15064
  @param res_all_fields        new list of all items
15088
15072
*/
15089
15073
 
15090
15074
static bool
15091
 
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
 
15075
change_refs_to_tmp_fields(Session *session, Item **ref_pointer_array,
15092
15076
                          List<Item> &res_selected_fields,
15093
15077
                          List<Item> &res_all_fields, uint32_t elements,
15094
15078
                          List<Item> &all_fields)
15101
15085
  uint32_t i, border= all_fields.elements - elements;
15102
15086
  for (i= 0; (item= it++); i++)
15103
15087
  {
15104
 
    res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
 
15088
    res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
15105
15089
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
15106
15090
      new_item;
15107
15091
  }
15111
15095
    itr++;
15112
15096
  itr.sublist(res_selected_fields, elements);
15113
15097
 
15114
 
  return thd->is_fatal_error;
 
15098
  return session->is_fatal_error;
15115
15099
}
15116
15100
 
15117
15101
 
15124
15108
/**
15125
15109
  Call ::setup for all sum functions.
15126
15110
 
15127
 
  @param thd           thread handler
 
15111
  @param session           thread handler
15128
15112
  @param func_ptr      sum function list
15129
15113
 
15130
15114
  @retval
15133
15117
    true   error
15134
15118
*/
15135
15119
 
15136
 
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
 
15120
static bool setup_sum_funcs(Session *session, Item_sum **func_ptr)
15137
15121
{
15138
15122
  Item_sum *func;
15139
15123
  while ((func= *(func_ptr++)))
15140
15124
  {
15141
 
    if (func->setup(thd))
 
15125
    if (func->setup(session))
15142
15126
      return(true);
15143
15127
  }
15144
15128
  return(false);
15221
15205
  currenct select for the table.
15222
15206
*/
15223
15207
 
15224
 
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
 
15208
static bool add_ref_to_table_cond(Session *session, JOIN_TAB *join_tab)
15225
15209
{
15226
15210
  if (!join_tab->ref.key_parts)
15227
15211
    return(false);
15239
15223
    Item *value=join_tab->ref.items[i];
15240
15224
    cond->add(new Item_func_equal(new Item_field(field), value));
15241
15225
  }
15242
 
  if (thd->is_fatal_error)
 
15226
  if (session->is_fatal_error)
15243
15227
    return(true);
15244
15228
 
15245
15229
  if (!cond->fixed)
15246
 
    cond->fix_fields(thd, (Item**)&cond);
 
15230
    cond->fix_fields(session, (Item**)&cond);
15247
15231
  if (join_tab->select)
15248
15232
  {
15249
15233
    error=(int) cond->add(join_tab->select->cond);
15260
15244
/**
15261
15245
  Free joins of subselect of this select.
15262
15246
 
15263
 
  @param thd      THD pointer
 
15247
  @param session      Session pointer
15264
15248
  @param select   pointer to st_select_lex which subselects joins we will free
15265
15249
*/
15266
15250
 
15267
 
void free_underlaid_joins(THD *thd __attribute__((unused)),
 
15251
void free_underlaid_joins(Session *session __attribute__((unused)),
15268
15252
                          SELECT_LEX *select)
15269
15253
{
15270
15254
  for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
15302
15286
    This substitution is needed GROUP BY queries with ROLLUP if
15303
15287
    SELECT list contains expressions over group by attributes.
15304
15288
 
15305
 
  @param thd                  reference to the context
 
15289
  @param session                  reference to the context
15306
15290
  @param expr                 expression to make replacement
15307
15291
  @param group_list           list of references to group by items
15308
15292
  @param changed        out:  returns 1 if item contains a replaced field item
15317
15301
    1   on error
15318
15302
*/
15319
15303
 
15320
 
static bool change_group_ref(THD *thd, Item_func *expr, order_st *group_list,
 
15304
static bool change_group_ref(Session *session, Item_func *expr, order_st *group_list,
15321
15305
                             bool *changed)
15322
15306
{
15323
15307
  if (expr->arg_count)
15324
15308
  {
15325
 
    Name_resolution_context *context= &thd->lex->current_select->context;
 
15309
    Name_resolution_context *context= &session->lex->current_select->context;
15326
15310
    Item **arg,**arg_end;
15327
15311
    bool arg_changed= false;
15328
15312
    for (arg= expr->arguments(),
15341
15325
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
15342
15326
                                        item->name)))
15343
15327
              return 1;                                 // fatal_error is set
15344
 
            thd->change_item_tree(arg, new_item);
 
15328
            session->change_item_tree(arg, new_item);
15345
15329
            arg_changed= true;
15346
15330
          }
15347
15331
        }
15348
15332
      }
15349
15333
      else if (item->type() == Item::FUNC_ITEM)
15350
15334
      {
15351
 
        if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
 
15335
        if (change_group_ref(session, (Item_func *) item, group_list, &arg_changed))
15352
15336
          return 1;
15353
15337
      }
15354
15338
    }
15378
15362
  */
15379
15363
  tmp_table_param.group_parts= send_group_parts;
15380
15364
 
15381
 
  if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
 
15365
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
15382
15366
                                                sizeof(Item**) +
15383
15367
                                                sizeof(List<Item>) +
15384
15368
                                                ref_pointer_array_size)
15395
15379
  */
15396
15380
  for (i= 0 ; i < send_group_parts ; i++)
15397
15381
  {
15398
 
    rollup.null_items[i]= new (thd->mem_root) Item_null_result();
 
15382
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
15399
15383
    List<Item> *rollup_fields= &rollup.fields[i];
15400
15384
    rollup_fields->empty();
15401
15385
    rollup.ref_pointer_arrays[i]= ref_array;
15437
15421
          Item* new_item= new Item_func_rollup_const(item);
15438
15422
          if (!new_item)
15439
15423
            return 1;
15440
 
          new_item->fix_fields(thd, (Item **) 0);
15441
 
          thd->change_item_tree(it.ref(), new_item);
 
15424
          new_item->fix_fields(session, (Item **) 0);
 
15425
          session->change_item_tree(it.ref(), new_item);
15442
15426
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
15443
15427
          { 
15444
15428
            if (*tmp->item == item)
15445
 
              thd->change_item_tree(tmp->item, new_item);
 
15429
              session->change_item_tree(tmp->item, new_item);
15446
15430
          }
15447
15431
        }
15448
15432
      }
15450
15434
    if (item->type() == Item::FUNC_ITEM && !found_in_group)
15451
15435
    {
15452
15436
      bool changed= false;
15453
 
      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
 
15437
      if (change_group_ref(session, (Item_func *) item, group_list, &changed))
15454
15438
        return 1;
15455
15439
      /*
15456
15440
        We have to prevent creation of a field in a temporary table for
15553
15537
          sub select.  Fortunately it's not common to have rollup in
15554
15538
          sub selects.
15555
15539
        */
15556
 
        item= item->copy_or_same(thd);
 
15540
        item= item->copy_or_same(session);
15557
15541
        ((Item_sum*) item)->make_unique();
15558
15542
        *(*func)= (Item_sum*) item;
15559
15543
        (*func)++;
15571
15555
              This is an element that is used by the GROUP BY and should be
15572
15556
              set to NULL in this level
15573
15557
            */
15574
 
            Item_null_result *null_item= new (thd->mem_root) Item_null_result();
 
15558
            Item_null_result *null_item= new (session->mem_root) Item_null_result();
15575
15559
            if (!null_item)
15576
15560
              return 1;
15577
15561
            item->maybe_null= 1;                // Value will be null sometimes
15677
15661
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
15678
15662
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
15679
15663
      {
15680
 
        if (create_myisam_from_heap(thd, table_arg, 
 
15664
        if (create_myisam_from_heap(session, table_arg, 
15681
15665
                                    tmp_table_param.start_recinfo,
15682
15666
                                    &tmp_table_param.recinfo,
15683
15667
                                    write_error, 0))
15719
15703
{
15720
15704
  List<Item> field_list;
15721
15705
  List<Item> item_list;
15722
 
  THD *thd=join->thd;
 
15706
  Session *session=join->session;
15723
15707
  select_result *result=join->result;
15724
15708
  Item *item_null= new Item_null();
15725
15709
  const CHARSET_INFO * const cs= system_charset_info;
15726
15710
  int quick_type;
15727
15711
  /* Don't log this into the slow query log */
15728
 
  thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
 
15712
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
15729
15713
  join->unit->offset_limit_cnt= 0;
15730
15714
 
15731
15715
  /* 
15732
15716
    NOTE: the number/types of items pushed into item_list must be in sync with
15733
 
    EXPLAIN column types as they're "defined" in THD::send_explain_fields()
 
15717
    EXPLAIN column types as they're "defined" in Session::send_explain_fields()
15734
15718
  */
15735
15719
  if (message)
15736
15720
  {
15740
15724
                                        strlen(join->select_lex->type), cs));
15741
15725
    for (uint32_t i=0 ; i < 7; i++)
15742
15726
      item_list.push_back(item_null);
15743
 
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15727
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
15744
15728
      item_list.push_back(item_null);
15745
15729
  
15746
15730
    item_list.push_back(new Item_string(message,strlen(message),cs));
15800
15784
    /* ref */
15801
15785
    item_list.push_back(item_null);
15802
15786
    /* in_rows */
15803
 
    if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15787
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
15804
15788
      item_list.push_back(item_null);
15805
15789
    /* rows */
15806
15790
    item_list.push_back(item_null);
15971
15955
      if (table_list->schema_table)
15972
15956
      {
15973
15957
        /* in_rows */
15974
 
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15958
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
15975
15959
          item_list.push_back(item_null);
15976
15960
        /* rows */
15977
15961
        item_list.push_back(item_null);
15991
15975
                                         MY_INT64_NUM_DECIMAL_DIGITS));
15992
15976
 
15993
15977
        /* Add "filtered" field to item_list. */
15994
 
        if (join->thd->lex->describe & DESCRIBE_EXTENDED)
 
15978
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
15995
15979
        {
15996
15980
          float f= 0.0; 
15997
15981
          if (examined_rows)
16064
16048
          {
16065
16049
            const COND *pushed_cond= tab->table->file->pushed_cond;
16066
16050
 
16067
 
            if (thd->variables.engine_condition_pushdown && pushed_cond)
 
16051
            if (session->variables.engine_condition_pushdown && pushed_cond)
16068
16052
            {
16069
16053
              extra.append(STRING_WITH_LEN("; Using where with pushed "
16070
16054
                                           "condition"));
16071
 
              if (thd->lex->describe & DESCRIBE_EXTENDED)
 
16055
              if (session->lex->describe & DESCRIBE_EXTENDED)
16072
16056
              {
16073
16057
                extra.append(STRING_WITH_LEN(": "));
16074
16058
                ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
16123
16107
          need_order=0;
16124
16108
          extra.append(STRING_WITH_LEN("; Using filesort"));
16125
16109
        }
16126
 
        if (distinct & test_all_bits(used_tables,thd->used_tables))
 
16110
        if (distinct & test_all_bits(used_tables,session->used_tables))
16127
16111
          extra.append(STRING_WITH_LEN("; Distinct"));
16128
16112
 
16129
16113
        if (tab->insideout_match_tab)
16185
16169
       unit;
16186
16170
       unit= unit->next_unit())
16187
16171
  {
16188
 
    if (mysql_explain_union(thd, unit, result))
 
16172
    if (mysql_explain_union(session, unit, result))
16189
16173
      return;
16190
16174
  }
16191
16175
  return;
16192
16176
}
16193
16177
 
16194
16178
 
16195
 
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
 
16179
bool mysql_explain_union(Session *session, SELECT_LEX_UNIT *unit, select_result *result)
16196
16180
{
16197
16181
  bool res= 0;
16198
16182
  SELECT_LEX *first= unit->first_select();
16203
16187
  {
16204
16188
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
16205
16189
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
16206
 
    sl->type= (((&thd->lex->select_lex)==sl)?
 
16190
    sl->type= (((&session->lex->select_lex)==sl)?
16207
16191
               (sl->first_inner_unit() || sl->next_select() ? 
16208
16192
                "PRIMARY" : "SIMPLE"):
16209
16193
               ((sl == first)?
16224
16208
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
16225
16209
    unit->fake_select_lex->type= "UNION RESULT";
16226
16210
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
16227
 
    if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
 
16211
    if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
16228
16212
      res= unit->exec();
16229
16213
    res|= unit->cleanup();
16230
16214
  }
16231
16215
  else
16232
16216
  {
16233
 
    thd->lex->current_select= first;
 
16217
    session->lex->current_select= first;
16234
16218
    unit->set_limit(unit->global_parameters);
16235
 
    res= mysql_select(thd, &first->ref_pointer_array,
 
16219
    res= mysql_select(session, &first->ref_pointer_array,
16236
16220
                        (TableList*) first->table_list.first,
16237
16221
                        first->with_wild, first->item_list,
16238
16222
                        first->where,
16241
16225
                        (order_st*) first->order_list.first,
16242
16226
                        (order_st*) first->group_list.first,
16243
16227
                        first->having,
16244
 
                        (order_st*) thd->lex->proc_list.first,
16245
 
                        first->options | thd->options | SELECT_DESCRIBE,
 
16228
                        (order_st*) session->lex->proc_list.first,
 
16229
                        first->options | session->options | SELECT_DESCRIBE,
16246
16230
                        result, unit, first);
16247
16231
  }
16248
 
  return(res || thd->is_error());
 
16232
  return(res || session->is_error());
16249
16233
}
16250
16234
 
16251
16235
 
16252
 
static void print_table_array(THD *thd, String *str, TableList **table, 
 
16236
static void print_table_array(Session *session, String *str, TableList **table, 
16253
16237
                              TableList **end)
16254
16238
{
16255
 
  (*table)->print(thd, str, QT_ORDINARY);
 
16239
  (*table)->print(session, str, QT_ORDINARY);
16256
16240
 
16257
16241
  for (TableList **tbl= table + 1; tbl < end; tbl++)
16258
16242
  {
16268
16252
      str->append(STRING_WITH_LEN(" semi join "));
16269
16253
    else
16270
16254
      str->append(STRING_WITH_LEN(" join "));
16271
 
    curr->print(thd, str, QT_ORDINARY);
 
16255
    curr->print(session, str, QT_ORDINARY);
16272
16256
    if (curr->on_expr)
16273
16257
    {
16274
16258
      str->append(STRING_WITH_LEN(" on("));
16281
16265
 
16282
16266
/**
16283
16267
  Print joins from the FROM clause.
16284
 
  @param thd     thread handler
 
16268
  @param session     thread handler
16285
16269
  @param str     string where table should be printed
16286
16270
  @param tables  list of tables in join
16287
16271
  @query_type    type of the query is being generated
16288
16272
*/
16289
16273
 
16290
 
static void print_join(THD *thd,
 
16274
static void print_join(Session *session,
16291
16275
                       String *str,
16292
16276
                       List<TableList> *tables,
16293
16277
                       enum_query_type query_type __attribute__((unused)))
16294
16278
{
16295
16279
  /* List is reversed => we should reverse it before using */
16296
16280
  List_iterator_fast<TableList> ti(*tables);
16297
 
  TableList **table= (TableList **)thd->alloc(sizeof(TableList*) *
 
16281
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
16298
16282
                                                tables->elements);
16299
16283
  if (table == 0)
16300
16284
    return;  // out of memory
16321
16305
    }
16322
16306
  }
16323
16307
  assert(tables->elements >= 1);
16324
 
  print_table_array(thd, str, table, table + tables->elements);
 
16308
  print_table_array(session, str, table, table + tables->elements);
16325
16309
}
16326
16310
 
16327
16311
 
16330
16314
 
16331
16315
  @details Prints out the USE|FORCE|IGNORE index hint.
16332
16316
 
16333
 
  @param      thd         the current thread
 
16317
  @param      session         the current thread
16334
16318
  @param[out] str         appends the index hint here
16335
16319
  @param      hint        what the hint is (as string : "USE INDEX"|
16336
16320
                          "FORCE INDEX"|"IGNORE INDEX")
16339
16323
*/
16340
16324
 
16341
16325
void 
16342
 
Index_hint::print(THD *thd, String *str)
 
16326
Index_hint::print(Session *session, String *str)
16343
16327
{
16344
16328
  switch (type)
16345
16329
  {
16350
16334
  str->append (STRING_WITH_LEN(" ("));
16351
16335
  if (key_name.length)
16352
16336
  {
16353
 
    if (thd && !my_strnncoll(system_charset_info,
 
16337
    if (session && !my_strnncoll(system_charset_info,
16354
16338
                             (const unsigned char *)key_name.str, key_name.length, 
16355
16339
                             (const unsigned char *)primary_key_name, 
16356
16340
                             strlen(primary_key_name)))
16357
16341
      str->append(primary_key_name);
16358
16342
    else
16359
 
      append_identifier(thd, str, key_name.str, key_name.length);
 
16343
      append_identifier(session, str, key_name.str, key_name.length);
16360
16344
  }
16361
16345
  str->append(')');
16362
16346
}
16368
16352
  @param str   string where table should be printed
16369
16353
*/
16370
16354
 
16371
 
void TableList::print(THD *thd, String *str, enum_query_type query_type)
 
16355
void TableList::print(Session *session, String *str, enum_query_type query_type)
16372
16356
{
16373
16357
  if (nested_join)
16374
16358
  {
16375
16359
    str->append('(');
16376
 
    print_join(thd, str, &nested_join->join_list, query_type);
 
16360
    print_join(session, str, &nested_join->join_list, query_type);
16377
16361
    str->append(')');
16378
16362
  }
16379
16363
  else
16391
16375
    {
16392
16376
      // A normal table
16393
16377
      {
16394
 
        append_identifier(thd, str, db, db_length);
 
16378
        append_identifier(session, str, db, db_length);
16395
16379
        str->append('.');
16396
16380
      }
16397
16381
      if (schema_table)
16398
16382
      {
16399
 
        append_identifier(thd, str, schema_table_name,
 
16383
        append_identifier(session, str, schema_table_name,
16400
16384
                          strlen(schema_table_name));
16401
16385
        cmp_name= schema_table_name;
16402
16386
      }
16403
16387
      else
16404
16388
      {
16405
 
        append_identifier(thd, str, table_name, table_name_length);
 
16389
        append_identifier(session, str, table_name, table_name_length);
16406
16390
        cmp_name= table_name;
16407
16391
      }
16408
16392
    }
16422
16406
        }
16423
16407
      }
16424
16408
 
16425
 
      append_identifier(thd, str, t_alias, strlen(t_alias));
 
16409
      append_identifier(session, str, t_alias, strlen(t_alias));
16426
16410
    }
16427
16411
 
16428
16412
    if (index_hints)
16433
16417
      while ((hint= it++))
16434
16418
      {
16435
16419
        str->append (STRING_WITH_LEN(" "));
16436
 
        hint->print (thd, str);
 
16420
        hint->print (session, str);
16437
16421
      }
16438
16422
    }
16439
16423
  }
16440
16424
}
16441
16425
 
16442
16426
 
16443
 
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
 
16427
void st_select_lex::print(Session *session, String *str, enum_query_type query_type)
16444
16428
{
16445
 
  /* QQ: thd may not be set for sub queries, but this should be fixed */
16446
 
  if (!thd)
16447
 
    thd= current_thd;
 
16429
  /* QQ: session may not be set for sub queries, but this should be fixed */
 
16430
  if (!session)
 
16431
    session= current_session;
16448
16432
 
16449
16433
  str->append(STRING_WITH_LEN("select "));
16450
16434
 
16451
16435
  /* First add options */
16452
16436
  if (options & SELECT_STRAIGHT_JOIN)
16453
16437
    str->append(STRING_WITH_LEN("straight_join "));
16454
 
  if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
16455
 
      (this == &thd->lex->select_lex))
 
16438
  if ((session->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
 
16439
      (this == &session->lex->select_lex))
16456
16440
    str->append(STRING_WITH_LEN("high_priority "));
16457
16441
  if (options & SELECT_DISTINCT)
16458
16442
    str->append(STRING_WITH_LEN("distinct "));
16486
16470
  {
16487
16471
    str->append(STRING_WITH_LEN(" from "));
16488
16472
    /* go through join tree */
16489
 
    print_join(thd, str, &top_join_list, query_type);
 
16473
    print_join(session, str, &top_join_list, query_type);
16490
16474
  }
16491
16475
  else if (where)
16492
16476
  {
16549
16533
  }
16550
16534
 
16551
16535
  // limit
16552
 
  print_limit(thd, str, query_type);
 
16536
  print_limit(session, str, query_type);
16553
16537
 
16554
16538
  // PROCEDURE unsupported here
16555
16539
}