~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Brian Aker
  • Date: 2008-10-08 02:28:58 UTC
  • mfrom: (489.1.13 codestyle)
  • Revision ID: brian@tangent.org-20081008022858-ea8esagkxmn0dupc
Merge of Monty's work.

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