~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/range.cc

Merge refactored command line using for innodb

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
100
100
           subject and may omit some details.
101
101
*/
102
102
 
103
 
#include <config.h>
 
103
#include "config.h"
104
104
 
105
105
#include <math.h>
106
106
#include <float.h>
109
109
#include <vector>
110
110
#include <algorithm>
111
111
 
112
 
#include <boost/dynamic_bitset.hpp>
113
 
 
114
 
#include <drizzled/check_stack_overrun.h>
115
 
#include <drizzled/error.h>
116
 
#include <drizzled/field/num.h>
117
 
#include <drizzled/internal/iocache.h>
118
 
#include <drizzled/internal/my_sys.h>
119
 
#include <drizzled/item/cmpfunc.h>
120
 
#include <drizzled/optimizer/cost_vector.h>
121
 
#include <drizzled/optimizer/quick_group_min_max_select.h>
122
 
#include <drizzled/optimizer/quick_index_merge_select.h>
123
 
#include <drizzled/optimizer/quick_range.h>
124
 
#include <drizzled/optimizer/quick_range_select.h>
125
 
#include <drizzled/optimizer/quick_ror_intersect_select.h>
126
 
#include <drizzled/optimizer/quick_ror_union_select.h>
127
 
#include <drizzled/optimizer/range.h>
128
 
#include <drizzled/optimizer/range_param.h>
129
 
#include <drizzled/optimizer/sel_arg.h>
130
 
#include <drizzled/optimizer/sel_imerge.h>
131
 
#include <drizzled/optimizer/sel_tree.h>
132
 
#include <drizzled/optimizer/sum.h>
133
 
#include <drizzled/optimizer/table_read_plan.h>
134
 
#include <drizzled/plugin/storage_engine.h>
135
 
#include <drizzled/records.h>
136
 
#include <drizzled/sql_base.h>
137
 
#include <drizzled/sql_select.h>
138
 
#include <drizzled/table_reference.h>
139
 
#include <drizzled/session.h>
140
 
 
141
 
#include <drizzled/unique.h>
142
 
 
143
 
#include <drizzled/temporal.h> /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
 
112
#include "drizzled/sql_base.h"
 
113
#include "drizzled/sql_select.h"
 
114
#include "drizzled/error.h"
 
115
#include "drizzled/optimizer/cost_vector.h"
 
116
#include "drizzled/item/cmpfunc.h"
 
117
#include "drizzled/field/num.h"
 
118
#include "drizzled/check_stack_overrun.h"
 
119
#include "drizzled/optimizer/sum.h"
 
120
#include "drizzled/optimizer/range.h"
 
121
#include "drizzled/optimizer/quick_range.h"
 
122
#include "drizzled/optimizer/quick_range_select.h"
 
123
#include "drizzled/optimizer/quick_group_min_max_select.h"
 
124
#include "drizzled/optimizer/quick_index_merge_select.h"
 
125
#include "drizzled/optimizer/quick_ror_intersect_select.h"
 
126
#include "drizzled/optimizer/quick_ror_union_select.h"
 
127
#include "drizzled/optimizer/table_read_plan.h"
 
128
#include "drizzled/optimizer/sel_arg.h"
 
129
#include "drizzled/optimizer/sel_imerge.h"
 
130
#include "drizzled/optimizer/sel_tree.h"
 
131
#include "drizzled/optimizer/range_param.h"
 
132
#include "drizzled/records.h"
 
133
#include "drizzled/internal/my_sys.h"
 
134
#include "drizzled/internal/iocache.h"
 
135
 
 
136
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
144
137
 
145
138
using namespace std;
146
139
namespace drizzled
218
211
  else
219
212
  {
220
213
    double n_blocks=
221
 
      ceil(static_cast<double>(table->cursor->stats.data_file_length) / IO_SIZE);
 
214
      ceil(uint64_t2double(table->cursor->stats.data_file_length) / IO_SIZE);
222
215
    double busy_blocks=
223
 
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, static_cast<double>(nrows)));
 
216
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
224
217
    if (busy_blocks < 1.0)
225
218
      busy_blocks= 1.0;
226
219
 
235
228
  }
236
229
}
237
230
 
 
231
struct st_ror_scan_info;
 
232
 
238
233
static optimizer::SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
239
234
                               COND *cond_func,
240
235
                               Field *field,
353
348
  {
354
349
    return 0;
355
350
  }
356
 
  if (! (select= new optimizer::SqlSelect()))
 
351
  if (! (select= new optimizer::SqlSelect))
