~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Monty Taylor
  • Date: 2008-10-22 01:52:54 UTC
  • Revision ID: monty@inaugust.com-20081022015254-65qfk9f2v0b8jlk3
Moved drizzle_com to drizzled/drizzle_common. Started splitting it up.

Show diffs side-by-side

added added

removed removed

Lines of Context:
106
106
#include <drizzled/server_includes.h>
107
107
#include <drizzled/sql_select.h>
108
108
 
109
 
#ifndef EXTRA_DEBUG
110
 
#define test_rb_tree(A,B) {}
111
 
#define test_use_count(A) {}
112
 
#endif
113
 
 
114
109
/*
115
110
  Convert double value to #rows. Currently this does floor(), and we
116
111
  might consider using round() instead.
639
634
class RANGE_OPT_PARAM
640
635
{
641
636
public:
642
 
  THD   *thd;   /* Current thread handle */
 
637
  Session       *session;   /* Current thread handle */
643
638
  Table *table; /* Table being analyzed */
644
639
  COND *cond;   /* Used inside get_mm_tree(). */
645
640
  table_map prev_tables;
1063
1058
   used_key_parts(0)
1064
1059
{}
1065
1060
 
1066
 
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,
1067
1062
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1068
1063
                                       bool *create_error)
1069
1064
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1077
1072
  key_part_info= head->key_info[index].key_part;
1078
1073
  my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
1079
1074
 
1080
 
  /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
1081
 
  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;
1082
1077
  mrr_buf_desc= NULL;
1083
1078
 
1084
1079
  if (!no_alloc && !parent_alloc)
1085
1080
  {
1086
1081
    // Allocates everything through the internal memroot
1087
 
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1088
 
    thd->mem_root= &alloc;
 
1082
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1083
    session->mem_root= &alloc;
1089
1084
  }
1090
1085
  else
1091
1086
    memset(&alloc, 0, sizeof(alloc));
1137
1132
      }
1138
1133
      if (free_file)
1139
1134
      {
1140
 
        file->ha_external_lock(current_thd, F_UNLCK);
 
1135
        file->ha_external_lock(current_session, F_UNLCK);
1141
1136
        file->close();
1142
1137
        delete file;
1143
1138
      }
1153
1148
}
1154
1149
 
1155
1150
 
1156
 
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
 
1151
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
1157
1152
                                                   Table *table)
1158
 
  :pk_quick_select(NULL), thd(thd_param)
 
1153
  :pk_quick_select(NULL), session(session_param)
1159
1154
{
1160
1155
  index= MAX_KEY;
1161
1156
  head= table;
1162
1157
  memset(&read_record, 0, sizeof(read_record));
1163
 
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
 
1158
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1164
1159
  return;
1165
1160
}
1166
1161
 
1203
1198
}
1204
1199
 
1205
1200
 
1206
 
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
 
1201
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
1207
1202
                                                       Table *table,
1208
1203
                                                       bool retrieve_full_rows,
1209
1204
                                                       MEM_ROOT *parent_alloc)
1210
 
  : 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),
1211
1206
    scans_inited(false)
