~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

update to latest from trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
634
634
class RANGE_OPT_PARAM
635
635
{
636
636
public:
637
 
  THD   *thd;   /* Current thread handle */
 
637
  Session       *session;   /* Current thread handle */
638
638
  Table *table; /* Table being analyzed */
639
639
  COND *cond;   /* Used inside get_mm_tree(). */
640
640
  table_map prev_tables;
1058
1058
   used_key_parts(0)
1059
1059
{}
1060
1060
 
1061
 
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, Table *table, uint32_t key_nr,
 
1061
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
1062
1062
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1063
1063
                                       bool *create_error)
1064
1064
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1072
1072
  key_part_info= head->key_info[index].key_part;
1073
1073
  my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
1074
1074
 
1075
 
  /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
1076
 
  mrr_buf_size= thd->variables.read_rnd_buff_size;
 
1075
  /* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
 
1076
  mrr_buf_size= session->variables.read_rnd_buff_size;
1077
1077
  mrr_buf_desc= NULL;
1078
1078
 
1079
1079
  if (!no_alloc && !parent_alloc)
1080
1080
  {
1081
1081
    // Allocates everything through the internal memroot
1082
 
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1083
 
    thd->mem_root= &alloc;
 
1082
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1083
    session->mem_root= &alloc;
1084
1084
  }
1085
1085
  else
1086
1086
    memset(&alloc, 0, sizeof(alloc));
1132
1132
      }
1133
1133
      if (free_file)
1134
1134
      {
1135
 
        file->ha_external_lock(current_thd, F_UNLCK);
 
1135
        file->ha_external_lock(current_session, F_UNLCK);
1136
1136
        file->close();
1137
1137
        delete file;
1138
1138
      }
1148
1148
}
1149
1149
 
1150
1150
 
1151
 
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
 
1151
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
1152
1152
                                                   Table *table)
1153
 
  :pk_quick_select(NULL), thd(thd_param)
 
1153
  :pk_quick_select(NULL), session(session_param)
1154
1154
{
1155
1155
  index= MAX_KEY;
1156
1156
  head= table;
1157
1157
  memset(&read_record, 0, sizeof(read_record));
1158
 
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
 
1158
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1159
1159
  return;
1160
1160
}
1161
1161
 
1198
1198
}
1199
1199
 
1200
1200
 
1201
 
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
 
1201
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
1202
1202
                                                       Table *table,
1203
1203
                                                       bool retrieve_full_rows,
1204
1204
                                                       MEM_ROOT *parent_alloc)
1205
 
  : cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
 
1205
  : cpk_quick(NULL), session(session_param), need_to_fetch_row(retrieve_full_rows),
1206
1206
    scans_inited(false)
1207
1207
{
1208
1208
  index= MAX_KEY;
1209
1209
  head= table;
1210
1210
  record= head->record[0];
1211
1211
  if (!parent_alloc)
1212
 
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
 
1212
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1213
1213
  else
1214
1214
    memset(&alloc, 0, sizeof(MEM_ROOT));
1215
1215
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
1259
1259
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
1260
1260
{
1261
1261
  handler *save_file= file, *org_file;
1262
 
  THD *thd;
 
1262
  Session *session;
1263
1263
 
1264
1264
  in_ror_merged_scan= 1;
1265
1265
  if (reuse_handler)
1279
1279
    return(0);
1280
1280
  }
1281
1281
 
1282
 
  thd= head->in_use;
1283
 
  if (!(file= head->file->clone(thd->mem_root)))
 
1282
  session= head->in_use;
 
1283
  if (!(file= head->file->clone(session->mem_root)))
1284
1284
  {
1285
1285
    /* 
1286
1286
      Manually set the error flag. Note: there seems to be quite a few
1296
1296
 
1297
1297
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1298
1298
 
1299
 
  if (file->ha_external_lock(thd, F_RDLCK))
 
1299
  if (file->ha_external_lock(session, F_RDLCK))
1300
1300
    goto failure;
1301
1301
 
1302
1302
  if (init() || reset())
1303
1303
  {
1304
 
    file->ha_external_lock(thd, F_UNLCK);
 
1304
    file->ha_external_lock(session, F_UNLCK);
1305
1305
    file->close();
1306
1306
    goto failure;
1307
1307
  }
1437
1437
}
1438
1438
 
1439
1439
 
1440
 
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
 
1440
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
1441
1441
                                               Table *table)
1442
 
  : thd(thd_param), scans_inited(false)
 
1442
  : session(session_param), scans_inited(false)
1443
1443
{
1444
1444
  index= MAX_KEY;
1445
1445
  head= table;
1446
1446
  rowid_length= table->file->ref_length;
1447
1447
  record= head->record[0];
1448
 
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1449
 
  thd_param->mem_root= &alloc;
 
1448
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1449
  session_param->mem_root= &alloc;
1450
1450
}
1451
1451
 
1452
1452
 
2080
2080
 
2081
2081
  SYNOPSIS
2082
2082
    SQL_SELECT::test_quick_select()
2083
 
      thd               Current thread
 
2083
      session               Current thread
2084
2084
      keys_to_use       Keys to use for range retrieval
2085
2085
      prev_tables       Tables assumed to be already read when the scan is
2086
2086
                        performed (but not read at the moment of this call)
2141
2141
    1 if found usable ranges and quick select has been successfully created.
2142
2142
*/
2143
2143
 