357
352
  {
358
353
    *error= 1;                  // out of memory
359
354
    return 0;
390
385
 
391
386
void optimizer::SqlSelect::cleanup()
392
387
{
393
 
  if (quick)
394
 
  {
395
 
    delete quick;
396
 
    quick= NULL;
397
 
  }
398
 
 
 
388
  delete quick;
 
389
  quick= 0;
399
390
  if (free_cond)
400
391
  {
401
392
    free_cond= 0;
402
393
    delete cond;
403
394
    cond= 0;
404
395
  }
405
 
  file->close_cached_file();
 
396
  close_cached_file(file);
406
397
}
407
398
 
408
399
 
469
460
    MAX_KEY if no such index was found.
470
461
*/
471
462
 
472
 
uint32_t optimizer::get_index_for_order(Table *table, Order *order, ha_rows limit)
 
463
uint32_t optimizer::get_index_for_order(Table *table, order_st *order, ha_rows limit)
473
464
{
474
465
  uint32_t idx;
475
466
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
476
 
  Order *ord;
 
467
  order_st *ord;
477
468
 
478
469
  for (ord= order; ord; ord= ord->next)
479
470
    if (!ord->asc)
548
539
static int fill_used_fields_bitmap(optimizer::Parameter *param)
549
540
{
550
541
  Table *table= param->table;
 
542
  my_bitmap_map *tmp;
551
543
  uint32_t pk;
552
 
  param->tmp_covered_fields.clear();
553
 
  param->needed_fields.resize(table->getShare()->sizeFields());
554
 
  param->needed_fields.reset();
 
544
  param->tmp_covered_fields.setBitmap(0);
 
545
  param->fields_bitmap_size= table->getShare()->column_bitmap_size;
 
546
  if (!(tmp= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)) ||
 
547
      param->needed_fields.init(tmp, table->getShare()->sizeFields()))
 
548
  {
 
549
    return 1;
 
550
  }
555
551
 
556
 
  param->needed_fields|= *table->read_set;
557
 
  param->needed_fields|= *table->write_set;
 
552
  param->needed_fields= *table->read_set;
 
553
  bitmap_union(&param->needed_fields, table->write_set);
558
554
 
559
555
  pk= param->table->getShare()->getPrimaryKey();
560
556
  if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
564
560
    KeyPartInfo *key_part_end= key_part +
565
561
                                 param->table->key_info[pk].key_parts;
566
562
    for (;key_part != key_part_end; ++key_part)
567
 
      param->needed_fields.reset(key_part->fieldnr-1);
 
563
      param->needed_fields.clearBit(key_part->fieldnr-1);
568
564
  }
569
565
  return 0;
570
566
}
645
641
{
646
642
  uint32_t idx;
647
643
  double scan_time;
648
 
  if (quick)
649
 
  {
650
 
    delete quick;
651
 
    quick= NULL;
652
 
  }
 
644
  delete quick;
 
645
  quick=0;
653
646
  needed_reg.reset();
654
647
  quick_keys.reset();
655
648
  if (keys_to_use.none())
742
735
    {
743
736
      int key_for_use= head->find_shortest_key(&head->covering_keys);
744
737
      double key_read_time=
745
 
        param.table->cursor->index_only_read_time(key_for_use, records) +
 
738
        param.table->cursor->index_only_read_time(key_for_use,
 
739
                                                rows2double(records)) +
746
740
        (double) records / TIME_FOR_COMPARE;
747
741
      if (key_read_time < read_time)
748
742
        read_time= key_read_time;
812
806
          objects are not allowed so don't use ROR-intersection for
813
807
          table deletes.
814
808
        */
815
 
        if ((session->getLex()->sql_command != SQLCOM_DELETE))
 
809
        if ((session->lex->sql_command != SQLCOM_DELETE))
816
810
        {
817
811
          /*
818
812
            Get best non-covering ROR-intersection plan and prepare data for
840
834
        optimizer::SEL_IMERGE *imerge= NULL;
841
835
        optimizer::TableReadPlan *best_conj_trp= NULL;
842
836
        optimizer::TableReadPlan *new_conj_trp= NULL;
843
 
        List<optimizer::SEL_IMERGE>::iterator it(tree->merges.begin());
 
837
        List_iterator_fast<optimizer::SEL_IMERGE> it(tree->merges);
844
838
        while ((imerge= it++))
845
839
        {
846
840
          new_conj_trp= get_best_disjunct_quick(session, &param, imerge, best_read_time);
864
858
      records= best_trp->records;
865
859
      if (! (quick= best_trp->make_quick(&param, true)) || quick->init())
866
860
      {
867
 
        /* quick can already be free here */
868
 
        if (quick)
869
 
        {
870
 
          delete quick;
871
 
          quick= NULL;
872
 
        }
 
861
        delete quick;
 
862
        quick= NULL;
873
863
      }
874
864
    }
875
865
 
1045
1035
  /* Calculate cost(rowid_to_row_scan) */
1046
1036
  {
1047
1037
    optimizer::CostVector sweep_cost;
1048
 
    Join *join= param->session->getLex()->select_lex.join;
 
1038
    Join *join= param->session->lex->select_lex.join;
1049
1039
    bool is_interrupted= test(join && join->tables == 1);
1050
1040
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
1051
1041
                        &sweep_cost);
1088
1078
  }
1089
1079
 
1090
1080
build_ror_index_merge:
1091
 
  if (!all_scans_ror_able || param->session->getLex()->sql_command == SQLCOM_DELETE)
 
1081
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1092
1082
    return(imerge_trp);
1093
1083
 
1094
1084
  /* Ok, it is possible to build a ROR-union, try it. */
1121
1111
      cost= param->table->cursor->
1122
1112
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
1123
1113
                        (*cur_child)->records) +
1124
 
              static_cast<double>((*cur_child)->records) / TIME_FOR_COMPARE;
 
1114
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
1125
1115
    }
1126
1116
    else
1127
1117
      cost= read_time;
1163
1153
  double roru_total_cost;
1164
1154
  {
1165
1155
    optimizer::CostVector sweep_cost;
1166
 
    Join *join= param->session->getLex()->select_lex.join;
 
1156
    Join *join= param->session->lex->select_lex.join;
1167
1157
    bool is_interrupted= test(join && join->tables == 1);
1168
1158
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
1169
1159
                        &sweep_cost);
