1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
4
* Copyright (C) 2008-2009 Sun Microsystems
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
109
109
#include <vector>
110
110
#include <algorithm>
112
#include <boost/dynamic_bitset.hpp>
114
#include "drizzled/check_stack_overrun.h"
112
#include "drizzled/sql_base.h"
113
#include "drizzled/sql_select.h"
115
114
#include "drizzled/error.h"
115
#include "drizzled/optimizer/cost_vector.h"
116
#include "drizzled/item/cmpfunc.h"
116
117
#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"
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"
121
123
#include "drizzled/optimizer/quick_group_min_max_select.h"
122
124
#include "drizzled/optimizer/quick_index_merge_select.h"
123
#include "drizzled/optimizer/quick_range.h"
124
#include "drizzled/optimizer/quick_range_select.h"
125
125
#include "drizzled/optimizer/quick_ror_intersect_select.h"
126
126
#include "drizzled/optimizer/quick_ror_union_select.h"
127
#include "drizzled/optimizer/range.h"
128
#include "drizzled/optimizer/range_param.h"
127
#include "drizzled/optimizer/table_read_plan.h"
129
128
#include "drizzled/optimizer/sel_arg.h"
130
129
#include "drizzled/optimizer/sel_imerge.h"
131
130
#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"
131
#include "drizzled/optimizer/range_param.h"
135
132
#include "drizzled/records.h"
136
#include "drizzled/sql_base.h"
137
#include "drizzled/sql_select.h"
138
#include "drizzled/table_reference.h"
133
#include "drizzled/internal/my_sys.h"
134
#include "drizzled/internal/iocache.h"
140
136
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
466
464
MAX_KEY if no such index was found.
469
uint32_t optimizer::get_index_for_order(Table *table, Order *order, ha_rows limit)
467
uint32_t optimizer::get_index_for_order(Table *table, order_st *order, ha_rows limit)
472
470
uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
475
473
for (ord= order; ord; ord= ord->next)
545
543
static int fill_used_fields_bitmap(optimizer::Parameter *param)
547
545
Table *table= param->table;
549
param->tmp_covered_fields.clear();
550
param->needed_fields.resize(table->getShare()->sizeFields());
551
param->needed_fields.reset();
548
param->tmp_covered_fields.setBitmap(0);
549
param->fields_bitmap_size= table->getShare()->column_bitmap_size;
550
if (!(tmp= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)) ||
551
param->needed_fields.init(tmp, table->getShare()->sizeFields()))
553
param->needed_fields|= *table->read_set;
554
param->needed_fields|= *table->write_set;
556
param->needed_fields= *table->read_set;
557
bitmap_union(¶m->needed_fields, table->write_set);
556
559
pk= param->table->getShare()->getPrimaryKey();
557
560
if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
561
564
KeyPartInfo *key_part_end= key_part +
562
565
param->table->key_info[pk].key_parts;
563
566
for (;key_part != key_part_end; ++key_part)
564
param->needed_fields.reset(key_part->fieldnr-1);
567
param->needed_fields.clearBit(key_part->fieldnr-1);
1193
typedef struct st_ror_scan_info
1195
uint32_t idx; /* # of used key in param->keys */
1196
uint32_t keynr; /* # of used key in table */
1197
ha_rows records; /* estimate of # records this scan will return */
1199
/* Set of intervals over key fields that will be used for row retrieval. */
1200
optimizer::SEL_ARG *sel_arg;
1202
/* Fields used in the query and covered by this ROR scan. */
1203
MyBitmap covered_fields;
1204
uint32_t used_fields_covered; /* # of set bits in covered_fields */
1205
int key_rec_length; /* length of key record (including rowid) */
1208
Cost of reading all index records with values in sel_arg intervals set
1209
(assuming there is no need to access full table records)
1211
double index_read_cost;
1212
uint32_t first_uncovered_field; /* first unused bit in covered_fields */
1213
uint32_t key_components; /* # of parts in the key */
1192
Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
1218
Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
1193
1219
sel_arg set of intervals.
1207
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1233
ROR_SCAN_INFO *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1209
optimizer::RorScanInfo *ror_scan= NULL;
1235
ROR_SCAN_INFO *ror_scan;
1236
my_bitmap_map *bitmap_buf;
1211
1238
uint32_t keynr;
1213
if (!(ror_scan= (optimizer::RorScanInfo*)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo))))
1240
if (!(ror_scan= (ROR_SCAN_INFO*)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO))))
1216
1243
ror_scan->idx= idx;
1220
1247
ror_scan->sel_arg= sel_arg;
1221
1248
ror_scan->records= param->table->quick_rows[keynr];
1223
ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1224
boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1250
if (!(bitmap_buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1255
if (ror_scan->covered_fields.init(bitmap_buf, param->table->getShare()->sizeFields()))
1259
ror_scan->covered_fields.clearAll();
1227
1261
KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1228
1262
KeyPartInfo *key_part_end= key_part +
1229
1263
param->table->key_info[keynr].key_parts;
1230
for (; key_part != key_part_end; ++key_part)
1264
for (;key_part != key_part_end; ++key_part)
1232
if (param->needed_fields.test(key_part->fieldnr-1))
1233
tmp_bitset.set(key_part->fieldnr-1);
1266
if (param->needed_fields.isBitSet(key_part->fieldnr-1))
1267
ror_scan->covered_fields.setBit(key_part->fieldnr-1);
1235
1269
double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1236
1270
ror_scan->index_read_cost=
1237
1271
param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1238
ror_scan->covered_fields= tmp_bitset.to_ulong();
1244
Compare two optimizer::RorScanInfo** by E(#records_matched) * key_record_length.
1277
Compare two ROR_SCAN_INFO** by E(#records_matched) * key_record_length.
1246
1279
cmp_ror_scan_info()
1247
1280
a ptr to first compared value
1256
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
1289
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
1258
1291
double val1= rows2double((*a)->records) * (*a)->key_rec_length;
1259
1292
double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1298
1331
/* Auxiliary structure for incremental ROR-intersection creation */
1299
typedef struct st_ror_intersect_info
1301
st_ror_intersect_info()
1308
index_scan_costs(0.0),
1312
st_ror_intersect_info(const optimizer::Parameter *in_param)
1315
covered_fields(in_param->table->getShare()->sizeFields()),
1316
out_rows(in_param->table->cursor->stats.records),
1319
index_scan_costs(0.0),
1322
covered_fields.reset();
1325
1334
const optimizer::Parameter *param;
1326
boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
1335
MyBitmap covered_fields; /* union of fields covered by all scans */
1328
1337
Fraction of table records that satisfies conditions of all scans.
1329
1338
This is the number of full records that will be retrieved if a
1339
1348
} ROR_INTERSECT_INFO;
1352
Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
1355
ror_intersect_init()
1356
param Parameter from test_quick_select
1364
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
1366
ROR_INTERSECT_INFO *info;
1368
if (!(info= (ROR_INTERSECT_INFO*)param->mem_root->alloc_root(sizeof(ROR_INTERSECT_INFO))))
1371
if (!(buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1373
if (info->covered_fields.init(buf, param->table->getShare()->sizeFields()))
1375
info->is_covering= false;
1376
info->index_scan_costs= 0.0;
1377
info->index_records= 0;
1378
info->out_rows= (double) param->table->cursor->stats.records;
1379
info->covered_fields.clearAll();
1342
1383
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1343
1384
const ROR_INTERSECT_INFO *src)
1445
1486
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1446
const optimizer::RorScanInfo *scan)
1487
const ROR_SCAN_INFO *scan)
1448
1489
double selectivity_mult= 1.0;
1449
1490
KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
1466
1507
sel_arg= sel_arg->next_key_part)
1469
test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
1510
test(info->covered_fields.isBitSet(key_part[sel_arg->part].fieldnr-1));
1470
1511
if (cur_covered != prev_covered)
1472
1513
/* create (part1val, ..., part{n-1}val) tuple. */
1553
1594
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1554
optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
1595
ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
1556
1597
double selectivity_mult= 1.0;
1579
1620
info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1580
1621
info->index_scan_costs += ror_scan->index_read_cost;
1581
boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1582
info->covered_fields|= tmp_bitset;
1583
if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
1622
bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
1623
if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
1624
&info->covered_fields))
1585
1626
info->is_covering= true;
1589
1630
info->total_cost= info->index_scan_costs;
1590
if (! info->is_covering)
1631
if (!info->is_covering)
1592
1633
optimizer::CostVector sweep_cost;
1593
1634
Join *join= info->param->session->lex->select_lex.join;
1638
1679
optimizer::SEL_TREE *tree,
1639
1680
double read_time)
1641
optimizer::RorScanInfo **ror_scan_mark;
1642
optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
1682
ROR_SCAN_INFO **ror_scan_mark;
1683
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
1644
for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1685
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1645
1686
(*scan)->key_components=
1646
1687
param->table->key_info[(*scan)->keynr].key_parts;
1653
1694
/*I=set of all covering indexes */
1654
1695
ror_scan_mark= tree->ror_scans;
1656
boost::dynamic_bitset<> *covered_fields= ¶m->tmp_covered_fields;
1657
if (covered_fields->empty())
1697
MyBitmap *covered_fields= ¶m->tmp_covered_fields;
1698
if (! covered_fields->getBitmap())
1659
covered_fields->resize(param->table->getShare()->sizeFields());
1700
my_bitmap_map *tmp_bitmap= (my_bitmap_map*)param->mem_root->alloc_root(param->fields_bitmap_size);
1701
covered_fields->setBitmap(tmp_bitmap);
1661
covered_fields->reset();
1703
if (! covered_fields->getBitmap() ||
1704
covered_fields->init(covered_fields->getBitmap(),
1705
param->table->getShare()->sizeFields()))
1707
covered_fields->clearAll();
1663
1709
double total_cost= 0.0f;
1664
1710
ha_rows records=0;
1672
1718
number of first not covered component
1673
1719
Calculate and save these values for each of remaining scans.
1675
for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1721
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1677
/* subtract one bitset from the other */
1678
(*scan)->subtractBitset(*covered_fields);
1723
bitmap_subtract(&(*scan)->covered_fields, covered_fields);
1679
1724
(*scan)->used_fields_covered=
1680
(*scan)->getBitCount();
1681
(*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
1725
(*scan)->covered_fields.getBitsSet();
1726
(*scan)->first_uncovered_field=
1727
(*scan)->covered_fields.getFirst();
1684
1730
internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1685
sizeof(optimizer::RorScanInfo*),
1731
sizeof(ROR_SCAN_INFO*),
1686
1732
(qsort_cmp)cmp_ror_scan_info_covering);
1688
1734
/* I=I-first(I) */
1691
1737
if (total_cost > read_time)
1693
1739
/* F=F-covered by first(I) */
1694
boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1695
*covered_fields|= tmp_bitset;
1696
all_covered= param->needed_fields.is_subset_of(*covered_fields);
1697
} while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
1740
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
1741
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
1742
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
1699
1744
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1720
1765
uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1721
if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
1766
if (!(trp->first_scan= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* best_num)))
1723
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
1768
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
1724
1769
trp->last_scan= trp->first_scan + best_num;
1725
1770
trp->is_covering= true;
1726
1771
trp->read_cost= total_cost;
1812
Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
1857
Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1813
1858
them. Also find and save clustered PK scan if there is one.
1815
optimizer::RorScanInfo **cur_ror_scan= NULL;
1816
optimizer::RorScanInfo *cpk_scan= NULL;
1860
ROR_SCAN_INFO **cur_ror_scan= NULL;
1861
ROR_SCAN_INFO *cpk_scan= NULL;
1817
1862
uint32_t cpk_no= 0;
1818
1863
bool cpk_scan_used= false;
1820
if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
1865
if (! (tree->ror_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* param->keys)))
1827
1872
for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1829
optimizer::RorScanInfo *scan;
1874
ROR_SCAN_INFO *scan;
1830
1875
if (! tree->ror_scans_map.test(idx))
1832
if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
1877
if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1834
1879
if (param->real_keynr[idx] == cpk_no)
1843
1888
tree->ror_scans_end= cur_ror_scan;
1845
1890
Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1846
optimizer::RorScanInfo's.
1847
1892
Step 2: Get best ROR-intersection using an approximate algorithm.
1849
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
1894
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
1850
1895
(qsort_cmp)cmp_ror_scan_info);
1852
optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1853
optimizer::RorScanInfo **intersect_scans_end= NULL;
1854
if (! (intersect_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*) * tree->n_ror_scans)))
1897
ROR_SCAN_INFO **intersect_scans= NULL; /* ROR scans used in index intersection */
1898
ROR_SCAN_INFO **intersect_scans_end= NULL;
1899
if (! (intersect_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*) * tree->n_ror_scans)))
1856
1901
intersect_scans_end= intersect_scans;
1858
1903
/* Create and incrementally update ROR intersection. */
1859
ROR_INTERSECT_INFO intersect(param);
1860
ROR_INTERSECT_INFO intersect_best(param);
1904
ROR_INTERSECT_INFO *intersect= NULL;
1905
ROR_INTERSECT_INFO *intersect_best= NULL;
1906
if (! (intersect= ror_intersect_init(param)) ||
1907
! (intersect_best= ror_intersect_init(param)))
1862
1910
/* [intersect_scans,intersect_scans_best) will hold the best intersection */
1863
optimizer::RorScanInfo **intersect_scans_best= NULL;
1911
ROR_SCAN_INFO **intersect_scans_best= NULL;
1864
1912
cur_ror_scan= tree->ror_scans;
1865
1913
intersect_scans_best= intersect_scans;
1866
while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
1914
while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1868
1916
/* S= S + first(R); R= R - first(R); */
1869
if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
1917
if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1871
1919
cur_ror_scan++;
1875
1923
*(intersect_scans_end++)= *(cur_ror_scan++);
1877
if (intersect.total_cost < min_cost)
1925
if (intersect->total_cost < min_cost)
1879
1927
/* Local minimum found, save it */
1880
ror_intersect_cpy(&intersect_best, &intersect);
1928
ror_intersect_cpy(intersect_best, intersect);
1881
1929
intersect_scans_best= intersect_scans_end;
1882
min_cost = intersect.total_cost;
1930
min_cost = intersect->total_cost;
1891
*are_all_covering= intersect.is_covering;
1939
*are_all_covering= intersect->is_covering;
1892
1940
uint32_t best_num= intersect_scans_best - intersect_scans;
1893
ror_intersect_cpy(&intersect, &intersect_best);
1941
ror_intersect_cpy(intersect, intersect_best);
1896
1944
Ok, found the best ROR-intersection of non-CPK key scans.
1897
1945
Check if we should add a CPK scan. If the obtained ROR-intersection is
1898
1946
covering, it doesn't make sense to add CPK scan.
1900
if (cpk_scan && ! intersect.is_covering)
1948
if (cpk_scan && !intersect->is_covering)
1902
if (ror_intersect_add(&intersect, cpk_scan, true) &&
1903
(intersect.total_cost < min_cost))
1950
if (ror_intersect_add(intersect, cpk_scan, true) &&
1951
(intersect->total_cost < min_cost))
1905
1953
cpk_scan_used= true;
1906
1954
intersect_best= intersect; //just set pointer here
1917
1965
if (! (trp->first_scan=
1918
(optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)*best_num)))
1966
(ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)*best_num)))
1920
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
1968
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
1921
1969
trp->last_scan= trp->first_scan + best_num;
1922
trp->is_covering= intersect_best.is_covering;
1923
trp->read_cost= intersect_best.total_cost;
1970
trp->is_covering= intersect_best->is_covering;
1971
trp->read_cost= intersect_best->total_cost;
1924
1972
/* Prevent divisons by zero */
1925
ha_rows best_rows = double2rows(intersect_best.out_rows);
1973
ha_rows best_rows = double2rows(intersect_best->out_rows);
1926
1974
if (! best_rows)
1928
1976
set_if_smaller(param->table->quick_condition_rows, best_rows);
1929
1977
trp->records= best_rows;
1930
trp->index_scan_costs= intersect_best.index_scan_costs;
1978
trp->index_scan_costs= intersect_best->index_scan_costs;
1931
1979
trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
3260
3308
#define CLONE_KEY1_MAYBE 1
3261
3309
#define CLONE_KEY2_MAYBE 2
3310
#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
3263
static uint32_t swap_clone_flag(uint32_t a)
3265
return ((a & 1) << 1) | ((a & 2) >> 1);
3268
3313
static optimizer::SEL_TREE *
3269
3314
tree_and(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
3983
4028
uint32_t mrr_buf_size,
3984
4029
memory::Root *parent_alloc)
3986
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3988
param->real_keynr[idx],
4031
optimizer::QuickRangeSelect *quick= NULL;
4032
bool create_err= false;
4034
quick= new optimizer::QuickRangeSelect(param->session,
4036
param->real_keynr[idx],
3994
if (get_quick_keys(param,
4044
get_quick_keys(param,
3996
4046
param->key[idx],
4242
4292
table_reference_st *ref,
4243
4293
ha_rows records)
4245
memory::Root *old_root= NULL;
4246
memory::Root *alloc= NULL;
4295
memory::Root *old_root, *alloc;
4296
optimizer::QuickRangeSelect *quick= NULL;
4247
4297
KeyInfo *key_info = &table->key_info[ref->key];
4248
4298
KEY_PART *key_part;
4249
4299
optimizer::QuickRange *range= NULL;
4301
bool create_err= false;
4251
4302
optimizer::CostVector cost;
4253
4304
old_root= session->mem_root;
4254
4305
/* The following call may change session->mem_root */
4255
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
4306
quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0, &create_err);
4256
4307
/* save mem_root set by QuickRangeSelect constructor */
4257
4308
alloc= session->mem_root;
5575
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5577
boost::dynamic_bitset<> map= bitsToBitset();
5578
for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5589
size_t optimizer::RorScanInfo::getBitCount() const
5591
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5592
return tmp_bitset.count();
5596
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5598
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5599
tmp_bitset-= in_bitset;
5600
covered_fields= tmp_bitset.to_ulong();
5604
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5607
uint64_t conv= covered_fields;
5610
res.push_back((conv & 1) + '0');
5615
std::reverse(res.begin(), res.end());
5617
string final(covered_fields_size - res.length(), '0');
5619
return (boost::dynamic_bitset<>(final));
5623
5626
} /* namespace drizzled */