2144
 
int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
 
2144
int SQL_SELECT::test_quick_select(Session *session, key_map keys_to_use,
2145
2145
                                  table_map prev_tables,
2146
2146
                                  ha_rows limit, bool force_quick_range, 
2147
2147
                                  bool ordered_output)
2175
2175
    KEY *key_info;
2176
2176
    PARAM param;
2177
2177
 
2178
 
    if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, NULL))
 
2178
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
2179
2179
      return(0);                           // Fatal error flag is set
2180
2180
 
2181
2181
    /* set up parameter that is passed to all functions */
2182
 
    param.thd= thd;
 
2182
    param.session= session;
2183
2183
    param.baseflag= head->file->ha_table_flags();
2184
2184
    param.prev_tables=prev_tables | const_tables;
2185
2185
    param.read_tables=read_tables;
2187
2187
    param.table=head;
2188
2188
    param.keys=0;
2189
2189
    param.mem_root= &alloc;
2190
 
    param.old_root= thd->mem_root;
 
2190
    param.old_root= session->mem_root;
2191
2191
    param.needed_reg= &needed_reg;
2192
2192
    param.imerge_cost_buff_size= 0;
2193
2193
    param.using_real_indexes= true;
2194
2194
    param.remove_jump_scans= true;
2195
2195
    param.force_default_mrr= ordered_output;
2196
2196
 
2197
 
    thd->no_errors=1;                           // Don't warn about NULL
2198
 
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
 
2197
    session->no_errors=1;                               // Don't warn about NULL
 
2198
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
2199
2199
    if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
2200
2200
                                                  sizeof(KEY_PART)*
2201
2201
                                                  head->s->key_parts)) ||
2202
2202
        fill_used_fields_bitmap(&param))
2203
2203
    {
2204
 
      thd->no_errors=0;
 
2204
      session->no_errors=0;
2205
2205
      free_root(&alloc,MYF(0));                 // Return memory & allocator
2206
2206
      return(0);                                // Can't use range
2207
2207
    }
2208
2208
    key_parts= param.key_parts;
2209
 
    thd->mem_root= &alloc;
 
2209
    session->mem_root= &alloc;
2210
2210
 
2211
2211
    /*
2212
2212
      Make an array with description of all key parts of all table keys.
2315
2315
          objects are not allowed so don't use ROR-intersection for
2316
2316
          table deletes.
2317
2317
        */
2318
 
        if ((thd->lex->sql_command != SQLCOM_DELETE))
 
2318
        if ((session->lex->sql_command != SQLCOM_DELETE))