1212
1207
{
1213
1208
  index= MAX_KEY;
1214
1209
  head= table;
1215
1210
  record= head->record[0];
1216
1211
  if (!parent_alloc)
1217
 
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
 
1212
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1218
1213
  else
1219
1214
    memset(&alloc, 0, sizeof(MEM_ROOT));
1220
1215
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
1264
1259
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
1265
1260
{
1266
1261
  handler *save_file= file, *org_file;
1267
 
  THD *thd;
 
1262
  Session *session;
1268
1263
 
1269
1264
  in_ror_merged_scan= 1;
1270
1265
  if (reuse_handler)
1284
1279
    return(0);
1285
1280
  }
1286
1281
 
1287
 
  thd= head->in_use;
1288
 
  if (!(file= head->file->clone(thd->mem_root)))
 
1282
  session= head->in_use;
 
1283
  if (!(file= head->file->clone(session->mem_root)))
1289
1284
  {
1290
1285
    /* 
1291
1286
      Manually set the error flag. Note: there seems to be quite a few
1301
1296
 
1302
1297
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1303
1298
 
1304
 
  if (file->ha_external_lock(thd, F_RDLCK))
 
1299
  if (file->ha_external_lock(session, F_RDLCK))
1305
1300
    goto failure;
1306
1301
 
1307
1302
  if (init() || reset())
1308
1303
  {
1309
 
    file->ha_external_lock(thd, F_UNLCK);
 
1304
    file->ha_external_lock(session, F_UNLCK);
1310
1305
    file->close();
1311
1306
    goto failure;
1312
1307
  }
1442
1437
}
1443
1438
 
1444
1439
 
1445
 
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
 
1440
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
1446
1441
                                               Table *table)
1447
 
  : thd(thd_param), scans_inited(false)
 
1442
  : session(session_param), scans_inited(false)
1448
1443
{
1449
1444
  index= MAX_KEY;
1450
1445
  head= table;
1451
1446
  rowid_length= table->file->ref_length;
1452
1447
  record= head->record[0];
1453
 
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1454
 
  thd_param->mem_root= &alloc;
 
1448
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1449
  session_param->mem_root= &alloc;
1455
1450
}
1456
1451
 
1457
1452
 
2085
2080
 
2086
2081
  SYNOPSIS
2087
2082
    SQL_SELECT::test_quick_select()
2088
 
      thd               Current thread
 
2083
      session               Current thread
2089
2084
      keys_to_use       Keys to use for range retrieval
2090
2085
      prev_tables       Tables assumed to be already read when the scan is
2091
2086
                        performed (but not read at the moment of this call)
2146
2141
    1 if found usable ranges and quick select has been successfully created.
2147
2142
*/
2148
2143
 
2149
 
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,
2150
2145
                                  table_map prev_tables,
2151
2146
                                  ha_rows limit, bool force_quick_range, 
2152
2147
                                  bool ordered_output)
2180
2175
    KEY *key_info;
2181
2176
    PARAM param;
2182
2177
 
2183
 
    if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, NULL))
 
2178
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
2184
2179
      return(0);                           // Fatal error flag is set
2185
2180
 
2186
2181
    /* set up parameter that is passed to all functions */
2187
 
    param.thd= thd;
 
2182
    param.session= session;
2188
2183
    param.baseflag= head->file->ha_table_flags();
2189
2184
    param.prev_tables=prev_tables | const_tables;
2190
2185
    param.read_tables=read_tables;
2192
2187
    param.table=head;
2193
2188
    param.keys=0;
2194
2189
    param.mem_root= &alloc;
2195
 
    param.old_root= thd->mem_root;
 
2190
    param.old_root= session->mem_root;
2196
2191
    param.needed_reg= &needed_reg;
2197
2192
    param.imerge_cost_buff_size= 0;
2198
2193
    param.using_real_indexes= true;
2199
2194
    param.remove_jump_scans= true;
2200
2195
    param.force_default_mrr= ordered_output;
2201
2196
 
2202
 
    thd->no_errors=1;                           // Don't warn about NULL
2203
 
    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);
2204
2199
    if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
2205
2200
                                                  sizeof(KEY_PART)*
2206
2201
                                                  head->s->key_parts)) ||
2207
2202
        fill_used_fields_bitmap(&param))
2208
2203
    {
2209
 
      thd->no_errors=0;
 
2204
      session->no_errors=0;
2210
2205
      free_root(&alloc,MYF(0));                 // Return memory & allocator
2211
2206
      return(0);                                // Can't use range
2212
2207
    }
2213
2208
    key_parts= param.key_parts;
2214
 
    thd->mem_root= &alloc;
 
2209
    session->mem_root= &alloc;
2215
2210
 