1170
1160
    roru_total_cost= roru_index_costs +
1171
 
                     static_cast<double>(roru_total_records)*log((double)n_child_scans) /
 
1161
                     rows2double(roru_total_records)*log((double)n_child_scans) /
1172
1162
                     (TIME_FOR_COMPARE_ROWID * M_LN2) +
1173
1163
                     sweep_cost.total_cost();
1174
1164
  }
1189
1179
}
1190
1180
 
1191
1181
 
 
1182
typedef struct st_ror_scan_info
 
1183
{
 
1184
  uint32_t      idx;      /* # of used key in param->keys */
 
1185
  uint32_t      keynr;    /* # of used key in table */
 
1186
  ha_rows   records;  /* estimate of # records this scan will return */
 
1187
 
 
1188
  /* Set of intervals over key fields that will be used for row retrieval. */
 
1189
  optimizer::SEL_ARG   *sel_arg;
 
1190
 
 
1191
  /* Fields used in the query and covered by this ROR scan. */
 
1192
  MyBitmap covered_fields;
 
1193
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
 
1194
  int       key_rec_length; /* length of key record (including rowid) */
 
1195
 
 
1196
  /*
 
1197
    Cost of reading all index records with values in sel_arg intervals set
 
1198
    (assuming there is no need to access full table records)
 
1199
  */
 
1200
  double    index_read_cost;
 
1201
  uint32_t      first_uncovered_field; /* first unused bit in covered_fields */
 
1202
  uint32_t      key_components; /* # of parts in the key */
 
1203
} ROR_SCAN_INFO;
 
1204
 
1192
1205
 
1193
1206
/*
1194
 
  Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
 
1207
  Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
1195
1208
  sel_arg set of intervals.
1196
1209
 
1197
1210
  SYNOPSIS
1206
1219
*/
1207
1220
 
1208
1221
static
1209
 
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
 
1222
ROR_SCAN_INFO *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1210
1223
{
1211
 
  optimizer::RorScanInfo *ror_scan= NULL;
 
1224
  ROR_SCAN_INFO *ror_scan;
 
1225
  my_bitmap_map *bitmap_buf;
1212
1226
 
1213
1227
  uint32_t keynr;
1214
1228
 
1215
 
  if (!(ror_scan= (optimizer::RorScanInfo*)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo))))
 
1229
  if (!(ror_scan= (ROR_SCAN_INFO*)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO))))
1216
1230
    return NULL;
1217
1231
 
1218
1232
  ror_scan->idx= idx;
1222
1236
  ror_scan->sel_arg= sel_arg;
1223
1237
  ror_scan->records= param->table->quick_rows[keynr];
1224
1238
 
1225
 
  ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1226
 
  boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1227
 
  tmp_bitset.reset();
 