2319
2319
        {
2320
2320
          /*
2321
2321
            Get best non-covering ROR-intersection plan and prepare data for
2358
2358
      }
2359
2359
    }
2360
2360
 
2361
 
    thd->mem_root= param.old_root;
 
2361
    session->mem_root= param.old_root;
2362
2362
 
2363
2363
    /* If we got a read plan, create a quick select from it. */
2364
2364
    if (best_trp)
2373
2373
 
2374
2374
  free_mem:
2375
2375
    free_root(&alloc,MYF(0));                   // Return memory & allocator
2376
 
    thd->mem_root= param.old_root;
2377
 
    thd->no_errors=0;
 
2376
    session->mem_root= param.old_root;
 
2377
    session->no_errors=0;
2378
2378
  }
2379
2379
 
2380
2380
  /*
2540
2540
  /* Calculate cost(rowid_to_row_scan) */
2541
2541
  {
2542
2542
    COST_VECT sweep_cost;
2543
 
    JOIN *join= param->thd->lex->select_lex.join;
 
2543
    JOIN *join= param->session->lex->select_lex.join;
2544
2544
    bool is_interrupted= test(join && join->tables == 1);
2545
2545
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
2546
2546
                        &sweep_cost);
2553
2553
  unique_calc_buff_size=
2554
2554
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
2555
2555
                                    param->table->file->ref_length,
2556
 
                                    param->thd->variables.sortbuff_size);
 
2556
                                    param->session->variables.sortbuff_size);
2557
2557
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
2558
2558
  {
2559
2559
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2565
2565
  imerge_cost +=
2566
2566
    Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2567
2567
                         param->table->file->ref_length,
2568
 
                         param->thd->variables.sortbuff_size);
 
2568
                         param->session->variables.sortbuff_size);
2569
2569
  if (imerge_cost < read_time)
2570
2570
  {
2571
2571
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
2581
2581
  }
2582
2582
 
2583
2583
build_ror_index_merge:
2584
 
  if (!all_scans_ror_able || param->thd->lex->sql_command == SQLCOM_DELETE)
 
2584
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
2585
2585
    return(imerge_trp);
2586
2586
 
2587
2587
  /* Ok, it is possible to build a ROR-union, try it. */
2656
2656
  double roru_total_cost;
2657
2657
  {
2658
2658
    COST_VECT sweep_cost;
2659
 
    JOIN *join= param->thd->lex->select_lex.join;
 
2659
    JOIN *join= param->session->lex->select_lex.join;
2660
2660
    bool is_interrupted= test(join && join->tables == 1);
2661
2661
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
2662
2662
                        &sweep_cost);
3124
3124
  if (!info->is_covering)
3125
3125
  {
3126
3126
    COST_VECT sweep_cost;
3127
 
    JOIN *join= info->param->thd->lex->select_lex.join;
 
3127
    JOIN *join= info->param->session->lex->select_lex.join;
3128
3128
    bool is_interrupted= test(join && join->tables == 1);
3129
3129
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3130
3130
                        is_interrupted, &sweep_cost);
3598
3598
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3599
3599
  QUICK_RANGE_SELECT *quick;
3600
3600
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
3601
 
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->thd, param->table)))
 
3601
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->session, param->table)))
3602
3602
    return NULL;
3603
3603
 
3604
3604
  quick_imerge->records= records;
3627
3627
  MEM_ROOT *alloc;
3628
3628
 
3629
3629
  if ((quick_intrsect=
3630
 
         new QUICK_ROR_INTERSECT_SELECT(param->thd, param->table,
 
3630
         new QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
3631
3631
                                        (retrieve_full_rows? (!is_covering) :
3632
3632
                                         false),
3633
3633
                                        parent_alloc)))
3679
3679
    It is impossible to construct a ROR-union that will not retrieve full
3680
3680
    rows, ignore retrieve_full_rows parameter.
3681
3681
  */
3682
 
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->thd, param->table)))
 