2216
2211
    /*
2217
2212
      Make an array with description of all key parts of all table keys.
2320
2315
          objects are not allowed so don't use ROR-intersection for
2321
2316
          table deletes.
2322
2317
        */
2323
 
        if ((thd->lex->sql_command != SQLCOM_DELETE))
 
2318
        if ((session->lex->sql_command != SQLCOM_DELETE))
2324
2319
        {
2325
2320
          /*
2326
2321
            Get best non-covering ROR-intersection plan and prepare data for
2363
2358
      }
2364
2359
    }
2365
2360
 
2366
 
    thd->mem_root= param.old_root;
 
2361
    session->mem_root= param.old_root;
2367
2362
 
2368
2363
    /* If we got a read plan, create a quick select from it. */
2369
2364
    if (best_trp)
2378
2373
 
2379
2374
  free_mem:
2380
2375
    free_root(&alloc,MYF(0));                   // Return memory & allocator
2381
 
    thd->mem_root= param.old_root;
2382
 
    thd->no_errors=0;
 
2376
    session->mem_root= param.old_root;
 
2377
    session->no_errors=0;
2383
2378
  }
2384
2379
 
2385
2380
  /*
2545
2540
  /* Calculate cost(rowid_to_row_scan) */
2546
2541
  {
2547
2542
    COST_VECT sweep_cost;
2548
 
    JOIN *join= param->thd->lex->select_lex.join;
 
2543
    JOIN *join= param->session->lex->select_lex.join;
2549
2544
    bool is_interrupted= test(join && join->tables == 1);
2550
2545
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
2551
2546
                        &sweep_cost);
2558
2553
  unique_calc_buff_size=
2559
2554
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
2560
2555
                                    param->table->file->ref_length,
2561
 
                                    param->thd->variables.sortbuff_size);
 
2556
                                    param->session->variables.sortbuff_size);
2562
2557
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
2563
2558
  {
2564
2559
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2570
2565
  imerge_cost +=
2571
2566
    Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2572
2567
                         param->table->file->ref_length,
2573
 
                         param->thd->variables.sortbuff_size);
 
2568
                         param->session->variables.sortbuff_size);
2574
2569
  if (imerge_cost < read_time)
2575
2570
  {
2576
2571
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
2586
2581
  }
2587
2582
 
2588
2583
build_ror_index_merge:
2589
 
  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)
2590
2585
    return(imerge_trp);
2591
2586
 
2592
2587
  /* Ok, it is possible to build a ROR-union, try it. */
2661
2656
  double roru_total_cost;
2662
2657
  {
2663
2658
    COST_VECT sweep_cost;
2664
 
    JOIN *join= param->thd->lex->select_lex.join;
 
2659
    JOIN *join= param->session->lex->select_lex.join;
2665
2660
    bool is_interrupted= test(join && join->tables == 1);
2666
2661
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
2667
2662
                        &sweep_cost);
3129
3124
  if (!info->is_covering)
3130
3125
  {
3131
3126
    COST_VECT sweep_cost;
3132
 
    JOIN *join= info->param->thd->lex->select_lex.join;
 
3127
    JOIN *join= info->param->session->lex->select_lex.join;
3133
3128
    bool is_interrupted= test(join && join->tables == 1);
3134
3129
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3135
3130
                        is_interrupted, &sweep_cost);
3603
3598
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3604
3599
  QUICK_RANGE_SELECT *quick;
3605
3600
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
3606
 
  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)))
3607
3602
    return NULL;
3608
3603
 
3609
3604
  quick_imerge->records= records;
3632
3627
  MEM_ROOT *alloc;
3633
3628
 
3634
3629
  if ((quick_intrsect=
3635
 
         new QUICK_ROR_INTERSECT_SELECT(param->thd, param->table,
 
3630
         new QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
3636
3631
                                        (retrieve_full_rows? (!is_covering) :
3637
3632
                                         false),
3638
3633
                                        parent_alloc)))
3684
3679
    It is impossible to construct a ROR-union that will not retrieve full
