diff options
author | Mattias Jonsson <mattias.jonsson@sun.com> | 2009-12-22 18:59:37 +0100 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@sun.com> | 2009-12-22 18:59:37 +0100 |
commit | 28e64daf2ddccbeb754d4204219463eddd44012f (patch) | |
tree | f9f710c1243fdf8313cb2ef3eaeeedb207dc03db /sql/sql_partition.cc | |
parent | a49b18a75c3241ff32e987e5fcee0db6df2ecf4c (diff) | |
download | mariadb-git-28e64daf2ddccbeb754d4204219463eddd44012f.tar.gz |
Bug#49742: Partition Pruning not working correctly for RANGE
Problem was when calculating the range of partitions for
pruning.
Solution was to get the calculation correct. I also simplified
it a bit for easier understanding.
mysql-test/r/partition_pruning.result:
Bug#49742: Partition Pruning not working correctly for RANGE
Added results.
mysql-test/t/partition_pruning.test:
Bug#49742: Partition Pruning not working correctly for RANGE
Added tests to prevent regressions.
sql/sql_partition.cc:
Bug#49742: Partition Pruning not working correctly for RANGE
Simplified calculation for partition id for ranges.
Easier to get right and understand.
Added comments.
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index e0697f563ea..2f22432c416 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2878,16 +2878,13 @@ int get_partition_id_range(partition_info *part_info, part_func_value-= 0x8000000000000000ULL; while (max_part_id > min_part_id) { - loc_part_id= (max_part_id + min_part_id + 1) >> 1; + loc_part_id= (max_part_id + min_part_id) / 2; if (range_array[loc_part_id] <= part_func_value) min_part_id= loc_part_id + 1; else - max_part_id= loc_part_id - 1; + max_part_id= loc_part_id; } loc_part_id= max_part_id; - if (part_func_value >= range_array[loc_part_id]) - if (loc_part_id != max_partition) - loc_part_id++; *part_id= (uint32)loc_part_id; if (loc_part_id == max_partition && part_func_value >= range_array[loc_part_id] && @@ -2961,6 +2958,7 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, bool include_endpoint) { longlong *range_array= part_info->range_int_array; + longlong part_end_val; uint max_partition= part_info->no_parts - 1; uint min_part_id= 0, max_part_id= max_partition, loc_part_id; /* Get the partitioning function value for the endpoint */ @@ -2994,46 +2992,45 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, } } - if (unsigned_flag) part_func_value-= 0x8000000000000000ULL; if (left_endpoint && !include_endpoint) part_func_value++; + + /* + Search for the partition containing part_func_value + (including the right endpoint). + */ while (max_part_id > min_part_id) { - loc_part_id= (max_part_id + min_part_id + 1) >> 1; - if (range_array[loc_part_id] <= part_func_value) + loc_part_id= (max_part_id + min_part_id) / 2; + if (range_array[loc_part_id] < part_func_value) min_part_id= loc_part_id + 1; else - max_part_id= loc_part_id - 1; + max_part_id= loc_part_id; } loc_part_id= max_part_id; - if (loc_part_id < max_partition && - part_func_value >= range_array[loc_part_id+1]) - { - loc_part_id++; - } + + /* Adjust for endpoints */ + part_end_val= range_array[loc_part_id]; if (left_endpoint) { - longlong bound= range_array[loc_part_id]; /* In case of PARTITION p VALUES LESS THAN MAXVALUE the maximum value is in the current partition. */ - if (part_func_value > bound || - (part_func_value == bound && - (!part_info->defined_max_value || loc_part_id < max_partition))) + if (part_func_value == part_end_val && + (loc_part_id < max_partition || !part_info->defined_max_value)) loc_part_id++; } else { - if (loc_part_id < max_partition) - { - if (part_func_value == range_array[loc_part_id]) - loc_part_id += test(include_endpoint); - else if (part_func_value > range_array[loc_part_id]) - loc_part_id++; - } + /* if 'WHERE <= X' and partition is LESS THAN (X) include next partition */ + if (include_endpoint && loc_part_id < max_partition && + part_func_value == part_end_val) + loc_part_id++; + + /* Right endpoint, set end after correct partition */ loc_part_id++; } DBUG_RETURN(loc_part_id); |