109
109
#include <vector>
110
110
#include <algorithm>
112
#include <boost/dynamic_bitset.hpp>
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>
141
#include <drizzled/unique.h>
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"
136
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
145
138
using namespace std;
146
139
namespace drizzled
469
460
MAX_KEY if no such index was found.
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)
475
466
uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
478
469
for (ord= order; ord; ord= ord->next)
548
539
static int fill_used_fields_bitmap(optimizer::Parameter *param)
550
541
Table *table= param->table;
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()))
556
param->needed_fields|= *table->read_set;
557
param->needed_fields|= *table->write_set;
552
param->needed_fields= *table->read_set;
553
bitmap_union(¶m->needed_fields, table->write_set);
559
555
pk= param->table->getShare()->getPrimaryKey();
560
556
if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
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++))
846
840
new_conj_trp= get_best_disjunct_quick(session, ¶m, imerge, best_read_time);
1045
1035
/* Calculate cost(rowid_to_row_scan) */
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,
1163
1153
double roru_total_cost;
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,
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();
1182
typedef struct st_ror_scan_info
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 */
1188
/* Set of intervals over key fields that will be used for row retrieval. */
1189
optimizer::SEL_ARG *sel_arg;
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) */
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)
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 */
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.
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)
1211
optimizer::RorScanInfo *ror_scan= NULL;
1224
ROR_SCAN_INFO *ror_scan;
1225
my_bitmap_map *bitmap_buf;
1213
1227
uint32_t keynr;
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))))
1218
1232
ror_scan->idx= idx;
1222
1236
ror_scan->sel_arg= sel_arg;
1223
1237
ror_scan->records= param->table->quick_rows[keynr];
1225
ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1226
boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1239
if (!(bitmap_buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1244
if (ror_scan->covered_fields.init(bitmap_buf, param->table->getShare()->sizeFields()))
1248
ror_scan->covered_fields.clearAll();
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)
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);
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();
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.
1248
1268
cmp_ror_scan_info()
1249
1269
a ptr to first compared value
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)
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;
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)
1300
1320
/* Auxiliary structure for incremental ROR-intersection creation */
1301
typedef struct st_ror_intersect_info
1303
st_ror_intersect_info()
1310
index_scan_costs(0.0),
1314
st_ror_intersect_info(const optimizer::Parameter *in_param)
1317
covered_fields(in_param->table->getShare()->sizeFields()),
1318
out_rows(in_param->table->cursor->stats.records),
1321
index_scan_costs(0.0),
1324
covered_fields.reset();
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 */
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;
1341
Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
1344
ror_intersect_init()
1345
param Parameter from test_quick_select
1353
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
1355
ROR_INTERSECT_INFO *info;
1357
if (!(info= (ROR_INTERSECT_INFO*)param->mem_root->alloc_root(sizeof(ROR_INTERSECT_INFO))))
1360
if (!(buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1362
if (info->covered_fields.init(buf, param->table->getShare()->sizeFields()))
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();
1344
1372
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1345
1373
const ROR_INTERSECT_INFO *src)
1570
1601
each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
1571
1602
per check this gives us:
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;
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))
1584
1615
info->is_covering= true;
1588
1619
info->total_cost= info->index_scan_costs;
1589
if (! info->is_covering)
1620
if (!info->is_covering)
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)
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;
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;
1652
1683
/*I=set of all covering indexes */
1653
1684
ror_scan_mark= tree->ror_scans;
1655
boost::dynamic_bitset<> *covered_fields= ¶m->tmp_covered_fields;
1656
if (covered_fields->empty())
1686
MyBitmap *covered_fields= ¶m->tmp_covered_fields;
1687
if (! covered_fields->getBitmap())
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);
1660
covered_fields->reset();
1692
if (! covered_fields->getBitmap() ||
1693
covered_fields->init(covered_fields->getBitmap(),
1694
param->table->getShare()->sizeFields()))
1696
covered_fields->clearAll();
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.
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)
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();
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);
1687
1723
/* I=I-first(I) */
1690
1726
if (total_cost > read_time)
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(¶m->needed_fields, covered_fields);
1731
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
1698
1733
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
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)))
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;
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.
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;
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)))
1826
1861
for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1828
optimizer::RorScanInfo *scan;
1863
ROR_SCAN_INFO *scan;
1829
1864
if (! tree->ror_scans_map.test(idx))
1831
if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
1866
if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1833
1868
if (param->real_keynr[idx] == cpk_no)
1842
1877
tree->ror_scans_end= cur_ror_scan;
1844
1879
Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1845
optimizer::RorScanInfo's.
1846
1881
Step 2: Get best ROR-intersection using an approximate algorithm.
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);
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)))
1855
1890
intersect_scans_end= intersect_scans;
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)))
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)
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))
1870
1908
cur_ror_scan++;
1874
1912
*(intersect_scans_end++)= *(cur_ror_scan++);
1876
if (intersect.total_cost < min_cost)
1914
if (intersect->total_cost < min_cost)
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;
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);
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.
1899
if (cpk_scan && ! intersect.is_covering)
1937
if (cpk_scan && !intersect->is_covering)
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))
1904
1942
cpk_scan_used= true;
1905
1943
intersect_best= intersect; //just set pointer here
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)))
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)
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;
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)
3262
static uint32_t swap_clone_flag(uint32_t a)
3264
return ((a & 1) << 1) | ((a & 2) >> 1);
3267
3290
static optimizer::SEL_TREE *
3268
3291
tree_and(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
4241
4269
table_reference_st *ref,
4242
4270
ha_rows records)
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;
4278
bool create_err= false;
4250
4279
optimizer::CostVector cost;
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;
4567
4596
get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree)
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. */
5574
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5576
boost::dynamic_bitset<> map= bitsToBitset();
5577
for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5588
size_t optimizer::RorScanInfo::getBitCount() const
5590
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5591
return tmp_bitset.count();
5595
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5597
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5598
tmp_bitset-= in_bitset;
5599
covered_fields= tmp_bitset.to_ulong();
5603
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5606
uint64_t conv= covered_fields;
5609
res.push_back((conv & 1) + '0');
5614
std::reverse(res.begin(), res.end());
5616
string final(covered_fields_size - res.length(), '0');
5618
return (boost::dynamic_bitset<>(final));
5622
5603
} /* namespace drizzled */