1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug #48665: sql-bench's insert test fails due to wrong result

When merging ranges during calculation of the result of OR
to two range sets the current range may be obsoleted by the 
resulting merged range.
The first overlapping range can be obsoleted as well.

Fixed by moving the pointer to the first overlapping range to the
pointer of the resulting union range.
Added few comments at key places in key_or().
This commit is contained in:
Georgi Kodinov
2009-11-19 18:26:19 +02:00
parent ef564a3759
commit a4683e30ae
3 changed files with 69 additions and 2 deletions

View File

@ -6671,6 +6671,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
{ // Found tmp.max < key2.min
SEL_ARG *next=tmp->next;
/* key1 on the left of key2 non-overlapping */
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{
// Join near ranges like tmp.max < 0 and key2.min >= 0
@ -6699,6 +6700,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
int tmp_cmp;
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
{
/* tmp is on the right of key2 non-overlapping */
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{ // ranges are connected
tmp->copy_min_to_min(key2);
@ -6733,25 +6735,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
}
}
// tmp.max >= key2.min && tmp.min <= key.max (overlapping ranges)
/*
tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
key2.min <= tmp.min <= key2.max
*/
if (eq_tree(tmp->next_key_part,key2->next_key_part))
{
if (tmp->is_same(key2))
{
/*
Found exact match of key2 inside key1.
Use the relevant range in key1.
*/
tmp->merge_flags(key2); // Copy maybe flags
key2->increment_use_count(-1); // Free not used tree
}
else
{
SEL_ARG *last=tmp;
SEL_ARG *first=tmp;
/*
Find the last range in tmp that overlaps key2 and has the same
condition on the rest of the keyparts.
*/
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
eq_tree(last->next->next_key_part,key2->next_key_part))
{
/*
We've found the last overlapping key1 range in last.
This means that the ranges between (and including) the
first overlapping range (tmp) and the last overlapping range
(last) are fully nested into the current range of key2
and can safely be discarded. We just need the minimum endpoint
of the first overlapping range (tmp) so we can compare it with
the minimum endpoint of the enclosing key2 range.
*/
SEL_ARG *save=last;
last=last->next;
key1=key1->tree_delete(save);
}
last->copy_min(tmp);
/*
The tmp range (the first overlapping range) could have been discarded
by the previous loop. We should re-direct tmp to the new united range
that's taking its place.
*/
tmp= last;
last->copy_min(first);
bool full_range= last->copy_min(key2);
if (!full_range)
{