1239
  if (!(bitmap_buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
 
1240
  {
 
1241
    return NULL;
 
1242
  }
 
1243
 
 
1244
  if (ror_scan->covered_fields.init(bitmap_buf, param->table->getShare()->sizeFields()))
 
1245
  {
 
1246
    return NULL;
 
1247
  }
 
1248
  ror_scan->covered_fields.clearAll();
1228
1249
 
1229
1250
  KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1230
1251
  KeyPartInfo *key_part_end= key_part +
1231
1252
                               param->table->key_info[keynr].key_parts;
1232
 
  for (; key_part != key_part_end; ++key_part)
 
1253
  for (;key_part != key_part_end; ++key_part)
1233
1254
  {
1234
 
    if (param->needed_fields.test(key_part->fieldnr-1))
1235
 
      tmp_bitset.set(key_part->fieldnr-1);
 
1255
    if (param->needed_fields.isBitSet(key_part->fieldnr-1))
 
1256
      ror_scan->covered_fields.setBit(key_part->fieldnr-1);
1236
1257
  }
1237
 
  double rows= param->table->quick_rows[ror_scan->keynr];
 
1258
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1238
1259
  ror_scan->index_read_cost=
1239
1260
    param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1240
 
  ror_scan->covered_fields= tmp_bitset.to_ulong();
1241
 
  return ror_scan;
 
1261
  return(ror_scan);
1242
1262
}
1243
1263
 
1244
1264
 
1245
1265
/*
1246
 
  Compare two optimizer::RorScanInfo** by  E(#records_matched) * key_record_length.
 
1266
  Compare two ROR_SCAN_INFO** by  E(#records_matched) * key_record_length.
1247
1267
  SYNOPSIS
1248
1268
    cmp_ror_scan_info()
1249
1269
      a ptr to first compared value
1255
1275
    1 a > b
1256
1276
*/
1257
1277
 
1258
 
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
 
1278
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
1259
1279
{
1260
 
  double val1= static_cast<double>((*a)->records) * (*a)->key_rec_length;
1261
 
  double val2= static_cast<double>((*b)->records) * (*b)->key_rec_length;
 
1280
  double val1= rows2double((*a)->records) * (*a)->key_rec_length;
 
1281
  double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1262
1282
  return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
1263
1283
}
1264
1284
 
1265
1285
 
1266
1286
/*
1267
 
  Compare two optimizer::RorScanInfo** by
 
1287
  Compare two ROR_SCAN_INFO** by
1268
1288
   (#covered fields in F desc,
1269
1289
    #components asc,
1270
1290
    number of first not covered component asc)
1280
1300
    1 a > b
1281
1301
*/
1282
1302
 
1283
 
static int cmp_ror_scan_info_covering(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
 
1303
static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
1284
1304
{
1285
1305
  if ((*a)->used_fields_covered > (*b)->used_fields_covered)
1286
1306
    return -1;
1298
1318
}
1299
1319
 
1300
1320
/* Auxiliary structure for incremental ROR-intersection creation */
1301
 
typedef struct st_ror_intersect_info
 
1321
typedef struct
1302
1322
{
1303
 
  st_ror_intersect_info()
1304
 
    :
1305
 
      param(NULL),
1306
 
      covered_fields(),
1307
 
      out_rows(0.0),
1308
 
      is_covering(false),
1309
 
      index_records(0),
1310
 
      index_scan_costs(0.0),
1311
 
      total_cost(0.0)
1312
 
  {}
1313
 
 
1314
 
  st_ror_intersect_info(const optimizer::Parameter *in_param)
1315
 
    :
1316
 
      param(in_param),
1317
 
      covered_fields(in_param->table->getShare()->sizeFields()),
1318
 
      out_rows(in_param->table->cursor->stats.records),
1319
 
      is_covering(false),
1320
 
      index_records(0),
1321
 
      index_scan_costs(0.0),
1322
 
      total_cost(0.0)
1323
 
  {
1324
 
    covered_fields.reset();
1325
 
  }
1326
 
 
1327
1323
  const optimizer::Parameter *param;
1328
 
  boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
 
1324
  MyBitmap covered_fields; /* union of fields covered by all scans */
1329
1325
  /*
1330
1326
    Fraction of table records that satisfies conditions of all scans.
1331
1327
    This is the number of full records that will be retrieved if a
1341
1337
} ROR_INTERSECT_INFO;
1342
1338
 
1343
1339
 
 
1340
/*
 
1341
  Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
 
1342
 
 
1343
  SYNOPSIS
 
1344
    ror_intersect_init()
 
1345
      param         Parameter from test_quick_select
 
1346
 
 
1347
  RETURN
 
1348
    allocated structure
 
1349
    NULL on error
 
1350
*/
 
1351
 
 
1352
static
 
1353
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
 
1354
{
 
1355
  ROR_INTERSECT_INFO *info;
 
1356
  my_bitmap_map* buf;
 
1357
  if (!(info= (ROR_INTERSECT_INFO*)param->mem_root->alloc_root(sizeof(ROR_INTERSECT_INFO))))
 
1358
    return NULL;
 
1359
  info->param= param;
 
1360
  if (!(buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
 
1361
    return NULL;
 
1362
  if (info->covered_fields.init(buf, param->table->getShare()->sizeFields()))
 
1363
    return NULL;
 
1364
  info->is_covering= false;
 
1365
  info->index_scan_costs= 0.0;
 
1366
  info->index_records= 0;
 
1367
  info->out_rows= (double) param->table->cursor->stats.records;
 
1368
  info->covered_fields.clearAll();
 
1369
  return info;
 
1370
}
 
1371
 
1344
1372
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1345
1373
                              const ROR_INTERSECT_INFO *src)
1346
1374
{
1445
1473
*/
1446
1474
 
1447
1475
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1448
 
                                   const optimizer::RorScanInfo *scan)
 
1476
                                   const ROR_SCAN_INFO *scan)
1449
1477
{
1450
1478
  double selectivity_mult= 1.0;
1451
1479
  KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
1455
1483
  optimizer::SEL_ARG *tuple_arg= NULL;
1456
1484
  key_part_map keypart_map= 0;
1457
1485
  bool cur_covered;
1458
 
  bool prev_covered= test(info->covered_fields.test(key_part->fieldnr-1));
 
1486
  bool prev_covered= test(info->covered_fields.isBitSet(key_part->fieldnr-1));
1459
1487
  key_range min_range;
1460
1488
  key_range max_range;
1461
1489
  min_range.key= key_val;
1468
1496
       sel_arg= sel_arg->next_key_part)
1469
1497
  {
1470
1498
    cur_covered=
1471
 
      test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
 
1499
      test(info->covered_fields.isBitSet(key_part[sel_arg->part].fieldnr-1));
1472
1500
    if (cur_covered != prev_covered)
1473
1501
    {
1474
1502
      /* create (part1val, ..., part{n-1}val) tuple. */
1494
1522
      if (cur_covered)
1495
1523
      {
1496
1524
        /* uncovered -> covered */
1497
 
        selectivity_mult *= static_cast<double>(records) / prev_records;
 
1525
        double tmp= rows2double(records)/rows2double(prev_records);
 
1526
        selectivity_mult *= tmp;
1498
1527
        prev_records= HA_POS_ERROR;
1499
1528
      }
1500
1529
      else
1507
1536
  }
1508
1537
  if (!prev_covered)
1509
1538
  {
1510
 
    selectivity_mult *= static_cast<double>(info->param->table->quick_rows[scan->keynr]) / prev_records;
 
1539
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
 
1540
                rows2double(prev_records);
 
1541
    selectivity_mult *= tmp;
1511
1542
  }
1512
 
  return selectivity_mult;
 
1543
  return(selectivity_mult);
1513
1544
}
1514
1545
 
1515
1546
 
1550
1581
*/
1551
1582
 
1552
1583
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1553
 
                              optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
 
1584
                              ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
1554
1585
{
1555
1586
  double selectivity_mult= 1.0;
1556
1587
 
1570
1601
      each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
1571
1602
      per check this gives us:
1572
1603
    */
1573
 
    info->index_scan_costs += static_cast<double>(info->index_records) /
 
1604
    info->index_scan_costs += rows2double(info->index_records) /
1574
1605
                              TIME_FOR_COMPARE_ROWID;
1575
1606
  }
1576
1607
  else
1577
1608
  {
1578
1609
    info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1579
1610
    info->index_scan_costs += ror_scan->index_read_cost;
1580
 
    boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1581
 
    info->covered_fields|= tmp_bitset;
1582
 
    if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
 
1611
    bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
 
1612
    if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
 
1613
                                               &info->covered_fields))
1583
1614
    {
1584
1615
      info->is_covering= true;
1585
1616
    }
1586
1617
  }
1587
1618
 
1588
1619
  info->total_cost= info->index_scan_costs;
1589
 
  if (! info->is_covering)
 
1620
  if (!info->is_covering)
1590
1621
  {
1591
1622
    optimizer::CostVector sweep_cost;
1592
 
    Join *join= info->param->session->getLex()->select_lex.join;
 
1623
    Join *join= info->param->session->lex->select_lex.join;
1593
1624
    bool is_interrupted= test(join && join->tables == 1);
1594
1625
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
1595
1626
                        is_interrupted, &sweep_cost);
1637
1668
                                                            optimizer::SEL_TREE *tree,
1638
1669
                                                            double read_time)
