mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug#48459: valgrind errors with query using 'Range checked
for each record' There was an error in an internal structure in the range optimizer (SEL_ARG). Bad design causes parts of a data structure not to be initialized when it is in a certain state. All client code must check that this state is not present before trying to access the structure's data. Fixed by - Checking the state before trying to access data (in several places, most of which not covered by test case.) - Copying the keypart id when cloning SEL_ARGs
This commit is contained in:
@ -446,9 +446,9 @@ public:
|
||||
range_key, *range_key_flag);
|
||||
*range_key_flag|= key_tree->min_flag;
|
||||
if (key_tree->next_key_part &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
|
||||
key_tree->next_key_part->part == key_tree->part+1 &&
|
||||
!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
|
||||
!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
|
||||
res+= key_tree->next_key_part->store_min_key(key, range_key,
|
||||
range_key_flag);
|
||||
return res;
|
||||
@ -462,9 +462,9 @@ public:
|
||||
range_key, *range_key_flag);
|
||||
(*range_key_flag)|= key_tree->max_flag;
|
||||
if (key_tree->next_key_part &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
|
||||
key_tree->next_key_part->part == key_tree->part+1 &&
|
||||
!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
|
||||
!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
|
||||
res+= key_tree->next_key_part->store_max_key(key, range_key,
|
||||
range_key_flag);
|
||||
return res;
|
||||
@ -1700,6 +1700,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
|
||||
tmp->prev= *next_arg; // Link into next/prev chain
|
||||
(*next_arg)->next=tmp;
|
||||
(*next_arg)= tmp;
|
||||
tmp->part= this->part;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7290,27 +7291,25 @@ int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Count how many times SEL_ARG graph "root" refers to its part "key"
|
||||
/**
|
||||
Count how many times SEL_ARG graph "root" refers to its part "key" via
|
||||
transitive closure.
|
||||
|
||||
SYNOPSIS
|
||||
count_key_part_usage()
|
||||
root An RB-Root node in a SEL_ARG graph.
|
||||
key Another RB-Root node in that SEL_ARG graph.
|
||||
@param root An RB-Root node in a SEL_ARG graph.
|
||||
@param key Another RB-Root node in that SEL_ARG graph.
|
||||
|
||||
DESCRIPTION
|
||||
The passed "root" node may refer to "key" node via root->next_key_part,
|
||||
root->next->n
|
||||
The passed "root" node may refer to "key" node via root->next_key_part,
|
||||
root->next->n
|
||||
|
||||
This function counts how many times the node "key" is referred (via
|
||||
SEL_ARG::next_key_part) by
|
||||
- intervals of RB-tree pointed by "root",
|
||||
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
|
||||
intervals of RB-tree pointed by "root",
|
||||
- and so on.
|
||||
This function counts how many times the node "key" is referred (via
|
||||
SEL_ARG::next_key_part) by
|
||||
- intervals of RB-tree pointed by "root",
|
||||
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
|
||||
intervals of RB-tree pointed by "root",
|
||||
- and so on.
|
||||
|
||||
Here is an example (horizontal links represent next_key_part pointers,
|
||||
vertical links - next/prev prev pointers):
|
||||
Here is an example (horizontal links represent next_key_part pointers,
|
||||
vertical links - next/prev prev pointers):
|
||||
|
||||
+----+ $
|
||||
|root|-----------------+
|
||||
@ -7330,8 +7329,8 @@ int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
|
||||
... +---+ $ |
|
||||
| |------------+
|
||||
+---+ $
|
||||
RETURN
|
||||
Number of links to "key" from nodes reachable from "root".
|
||||
@return
|
||||
Number of links to "key" from nodes reachable from "root".
|
||||
*/
|
||||
|
||||
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
|
||||
@ -7586,8 +7585,8 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
|
||||
param->first_null_comp= key_tree->part+1;
|
||||
|
||||
if (key_tree->next_key_part &&
|
||||
key_tree->next_key_part->part == key_tree->part+1 &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
|
||||
key_tree->next_key_part->part == key_tree->part+1)
|
||||
{ // const key as prefix
|
||||
if (min_key_length == max_key_length &&
|
||||
!memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
|
||||
@ -7868,8 +7867,8 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
|
||||
&tmp_max_key,max_key_flag);
|
||||
|
||||
if (key_tree->next_key_part &&
|
||||
key_tree->next_key_part->part == key_tree->part+1 &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
|
||||
key_tree->next_key_part->part == key_tree->part+1)
|
||||
{ // const key as prefix
|
||||
if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
|
||||
memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
|
||||
|
Reference in New Issue
Block a user