227
class RANGE_OPT_PARAM;
229
A construction block of the SEL_ARG-graph.
231
The following description only covers graphs of SEL_ARG objects with
232
sel_arg->type==KEY_RANGE:
234
One SEL_ARG object represents an "elementary interval" in form
236
min_value <=? table.keypartX <=? max_value
238
The interval is a non-empty interval of any kind: with[out] minimum/maximum
239
bound, [half]open/closed, single-point interval, etc.
241
1. SEL_ARG GRAPH STRUCTURE
243
SEL_ARG objects are linked together in a graph. The meaning of the graph
244
is better demostrated by an example:
249
| part=1 $ part=2 $ part=3
251
| +-------+ $ +-------+ $ +--------+
252
| | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
253
| +-------+ $ +-------+ $ +--------+
259
\->| kp1=2 |--$--------------$-+
260
+-------+ $ $ | +--------+
262
+-------+ $ $ | +--------+
263
| kp1=3 |--$--------------$-+ |
264
+-------+ $ $ +--------+
268
The entire graph is partitioned into "interval lists".
270
An interval list is a sequence of ordered disjoint intervals over the same
271
key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
272
all intervals in the list form an RB-tree, linked via left/right/parent
273
pointers. The RB-tree root SEL_ARG object will be further called "root of the
276
In the example pic, there are 4 interval lists:
277
"kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
278
The vertical lines represent SEL_ARG::next/prev pointers.
280
In an interval list, each member X may have SEL_ARG::next_key_part pointer
281
pointing to the root of another interval list Y. The pointed interval list
282
must cover a key part with greater number (i.e. Y->part > X->part).
284
In the example pic, the next_key_part pointers are represented by
287
2. SEL_ARG GRAPH SEMANTICS
289
It represents a condition in a special form (we don't have a name for it ATM)
290
The SEL_ARG::next/prev is "OR", and next_key_part is "AND".
292
For example, the picture represents the condition in form:
293
(kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
294
(kp1=2 AND (kp3=11 OR kp3=14)) OR
295
(kp1=3 AND (kp3=11 OR kp3=14))
300
Use get_mm_tree() to construct SEL_ARG graph from WHERE condition.
301
Then walk the SEL_ARG graph and get a list of dijsoint ordered key
302
intervals (i.e. intervals in form
304
(constA1, .., const1_K) < (keypart1,.., keypartK) < (constB1, .., constB_K)
306
Those intervals can be used to access the index. The uses are in:
307
- check_quick_select() - Walk the SEL_ARG graph and find an estimate of
308
how many table records are contained within all
310
- get_quick_select() - Walk the SEL_ARG, materialize the key intervals,
311
and create QuickRangeSelect object that will
312
read records within these intervals.
314
4. SPACE COMPLEXITY NOTES
316
SEL_ARG graph is a representation of an ordered disjoint sequence of
317
intervals over the ordered set of index tuple values.
319
For multi-part keys, one can construct a WHERE expression such that its
320
list of intervals will be of combinatorial size. Here is an example:
322
(keypart1 IN (1,2, ..., n1)) AND
323
(keypart2 IN (1,2, ..., n2)) AND
324
(keypart3 IN (1,2, ..., n3))
326
For this WHERE clause the list of intervals will have n1*n2*n3 intervals
329
(keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
331
SEL_ARG graph structure aims to reduce the amount of required space by
332
"sharing" the elementary intervals when possible (the pic at the
333
beginning of this comment has examples of such sharing). The sharing may
334
prevent combinatorial blowup:
336
There are WHERE clauses that have combinatorial-size interval lists but
337
will be represented by a compact SEL_ARG graph.
339
(keypartN IN (1,2, ..., n1)) AND
341
(keypart2 IN (1,2, ..., n2)) AND
342
(keypart1 IN (1,2, ..., n3))
344
but not in all cases:
346
- There are WHERE clauses that do have a compact SEL_ARG-graph
347
representation but get_mm_tree() and its callees will construct a
348
graph of combinatorial size.
350
(keypart1 IN (1,2, ..., n1)) AND
351
(keypart2 IN (1,2, ..., n2)) AND
353
(keypartN IN (1,2, ..., n3))
355
- There are WHERE clauses for which the minimal possible SEL_ARG graph
356
representation will have combinatorial size.
358
By induction: Let's take any interval on some keypart in the middle:
362
Then let's AND it with this interval 'structure' from preceding and
365
(kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
367
We will obtain this SEL_ARG graph:
371
+---------+ $ +---------+ $ +---------+
372
| kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
373
+---------+ $ +---------+ $ +---------+
375
+---------+ $ +---------+ $
376
| kp14=c2 |--$-->| kp15=c0 | $
377
+---------+ $ +---------+ $
380
Note that we had to duplicate "kp15=c0" and there was no way to avoid
382
The induction step: AND the obtained expression with another "wrapping"
384
When the process ends because of the limit on max. number of keyparts
387
WHERE clause length is O(3*#max_keyparts)
388
SEL_ARG graph size is O(2^(#max_keyparts/2))
390
(it is also possible to construct a case where instead of 2 in 2^n we
391
have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
394
We avoid consuming too much memory by setting a limit on the number of
395
SEL_ARG object we can construct during one range analysis invocation.
398
class SEL_ARG :public Sql_alloc
401
uint8_t min_flag,max_flag,maybe_flag;
402
uint8_t part; // Which key part
405
Number of children of this element in the RB-tree, plus 1 for this
410
Valid only for elements which are RB-tree roots: Number of times this
411
RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
412
SEL_TREE::keys[i] or by a temporary SEL_ARG* variable)
417
unsigned char *min_value,*max_value; // Pointer to range
420
eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
422
SEL_ARG *left,*right; /* R-B tree children */
423
SEL_ARG *next,*prev; /* Links for bi-directional interval list */
424
SEL_ARG *parent; /* R-B tree parent */
425
SEL_ARG *next_key_part;
426
enum leaf_color { BLACK,RED } color;
427
enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
429
enum { MAX_SEL_ARGS = 16000 };
435
SEL_ARG(Field *,const unsigned char *, const unsigned char *);
437
SEL_ARG(Field *field,
439
unsigned char *min_value,
440
unsigned char *max_value,
445
SEL_ARG(enum Type type_arg)
457
inline bool is_same(SEL_ARG *arg)
459
if (type != arg->type || part != arg->part)
461
if (type != KEY_RANGE)
463
return (cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0);
466
inline void merge_flags(SEL_ARG *arg)
468
maybe_flag|= arg->maybe_flag;
471
inline void maybe_smaller()
476
/* Return true iff it's a single-point null interval */
477
inline bool is_null_interval()
479
return (maybe_null && max_value[0] == 1);
482
inline int cmp_min_to_min(SEL_ARG *arg)
484
return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
487
inline int cmp_min_to_max(SEL_ARG *arg)
489
return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
492
inline int cmp_max_to_max(SEL_ARG *arg)
494
return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
497
inline int cmp_max_to_min(SEL_ARG *arg)
499
return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
502
SEL_ARG *clone_and(SEL_ARG *arg)
503
{ // Get overlapping range
504
unsigned char *new_min= NULL;
505
unsigned char *new_max= NULL;
509
if (cmp_min_to_min(arg) >= 0)
516
new_min=arg->min_value; flag_min=arg->min_flag;
518
if (cmp_max_to_max(arg) <= 0)
525
new_max= arg->max_value;
526
flag_max= arg->max_flag;
528
return (new SEL_ARG(field,
534
test(maybe_flag && arg->maybe_flag)));
537
SEL_ARG *clone_first(SEL_ARG *arg)
538
{ // min <= X < arg->min
539
return (new SEL_ARG(field,part,
543
arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
544
maybe_flag | arg->maybe_flag));
547
SEL_ARG *clone_last(SEL_ARG *arg)
548
{ // min <= X <= key_max
549
return (new SEL_ARG(field,
555
maybe_flag | arg->maybe_flag));
558
SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
560
bool copy_min(SEL_ARG *arg)
561
{ // Get overlapping range
562
if (cmp_min_to_min(arg) > 0)
564
min_value= arg->min_value;
565
min_flag=arg->min_flag;
566
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
567
(NO_MAX_RANGE | NO_MIN_RANGE))
569
return 1; // Full range
572
maybe_flag|= arg->maybe_flag;
576
bool copy_max(SEL_ARG *arg)
577
{ // Get overlapping range
578
if (cmp_max_to_max(arg) <= 0)
580
max_value= arg->max_value;
581
max_flag= arg->max_flag;
582
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
583
(NO_MAX_RANGE | NO_MIN_RANGE))
585
return 1; // Full range
588
maybe_flag|= arg->maybe_flag;
592
void copy_min_to_min(SEL_ARG *arg)
594
min_value= arg->min_value;
595
min_flag= arg->min_flag;
598
void copy_min_to_max(SEL_ARG *arg)
600
max_value= arg->min_value;
601
max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
604
void copy_max_to_min(SEL_ARG *arg)
606
min_value= arg->max_value;
607
min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
610
/* returns a number of keypart values (0 or 1) appended to the key buffer */
611
int store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
613
/* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
614
if ((! (min_flag & NO_MIN_RANGE) &&
615
! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
617
if (maybe_null && *min_value)
620
memset(*min_key+1, 0, length-1);
624
memcpy(*min_key,min_value,length);
632
/* returns a number of keypart values (0 or 1) appended to the key buffer */
633
int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
635
if (! (max_flag & NO_MAX_RANGE) &&
636
! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
638
if (maybe_null && *max_value)
641
memset(*max_key + 1, 0, length-1);
645
memcpy(*max_key,max_value,length);
653
/* returns a number of keypart values appended to the key buffer */
654
int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
656
SEL_ARG *key_tree= first();
657
uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
660
*range_key_flag|= key_tree->min_flag;
662
if (key_tree->next_key_part &&
663
key_tree->next_key_part->part == key_tree->part+1 &&
664
! (*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
665
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
667
res+= key_tree->next_key_part->store_min_key(key,
674
/* returns a number of keypart values appended to the key buffer */
675
int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
677
SEL_ARG *key_tree= last();
678
uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
681
(*range_key_flag)|= key_tree->max_flag;
682
if (key_tree->next_key_part &&
683
key_tree->next_key_part->part == key_tree->part+1 &&
684
! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
685
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
686
res+= key_tree->next_key_part->store_max_key(key,
692
SEL_ARG *insert(SEL_ARG *key);
693
SEL_ARG *tree_delete(SEL_ARG *key);
694
SEL_ARG *find_range(SEL_ARG *key);
695
SEL_ARG *rb_insert(SEL_ARG *leaf);
697
friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
699
friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
700
void test_use_count(SEL_ARG *root);
706
inline bool simple_key()
708
return (! next_key_part && elements == 1);
711
void increment_use_count(long count)
715
next_key_part->use_count+= count;
716
count*= (next_key_part->use_count - count);
717
for (SEL_ARG *pos= next_key_part->first(); pos; pos= pos->next)
718
if (pos->next_key_part)
719
pos->increment_use_count(count);
725
for (SEL_ARG *pos= first(); pos; pos= pos->next)
726
if (pos->next_key_part)
728
pos->next_key_part->use_count--;
729
pos->next_key_part->free_tree();
733
inline SEL_ARG **parent_ptr()
735
return parent->left == this ? &parent->left : &parent->right;
740
Check if this SEL_ARG object represents a single-point interval
746
Check if this SEL_ARG object (not tree) represents a single-point
747
interval, i.e. if it represents a "keypart = const" or
751
true This SEL_ARG object represents a singlepoint interval
755
bool is_singlepoint()
758
Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
759
flags, and the same for right edge.
761
if (min_flag || max_flag)
763
unsigned char *min_val= min_value;
764
unsigned char *max_val= max_value;
768
/* First byte is a NULL value indicator */
769
if (*min_val != *max_val)
773
return true; /* This "x IS NULL" */
777
return ! field->key_cmp(min_val, max_val);
780
SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
783
227
class SEL_IMERGE;
1584
SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
1587
min_flag=arg.min_flag;
1588
max_flag=arg.max_flag;
1589
maybe_flag=arg.maybe_flag;
1590
maybe_null=arg.maybe_null;
1593
min_value=arg.min_value;
1594
max_value=arg.max_value;
1595
next_key_part=arg.next_key_part;
1596
use_count=1; elements=1;
1600
inline void SEL_ARG::make_root()
1602
left=right= &null_element;
1605
use_count=0; elements=1;
1608
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1609
const unsigned char *max_value_arg)
1610
:min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
1611
elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
1612
max_value((unsigned char*) max_value_arg), next(0),prev(0),
1613
next_key_part(0),color(BLACK),type(KEY_RANGE)
1615
left=right= &null_element;
1618
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1619
unsigned char *min_value_, unsigned char *max_value_,
1620
uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
1621
:min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1622
part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1623
field(field_), min_value(min_value_), max_value(max_value_),
1624
next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
1626
left=right= &null_element;
1629
SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
1634
/* Bail out if we have already generated too many SEL_ARGs */
1635
if (++param->alloced_sel_args > MAX_SEL_ARGS)
1638
if (type != KEY_RANGE)
1640
if (!(tmp= new (param->mem_root) SEL_ARG(type)))
1641
return 0; // out of memory
1642
tmp->prev= *next_arg; // Link into next/prev chain
1643
(*next_arg)->next=tmp;
1648
if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
1649
min_flag, max_flag, maybe_flag)))
1651
tmp->parent=new_parent;
1652
tmp->next_key_part=next_key_part;
1653
if (left != &null_element)
1654
if (!(tmp->left=left->clone(param, tmp, next_arg)))
1657
tmp->prev= *next_arg; // Link into next/prev chain
1658
(*next_arg)->next=tmp;
1661
if (right != &null_element)
1662
if (!(tmp->right= right->clone(param, tmp, next_arg)))
1665
increment_use_count(1);
1667
tmp->elements= this->elements;
1671
SEL_ARG *SEL_ARG::first()
1673
SEL_ARG *next_arg=this;
1674
if (!next_arg->left)
1675
return 0; // MAYBE_KEY
1676
while (next_arg->left != &null_element)
1677
next_arg=next_arg->left;
1681
SEL_ARG *SEL_ARG::last()
1683
SEL_ARG *next_arg=this;
1684
if (!next_arg->right)
1685
return 0; // MAYBE_KEY
1686
while (next_arg->right != &null_element)
1687
next_arg=next_arg->right;
1693
Check if a compare is ok, when one takes ranges in account
1694
Returns -2 or 2 if the ranges where 'joined' like < 2 and >= 2
1697
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
1701
/* First check if there was a compare to a min or max element */
1702
if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1704
if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
1705
(b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
1707
return (a_flag & NO_MIN_RANGE) ? -1 : 1;
1709
if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1710
return (b_flag & NO_MIN_RANGE) ? 1 : -1;
1712
if (field->real_maybe_null()) // If null is part of key
1719
goto end; // NULL where equal
1720
a++; b++; // Skip NULL marker
1722
cmp=field->key_cmp(a , b);
1723
if (cmp) return cmp < 0 ? -1 : 1; // The values differed
1725
// Check if the compared equal arguments was defined with open/closed range
1727
if (a_flag & (NEAR_MIN | NEAR_MAX))
1729
if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
1731
if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
1732
return (a_flag & NEAR_MIN) ? 2 : -2;
1733
return (a_flag & NEAR_MIN) ? 1 : -1;
1735
if (b_flag & (NEAR_MIN | NEAR_MAX))
1736
return (b_flag & NEAR_MIN) ? -2 : 2;
1737
return 0; // The elements where equal
1741
SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
1743
SEL_ARG tmp_link,*next_arg,*root;
1744
next_arg= &tmp_link;
1745
if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
1747
next_arg->next=0; // Fix last link
1748
tmp_link.next->prev=0; // Fix first link
1749
if (root) // If not OOM
1756
979
Find the best index to retrieve first N records in given order
5288
4539
// Add tree at key2 to tree at key1
5289
bool key2_shared=key2->use_count != 0;
5290
key1->maybe_flag|=key2->maybe_flag;
4540
bool key2_shared= key2->use_count != 0;
4541
key1->maybe_flag|= key2->maybe_flag;
5292
4543
for (key2=key2->first(); key2; )
5294
SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
4545
optimizer::SEL_ARG *tmp= key1->find_range(key2); // Find key1.min <= key2.min
5299
tmp=key1->first(); // tmp.min > key2.min
4550
tmp=key1->first(); // tmp.min > key2.min
5302
4553
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
5303
4554
{ // Found tmp.max < key2.min
5304
SEL_ARG *next=tmp->next;
4555
optimizer::SEL_ARG *next= tmp->next;
5305
4556
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5307
// Join near ranges like tmp.max < 0 and key2.min >= 0
5308
SEL_ARG *key2_next=key2->next;
5311
if (!(key2=new SEL_ARG(*key2)))
5312
return 0; // out of memory
5313
key2->increment_use_count(key1->use_count+1);
5314
key2->next=key2_next; // New copy of key2
5316
key2->copy_min(tmp);
5317
if (!(key1=key1->tree_delete(tmp)))
5318
{ // Only one key in tree
4558
// Join near ranges like tmp.max < 0 and key2.min >= 0
4559
optimizer::SEL_ARG *key2_next=key2->next;
4562
if (! (key2=new optimizer::SEL_ARG(*key2)))
4563
return 0; // out of memory
4564
key2->increment_use_count(key1->use_count+1);
4565
key2->next= key2_next; // New copy of key2
4567
key2->copy_min(tmp);
4568
if (! (key1=key1->tree_delete(tmp)))
4569
{ // Only one key in tree
5325
if (!(tmp=next)) // tmp.min > key2.min
5326
break; // Copy rest of key2
4576
if (! (tmp= next)) // tmp.min > key2.min
4577
break; // Copy rest of key2
5329
4580
{ // tmp.min > key2.min
5331
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
4582
if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
5333
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5334
{ // ranges are connected
5335
tmp->copy_min_to_min(key2);
5336
key1->merge_flags(key2);
5337
if (tmp->min_flag & NO_MIN_RANGE &&
5338
tmp->max_flag & NO_MAX_RANGE)
5340
if (key1->maybe_flag)
5341
return new SEL_ARG(SEL_ARG::MAYBE_KEY);
5344
key2->increment_use_count(-1); // Free not used tree
5350
SEL_ARG *next=key2->next; // Keys are not overlapping
5353
SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
5356
key1=key1->insert(cpy);
5357
key2->increment_use_count(key1->use_count+1);
5360
key1=key1->insert(key2); // Will destroy key2_root
4584
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
4585
{ // ranges are connected
4586
tmp->copy_min_to_min(key2);
4587
key1->merge_flags(key2);
4588
if (tmp->min_flag & NO_MIN_RANGE &&
4589
tmp->max_flag & NO_MAX_RANGE)
4591
if (key1->maybe_flag)
4592
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
4595
key2->increment_use_count(-1); // Free not used tree
4601
optimizer::SEL_ARG *next= key2->next; // Keys are not overlapping
4604
optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2); // Must make copy
4607
key1= key1->insert(cpy);
4608
key2->increment_use_count(key1->use_count+1);
4611
key1= key1->insert(key2); // Will destroy key2_root
5370
4621
if (tmp->is_same(key2))
5372
tmp->merge_flags(key2); // Copy maybe flags
5373
key2->increment_use_count(-1); // Free not used tree
4623
tmp->merge_flags(key2); // Copy maybe flags
4624
key2->increment_use_count(-1); // Free not used tree
5378
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
5379
eq_tree(last->next->next_key_part,key2->next_key_part))
5383
key1=key1->tree_delete(save);
4628
optimizer::SEL_ARG *last= tmp;
4629
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
4630
eq_tree(last->next->next_key_part,key2->next_key_part))
4632
optimizer::SEL_ARG *save= last;
4634
key1= key1->tree_delete(save);
5385
4636
last->copy_min(tmp);
5386
if (last->copy_min(key2) || last->copy_max(key2))
5389
for (; key2 ; key2=key2->next)
5390
key2->increment_use_count(-1); // Free not used tree
5391
if (key1->maybe_flag)
5392
return new SEL_ARG(SEL_ARG::MAYBE_KEY);
4637
if (last->copy_min(key2) || last->copy_max(key2))
4640
for (; key2; key2= key2->next)
4641
key2->increment_use_count(-1); // Free not used tree
4642
if (key1->maybe_flag)
4643
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
5400
4651
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
5401
4652
{ // tmp.min <= x < key2.min
5402
SEL_ARG *new_arg=tmp->clone_first(key2);
4653
optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
5405
4656
if ((new_arg->next_key_part= key1->next_key_part))
5406
new_arg->increment_use_count(key1->use_count+1);
4657
new_arg->increment_use_count(key1->use_count+1);
5407
4658
tmp->copy_min_to_min(key2);
5408
key1=key1->insert(new_arg);
4659
key1= key1->insert(new_arg);
5411
4662
// tmp.min >= key2.min && tmp.min <= key2.max
5412
SEL_ARG key(*key2); // Get copy we can modify
4663
optimizer::SEL_ARG key(*key2); // Get copy we can modify
5415
4666
if (tmp->cmp_min_to_min(&key) > 0)
5416
4667
{ // key.min <= x < tmp.min
5417
SEL_ARG *new_arg=key.clone_first(tmp);
5420
if ((new_arg->next_key_part=key.next_key_part))
5421
new_arg->increment_use_count(key1->use_count+1);
5422
key1=key1->insert(new_arg);
4668
optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
4671
if ((new_arg->next_key_part=key.next_key_part))
4672
new_arg->increment_use_count(key1->use_count+1);
4673
key1= key1->insert(new_arg);
5424
4675
if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
5425
4676
{ // tmp.min. <= x <= tmp.max
5426
tmp->maybe_flag|= key.maybe_flag;
5427
key.increment_use_count(key1->use_count+1);
5428
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5429
if (!cmp) // Key2 is ready
5431
key.copy_max_to_min(tmp);
5432
if (!(tmp=tmp->next))
5434
SEL_ARG *tmp2= new SEL_ARG(key);
5437
key1=key1->insert(tmp2);
5441
if (tmp->cmp_min_to_max(&key) > 0)
5443
SEL_ARG *tmp2= new SEL_ARG(key);
5446
key1=key1->insert(tmp2);
4677
tmp->maybe_flag|= key.maybe_flag;
4678
key.increment_use_count(key1->use_count+1);
4679
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4680
if (! cmp) // Key2 is ready
4682
key.copy_max_to_min(tmp);
4683
if (! (tmp= tmp->next))
4685
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4688
key1= key1->insert(tmp2);
4692
if (tmp->cmp_min_to_max(&key) > 0)
4694
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4697
key1= key1->insert(tmp2);
5452
SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
5455
tmp->copy_max_to_min(&key);
5456
tmp->increment_use_count(key1->use_count+1);
5457
/* Increment key count as it may be used for next loop */
5458
key.increment_use_count(1);
5459
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5460
key1=key1->insert(new_arg);
4703
optimizer::SEL_ARG *new_arg= tmp->clone_last(&key); // tmp.min <= x <= key.max
4706
tmp->copy_max_to_min(&key);
4707
tmp->increment_use_count(key1->use_count+1);
4708
/* Increment key count as it may be used for next loop */
4709
key.increment_use_count(1);
4710
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4711
key1= key1->insert(new_arg);
5470
SEL_ARG *next=key2->next;
4721
optimizer::SEL_ARG *next= key2->next;
5471
4722
if (key2_shared)
5473
SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
4724
optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2); // Must make copy
5476
4727
key2->increment_use_count(key1->use_count+1);
5477
key1=key1->insert(tmp);
4728
key1= key1->insert(tmp);
5480
key1=key1->insert(key2); // Will destroy key2_root
4731
key1= key1->insert(key2); // Will destroy key2_root
5483
4734
key1->use_count++;
5488
4739
/* Compare if two trees are equal */
5490
static bool eq_tree(SEL_ARG* a,SEL_ARG *b)
4740
static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
5494
if (!a || !b || !a->is_same(b))
5496
if (a->left != &null_element && b->left != &null_element)
5498
if (!eq_tree(a->left,b->left))
5501
else if (a->left != &null_element || b->left != &null_element)
5503
if (a->right != &null_element && b->right != &null_element)
5505
if (!eq_tree(a->right,b->right))
5508
else if (a->right != &null_element || b->right != &null_element)
4747
if (! a || ! b || ! a->is_same(b))
4752
if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
4754
if (! eq_tree(a->left,b->left))
4757
else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
4762
if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
4764
if (! eq_tree(a->right,b->right))
4767
else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
5510
4772
if (a->next_key_part != b->next_key_part)
5512
if (!a->next_key_part != !b->next_key_part ||
5513
!eq_tree(a->next_key_part, b->next_key_part))
5521
SEL_ARG::insert(SEL_ARG *key)
5523
SEL_ARG *element, **par= NULL, *last_element= NULL;
5525
for (element= this; element != &null_element ; )
5527
last_element=element;
5528
if (key->cmp_min_to_min(element) > 0)
5530
par= &element->right; element= element->right;
5534
par = &element->left; element= element->left;
5538
key->parent=last_element;
5540
if (par == &last_element->left)
5542
key->next=last_element;
5543
if ((key->prev=last_element->prev))
5544
key->prev->next=key;
5545
last_element->prev=key;
5549
if ((key->next=last_element->next))
5550
key->next->prev=key;
5551
key->prev=last_element;
5552
last_element->next=key;
5554
key->left=key->right= &null_element;
5555
SEL_ARG *root=rb_insert(key); // rebalance tree
5556
root->use_count=this->use_count; // copy root info
5557
root->elements= this->elements+1;
5558
root->maybe_flag=this->maybe_flag;
5564
** Find best key with min <= given key
5565
** Because the call context this should never return 0 to get_range
5569
SEL_ARG::find_range(SEL_ARG *key)
5571
SEL_ARG *element=this,*found=0;
5575
if (element == &null_element)
5577
int cmp=element->cmp_min_to_min(key);
5583
element=element->right;
5586
element=element->left;
5592
Remove a element from the tree
5596
key Key that is to be deleted from tree (this)
5599
This also frees all sub trees that is used by the element
5602
root of new tree (with key deleted)
5606
SEL_ARG::tree_delete(SEL_ARG *key)
5608
enum leaf_color remove_color;
5609
SEL_ARG *root,*nod,**par,*fix_par;
5614
/* Unlink from list */
5616
key->prev->next=key->next;
5618
key->next->prev=key->prev;
5619
key->increment_use_count(-1);
5623
par=key->parent_ptr();
5625
if (key->left == &null_element)
5627
*par=nod=key->right;
5628
fix_par=key->parent;
5629
if (nod != &null_element)
5630
nod->parent=fix_par;
5631
remove_color= key->color;
5633
else if (key->right == &null_element)
5635
*par= nod=key->left;
5636
nod->parent=fix_par=key->parent;
5637
remove_color= key->color;
5641
SEL_ARG *tmp=key->next; // next bigger key (exist!)
5642
nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
5643
fix_par=tmp->parent;
5644
if (nod != &null_element)
5645
nod->parent=fix_par;
5646
remove_color= tmp->color;
5648
tmp->parent=key->parent; // Move node in place of key
5649
(tmp->left=key->left)->parent=tmp;
5650
if ((tmp->right=key->right) != &null_element)
5651
tmp->right->parent=tmp;
5652
tmp->color=key->color;
5654
if (fix_par == key) // key->right == key->next
5655
fix_par=tmp; // new parent of nod
5658
if (root == &null_element)
5659
return 0; // Maybe root later
5660
if (remove_color == BLACK)
5661
root=rb_delete_fixup(root,nod,fix_par);
5663
test_rb_tree(root,root->parent);
5664
#endif /* EXTRA_DEBUG */
5666
root->use_count=this->use_count; // Fix root counters
5667
root->elements=this->elements-1;
5668
root->maybe_flag=this->maybe_flag;
5673
/* Functions to fix up the tree after insert and delete */
5675
static void left_rotate(SEL_ARG **root,SEL_ARG *leaf)
5677
SEL_ARG *y=leaf->right;
5678
leaf->right=y->left;
5679
if (y->left != &null_element)
5680
y->left->parent=leaf;
5681
if (!(y->parent=leaf->parent))
5684
*leaf->parent_ptr()=y;
5689
static void right_rotate(SEL_ARG **root,SEL_ARG *leaf)
5691
SEL_ARG *y=leaf->left;
5692
leaf->left=y->right;
5693
if (y->right != &null_element)
5694
y->right->parent=leaf;
5695
if (!(y->parent=leaf->parent))
5698
*leaf->parent_ptr()=y;
5705
SEL_ARG::rb_insert(SEL_ARG *leaf)
5707
SEL_ARG *y,*par,*par2,*root;
5708
root= this; root->parent= 0;
5711
while (leaf != root && (par= leaf->parent)->color == RED)
5712
{ // This can't be root or 1 level under
5713
if (par == (par2= leaf->parent->parent)->left)
5716
if (y->color == RED)
5721
leaf->color=RED; /* And the loop continues */
5725
if (leaf == par->right)
5727
left_rotate(&root,leaf->parent);
5728
par=leaf; /* leaf is now parent to old leaf */
5732
right_rotate(&root,par2);
5739
if (y->color == RED)
5744
leaf->color=RED; /* And the loop continues */
5748
if (leaf == par->left)
5750
right_rotate(&root,par);
5755
left_rotate(&root,par2);
5762
test_rb_tree(root,root->parent);
5763
#endif /* EXTRA_DEBUG */
5769
SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key,SEL_ARG *par)
5775
while (x != root && x->color == SEL_ARG::BLACK)
5780
if (w->color == SEL_ARG::RED)
5782
w->color=SEL_ARG::BLACK;
5783
par->color=SEL_ARG::RED;
5784
left_rotate(&root,par);
5787
if (w->left->color == SEL_ARG::BLACK && w->right->color == SEL_ARG::BLACK)
5789
w->color=SEL_ARG::RED;
5794
if (w->right->color == SEL_ARG::BLACK)
5796
w->left->color=SEL_ARG::BLACK;
5797
w->color=SEL_ARG::RED;
5798
right_rotate(&root,w);
5801
w->color=par->color;
5802
par->color=SEL_ARG::BLACK;
5803
w->right->color=SEL_ARG::BLACK;
5804
left_rotate(&root,par);
5812
if (w->color == SEL_ARG::RED)
5814
w->color=SEL_ARG::BLACK;
5815
par->color=SEL_ARG::RED;
5816
right_rotate(&root,par);
5819
if (w->right->color == SEL_ARG::BLACK && w->left->color == SEL_ARG::BLACK)
5821
w->color=SEL_ARG::RED;
5826
if (w->left->color == SEL_ARG::BLACK)
5828
w->right->color=SEL_ARG::BLACK;
5829
w->color=SEL_ARG::RED;
5830
left_rotate(&root,w);
5833
w->color=par->color;
5834
par->color=SEL_ARG::BLACK;
5835
w->left->color=SEL_ARG::BLACK;
5836
right_rotate(&root,par);
5843
x->color=SEL_ARG::BLACK;
5848
/* Test that the properties for a red-black tree hold */
5851
int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
5853
int count_l,count_r;
5855
if (element == &null_element)
5856
return 0; // Found end of tree
5857
if (element->parent != parent)
5859
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Parent doesn't point at parent");
5862
if (element->color == SEL_ARG::RED &&
5863
(element->left->color == SEL_ARG::RED ||
5864
element->right->color == SEL_ARG::RED))
5866
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found two red in a row");
5869
if (element->left == element->right && element->left != &null_element)
5871
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found right == left");
5874
count_l=test_rb_tree(element->left,element);
5875
count_r=test_rb_tree(element->right,element);
5876
if (count_l >= 0 && count_r >= 0)
5878
if (count_l == count_r)
5879
return count_l+(element->color == SEL_ARG::BLACK);
5880
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Incorrect black-count: %d - %d",
5883
return -1; // Error, no more warnings
5888
Count how many times SEL_ARG graph "root" refers to its part "key"
5891
count_key_part_usage()
5892
root An RB-Root node in a SEL_ARG graph.
5893
key Another RB-Root node in that SEL_ARG graph.
5896
The passed "root" node may refer to "key" node via root->next_key_part,
5899
This function counts how many times the node "key" is referred (via
5900
SEL_ARG::next_key_part) by
5901
- intervals of RB-tree pointed by "root",
5902
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
5903
intervals of RB-tree pointed by "root",
5906
Here is an example (horizontal links represent next_key_part pointers,
5907
vertical links - next/prev prev pointers):
5910
|root|-----------------+
5914
+----+ +---+ $ | +---+ Here the return value
5915
| |- ... -| |---$-+--+->|key| will be 4.
5916
+----+ +---+ $ | | +---+
5921
| |---| |---------+ |
5928
Number of links to "key" from nodes reachable from "root".
5931
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
5934
for (root=root->first(); root ; root=root->next)
5936
if (root->next_key_part)
5938
if (root->next_key_part == key)
5940
if (root->next_key_part->part < key->part)
5941
count+=count_key_part_usage(root->next_key_part,key);
5949
Check if SEL_ARG::use_count value is correct
5952
SEL_ARG::test_use_count()
5953
root The root node of the SEL_ARG graph (an RB-tree root node that
5954
has the least value of sel_arg->part in the entire graph, and
5955
thus is the "origin" of the graph)
5958
Check if SEL_ARG::use_count value is correct. See the definition of
5959
use_count for what is "correct".
5962
void SEL_ARG::test_use_count(SEL_ARG *root)
5965
if (this == root && use_count != 1)
5967
errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count %lu for root",use_count);
5970
if (this->type != SEL_ARG::KEY_RANGE)
5972
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
5975
if (pos->next_key_part)
5977
ulong count=count_key_part_usage(root,pos->next_key_part);
5978
if (count > pos->next_key_part->use_count)
5980
errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count for key at 0x%lx, %lu "
5981
"should be %lu", (long unsigned int)pos,
5982
pos->next_key_part->use_count, count);
5985
pos->next_key_part->test_use_count(root);
5988
if (e_count != elements)
5989
errmsg_printf(ERRMSG_LVL_WARN, "Wrong use count: %u (should be %u) for tree at 0x%lx",
5990
e_count, elements, (long unsigned int) this);
4774
if (! a->next_key_part != ! b->next_key_part ||
4775
! eq_tree(a->next_key_part, b->next_key_part))
5995
4783
/****************************************************************************
5996
4784
MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.