1639
1670
{
1640
 
  optimizer::RorScanInfo **ror_scan_mark;
1641
 
  optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
 
1671
  ROR_SCAN_INFO **ror_scan_mark;
 
1672
  ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
1642
1673
 
1643
 
  for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
 
1674
  for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1644
1675
    (*scan)->key_components=
1645
1676
      param->table->key_info[(*scan)->keynr].key_parts;
1646
1677
 
1652
1683
  /*I=set of all covering indexes */
1653
1684
  ror_scan_mark= tree->ror_scans;
1654
1685
 
1655
 
  boost::dynamic_bitset<> *covered_fields= &param->tmp_covered_fields;
1656
 
  if (covered_fields->empty())
 
1686
  MyBitmap *covered_fields= &param->tmp_covered_fields;
 
1687
  if (! covered_fields->getBitmap())
1657
1688
  {
1658
 
    covered_fields->resize(param->table->getShare()->sizeFields());
 
1689
    my_bitmap_map *tmp_bitmap= (my_bitmap_map*)param->mem_root->alloc_root(param->fields_bitmap_size);
 
1690
    covered_fields->setBitmap(tmp_bitmap);
1659
1691
  }
1660
 
  covered_fields->reset();
 
1692
  if (! covered_fields->getBitmap() ||
 
1693
      covered_fields->init(covered_fields->getBitmap(),
 
1694
                           param->table->getShare()->sizeFields()))
 
1695
    return 0;
 
1696
  covered_fields->clearAll();
1661
1697
 
1662
1698
  double total_cost= 0.0f;
1663
1699
  ha_rows records=0;
1671
1707
        number of first not covered component
1672
1708
      Calculate and save these values for each of remaining scans.
1673
1709
    */
1674
 
    for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
 
1710
    for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1675
1711
    {
1676
 
      /* subtract one bitset from the other */
1677
 
      (*scan)->subtractBitset(*covered_fields);
 
1712
      bitmap_subtract(&(*scan)->covered_fields, covered_fields);
1678
1713
      (*scan)->used_fields_covered=
1679
 
        (*scan)->getBitCount();
1680
 
      (*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
 
1714
        (*scan)->covered_fields.getBitsSet();
 
1715
      (*scan)->first_uncovered_field=
 
1716
        (*scan)->covered_fields.getFirst();
1681
1717
    }
1682
1718
 
1683
1719
    internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1684
 
                       sizeof(optimizer::RorScanInfo*),
 
1720
                       sizeof(ROR_SCAN_INFO*),
1685
1721
                       (qsort_cmp)cmp_ror_scan_info_covering);
1686
1722
 
1687
1723
    /* I=I-first(I) */
1690
1726
    if (total_cost > read_time)
1691
1727
      return NULL;
1692
1728
    /* F=F-covered by first(I) */
1693
 
    boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1694
 
    *covered_fields|= tmp_bitset;
1695
 
    all_covered= param->needed_fields.is_subset_of(*covered_fields);
1696
 
  } while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
 
1729
    bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
 
1730
    all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
 
1731
  } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
1697
1732
 
1698
1733
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1699
1734
    return NULL;
1703
1738
    cost total_cost.
1704
1739
  */
1705
1740
  /* Add priority queue use cost. */
1706
 
  total_cost += static_cast<double>(records) *
 
1741
  total_cost += rows2double(records)*
1707
1742
                log((double)(ror_scan_mark - tree->ror_scans)) /
1708
1743
                (TIME_FOR_COMPARE_ROWID * M_LN2);
1709
1744
 
1717
1752
  }
1718
1753
 
1719
1754
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1720
 
  if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
 
1755
  if (!(trp->first_scan= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* best_num)))
1721
1756
    return NULL;
1722
 
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
 
1757
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
1723
1758
  trp->last_scan=  trp->first_scan + best_num;
1724
1759
  trp->is_covering= true;
1725
1760
  trp->read_cost= total_cost;
1808
1843
    return NULL;
