1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include "drizzled/sql_base.h"
23
#include "drizzled/sql_select.h"
24
#include "drizzled/memory/sql_alloc.h"
25
#include "drizzled/optimizer/range.h"
26
#include "drizzled/optimizer/range_param.h"
27
#include "drizzled/optimizer/sel_arg.h"
28
#include "drizzled/optimizer/sel_tree.h"
29
#include "drizzled/optimizer/sel_imerge.h"
32
using namespace drizzled;
34
static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
35
static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
37
bool optimizer::sel_trees_can_be_ored(optimizer::SEL_TREE *tree1,
38
optimizer::SEL_TREE *tree2,
39
optimizer::RangeParameter* param)
41
key_map common_keys= tree1->keys_map;
42
common_keys&= tree2->keys_map;
44
if (common_keys.none())
49
/* trees have a common key, check if they refer to same key part */
50
optimizer::SEL_ARG **key1,**key2;
51
for (uint32_t key_no=0; key_no < param->keys; key_no++)
53
if (common_keys.test(key_no))
55
key1= tree1->keys + key_no;
56
key2= tree2->keys + key_no;
57
if ((*key1)->part == (*key2)->part)
68
Perform OR operation on 2 index_merge lists, storing result in first list.
71
The following conversion is implemented:
72
(a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
75
i.e. all conjuncts except the first one are currently dropped.
76
This is done to avoid producing N*K ways to do index_merge.
78
If (a_1||b_1) produce a condition that is always true, NULL is returned
79
and index_merge is discarded (while it is actually possible to try
82
As a consequence of this, choice of keys to do index_merge read may depend
83
on the order of conditions in WHERE part of the query.
86
0 OK, result is stored in *im1
87
other Error, both passed lists are unusable
90
static int imerge_list_or_list(optimizer::RangeParameter *param,
91
List<optimizer::SEL_IMERGE> *im1,
92
List<optimizer::SEL_IMERGE> *im2)
94
optimizer::SEL_IMERGE *imerge= im1->head();
96
im1->push_back(imerge);
98
return imerge->or_sel_imerge_with_checks(param, im2->head());
103
Perform OR operation on index_merge list and key tree.
106
0 OK, result is stored in *im1.
110
static int imerge_list_or_tree(optimizer::RangeParameter *param,
111
List<optimizer::SEL_IMERGE> *im1,
112
optimizer::SEL_TREE *tree)
114
optimizer::SEL_IMERGE *imerge= NULL;
115
List_iterator<optimizer::SEL_IMERGE> it(*im1);
116
while ((imerge= it++))
118
if (imerge->or_sel_tree_with_checks(param, tree))
121
return im1->is_empty();
125
optimizer::SEL_TREE *
126
optimizer::tree_or(optimizer::RangeParameter *param,
127
optimizer::SEL_TREE *tree1,
128
optimizer::SEL_TREE *tree2)
130
if (! tree1 || ! tree2)
135
if (tree1->type == optimizer::SEL_TREE::IMPOSSIBLE || tree2->type == optimizer::SEL_TREE::ALWAYS)
140
if (tree2->type == optimizer::SEL_TREE::IMPOSSIBLE || tree1->type == optimizer::SEL_TREE::ALWAYS)
145
if (tree1->type == optimizer::SEL_TREE::MAYBE)
147
return tree1; // Can't use this
150
if (tree2->type == optimizer::SEL_TREE::MAYBE)
155
optimizer::SEL_TREE *result= NULL;
158
if (sel_trees_can_be_ored(tree1, tree2, param))
160
/* Join the trees key per key */
161
optimizer::SEL_ARG **key1= NULL;
162
optimizer::SEL_ARG **key2= NULL;
163
optimizer::SEL_ARG **end= NULL;
164
for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys;
168
*key1= key_or(param, *key1, *key2);
171
result= tree1; // Added to tree1
172
result_keys.set(key1 - tree1->keys);
176
result->keys_map= result_keys;
180
/* ok, two trees have KEY type but cannot be used without index merge */
181
if (tree1->merges.is_empty() && tree2->merges.is_empty())
183
if (param->remove_jump_scans)
185
bool no_trees= optimizer::remove_nonrange_trees(param, tree1);
186
no_trees= no_trees || optimizer::remove_nonrange_trees(param, tree2);
189
return (new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS));
192
optimizer::SEL_IMERGE *merge= NULL;
193
/* both trees are "range" trees, produce new index merge structure */
194
if (! (result= new optimizer::SEL_TREE()) ||
195
! (merge= new optimizer::SEL_IMERGE()) ||
196
(result->merges.push_back(merge)) ||
197
(merge->or_sel_tree(param, tree1)) ||
198
(merge->or_sel_tree(param, tree2)))
204
result->type= tree1->type;
207
else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
209
if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
210
result= new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS);
216
/* one tree is index merge tree and another is range tree */
217
if (tree1->merges.is_empty())
218
std::swap(tree1, tree2);
220
if (param->remove_jump_scans && optimizer::remove_nonrange_trees(param, tree2))
221
return(new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS));
222
/* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
223
if (imerge_list_or_tree(param, &tree1->merges, tree2))
224
result= new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS);
233
static optimizer::SEL_ARG *
234
key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
254
if (key1->part != key2->part)
258
return 0; // Can't optimize this
261
// If one of the key is MAYBE_KEY then the found region may be bigger
262
if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
268
if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
275
if (key1->use_count > 0)
277
if (key2->use_count == 0 || key1->elements > key2->elements)
279
std::swap(key1,key2);
281
if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
285
// Add tree at key2 to tree at key1
286
bool key2_shared= key2->use_count != 0;
287
key1->maybe_flag|= key2->maybe_flag;
289
for (key2=key2->first(); key2; )
291
optimizer::SEL_ARG *tmp= key1->find_range(key2); // Find key1.min <= key2.min
296
tmp=key1->first(); // tmp.min > key2.min
299
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
300
{ // Found tmp.max < key2.min
301
optimizer::SEL_ARG *next= tmp->next;
302
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
304
// Join near ranges like tmp.max < 0 and key2.min >= 0
305
optimizer::SEL_ARG *key2_next=key2->next;
308
if (! (key2=new optimizer::SEL_ARG(*key2)))
309
return 0; // out of memory
310
key2->increment_use_count(key1->use_count+1);
311
key2->next= key2_next; // New copy of key2
314
if (! (key1=key1->tree_delete(tmp)))
315
{ // Only one key in tree
322
if (! (tmp= next)) // tmp.min > key2.min
323
break; // Copy rest of key2
326
{ // tmp.min > key2.min
328
if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
330
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
331
{ // ranges are connected
332
tmp->copy_min_to_min(key2);
333
key1->merge_flags(key2);
334
if (tmp->min_flag & NO_MIN_RANGE &&
335
tmp->max_flag & NO_MAX_RANGE)
337
if (key1->maybe_flag)
338
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
341
key2->increment_use_count(-1); // Free not used tree
347
optimizer::SEL_ARG *next= key2->next; // Keys are not overlapping
350
optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2); // Must make copy
353
key1= key1->insert(cpy);
354
key2->increment_use_count(key1->use_count+1);
357
key1= key1->insert(key2); // Will destroy key2_root
364
// tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
365
if (eq_tree(tmp->next_key_part,key2->next_key_part))
367
if (tmp->is_same(key2))
369
tmp->merge_flags(key2); // Copy maybe flags
370
key2->increment_use_count(-1); // Free not used tree
374
optimizer::SEL_ARG *last= tmp;
375
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
376
eq_tree(last->next->next_key_part,key2->next_key_part))
378
optimizer::SEL_ARG *save= last;
380
key1= key1->tree_delete(save);
383
if (last->copy_min(key2) || last->copy_max(key2))
386
for (; key2; key2= key2->next)
387
key2->increment_use_count(-1); // Free not used tree
388
if (key1->maybe_flag)
389
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
397
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
398
{ // tmp.min <= x < key2.min
399
optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
402
if ((new_arg->next_key_part= key1->next_key_part))
403
new_arg->increment_use_count(key1->use_count+1);
404
tmp->copy_min_to_min(key2);
405
key1= key1->insert(new_arg);
408
// tmp.min >= key2.min && tmp.min <= key2.max
409
optimizer::SEL_ARG key(*key2); // Get copy we can modify
412
if (tmp->cmp_min_to_min(&key) > 0)
413
{ // key.min <= x < tmp.min
414
optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
417
if ((new_arg->next_key_part=key.next_key_part))
418
new_arg->increment_use_count(key1->use_count+1);
419
key1= key1->insert(new_arg);
421
if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
422
{ // tmp.min. <= x <= tmp.max
423
tmp->maybe_flag|= key.maybe_flag;
424
key.increment_use_count(key1->use_count+1);
425
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
426
if (! cmp) // Key2 is ready
428
key.copy_max_to_min(tmp);
429
if (! (tmp= tmp->next))
431
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
434
key1= key1->insert(tmp2);
438
if (tmp->cmp_min_to_max(&key) > 0)
440
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
443
key1= key1->insert(tmp2);
449
optimizer::SEL_ARG *new_arg= tmp->clone_last(&key); // tmp.min <= x <= key.max
452
tmp->copy_max_to_min(&key);
453
tmp->increment_use_count(key1->use_count+1);
454
/* Increment key count as it may be used for next loop */
455
key.increment_use_count(1);
456
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
457
key1= key1->insert(new_arg);
467
optimizer::SEL_ARG *next= key2->next;
470
optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2); // Must make copy
473
key2->increment_use_count(key1->use_count+1);
474
key1= key1->insert(tmp);
477
key1= key1->insert(key2); // Will destroy key2_root
486
Remove the trees that are not suitable for record retrieval.
488
param Range analysis parameter
489
tree Tree to be processed, tree->type is KEY or KEY_SMALLER
492
This function walks through tree->keys[] and removes the SEL_ARG* trees
493
that are not "maybe" trees (*) and cannot be used to construct quick range
495
(*) - have type MAYBE or MAYBE_KEY. Perhaps we should remove trees of
496
these types here as well.
498
A SEL_ARG* tree cannot be used to construct quick select if it has
499
tree->part != 0. (e.g. it could represent "keypart2 < const").
501
WHY THIS FUNCTION IS NEEDED
503
Normally we allow construction of optimizer::SEL_TREE objects that have SEL_ARG
504
trees that do not allow quick range select construction. For example for
505
" keypart1=1 AND keypart2=2 " the execution will proceed as follows:
506
tree1= optimizer::SEL_TREE { SEL_ARG{keypart1=1} }
507
tree2= optimizer::SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
509
call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
512
There is an exception though: when we construct index_merge optimizer::SEL_TREE,
513
any SEL_ARG* tree that cannot be used to construct quick range select can
514
be removed, because current range analysis code doesn't provide any way
515
that tree could be later combined with another tree.
516
Consider an example: we should not construct
517
st1 = optimizer::SEL_TREE {
518
merges = SEL_IMERGE {
519
optimizer::SEL_TREE(t.key1part1 = 1),
520
optimizer::SEL_TREE(t.key2part2 = 2) -- (*)
524
- (*) cannot be used to construct quick range select,
525
- There is no execution path that would cause (*) to be converted to
526
a tree that could be used.
528
The latter is easy to verify: first, notice that the only way to convert
529
(*) into a usable tree is to call tree_and(something, (*)).
531
Second look at what tree_and/tree_or function would do when passed a
532
optimizer::SEL_TREE that has the structure like st1 tree has, and conlcude that
533
tree_and(something, (*)) will not be called.
536
0 Ok, some suitable trees left
537
1 No tree->keys[] left.
539
bool optimizer::remove_nonrange_trees(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree)
542
for (uint32_t i= 0; i < param->keys; i++)
546
if (tree->keys[i]->part)
549
tree->keys_map.reset(i);
559
/* Compare if two trees are equal */
560
static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
567
if (! a || ! b || ! a->is_same(b))
572
if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
574
if (! eq_tree(a->left,b->left))
577
else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
582
if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
584
if (! eq_tree(a->right,b->right))
587
else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
592
if (a->next_key_part != b->next_key_part)
594
if (! a->next_key_part != ! b->next_key_part ||
595
! eq_tree(a->next_key_part, b->next_key_part))