3685
3680
    rows, ignore retrieve_full_rows parameter.
3686
3681
  */
3687
 
  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)))
3688
3683
  {
3689
3684
    for (scan= first_ror; scan != last_ror; scan++)
3690
3685
    {
3840
3835
        */
3841
3836
#define NOT_IN_IGNORE_THRESHOLD 1000
3842
3837
        MEM_ROOT *tmp_root= param->mem_root;
3843
 
        param->thd->mem_root= param->old_root;
 
3838
        param->session->mem_root= param->old_root;
3844
3839
        /* 
3845
3840
          Create one Item_type constant object. We'll need it as
3846
3841
          get_mm_parts only accepts constant values wrapped in Item_Type
3847
3842
          objects.
3848
3843
          We create the Item on param->mem_root which points to
3849
 
          per-statement mem_root (while thd->mem_root is currently pointing
 
3844
          per-statement mem_root (while session->mem_root is currently pointing
3850
3845
          to mem_root local to range optimizer).
3851
3846
        */
3852
3847
        Item *value_item= func->array->create_item();
3853
 
        param->thd->mem_root= tmp_root;
 
3848
        param->session->mem_root= tmp_root;
3854
3849
 
3855
3850
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
3856
3851
          break;
4106
4101
      while ((item=li++))
4107
4102
      {
4108
4103
        SEL_TREE *new_tree=get_mm_tree(param,item);
4109
 
        if (param->thd->is_fatal_error || 
 
4104
        if (param->session->is_fatal_error || 
4110
4105
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
4111
4106
          return(0);    // out of memory
4112
4107
        tree=tree_and(param,tree,new_tree);
4138
4133
  {
4139
4134
    /*
4140
4135
      During the cond->val_int() evaluation we can come across a subselect 
4141
 
      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 
4142
4137
      all the memory allocated has the same life span as the subselect 
4143
4138
      item itself. So we have to restore the thread's mem_root here.
4144
4139
    */
4145
4140
    MEM_ROOT *tmp_root= param->mem_root;
4146
 
    param->thd->mem_root= param->old_root;
 
4141
    param->session->mem_root= param->old_root;
4147
4142
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4148
4143
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
4149
 
    param->thd->mem_root= tmp_root;
 
4144
    param->session->mem_root= tmp_root;
4150
4145
    return(tree);
4151
4146
  }
4152
4147
 
4324
4319
    the argument can be any, e.g. a subselect. The subselect
4325
4320
    items, in turn, assume that all the memory allocated during
4326
4321
    the evaluation has the same life span as the item itself.
4327
 
    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.
4328
4323
  */
4329
 
  param->thd->mem_root= param->old_root;
 
4324
  param->session->mem_root= param->old_root;
4330
4325
  if (!value)                                   // IS NULL or IS NOT NULL
4331
4326
  {
4332
4327
    if (field->table->maybe_null)               // Can't use a key on this
4612
4607
  }
4613
4608
 
4614
4609
end:
4615
 
  param->thd->mem_root= alloc;
 
4610
  param->session->mem_root= alloc;
4616
4611
  return(tree);
4617
4612
}
4618
4613
 
5537
5532
    return(0);                          // Maybe root later
5538
5533
  if (remove_color == BLACK)
5539
5534
    root=rb_delete_fixup(root,nod,fix_par);
 
5535
#ifdef EXTRA_DEBUG
5540
5536
  test_rb_tree(root,root->parent);
 
5537
#endif /* EXTRA_DEBUG */
5541
5538
 
5542
5539
  root->use_count=this->use_count;              // Fix root counters
5543
5540
  root->elements=this->elements-1;
5634
5631
    }
5635
5632
  }
5636
5633
  root->color=BLACK;
 
5634
#ifdef EXTRA_DEBUG
5637
5635
  test_rb_tree(root,root->parent);
 
5636
#endif /* EXTRA_DEBUG */
 
5637
 
5638
5638
  return root;
5639
5639
}
5640
5640
 
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