3682
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->session, param->table)))
3683
3683
  {
3684
3684
    for (scan= first_ror; scan != last_ror; scan++)
3685
3685
    {
3835
3835
        */
3836
3836
#define NOT_IN_IGNORE_THRESHOLD 1000
3837
3837
        MEM_ROOT *tmp_root= param->mem_root;
3838
 
        param->thd->mem_root= param->old_root;
 
3838
        param->session->mem_root= param->old_root;
3839
3839
        /* 
3840
3840
          Create one Item_type constant object. We'll need it as
3841
3841
          get_mm_parts only accepts constant values wrapped in Item_Type
3842
3842
          objects.
3843
3843
          We create the Item on param->mem_root which points to
3844
 
          per-statement mem_root (while thd->mem_root is currently pointing
 
3844
          per-statement mem_root (while session->mem_root is currently pointing
3845
3845
          to mem_root local to range optimizer).
3846
3846
        */
3847
3847
        Item *value_item= func->array->create_item();
3848
 
        param->thd->mem_root= tmp_root;
 
3848
        param->session->mem_root= tmp_root;
3849
3849
 
3850
3850
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
3851
3851
          break;
4101
4101
      while ((item=li++))
4102
4102
      {
4103
4103
        SEL_TREE *new_tree=get_mm_tree(param,item);
4104
 
        if (param->thd->is_fatal_error || 
 
4104
        if (param->session->is_fatal_error || 
4105
4105
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
4106
4106
          return(0);    // out of memory
4107
4107
        tree=tree_and(param,tree,new_tree);
4133
4133
  {
4134
4134
    /*
4135
4135
      During the cond->val_int() evaluation we can come across a subselect 
4136
 
      item which may allocate memory on the thd->mem_root and assumes 
 
4136
      item which may allocate memory on the session->mem_root and assumes 
4137
4137
      all the memory allocated has the same life span as the subselect 
4138
4138
      item itself. So we have to restore the thread's mem_root here.
4139
4139
    */
4140
4140
    MEM_ROOT *tmp_root= param->mem_root;
4141
 
    param->thd->mem_root= param->old_root;
 
4141
    param->session->mem_root= param->old_root;
4142
4142
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4143
4143
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
4144
 
    param->thd->mem_root= tmp_root;
 
4144
    param->session->mem_root= tmp_root;
4145
4145
    return(tree);
4146
4146
  }
4147
4147
 
4319
4319
    the argument can be any, e.g. a subselect. The subselect
4320
4320
    items, in turn, assume that all the memory allocated during
4321
4321
    the evaluation has the same life span as the item itself.
4322
 
    TODO: opt_range.cc should not reset thd->mem_root at all.
 
4322
    TODO: opt_range.cc should not reset session->mem_root at all.
4323
4323
  */
4324
 
  param->thd->mem_root= param->old_root;
 
4324
  param->session->mem_root= param->old_root;
4325
4325
  if (!value)                                   // IS NULL or IS NOT NULL
4326
4326
  {
4327
4327
    if (field->table->maybe_null)               // Can't use a key on this
4607
4607
  }
4608
4608
 
4609
4609
end:
4610
 
  param->thd->mem_root= alloc;
 
4610
  param->session->mem_root= alloc;
4611
4611
  return(tree);
4612
4612
}
4613
4613
 
6200
6200
      !(pk_is_clustered && keynr == param->table->s->primary_key))
6201
6201
     *mrr_flags |= HA_MRR_INDEX_ONLY;
6202
6202
  
6203
 
  if (current_thd->lex->sql_command != SQLCOM_SELECT)
 
6203
  if (current_session->lex->sql_command != SQLCOM_SELECT)
6204
6204
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6205
6205
 
6206
 
  *bufsize= param->thd->variables.read_rnd_buff_size;
 
6206
  *bufsize= param->session->variables.read_rnd_buff_size;
6207
6207
  rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
6208
6208
                                          bufsize, mrr_flags, cost);
6209
6209
  if (rows != HA_POS_ERROR)
6330
6330
  NOTES
6331
6331
    The caller must call QUICK_SELECT::init for returned quick select.
6332
6332
 
6333
 
    CAUTION! This function may change thd->mem_root to a MEM_ROOT which will be
 
6333
    CAUTION! This function may change session->mem_root to a MEM_ROOT which will be
6334
6334
    deallocated when the returned quick select is deleted.
6335
6335
 
6336
6336
  RETURN
6345
6345
  QUICK_RANGE_SELECT *quick;
6346
6346
  bool create_err= false;
6347
6347
 
6348
 
  quick=new QUICK_RANGE_SELECT(param->thd, param->table,
 
6348
  quick=new QUICK_RANGE_SELECT(param->session, param->table,
6349
6349
                               param->real_keynr[idx],
6350
6350
                               test(parent_alloc), NULL, &create_err);
6351
6351
 
6583
6583
 
6584
6584
  SYNOPSIS
6585
6585
    get_quick_select_for_ref()
6586
 
      thd      Thread handle
 
6586
      session      Thread handle
6587
6587
      table    Table to access
6588
6588
      ref      ref[_or_null] scan parameters
6589
6589
      records  Estimate of number of records (needed only to construct
6597
6597
    NULL on error.
6598
6598
*/
6599
6599
 
6600
 
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
 
6600
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
6601
6601
                                             TABLE_REF *ref, ha_rows records)
6602
6602
{
6603
6603
  MEM_ROOT *old_root, *alloc;
6609
6609
  bool create_err= false;
6610
6610
  COST_VECT cost;
6611
6611
 
6612
 
  old_root= thd->mem_root;
6613
 
  /* The following call may change thd->mem_root */
6614
 
  quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0, 0, &create_err);
 
6612
  old_root= session->mem_root;
 
6613
  /* The following call may change session->mem_root */
 
6614
  quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0, &create_err);
6615
6615
  /* save mem_root set by QUICK_RANGE_SELECT constructor */
6616
 
  alloc= thd->mem_root;
 
6616
  alloc= session->mem_root;
6617
6617
  /*
6618
 
    return back default mem_root (thd->mem_root) changed by
 
6618
    return back default mem_root (session->mem_root) changed by
6619
6619
    QUICK_RANGE_SELECT constructor
6620
6620
  */
6621
 
  thd->mem_root= old_root;
 
6621
  session->mem_root= old_root;
6622
6622
 
6623
6623
  if (!quick || create_err)
6624
6624
    return 0;                   /* no ranges found */
6626
6626
    goto err;
6627
6627
  quick->records= records;
6628
6628
 
6629
 
  if ((cp_buffer_from_ref(thd, ref) && thd->is_fatal_error) ||
 
6629
  if ((cp_buffer_from_ref(session, ref) && session->is_fatal_error) ||
6630
6630
      !(range= new(alloc) QUICK_RANGE()))
6631
6631
    goto err;                                   // out of memory
6632
6632
 
6678
6678
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
6679
6679
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION | 
6680
6680
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
6681
 
  if (thd->lex->sql_command != SQLCOM_SELECT)
 
6681
  if (session->lex->sql_command != SQLCOM_SELECT)
6682
6682
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6683
6683
 
6684
 
  quick->mrr_buf_size= thd->variables.read_rnd_buff_size;
 
6684
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
6685
6685
  if (table->file->multi_range_read_info(quick->index, 1, (uint)records,
6686
6686
                                         &quick->mrr_buf_size,
6687
6687
                                         &quick->mrr_flags, &cost))
6735
6735
 
6736
6736
  unique= new Unique(refpos_order_cmp, (void *)file,
6737
6737
                     file->ref_length,
6738
 
                     thd->variables.sortbuff_size);
 
6738
                     session->variables.sortbuff_size);
6739
6739
  if (!unique)
6740
6740
    return(1);
6741
6741
  for (;;)
6763
6763
      break;
6764
6764
    }
6765
6765
 
6766
 
    if (thd->killed)
 
6766
    if (session->killed)
6767
6767
      return(1);
6768
6768
 
6769
6769
    /* skip row if it will be retrieved by clustered PK scan */
6784
6784
  /* index_merge currently doesn't support "using index" at all */
6785
6785
  file->extra(HA_EXTRA_NO_KEYREAD);
6786
6786
  /* start table scan */
6787
 
  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
 
6787
  init_read_record(&read_record, session, head, (SQL_SELECT*) 0, 1, 1);
6788
6788
  return(result);
6789
6789
}
6790
6790
 
