Commit 6592afd5 authored by Mattias Jonsson's avatar Mattias Jonsson

Bug#14342883: SELECT QUERY RETURNS NOT ALL

ROWS THAT ARE EXPECTED

For non range/list partitioned tables (i.e. HASH/KEY):

When prune_partitions finds a multi-range list
(or in this test '<>') for a field of the partition index,
even if it cannot make any use of the multi-range,
it will continue with the next field of the partition index
and use that for pruning (even if it the previous
field could not be used). This results in partitions is
pruned away, leaving partitions that only matches
the last field in the partition index, and will exclude
partitions which might match any previous fields.

Fixed by skipping rest of partitioning key fields/parts
if current key field/part could not be used.

Also notice it is the order of the fields in the CREATE TABLE
statement that triggers this bug, not the order of fields in
primary/unique key or PARTITION BY KEY ().
It must not be the last field in the partitioning expression that
is not equal (or have a non single point range).
I.e. the partitioning index is created with the same field order
as in the CREATE TABLE. And for the bug to appear
the last field must be a single point and some previous field
must be a multi-point range.
parent 51672ec2
......@@ -3071,27 +3071,28 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
ppar->cur_subpart_fields+= ppar->is_subpart_keypart[key_tree_part];
*(ppar->arg_stack_end++)= key_tree;
if (ignore_part_fields)
{
/*
We come here when a condition on the first partitioning
fields led to evaluating the partitioning condition
(due to finding a condition of the type a < const or
b > const). Thus we must ignore the rest of the
partitioning fields but we still want to analyse the
subpartitioning fields.
*/
if (key_tree->next_key_part)
res= find_used_partitions(ppar, key_tree->next_key_part);
else
res= -1;
goto pop_and_go_right;
}
if (key_tree->type == SEL_ARG::KEY_RANGE)
{
if (ppar->part_info->get_part_iter_for_interval &&
key_tree->part <= ppar->last_part_partno)
{
if (ignore_part_fields)
{
/*
We come here when a condition on the first partitioning
fields led to evaluating the partitioning condition
(due to finding a condition of the type a < const or
b > const). Thus we must ignore the rest of the
partitioning fields but we still want to analyse the
subpartitioning fields.
*/
if (key_tree->next_key_part)
res= find_used_partitions(ppar, key_tree->next_key_part);
else
res= -1;
goto pop_and_go_right;
}
/* Collect left and right bound, their lengths and flags */
uchar *min_key= ppar->cur_min_key;
uchar *max_key= ppar->cur_max_key;
......@@ -3332,6 +3333,13 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
res= -1;
goto pop_and_go_right;
}
/*
No meaning in continuing with rest of partitioning key parts.
Will try to continue with subpartitioning key parts.
*/
ppar->ignore_part_fields= true;
did_set_ignore_part_fields= true;
goto process_next_key_part;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment