234
class SEL_TREE :public memory::SqlAlloc
238
Starting an effort to document this field:
239
(for some i, keys[i]->type == optimizer::SEL_ARG::IMPOSSIBLE) =>
240
(type == SEL_TREE::IMPOSSIBLE)
251
SEL_TREE(enum Type type_arg) :type(type_arg) {}
252
SEL_TREE() :type(KEY)
255
memset(keys, 0, sizeof(keys));
258
Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
259
keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
260
merit in range analyzer functions (e.g. get_mm_parts) returning a
261
pointer to such SEL_TREE instead of NULL)
263
optimizer::SEL_ARG *keys[MAX_KEY];
264
key_map keys_map; /* bitmask of non-NULL elements in keys */
267
Possible ways to read rows using index_merge. The list is non-empty only
268
if type==KEY. Currently can be non empty only if keys_map.none().
270
List<SEL_IMERGE> merges;
272
/* The members below are filled/used only after get_mm_tree is done */
273
key_map ror_scans_map; /* bitmask of ROR scan-able elements in keys */
274
uint32_t n_ror_scans; /* number of set bits in ror_scans_map */
276
struct st_ror_scan_info **ror_scans; /* list of ROR key scans */
277
struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
278
/* Note that #records for each key scan is stored in table->quick_rows */
281
233
struct st_ror_scan_info;
283
static SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
235
static optimizer::SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
286
238
Item_func::Functype type,
308
260
COST_VECT *cost);
310
262
static optimizer::RangeReadPlan *get_key_scans_params(optimizer::Parameter *param,
263
optimizer::SEL_TREE *tree,
312
264
bool index_read_must_be_used,
313
265
bool update_tbl_stats,
314
266
double read_time);
317
269
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
270
optimizer::SEL_TREE *tree,
319
271
double read_time,
320
272
bool *are_all_covering);
323
275
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
276
optimizer::SEL_TREE *tree,
325
277
double read_time);
328
280
optimizer::TableReadPlan *get_best_disjunct_quick(optimizer::Parameter *param,
281
optimizer::SEL_IMERGE *imerge,
330
282
double read_time);
333
optimizer::GroupMinMaxReadPlan *get_best_group_min_max(optimizer::Parameter *param, SEL_TREE *tree);
285
optimizer::GroupMinMaxReadPlan *get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree);
335
287
static void print_sel_tree(optimizer::Parameter *param,
288
optimizer::SEL_TREE *tree,
337
289
key_map *tree_map,
338
290
const char *msg);
340
static SEL_TREE *tree_and(optimizer::RangeParameter *param, SEL_TREE *tree1, SEL_TREE *tree2);
342
static SEL_TREE *tree_or(optimizer::RangeParameter *param, SEL_TREE *tree1, SEL_TREE *tree2);
292
static optimizer::SEL_TREE *tree_and(optimizer::RangeParameter *param,
293
optimizer::SEL_TREE *tree1,
294
optimizer::SEL_TREE *tree2);
344
296
static optimizer::SEL_ARG *sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
346
static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
348
298
static optimizer::SEL_ARG *key_and(optimizer::RangeParameter *param,
349
299
optimizer::SEL_ARG *key1,
350
300
optimizer::SEL_ARG *key2,
353
303
static bool get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1);
355
static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
357
305
optimizer::SEL_ARG optimizer::null_element(optimizer::SEL_ARG::IMPOSSIBLE);
359
307
static bool null_part_in_key(KEY_PART *key_part,
360
308
const unsigned char *key,
361
309
uint32_t length);
363
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, optimizer::RangeParameter *param);
367
SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
368
a condition in the following form:
369
(t_1||t_2||...||t_N) && (next)
371
where all t_i are SEL_TREEs, next is another SEL_IMERGE and no pair
372
(t_i,t_j) contains SEL_ARGS for the same index.
374
SEL_TREE contained in SEL_IMERGE always has merges=NULL.
376
This class relies on memory manager to do the cleanup.
379
class SEL_IMERGE : public memory::SqlAlloc
381
enum { PREALLOCED_TREES= 10};
383
SEL_TREE *trees_prealloced[PREALLOCED_TREES];
384
SEL_TREE **trees; /* trees used to do index_merge */
385
SEL_TREE **trees_next; /* last of these trees */
386
SEL_TREE **trees_end; /* end of allocated space */
388
optimizer::SEL_ARG ***best_keys; /* best keys to read in SEL_TREEs */
391
trees(&trees_prealloced[0]),
393
trees_end(trees + PREALLOCED_TREES)
395
int or_sel_tree(optimizer::RangeParameter *param, SEL_TREE *tree);
396
int or_sel_tree_with_checks(optimizer::RangeParameter *param, SEL_TREE *new_tree);
397
int or_sel_imerge_with_checks(optimizer::RangeParameter *param, SEL_IMERGE* imerge);
402
Add SEL_TREE to this index_merge without any checks,
405
This function implements the following:
406
(x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs
412
int SEL_IMERGE::or_sel_tree(optimizer::RangeParameter *param, SEL_TREE *tree)
414
if (trees_next == trees_end)
416
const int realloc_ratio= 2; /* Double size for next round */
417
uint32_t old_elements= (trees_end - trees);
418
uint32_t old_size= sizeof(SEL_TREE**) * old_elements;
419
uint32_t new_size= old_size * realloc_ratio;
420
SEL_TREE **new_trees;
421
if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
423
memcpy(new_trees, trees, old_size);
425
trees_next= trees + old_elements;
426
trees_end= trees + old_elements * realloc_ratio;
428
*(trees_next++)= tree;
434
Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree,
435
combining new_tree with one of the trees in this SEL_IMERGE if they both
436
have SEL_ARGs for the same key.
439
or_sel_tree_with_checks()
440
param Parameter from SqlSelect::test_quick_select
441
new_tree SEL_TREE with type KEY or KEY_SMALLER.
444
This does the following:
445
(t_1||...||t_k)||new_tree =
447
= (t_1||...||t_k||new_tree)
449
= (t_1||....||(t_j|| new_tree)||...||t_k),
451
where t_i, y are SEL_TREEs.
452
new_tree is combined with the first t_j it has a SEL_ARG on common
453
key with. As a consequence of this, choice of keys to do index_merge
454
read may depend on the order of conditions in WHERE part of the query.
458
1 One of the trees was combined with new_tree to SEL_TREE::ALWAYS,
459
and (*this) should be discarded.
460
-1 An error occurred.
462
int SEL_IMERGE::or_sel_tree_with_checks(optimizer::RangeParameter *param, SEL_TREE *new_tree)
464
for (SEL_TREE** tree = trees;
468
if (sel_trees_can_be_ored(*tree, new_tree, param))
470
*tree = tree_or(param, *tree, new_tree);
473
if (((*tree)->type == SEL_TREE::MAYBE) ||
474
((*tree)->type == SEL_TREE::ALWAYS))
476
/* SEL_TREE::IMPOSSIBLE is impossible here */
481
/* New tree cannot be combined with any of existing trees. */
482
return or_sel_tree(param, new_tree);
487
Perform OR operation on this index_merge and supplied index_merge list.
491
1 - One of conditions in result is always true and this SEL_IMERGE
493
-1 - An error occurred
496
int SEL_IMERGE::or_sel_imerge_with_checks(optimizer::RangeParameter *param, SEL_IMERGE* imerge)
498
for (SEL_TREE** tree= imerge->trees;
499
tree != imerge->trees_next;
502
if (or_sel_tree_with_checks(param, *tree))
311
bool sel_trees_can_be_ored(optimizer::SEL_TREE *tree1,
312
optimizer::SEL_TREE *tree2,
313
optimizer::RangeParameter *param);
510
321
Perform AND operation on two index_merge lists and store result in *im1.
513
inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
324
inline void imerge_list_and_list(List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
515
326
im1->concat(im2);
520
Perform OR operation on 2 index_merge lists, storing result in first list.
523
The following conversion is implemented:
524
(a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
527
i.e. all conjuncts except the first one are currently dropped.
528
This is done to avoid producing N*K ways to do index_merge.
530
If (a_1||b_1) produce a condition that is always true, NULL is returned
531
and index_merge is discarded (while it is actually possible to try
534
As a consequence of this, choice of keys to do index_merge read may depend
535
on the order of conditions in WHERE part of the query.
538
0 OK, result is stored in *im1
539
other Error, both passed lists are unusable
542
static int imerge_list_or_list(optimizer::RangeParameter *param,
543
List<SEL_IMERGE> *im1,
544
List<SEL_IMERGE> *im2)
546
SEL_IMERGE *imerge= im1->head();
548
im1->push_back(imerge);
550
return imerge->or_sel_imerge_with_checks(param, im2->head());
555
Perform OR operation on index_merge list and key tree.
558
0 OK, result is stored in *im1.
562
static int imerge_list_or_tree(optimizer::RangeParameter *param,
563
List<SEL_IMERGE> *im1,
567
List_iterator<SEL_IMERGE> it(*im1);
568
while ((imerge= it++))
570
if (imerge->or_sel_tree_with_checks(param, tree))
573
return im1->is_empty();
577
330
/***************************************************************************
578
331
** Basic functions for SqlSelect and QuickRangeSelect
579
332
***************************************************************************/
3593
Check if two SEL_TREES can be combined into one (i.e. a single key range
3594
read can be constructed for "cond_of_tree1 OR cond_of_tree2" ) without
3598
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
3599
optimizer::RangeParameter* param)
3601
key_map common_keys= tree1->keys_map;
3602
common_keys&= tree2->keys_map;
3604
if (common_keys.none())
3607
/* trees have a common key, check if they refer to same key part */
3608
optimizer::SEL_ARG **key1,**key2;
3609
for (uint32_t key_no=0; key_no < param->keys; key_no++)
3611
if (common_keys.test(key_no))
3613
key1= tree1->keys + key_no;
3614
key2= tree2->keys + key_no;
3615
if ((*key1)->part == (*key2)->part)
3626
Remove the trees that are not suitable for record retrieval.
3628
param Range analysis parameter
3629
tree Tree to be processed, tree->type is KEY or KEY_SMALLER
3632
This function walks through tree->keys[] and removes the SEL_ARG* trees
3633
that are not "maybe" trees (*) and cannot be used to construct quick range
3635
(*) - have type MAYBE or MAYBE_KEY. Perhaps we should remove trees of
3636
these types here as well.
3638
A SEL_ARG* tree cannot be used to construct quick select if it has
3639
tree->part != 0. (e.g. it could represent "keypart2 < const").
3641
WHY THIS FUNCTION IS NEEDED
3643
Normally we allow construction of SEL_TREE objects that have SEL_ARG
3644
trees that do not allow quick range select construction. For example for
3645
" keypart1=1 AND keypart2=2 " the execution will proceed as follows:
3646
tree1= SEL_TREE { SEL_ARG{keypart1=1} }
3647
tree2= SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
3649
call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
3652
There is an exception though: when we construct index_merge SEL_TREE,
3653
any SEL_ARG* tree that cannot be used to construct quick range select can
3654
be removed, because current range analysis code doesn't provide any way
3655
that tree could be later combined with another tree.
3656
Consider an example: we should not construct
3658
merges = SEL_IMERGE {
3659
SEL_TREE(t.key1part1 = 1),
3660
SEL_TREE(t.key2part2 = 2) -- (*)
3664
- (*) cannot be used to construct quick range select,
3665
- There is no execution path that would cause (*) to be converted to
3666
a tree that could be used.
3668
The latter is easy to verify: first, notice that the only way to convert
3669
(*) into a usable tree is to call tree_and(something, (*)).
3671
Second look at what tree_and/tree_or function would do when passed a
3672
SEL_TREE that has the structure like st1 tree has, and conlcude that
3673
tree_and(something, (*)) will not be called.
3676
0 Ok, some suitable trees left
3677
1 No tree->keys[] left.
3680
static bool remove_nonrange_trees(optimizer::RangeParameter *param, SEL_TREE *tree)
3683
for (uint32_t i=0; i < param->keys; i++)
3687
if (tree->keys[i]->part)
3689
tree->keys[i]= NULL;
3690
tree->keys_map.reset(i);
3701
tree_or(optimizer::RangeParameter *param,SEL_TREE *tree1,SEL_TREE *tree2)
3703
if (!tree1 || !tree2)
3705
if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
3707
if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
3709
if (tree1->type == SEL_TREE::MAYBE)
3710
return(tree1); // Can't use this
3711
if (tree2->type == SEL_TREE::MAYBE)
3714
SEL_TREE *result= 0;
3715
key_map result_keys;
3716
result_keys.reset();
3717
if (sel_trees_can_be_ored(tree1, tree2, param))
3719
/* Join the trees key per key */
3720
optimizer::SEL_ARG **key1,**key2,**end;
3721
for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ;
3722
key1 != end ; key1++,key2++)
3724
*key1=key_or(param, *key1, *key2);
3727
result=tree1; // Added to tree1
3728
result_keys.set(key1 - tree1->keys);
3732
result->keys_map= result_keys;
3736
/* ok, two trees have KEY type but cannot be used without index merge */
3737
if (tree1->merges.is_empty() && tree2->merges.is_empty())
3739
if (param->remove_jump_scans)
3741
bool no_trees= remove_nonrange_trees(param, tree1);
3742
no_trees= no_trees || remove_nonrange_trees(param, tree2);
3744
return(new SEL_TREE(SEL_TREE::ALWAYS));
3747
/* both trees are "range" trees, produce new index merge structure */
3748
if (!(result= new SEL_TREE()) || !(merge= new SEL_IMERGE()) ||
3749
(result->merges.push_back(merge)) ||
3750
(merge->or_sel_tree(param, tree1)) ||
3751
(merge->or_sel_tree(param, tree2)))
3754
result->type= tree1->type;
3756
else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
3758
if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
3759
result= new SEL_TREE(SEL_TREE::ALWAYS);
3765
/* one tree is index merge tree and another is range tree */
3766
if (tree1->merges.is_empty())
3767
std::swap(tree1, tree2);
3769
if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
3770
return(new SEL_TREE(SEL_TREE::ALWAYS));
3771
/* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
3772
if (imerge_list_or_tree(param, &tree1->merges, tree2))
3773
result= new SEL_TREE(SEL_TREE::ALWAYS);
3782
3346
/* And key trees where key1->part < key2 -> part */
3977
static optimizer::SEL_ARG *
3978
key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
3998
if (key1->part != key2->part)
4002
return 0; // Can't optimize this
4005
// If one of the key is MAYBE_KEY then the found region may be bigger
4006
if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
4012
if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
4019
if (key1->use_count > 0)
4021
if (key2->use_count == 0 || key1->elements > key2->elements)
4023
std::swap(key1,key2);
4025
if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
4029
// Add tree at key2 to tree at key1
4030
bool key2_shared= key2->use_count != 0;
4031
key1->maybe_flag|= key2->maybe_flag;
4033
for (key2=key2->first(); key2; )
4035
optimizer::SEL_ARG *tmp= key1->find_range(key2); // Find key1.min <= key2.min
4040
tmp=key1->first(); // tmp.min > key2.min
4043
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
4044
{ // Found tmp.max < key2.min
4045
optimizer::SEL_ARG *next= tmp->next;
4046
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
4048
// Join near ranges like tmp.max < 0 and key2.min >= 0
4049
optimizer::SEL_ARG *key2_next=key2->next;
4052
if (! (key2=new optimizer::SEL_ARG(*key2)))
4053
return 0; // out of memory
4054
key2->increment_use_count(key1->use_count+1);
4055
key2->next= key2_next; // New copy of key2
4057
key2->copy_min(tmp);
4058
if (! (key1=key1->tree_delete(tmp)))
4059
{ // Only one key in tree
4066
if (! (tmp= next)) // tmp.min > key2.min
4067
break; // Copy rest of key2
4070
{ // tmp.min > key2.min
4072
if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
4074
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
4075
{ // ranges are connected
4076
tmp->copy_min_to_min(key2);
4077
key1->merge_flags(key2);
4078
if (tmp->min_flag & NO_MIN_RANGE &&
4079
tmp->max_flag & NO_MAX_RANGE)
4081
if (key1->maybe_flag)
4082
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
4085
key2->increment_use_count(-1); // Free not used tree
4091
optimizer::SEL_ARG *next= key2->next; // Keys are not overlapping
4094
optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2); // Must make copy
4097
key1= key1->insert(cpy);
4098
key2->increment_use_count(key1->use_count+1);
4101
key1= key1->insert(key2); // Will destroy key2_root
4108
// tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
4109
if (eq_tree(tmp->next_key_part,key2->next_key_part))
4111
if (tmp->is_same(key2))
4113
tmp->merge_flags(key2); // Copy maybe flags
4114
key2->increment_use_count(-1); // Free not used tree
4118
optimizer::SEL_ARG *last= tmp;
4119
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
4120
eq_tree(last->next->next_key_part,key2->next_key_part))
4122
optimizer::SEL_ARG *save= last;
4124
key1= key1->tree_delete(save);
4126
last->copy_min(tmp);
4127
if (last->copy_min(key2) || last->copy_max(key2))
4130
for (; key2; key2= key2->next)
4131
key2->increment_use_count(-1); // Free not used tree
4132
if (key1->maybe_flag)
4133
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
4141
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
4142
{ // tmp.min <= x < key2.min
4143
optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
4146
if ((new_arg->next_key_part= key1->next_key_part))
4147
new_arg->increment_use_count(key1->use_count+1);
4148
tmp->copy_min_to_min(key2);
4149
key1= key1->insert(new_arg);
4152
// tmp.min >= key2.min && tmp.min <= key2.max
4153
optimizer::SEL_ARG key(*key2); // Get copy we can modify
4156
if (tmp->cmp_min_to_min(&key) > 0)
4157
{ // key.min <= x < tmp.min
4158
optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
4161
if ((new_arg->next_key_part=key.next_key_part))
4162
new_arg->increment_use_count(key1->use_count+1);
4163
key1= key1->insert(new_arg);
4165
if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
4166
{ // tmp.min. <= x <= tmp.max
4167
tmp->maybe_flag|= key.maybe_flag;
4168
key.increment_use_count(key1->use_count+1);
4169
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4170
if (! cmp) // Key2 is ready
4172
key.copy_max_to_min(tmp);
4173
if (! (tmp= tmp->next))
4175
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4178
key1= key1->insert(tmp2);
4182
if (tmp->cmp_min_to_max(&key) > 0)
4184
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4187
key1= key1->insert(tmp2);
4193
optimizer::SEL_ARG *new_arg= tmp->clone_last(&key); // tmp.min <= x <= key.max
4196
tmp->copy_max_to_min(&key);
4197
tmp->increment_use_count(key1->use_count+1);
4198
/* Increment key count as it may be used for next loop */
4199
key.increment_use_count(1);
4200
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4201
key1= key1->insert(new_arg);
4211
optimizer::SEL_ARG *next= key2->next;
4214
optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2); // Must make copy
4217
key2->increment_use_count(key1->use_count+1);
4218
key1= key1->insert(tmp);
4221
key1= key1->insert(key2); // Will destroy key2_root
4229
/* Compare if two trees are equal */
4230
static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
4237
if (! a || ! b || ! a->is_same(b))
4242
if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
4244
if (! eq_tree(a->left,b->left))
4247
else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
4252
if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
4254
if (! eq_tree(a->right,b->right))
4257
else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
4262
if (a->next_key_part != b->next_key_part)
4264
if (! a->next_key_part != ! b->next_key_part ||
4265
! eq_tree(a->next_key_part, b->next_key_part))
4273
3541
/****************************************************************************
4274
3542
MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
4275
3543
****************************************************************************/