7686
7686
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7687
7687
                       KEY_PART_INFO *first_non_group_part,
7688
7688
                       KEY_PART_INFO *min_max_arg_part,
7689
 
                       KEY_PART_INFO *last_part, THD *thd,
 
7689
                       KEY_PART_INFO *last_part, Session *session,
7690
7690
                       unsigned char *key_infix, uint32_t *key_infix_len,
7691
7691
                       KEY_PART_INFO **first_non_infix_part);
7692
7692
static bool
7832
7832
static TRP_GROUP_MIN_MAX *
7833
7833
get_best_group_min_max(PARAM *param, SEL_TREE *tree)
7834
7834
{
7835
 
  THD *thd= param->thd;
7836
 
  JOIN *join= thd->lex->current_select->join;
 
7835
  Session *session= param->session;
 
7836
  JOIN *join= session->lex->current_select->join;
7837
7837
  Table *table= param->table;
7838
7838
  bool have_min= false;              /* true if there is a MIN function. */
7839
7839
  bool have_max= false;              /* true if there is a MAX function. */
8094
8094
                                                        &dummy);
8095
8095
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8096
8096
                                    first_non_group_part, min_max_arg_part,
8097
 
                                    last_part, thd, key_infix, &key_infix_len,
 
8097
                                    last_part, session, key_infix, &key_infix_len,