1809
1844
 
1810
1845
  /*
1811
 
    Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
 
1846
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1812
1847
    them. Also find and save clustered PK scan if there is one.
1813
1848
  */
1814
 
  optimizer::RorScanInfo **cur_ror_scan= NULL;
1815
 
  optimizer::RorScanInfo *cpk_scan= NULL;
 
1849
  ROR_SCAN_INFO **cur_ror_scan= NULL;
 
1850
  ROR_SCAN_INFO *cpk_scan= NULL;
1816
1851
  uint32_t cpk_no= 0;
1817
1852
  bool cpk_scan_used= false;
1818
1853
 
1819
 
  if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
 
1854
  if (! (tree->ror_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* param->keys)))
1820
1855
  {
1821
1856
    return NULL;
1822
1857
  }
1825
1860
 
1826
1861
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1827
1862
  {
1828
 
    optimizer::RorScanInfo *scan;
 
1863
    ROR_SCAN_INFO *scan;
1829
1864
    if (! tree->ror_scans_map.test(idx))
1830
1865
      continue;
1831
 
    if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
 
1866
    if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1832
1867
      return NULL;
1833
1868
    if (param->real_keynr[idx] == cpk_no)
1834
1869
    {
1842
1877
  tree->ror_scans_end= cur_ror_scan;
1843
1878
  /*
1844
1879
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1845
 
    optimizer::RorScanInfo's.
 
1880
    ROR_SCAN_INFO's.
1846
1881
    Step 2: Get best ROR-intersection using an approximate algorithm.
1847
1882
  */
1848
 
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
 
1883
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
1849
1884
                     (qsort_cmp)cmp_ror_scan_info);
1850
1885
 
1851
 
  optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1852
 
  optimizer::RorScanInfo **intersect_scans_end= NULL;
1853
 
  if (! (intersect_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*) * tree->n_ror_scans)))
 
1886
  ROR_SCAN_INFO **intersect_scans= NULL; /* ROR scans used in index intersection */
 
1887
  ROR_SCAN_INFO **intersect_scans_end= NULL;
 
1888
  if (! (intersect_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*) * tree->n_ror_scans)))
1854
1889
    return NULL;
1855
1890
  intersect_scans_end= intersect_scans;
1856
1891
 
1857
1892
  /* Create and incrementally update ROR intersection. */
1858
 
  ROR_INTERSECT_INFO intersect(param);
1859
 
  ROR_INTERSECT_INFO intersect_best(param);
 
1893
  ROR_INTERSECT_INFO *intersect= NULL;
 
1894
  ROR_INTERSECT_INFO *intersect_best= NULL;
 
1895
  if (! (intersect= ror_intersect_init(param)) ||
 
1896
      ! (intersect_best= ror_intersect_init(param)))
 
1897
    return NULL;
1860
1898
 
1861
1899
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
1862
 
  optimizer::RorScanInfo **intersect_scans_best= NULL;
 
1900
  ROR_SCAN_INFO **intersect_scans_best= NULL;
1863
1901
  cur_ror_scan= tree->ror_scans;
1864
1902
  intersect_scans_best= intersect_scans;
1865
 
  while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
 
1903
  while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1866
1904
  {
1867
1905
    /* S= S + first(R);  R= R - first(R); */
1868
 
    if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
 
1906
    if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1869
1907
    {
1870
1908
      cur_ror_scan++;
1871
1909
      continue;
1873
1911
 
1874
1912
    *(intersect_scans_end++)= *(cur_ror_scan++);
1875
1913
 
1876
 
    if (intersect.total_cost < min_cost)
 
1914
    if (intersect->total_cost < min_cost)
1877
1915
    {
1878
1916
      /* Local minimum found, save it */
1879
 
      ror_intersect_cpy(&intersect_best, &intersect);
 
1917
      ror_intersect_cpy(intersect_best, intersect);
1880
1918
      intersect_scans_best= intersect_scans_end;
1881
 
      min_cost = intersect.total_cost;
 
1919
      min_cost = intersect->total_cost;
1882
1920
    }
1883
1921
  }
1884
1922
 
1887
1925
    return NULL;
1888
1926
  }
1889
1927
 
1890
 
  *are_all_covering= intersect.is_covering;
 
1928
  *are_all_covering= intersect->is_covering;
1891
1929
  uint32_t best_num= intersect_scans_best - intersect_scans;
1892
 
  ror_intersect_cpy(&intersect, &intersect_best);
 
1930
  ror_intersect_cpy(intersect, intersect_best);
1893
1931
 
1894
1932
  /*
1895
1933
    Ok, found the best ROR-intersection of non-CPK key scans.
1896
1934
    Check if we should add a CPK scan. If the obtained ROR-intersection is
1897
1935
    covering, it doesn't make sense to add CPK scan.
1898
1936
  */
1899
 
  if (cpk_scan && ! intersect.is_covering)
 
1937
  if (cpk_scan && !intersect->is_covering)
1900
1938
  {
1901
 
    if (ror_intersect_add(&intersect, cpk_scan, true) &&
1902
 
        (intersect.total_cost < min_cost))
 
1939
    if (ror_intersect_add(intersect, cpk_scan, true) &&
 
1940
        (intersect->total_cost < min_cost))
1903
1941
    {
1904
1942
      cpk_scan_used= true;
1905
1943
      intersect_best= intersect; //just set pointer here
1914
1952
      return trp;
1915
1953
 
1916
1954
    if (! (trp->first_scan=
1917
 
           (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)*best_num)))
 
1955
           (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)*best_num)))
