Skip to content

Commit

Permalink
MDEV-9505: Valgrind failure in SEL_ARG::store_min,find_used_partitions
Browse files Browse the repository at this point in the history
create_partition_index_description() had wrong logic to calculate
length of the key value buffer that is used by the range optimizer.

For some reason it used MAX(partitioning_columns_len,
subpartitioning_columns_len) while it should use SUM of these values.
  • Loading branch information
spetrunia committed Feb 1, 2016
1 parent a4ff37e commit 74f15e2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 11 deletions.
18 changes: 18 additions & 0 deletions mysql-test/r/partition_pruning.result
Original file line number Diff line number Diff line change
Expand Up @@ -3467,3 +3467,21 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 PRIMARY t2 p_1000 ref PRIMARY PRIMARY 8 const 2 Using index
1 PRIMARY t1 p_1000 ALL PRIMARY NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
drop table t1,t2;
#
# MDEV-9505: Valgrind failure in SEL_ARG::store_min,find_used_partitions,...
#
create table t1 (a int, b char(10), c varchar(5), d int)
partition by range columns(a,b,c)
subpartition by key (c,d)
subpartitions 3
( partition p0 values less than (1,'abc','abc'),
partition p1 values less than (2,'abc','abc'),
partition p2 values less than (3,'abc','abc'),
partition p3 values less than (4,'abc','abc')
);
insert into t1 values (1,'a','b',1),(2,'a','b',2),(3,'a','b',3);
select * from t1 where (a = 1 AND b < 'd' AND (c = 'b' OR (c = 'c' AND d = 1)) OR
(a = 1 AND b >= 'a' AND (c = 'c' OR (c = 'd' AND d = 2))));
a b c d
1 a b 1
drop table t1;
19 changes: 19 additions & 0 deletions mysql-test/t/partition_pruning.test
Original file line number Diff line number Diff line change
Expand Up @@ -1517,3 +1517,22 @@ and dept_id in (select dept_id from t2 where COMPANY_ID = 1000);

drop table t1,t2;

--echo #
--echo # MDEV-9505: Valgrind failure in SEL_ARG::store_min,find_used_partitions,...
--echo #
create table t1 (a int, b char(10), c varchar(5), d int)
partition by range columns(a,b,c)
subpartition by key (c,d)
subpartitions 3
( partition p0 values less than (1,'abc','abc'),
partition p1 values less than (2,'abc','abc'),
partition p2 values less than (3,'abc','abc'),
partition p3 values less than (4,'abc','abc')
);

insert into t1 values (1,'a','b',1),(2,'a','b',2),(3,'a','b',3);
select * from t1 where (a = 1 AND b < 'd' AND (c = 'b' OR (c = 'c' AND d = 1)) OR
(a = 1 AND b >= 'a' AND (c = 'c' OR (c = 'd' AND d = 2))));
drop table t1;


16 changes: 5 additions & 11 deletions sql/opt_range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4931,15 +4931,14 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
Field **field= (ppar->part_fields)? part_info->part_field_array :
part_info->subpart_field_array;
bool in_subpart_fields= FALSE;
uint max_key_len= 0;
uint cur_key_len= 0;
uint total_key_len= 0;
for (uint part= 0; part < total_parts; part++, key_part++)
{
key_part->key= 0;
key_part->part= part;
key_part->length= (uint16)(*field)->key_length();
key_part->store_length= (uint16)get_partition_field_store_length(*field);
cur_key_len += key_part->store_length;
total_key_len += key_part->store_length;

DBUG_PRINT("info", ("part %u length %u store_length %u", part,
key_part->length, key_part->store_length));
Expand All @@ -4965,18 +4964,13 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
{
field= part_info->subpart_field_array;
in_subpart_fields= TRUE;
max_key_len= cur_key_len;
cur_key_len= 0;
}
}
range_par->key_parts_end= key_part;

if (cur_key_len > max_key_len)
max_key_len= cur_key_len;

max_key_len++; /* Take into account the "+1" in QUICK_RANGE::QUICK_RANGE */
if (!(range_par->min_key= (uchar*)alloc_root(alloc,max_key_len)) ||
!(range_par->max_key= (uchar*)alloc_root(alloc,max_key_len)))
total_key_len++; /* Take into account the "+1" in QUICK_RANGE::QUICK_RANGE */
if (!(range_par->min_key= (uchar*)alloc_root(alloc,total_key_len)) ||
!(range_par->max_key= (uchar*)alloc_root(alloc,total_key_len)))
{
return true;
}
Expand Down

0 comments on commit 74f15e2

Please sign in to comment.