8098
8098
                                    &first_non_infix_part))
8099
8099
          goto next_index;
8100
8100
      }
8367
8367
    first_non_group_part   [in]  First index part after group attribute parts
8368
8368
    min_max_arg_part       [in]  The keypart of the MIN/MAX argument if any
8369
8369
    last_part              [in]  Last keypart of the index
8370
 
    thd                    [in]  Current thread
 
8370
    session                    [in]  Current thread
8371
8371
    key_infix              [out] Infix of constants to be used for index lookup
8372
8372
    key_infix_len          [out] Lenghth of the infix
8373
8373
    first_non_infix_part   [out] The first keypart after the infix (if any)
8394
8394
                       KEY_PART_INFO *first_non_group_part,
8395
8395
                       KEY_PART_INFO *min_max_arg_part,
8396
8396
                       KEY_PART_INFO *last_part,
8397
 
                       THD *thd __attribute__((unused)),
 
8397
                       Session *session __attribute__((unused)),
8398
8398
                       unsigned char *key_infix, uint32_t *key_infix_len,
8399
8399
                       KEY_PART_INFO **first_non_infix_part)
8400
8400
{
8691
8691
  QUICK_GROUP_MIN_MAX_SELECT *quick;
8692
8692
 
8693
8693
  quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
8694
 
                                        param->thd->lex->current_select->join,
 
8694
                                        param->session->lex->current_select->join,
8695
8695
                                        have_min, have_max, min_max_arg_part,
8696
8696
                                        group_prefix_len, group_key_parts,
8697
8697
                                        used_key_parts, index_info, index,
8819
8819
  assert(!parent_alloc);
8820
8820
  if (!parent_alloc)
8821
8821
  {
8822
 
    init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0);
8823
 
    join->thd->mem_root= &alloc;
 
8822
    init_sql_alloc(&alloc, join->session->variables.range_alloc_block_size, 0);
 
8823
    join->session->mem_root= &alloc;
8824
8824
  }
8825
8825
  else
8826
8826
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used