1918
1956
      return NULL;
1919
 
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
 
1957
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
1920
1958
    trp->last_scan=  trp->first_scan + best_num;
1921
 
    trp->is_covering= intersect_best.is_covering;
1922
 
    trp->read_cost= intersect_best.total_cost;
 
1959
    trp->is_covering= intersect_best->is_covering;
 
1960
    trp->read_cost= intersect_best->total_cost;
1923
1961
    /* Prevent divisons by zero */
1924
 
    ha_rows best_rows = double2rows(intersect_best.out_rows);
 
1962
    ha_rows best_rows = double2rows(intersect_best->out_rows);
1925
1963
    if (! best_rows)
1926
1964
      best_rows= 1;
1927
1965
    set_if_smaller(param->table->quick_condition_rows, best_rows);
1928
1966
    trp->records= best_rows;
1929
 
    trp->index_scan_costs= intersect_best.index_scan_costs;
 
1967
    trp->index_scan_costs= intersect_best->index_scan_costs;
1930
1968
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
1931
1969
  }
1932
1970
  return trp;
2565
2603
 
2566
2604
  if (cond->type() == Item::COND_ITEM)
2567
2605
  {
2568
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2606
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2569
2607
 
2570
2608
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
2571
2609
    {
2977
3015
   * it is, then we must convert to the highest Timestamp value (or lowest,
2978
3016
   * depending on whether the datetime is before or after the epoch.
2979
3017
   */
2980
 
  if (field->is_timestamp())
 
3018
  if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
2981
3019
  {
2982
3020
    /*
2983
3021
     * The left-side of the range comparison is a timestamp field.  Therefore,
3123
3161
    tree= &optimizer::null_element;                        // cmp with NULL is never true
3124
3162
    goto end;
3125
3163
  }
3126
 
 
3127
 
  /*
3128
 
    Any predicate except "<=>"(null-safe equality operator) involving NULL as a
3129
 
    constant is always FALSE
3130
 
    Put IMPOSSIBLE Tree(null_element) here.
3131
 
  */  
3132
 
  if (type != Item_func::EQUAL_FUNC && field->is_real_null())
3133
 
  {
3134
 
    tree= &optimizer::null_element;
3135
 
    goto end;
3136
 
  }
3137
 
 
3138
3164
  str= (unsigned char*) alloc->alloc_root(key_part->store_length+1);
3139
3165
  if (!str)
3140
3166
    goto end;
3258
3284
 
3259
3285
#define CLONE_KEY1_MAYBE 1
3260
3286
#define CLONE_KEY2_MAYBE 2
 
3287
#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
3261
3288
 
3262
 
static uint32_t swap_clone_flag(uint32_t a)
3263
 
{
3264
 
  return ((a & 1) << 1) | ((a & 2) >> 1);
3265
 
}
3266
3289
 
3267
3290
static optimizer::SEL_TREE *
3268
3291
tree_and(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
3314
3337
  /* dispose index_merge if there is a "range" option */
3315
3338
  if (result_keys.any())
3316
3339
  {
3317
 
    tree1->merges.clear();
 
3340
    tree1->merges.empty();
3318
3341
    return(tree1);
3319
3342
  }
3320
3343
 
3738
3761
  /* Ok got a tuple */
3739
3762
  RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
3740
3763
 
3741
 
  range->ptr= (char*)(size_t)(key_tree->part);
 
3764
  range->ptr= (char*)(int)(key_tree->part);
3742
3765
  {
3743
3766
    range->range_flag= cur->min_key_flag | cur->max_key_flag;
3744
3767
 
3859
3882
      !(pk_is_clustered && keynr == param->table->getShare()->getPrimaryKey()))
3860
3883
     *mrr_flags |= HA_MRR_INDEX_ONLY;
3861
3884
 
3862
 
  if (session->getLex()->sql_command != SQLCOM_SELECT)
 
3885
  if (session->lex->sql_command != SQLCOM_SELECT)
3863
3886
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
3864
3887
 
3865
3888
  *bufsize= param->session->variables.read_rnd_buff_size;
3982
4005
                            uint32_t mrr_buf_size,
3983
4006
                            memory::Root *parent_alloc)
3984
4007
{
3985
 
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3986
 
                                                                      param->table,
3987
 
                                                                      param->real_keynr[idx],
3988
 
                                                                      test(parent_alloc),
3989
 
                                                                      NULL);
 
4008
  optimizer::QuickRangeSelect *quick= NULL;
 
4009
  bool create_err= false;
 
4010
 
 
4011
  quick= new optimizer::QuickRangeSelect(param->session,
 
4012
                                         param->table,
 
4013
                                         param->real_keynr[idx],
 
4014
                                         test(parent_alloc),
 
4015
                                         NULL,
 
4016
                                         &create_err);
3990
4017
 
3991
4018
  if (quick)
3992
4019
  {
3993
 
          if (get_quick_keys(param,
 
4020
    if (create_err ||
 
4021
              get_quick_keys(param,
3994
4022
                       quick,
3995
4023
                       param->key[idx],
3996
4024
                       key_tree,
4211
4239
}
4212
4240
 
4213
4241
 
4214
 
bool optimizer::QuickSelectInterface::is_keys_used(const boost::dynamic_bitset<>& fields)
 
4242
bool optimizer::QuickSelectInterface::is_keys_used(const MyBitmap *fields)
4215
4243
{
4216
4244
  return is_key_used(head, index, fields);
4217
4245
}
4241
4269
                                                                 table_reference_st *ref,
4242
4270
                                                                 ha_rows records)
4243
4271
{
4244
 
  memory::Root *old_root= NULL;
4245
 
  memory::Root *alloc= NULL;
 
4272
  memory::Root *old_root, *alloc;
 
4273
  optimizer::QuickRangeSelect *quick= NULL;
4246
4274
  KeyInfo *key_info = &table->key_info[ref->key];
4247
4275
  KEY_PART *key_part;
4248
4276
  optimizer::QuickRange *range= NULL;
4249
4277
  uint32_t part;
 
4278
  bool create_err= false;
4250
4279
  optimizer::CostVector cost;
4251
4280
 
4252
4281
  old_root= session->mem_root;
4253
4282
  /* The following call may change session->mem_root */
4254
 
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
 
4283
  quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0, &create_err);
4255
4284
  /* save mem_root set by QuickRangeSelect constructor */
4256
4285
  alloc= session->mem_root;
4257
4286
  /*
4260
4289
  */
4261
4290
  session->mem_root= old_root;
4262
4291
 
4263
 
  if (! quick)
 
4292
  if (!quick || create_err)
4264
4293
    return 0;                   /* no ranges found */
4265
4294
  if (quick->init())
4266
4295
    goto err;
4319
4348
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
4320
4349
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
4321
4350
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
4322
 
  if (session->getLex()->sql_command != SQLCOM_SELECT)
 
4351
  if (session->lex->sql_command != SQLCOM_SELECT)
4323
4352
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
4324
4353
 
4325
4354
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
4567
4596
get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree)
4568
4597
{
4569
4598
  Session *session= param->session;
4570
 
  Join *join= session->getLex()->current_select->join;
 
4599
  Join *join= session->lex->current_select->join;
4571
4600
  Table *table= param->table;
4572
4601
  bool have_min= false;              /* true if there is a MIN function. */
4573
4602
  bool have_max= false;              /* true if there is a MAX function. */
4582
4611
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
4583
4612
  optimizer::GroupMinMaxReadPlan *read_plan= NULL; /* The eventually constructed TRP. */
4584
4613
  uint32_t key_part_nr;
4585
 
  Order *tmp_group= NULL;
 
4614
  order_st *tmp_group= NULL;
4586
4615
  Item *item= NULL;
4587
4616
  Item_field *item_field= NULL;
4588
4617
 
4599
4628
    return NULL;
4600
4629
 
4601
4630
  /* Analyze the query in more detail. */
4602
 
  List<Item>::iterator select_items_it(join->fields_list.begin());
 
4631
  List_iterator<Item> select_items_it(join->fields_list);
4603
4632
 
4604
4633
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
4605
4634
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
4755
4784
    */
4756
4785
    else if (join->select_distinct)
4757
4786
    {
4758
 
      select_items_it= join->fields_list.begin();
 
4787
      select_items_it.rewind();
4759
4788
      used_key_parts_map.reset();
4760
4789
      uint32_t max_key_part= 0;
4761
4790
      while ((item= select_items_it++))
5036
5065
  Item::Type cond_type= cond->type();
5037
5066
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
5038
5067
  {
5039
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
5068
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
5040
5069
    Item *and_or_arg= NULL;
5041
5070
    while ((and_or_arg= li++))
5042
5071
    {
5471
5500
  optimizer::QuickGroupMinMaxSelect *quick= NULL;
5472
5501
 
5473
5502
  quick= new optimizer::QuickGroupMinMaxSelect(param->table,
5474
 
                                               param->session->getLex()->current_select->join,
 
5503
                                               param->session->lex->current_select->join,
5475
5504
                                               have_min,
5476
5505
                                               have_max,
5477
5506
                                               min_max_arg_part,
5571
5600
}
5572
5601
 
5573
5602
 
5574
 
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5575
 
{
5576
 
  boost::dynamic_bitset<> map= bitsToBitset();
5577
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5578
 
  {
5579
 
    if (! map.test(i))
5580
 
    {
5581
 
      return i;
5582
 
    }
5583
 
  }
5584
 
  return map.size();
5585
 
}
5586
 
 
5587
 
 
5588
 
size_t optimizer::RorScanInfo::getBitCount() const
5589
 
{
5590
 
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5591
 
  return tmp_bitset.count();
5592
 
}
5593
 
 
5594
 
 
5595
 
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5596
 
{
5597
 
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5598
 
  tmp_bitset-= in_bitset;
5599
 
  covered_fields= tmp_bitset.to_ulong();
5600
 
}
5601
 
 
5602
 
 
5603
 
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5604
 
{
5605
 
  string res;
5606
 
  uint64_t conv= covered_fields;
5607
 
  while (conv)
5608
 
  {
5609
 
    res.push_back((conv & 1) + '0');
5610
 
    conv>>= 1;
5611
 
  }
5612
 
  if (! res.empty())
5613
 
  {
5614
 
    std::reverse(res.begin(), res.end());
5615
 
  }
5616
 
  string final(covered_fields_size - res.length(), '0');
5617
 
  final.append(res);
5618
 
  return (boost::dynamic_bitset<>(final));
5619
 
}
5620
 
 
5621
 
 
5622
5603
} /* namespace drizzled */