mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
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.
This commit is contained in:
parent
ec766b5dab
commit
88546a183a
1 changed files with 24 additions and 16 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue